1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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.
This commit is contained in:
Marc-Andre Laperle 2023-12-27 16:44:53 -05:00 committed by GitHub
parent c1197e2504
commit 8d24554856
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 5 deletions

View file

@ -374,4 +374,37 @@ public class VariableTemplateTests extends AST2CPPTestBase {
BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableType("waldo", CommonCPPTypes.int_);
}
// template<bool _Test>
// struct enable_if {
// };
//
// template <>
// struct enable_if<true> {
// using typwe = int;
// };
//
// template <class ... _Traits>
// inline constexpr bool trait_v = true;
//
// template<class _Tx>
// struct function_impl {
// template<class ... _Traits>
// using typse = typename enable_if<trait_v<_Traits...>>::typwe;
// };
//
// template <class _Fty>
// class function : public function_impl<_Fty> {
// public:
// template<class _Fx, typename function_impl<_Fty>::template typse<> = 0>
// function(_Fx _func) {
// }
// };
//
// int main() {
// function<void> func(0);
// }
public void testVariableInstanceInImplicitName() throws Exception {
parseAndCheckImplicitNameBindings();
}
}

View file

@ -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 {