1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-09 10:05:24 +02:00

Bug 484786 - Name resolution problem with variadic alias template

Change-Id: If413f0241cbcf1164cb61e9fcaf371b9f899c56b
This commit is contained in:
Sergey Prigogin 2015-12-22 15:21:19 -08:00
parent 70abd7a153
commit 49b368428f
2 changed files with 93 additions and 52 deletions

View file

@ -8954,4 +8954,30 @@ public class AST2TemplateTests extends AST2TestBase {
public void testRegression_421823() throws Exception {
parseAndCheckBindings();
}
// template<typename E>
// class G {};
//
// template<typename E>
// void waldo(G<E>);
//
// template <typename T>
// struct A {
// typedef G<T> type;
// };
//
// template <typename... T>
// using B = typename A<T...>::type;
//
// template <typename T>
// class C : public B<T> {
// };
//
// void test() {
// C<int> a;
// waldo(a);
// }
public void testRecursiveTemplateClass_484786() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -233,50 +233,12 @@ public class CPPTemplates {
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
}
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
final int numArgs = arguments.length;
final int numParams= parameters.length;
final int length= Math.max(numArgs, numParams);
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
boolean isPack= false;
ICPPTemplateParameter param= null;
for (int i = 0; i < length; i++) {
if (!isPack || param == null) {
if (i < numParams) {
param= parameters[i];
isPack= param.isParameterPack();
} else {
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
}
}
if (i < numArgs) {
ICPPTemplateArgument arg= arguments[i];
ICPPTemplateArgument newArg = matchTemplateParameterAndArgument(template, param, arg, map, point);
if (newArg == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
if (newArg != arg) {
if (arguments == args) {
arguments= args.clone();
}
arguments[i]= newArg;
}
if (!isPack) {
map.put(param, newArg);
}
} else {
// Parameter pack with empty arguments.
assert isPack;
}
if (arguments == args) {
arguments= args.clone(); // The createParameterMap call may modify the arguments array.
}
if (isPack) {
int packOffset= numParams - 1;
int packSize= numArgs - packOffset;
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
System.arraycopy(arguments, packOffset, pack, 0, packSize);
map.put(param, pack);
CPPTemplateParameterMap map = createParameterMap(template, arguments, point);
if (map == null) {
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
}
ICPPTemplateInstance prim= getInstance(template, arguments, isDefinition);
@ -735,7 +697,10 @@ public class CPPTemplates {
if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args);
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
if (parameterMap == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
IType aliasedType = aliasTemplate.getType();
IBinding owner = template.getOwner();
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
@ -750,7 +715,10 @@ public class CPPTemplates {
if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args);
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
if (parameterMap == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
IType aliasedType = aliasTemplateInstance.getType();
IBinding owner = aliasTemplateInstance.getOwner();
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
@ -2866,14 +2834,61 @@ public class CPPTemplates {
return s1.equals(s2);
}
public static ICPPTemplateParameterMap createParameterMap(ICPPTemplateDefinition tdef, ICPPTemplateArgument[] args) {
ICPPTemplateParameter[] tpars= tdef.getTemplateParameters();
int len= Math.min(tpars.length, args.length);
CPPTemplateParameterMap result= new CPPTemplateParameterMap(len);
for (int i = 0; i < len; i++) {
result.put(tpars[i], args[i]);
/**
* Creates a template parameter map for the given template definition and template arguments. The template
* arguments are adjusted by converting types of the non-type arguments to match the types of the template
* parameters.
*
* @param template the template definition
* @param arguments the template arguments; arguments may be modified by this method due to type
* conversion performed for non-type arguments
* @param point the point of instantiation
* @return the created template parameter map, or {@code null} if the arguments are invalid
*/
private static CPPTemplateParameterMap createParameterMap(ICPPTemplateDefinition template,
ICPPTemplateArgument[] arguments, IASTNode point) {
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
final int numArgs = arguments.length;
final int numParams= parameters.length;
final int length= Math.max(numArgs, numParams);
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
boolean isPack= false;
ICPPTemplateParameter param= null;
for (int i = 0; i < length; i++) {
if (!isPack || param == null) {
if (i >= numParams)
return null;
param= parameters[i];
isPack= param.isParameterPack();
}
if (i < numArgs) {
ICPPTemplateArgument arg= arguments[i];
ICPPTemplateArgument newArg =
matchTemplateParameterAndArgument(template, param, arg, map, point);
if (newArg == null)
return null;
if (newArg != arg) {
arguments[i]= newArg;
}
if (!isPack) {
map.put(param, newArg);
}
} else {
// Parameter pack with empty arguments.
assert isPack;
}
}
return result;
if (isPack) {
int packOffset= numParams - 1;
int packSize= numArgs - packOffset;
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
System.arraycopy(arguments, packOffset, pack, 0, packSize);
map.put(param, pack);
}
return map;
}
/**