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:
parent
5552a46c51
commit
9c97d4ae66
3 changed files with 102 additions and 4 deletions
|
@ -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 {};
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue