Bug 540676 - Improve parsing of alias templates

- If the argument for a template template paramter is unknown
(ICPPUnknownType), don't create a problem.
- Ensure that a possible argument-parameter mismatch is caught at
template instantiation time.

Change-Id: Ief61ef93f9d0c19d043aedb89f1c5e66c0374ef2
Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
Hannes Vogt 2018-11-03 22:01:29 +01:00 committed by Nathan Ridge
parent c3d4f06575
commit f9c8f0da02
2 changed files with 49 additions and 3 deletions

View file

@ -10984,4 +10984,44 @@ public class AST2TemplateTests extends AST2CPPTestBase {
public void testDependentTemplateTemplateArgument_540450() throws Exception {
parseAndCheckBindings();
}
// struct type{};
//
// template <template <class> class T1>
// using template_template_alias = type;
//
// template<typename T2>
// struct foo{
// template <typename T3>
// struct apply{};
// };
//
// template <class T4>
// using trigger = template_template_alias<foo<T4>::template apply>;
public void testAliasTemplateWithTemplateTemplateParameter_540676() throws Exception {
parseAndCheckBindings();
}
// struct type{};
//
// template <template <class, class> class T1> // number of arguments doesn't match
// using template_template_alias = type;
//
// template<typename T2>
// struct foo{
// template <typename T3>
// struct apply{};
// };
//
// template <class T4>
// using trigger = template_template_alias<foo<T4>::template apply>;
//
// using A = trigger<type>;
//
// template <typename> struct B;
// using C = B<A>;
public void testInvalidAliasTemplateWithTemplateTemplateParameter_540676() throws Exception {
BindingAssertionHelper bh= new AST2AssertionHelper(getAboveComment(), CPP);
bh.assertProblem("B<A>", 4);
}
}

View file

@ -1629,9 +1629,13 @@ public class CPPTemplates {
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} else if (args != newArgs) {
IType target = instantiateType(instance.getType(), context);
CPPTemplateParameterMap map =
instantiateArgumentMap(instance.getTemplateParameterMap(), context);
result = new CPPAliasTemplateInstance(template, target, instance.getOwner(), map, newArgs);
CPPTemplateParameterMap map = createParameterMap(template, newArgs);
if (map == null) {
result = (IType) createProblem(template,
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} else {
result = new CPPAliasTemplateInstance(template, target, instance.getOwner(), map, newArgs);
}
} else {
result = type;
}
@ -2737,6 +2741,8 @@ public class CPPTemplates {
if (param instanceof ICPPTemplateTemplateParameter) {
IType t= arg.getTypeValue();
if (t instanceof ICPPUnknownType)
return arg;
while (!(t instanceof ICPPTemplateDefinition)) {
if (t instanceof ICPPClassSpecialization) {
// Undo the effect of specializing a template when the unqualified name