mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-09 18:15:23 +02:00
Bug 484786 - Name resolution problem with variadic alias template
Change-Id: If413f0241cbcf1164cb61e9fcaf371b9f899c56b
This commit is contained in:
parent
70abd7a153
commit
49b368428f
2 changed files with 93 additions and 52 deletions
|
@ -8954,4 +8954,30 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
public void testRegression_421823() throws Exception {
|
public void testRegression_421823() throws Exception {
|
||||||
parseAndCheckBindings();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,50 +233,12 @@ public class CPPTemplates {
|
||||||
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
|
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
if (arguments == args) {
|
||||||
final int numArgs = arguments.length;
|
arguments= args.clone(); // The createParameterMap call may modify the arguments array.
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
CPPTemplateParameterMap map = createParameterMap(template, arguments, point);
|
||||||
if (isPack) {
|
if (map == null) {
|
||||||
int packOffset= numParams - 1;
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
|
||||||
int packSize= numArgs - packOffset;
|
|
||||||
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
|
|
||||||
System.arraycopy(arguments, packOffset, pack, 0, packSize);
|
|
||||||
map.put(param, pack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ICPPTemplateInstance prim= getInstance(template, arguments, isDefinition);
|
ICPPTemplateInstance prim= getInstance(template, arguments, isDefinition);
|
||||||
|
@ -735,7 +697,10 @@ public class CPPTemplates {
|
||||||
if (args == null) {
|
if (args == null) {
|
||||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
|
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();
|
IType aliasedType = aliasTemplate.getType();
|
||||||
IBinding owner = template.getOwner();
|
IBinding owner = template.getOwner();
|
||||||
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
|
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
|
||||||
|
@ -750,7 +715,10 @@ public class CPPTemplates {
|
||||||
if (args == null) {
|
if (args == null) {
|
||||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
|
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();
|
IType aliasedType = aliasTemplateInstance.getType();
|
||||||
IBinding owner = aliasTemplateInstance.getOwner();
|
IBinding owner = aliasTemplateInstance.getOwner();
|
||||||
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
|
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id);
|
||||||
|
@ -2866,14 +2834,61 @@ public class CPPTemplates {
|
||||||
return s1.equals(s2);
|
return s1.equals(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPTemplateParameterMap createParameterMap(ICPPTemplateDefinition tdef, ICPPTemplateArgument[] args) {
|
/**
|
||||||
ICPPTemplateParameter[] tpars= tdef.getTemplateParameters();
|
* Creates a template parameter map for the given template definition and template arguments. The template
|
||||||
int len= Math.min(tpars.length, args.length);
|
* arguments are adjusted by converting types of the non-type arguments to match the types of the template
|
||||||
CPPTemplateParameterMap result= new CPPTemplateParameterMap(len);
|
* parameters.
|
||||||
for (int i = 0; i < len; i++) {
|
*
|
||||||
result.put(tpars[i], args[i]);
|
* @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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue