mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +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();
|
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>
|
// template <typename T>
|
||||||
// struct Struct {};
|
// struct Struct {};
|
||||||
//
|
//
|
||||||
|
|
|
@ -27,6 +27,8 @@ public class InstantiationContext {
|
||||||
private int packOffset;
|
private int packOffset;
|
||||||
private final ICPPTypeSpecialization contextTypeSpecialization;
|
private final ICPPTypeSpecialization contextTypeSpecialization;
|
||||||
private final IASTNode point;
|
private final IASTNode point;
|
||||||
|
private boolean expandPack;
|
||||||
|
private boolean packExpanded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
|
* @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() {
|
public final boolean hasPackOffset() {
|
||||||
return packOffset != -1;
|
return packOffset != -1;
|
||||||
|
@ -155,11 +157,50 @@ public class InstantiationContext {
|
||||||
this.packOffset = packOffset;
|
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)
|
* @see ICPPTemplateParameterMap#getArgument(ICPPTemplateParameter, int)
|
||||||
*/
|
*/
|
||||||
public ICPPTemplateArgument getArgument(ICPPTemplateParameter param) {
|
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;
|
int shift = packSize - 1;
|
||||||
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
|
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
|
||||||
System.arraycopy(result, 0, newResult, 0, i + resultShift);
|
System.arraycopy(result, 0, newResult, 0, i + resultShift);
|
||||||
|
context.setExpandPack(true);
|
||||||
int oldPackOffset = context.getPackOffset();
|
int oldPackOffset = context.getPackOffset();
|
||||||
for (int j= 0; j < packSize; j++) {
|
for (int j= 0; j < packSize; j++) {
|
||||||
context.setPackOffset(j);
|
context.setPackOffset(j);
|
||||||
|
@ -1334,9 +1335,18 @@ public class CPPTemplates {
|
||||||
shift = 0;
|
shift = 0;
|
||||||
break;
|
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;
|
newResult[i + resultShift + j]= newArg;
|
||||||
}
|
}
|
||||||
context.setPackOffset(oldPackOffset);
|
context.setPackOffset(oldPackOffset);
|
||||||
|
context.setExpandPack(false);
|
||||||
result= newResult;
|
result= newResult;
|
||||||
resultShift += shift;
|
resultShift += shift;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1668,7 +1678,7 @@ public class CPPTemplates {
|
||||||
ICPPTemplateArgument arg= null;
|
ICPPTemplateArgument arg= null;
|
||||||
if (tpar.isParameterPack()) {
|
if (tpar.isParameterPack()) {
|
||||||
if (context.hasPackOffset()) {
|
if (context.hasPackOffset()) {
|
||||||
ICPPTemplateArgument[] args = context.getParameterMap().getPackExpansion(tpar);
|
ICPPTemplateArgument[] args = context.getPackExpansion(tpar);
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
if (context.getPackOffset() >= args.length) {
|
if (context.getPackOffset() >= args.length) {
|
||||||
return new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE,
|
return new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
@ -1676,9 +1686,18 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
arg= args[context.getPackOffset()];
|
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 {
|
} else {
|
||||||
arg= context.getParameterMap().getArgument(tpar);
|
arg= context.getArgument(tpar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg != null) {
|
if (arg != null) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue