1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 22:22:11 +02:00

Bug 486971 - Name resolution problem with alias template and parameter

pack

This change solves the example in the bug but I'm not sure if it works
properly in other similar cases.

Change-Id: I6fb6b0c2501ef1fcd25bb31fae019ec5ec0379f9
This commit is contained in:
Sergey Prigogin 2016-02-11 18:30:39 -08:00 committed by Gerrit Code Review @ Eclipse.org
parent 5552a46c51
commit 9c97d4ae66
3 changed files with 102 additions and 4 deletions

View file

@ -7247,6 +7247,44 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings();
}
// template<typename T>
// struct B {
// typedef T type;
// };
//
// template <class... T>
// class C {};
//
// template <class... T>
// using D = C<typename B<T>::type...>;
//
// template <class... T>
// class Group {};
//
// template <class... U>
// D<U...> waldo1(Group<U...>);
//
// template <class U, class... V>
// D<U, V...> waldo2(Group<U>, Group<V...>);
//
// template <class... U, class V>
// D<U..., V> waldo3(Group<U...>, Group<V>);
//
// template <class... U, class... V>
// D<U..., V...> waldo4(Group<U...>, Group<V...>);
//
// void test() {
// Group<int> one;
// Group<int, int> two;
// waldo1(two);
// waldo2(one, two);
// waldo3(two, one);
// waldo4(two, two);
// }
public void testAliasTemplate_486971() throws Exception {
parseAndCheckBindings();
}
// template <typename T>
// struct Struct {};
//

View file

@ -27,6 +27,8 @@ public class InstantiationContext {
private int packOffset;
private final ICPPTypeSpecialization contextTypeSpecialization;
private final IASTNode point;
private boolean expandPack;
private boolean packExpanded;
/**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
@ -135,7 +137,7 @@ public class InstantiationContext {
}
/**
* Returns true if the pack offset is specified.
* Returns {@code true} if the pack offset is specified.
*/
public final boolean hasPackOffset() {
return packOffset != -1;
@ -155,11 +157,50 @@ public class InstantiationContext {
this.packOffset = packOffset;
}
/**
* Returns {@code true} if a parameter pack should be expanded by substituting individual template
* arguments in place of a template parameter that represents a pack.
*/
public boolean shouldExpandPack() {
return expandPack;
}
/**
* Sets the flag that indicates that a parameter pack should be expanded by substituting individual
* template arguments in place of a template parameter that represents a pack.
*/
public void setExpandPack(boolean expand) {
this.expandPack = expand;
}
/**
* Returns {@code true} if individual template argument substitution in place of a template parameter that
* represents a pack actually happened.
*/
public boolean isPackExpanded() {
return packExpanded;
}
/**
* Indicates that individual template argument substitution in place of a template parameter that
* represents a pack actually happened.
*/
public void setPackExpanded(boolean expanded) {
this.packExpanded = expanded;
}
/**
* @see ICPPTemplateParameterMap#getArgument(ICPPTemplateParameter, int)
*/
public ICPPTemplateArgument getArgument(ICPPTemplateParameter param) {
return parameterMap.getArgument(param, packOffset);
return parameterMap == null ? null : parameterMap.getArgument(param, packOffset);
}
/**
* @see ICPPTemplateParameterMap#getPackExpansion(ICPPTemplateParameter)
*/
public ICPPTemplateArgument[] getPackExpansion(ICPPTemplateParameter param) {
return parameterMap == null ? null : parameterMap.getPackExpansion(param);
}
/**

View file

@ -1322,6 +1322,7 @@ public class CPPTemplates {
int shift = packSize - 1;
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift);
context.setExpandPack(true);
int oldPackOffset = context.getPackOffset();
for (int j= 0; j < packSize; j++) {
context.setPackOffset(j);
@ -1334,9 +1335,18 @@ public class CPPTemplates {
shift = 0;
break;
}
if (context.isPackExpanded()) {
IType type = newArg.getTypeValue();
if (type != null) {
type = new CPPParameterPackType(type);
newArg = new CPPTemplateTypeArgument(type);
}
context.setPackExpanded(false);
}
newResult[i + resultShift + j]= newArg;
}
context.setPackOffset(oldPackOffset);
context.setExpandPack(false);
result= newResult;
resultShift += shift;
continue;
@ -1668,7 +1678,7 @@ public class CPPTemplates {
ICPPTemplateArgument arg= null;
if (tpar.isParameterPack()) {
if (context.hasPackOffset()) {
ICPPTemplateArgument[] args = context.getParameterMap().getPackExpansion(tpar);
ICPPTemplateArgument[] args = context.getPackExpansion(tpar);
if (args != null) {
if (context.getPackOffset() >= args.length) {
return new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE,
@ -1676,9 +1686,18 @@ public class CPPTemplates {
}
arg= args[context.getPackOffset()];
}
if (context.shouldExpandPack()) {
if (arg != null) {
IType type = arg.getTypeValue();
if (type instanceof ICPPParameterPackType) {
arg = new CPPTemplateTypeArgument(((ICPPParameterPackType) type).getType());
context.setPackExpanded(true);
}
}
}
}
} else {
arg= context.getParameterMap().getArgument(tpar);
arg= context.getArgument(tpar);
}
if (arg != null) {