From 8d245548560899a82bcf1de41daeaa44cccb717d Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Wed, 27 Dec 2023 16:44:53 -0500 Subject: [PATCH] Fix a case of variable template instance not resolved (#655) When the variable template was instantiated through an implicit name (constructor), the current look-up point was used to determine whether or not the variable instance was an explicit specialization but it's not enough. During resolution of implicit name, the look-up was on the constructor call, not on the variable instance. I'm not sure if the current look-up should be changed but we already had the information about the AST node being an explicit specialization down the stack, so we just pass that info now and it seems safer than changing the look-up point. --- .../ast2/cxx14/VariableTemplateTests.java | 33 +++++++++++++++++++ .../parser/cpp/semantics/CPPTemplates.java | 18 +++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java index df3a1b57109..7a76ce47567 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java @@ -374,4 +374,37 @@ public class VariableTemplateTests extends AST2CPPTestBase { BindingAssertionHelper helper = getAssertionHelper(); helper.assertVariableType("waldo", CommonCPPTypes.int_); } + + // template + // struct enable_if { + // }; + // + // template <> + // struct enable_if { + // using typwe = int; + // }; + // + // template + // inline constexpr bool trait_v = true; + // + // template + // struct function_impl { + // template + // using typse = typename enable_if>::typwe; + // }; + // + // template + // class function : public function_impl<_Fty> { + // public: + // template::template typse<> = 0> + // function(_Fx _func) { + // } + // }; + // + // int main() { + // function func(0); + // } + public void testVariableInstanceInImplicitName() throws Exception { + parseAndCheckImplicitNameBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index f7801bafed8..78d43af320a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -298,7 +298,8 @@ public class CPPTemplates { return result; } - return instantiatePrimaryTemplate(template, arguments, new InstantiationContext(map), isDefinition); + return instantiatePrimaryTemplate(template, arguments, new InstantiationContext(map), isDefinition, + isExplicitSpecialization); } catch (DOMException e) { return e.getProblem(); } @@ -443,7 +444,8 @@ public class CPPTemplates { * May return {@code null}. */ private static IBinding instantiatePrimaryTemplate(ICPPPartiallySpecializable template, - ICPPTemplateArgument[] arguments, InstantiationContext context, boolean isDef) throws DOMException { + ICPPTemplateArgument[] arguments, InstantiationContext context, boolean isDef, + boolean isExplicitSpecialization) throws DOMException { assert !(template instanceof ICPPClassTemplatePartialSpecialization); ICPPTemplateInstance instance = getInstance(template, arguments, isDef); if (instance != null) { @@ -451,7 +453,7 @@ public class CPPTemplates { } IBinding owner = template.getOwner(); - instance = createInstance(owner, template, context.getParameterMap(), arguments); + instance = createInstance(owner, template, context.getParameterMap(), arguments, isExplicitSpecialization); addInstance(template, arguments, instance); return instance; } @@ -899,6 +901,11 @@ public class CPPTemplates { public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template, ICPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) { + return createInstance(owner, template, tpMap, args, false); + } + + public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template, + ICPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, boolean isExplicitSpecialization) { if (owner instanceof ICPPSpecialization) { ICPPTemplateParameterMap map = ((ICPPSpecialization) owner).getTemplateParameterMap(); if (map != null) { @@ -937,8 +944,9 @@ public class CPPTemplates { IValue value; IASTNode point = CPPSemantics.getCurrentLookupPoint(); ICPPASTDeclarator decl = ASTQueries.findAncestorWithType(point, ICPPASTDeclarator.class); - if (point instanceof IASTName && ((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition - && decl != null && decl.getInitializer() != null) { + if (isExplicitSpecialization && point instanceof IASTName + && ((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition && decl != null + && decl.getInitializer() != null) { // Explicit specialization. value = SemanticUtil.getValueOfInitializer(decl.getInitializer(), type); } else {