mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-08 01:25:23 +02:00
Bug 530086 - Instantiation of template argument where substituted argument is a pack expansion
The first patch for bug 527697 made us not instantiate such an argument, because determinePackSize() would return PACK_SIZE_DEFER. The motivation for that fix was to avoid sizeof...(T) prematurely instantiating to a concrete value in cases where T was mapped to a pack expansion. This patch reverts the change to determinePackSize() and applies a different fix for the sizeof...(T), specific to EvalUnaryTypeId. Change-Id: Idc231aeecb5d50e93dda364c6d2deb08057cc8b6
This commit is contained in:
parent
911376f775
commit
5c8a84960c
3 changed files with 67 additions and 20 deletions
|
@ -10557,7 +10557,23 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
|||
//
|
||||
// template <int... I>
|
||||
// void foo(index_sequence<I...>);
|
||||
public void testTemplateAliasWithVariadicNonTypeArgs_530086() throws Exception {
|
||||
public void testTemplateAliasWithVariadicNonTypeArgs_530086a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <int...>
|
||||
// struct integer_sequence {};
|
||||
//
|
||||
// template <int... I>
|
||||
// using index_sequence = integer_sequence<I...>;
|
||||
//
|
||||
// template <typename, int... I>
|
||||
// void bar(index_sequence<I...>);
|
||||
//
|
||||
// void foo() {
|
||||
// bar<int>(integer_sequence<0>{});
|
||||
// }
|
||||
public void testTemplateAliasWithVariadicArgs_530086b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ public class CPPTemplates {
|
|||
|
||||
// Used to indicate that two different packs with different sizes were found.
|
||||
static final int PACK_SIZE_FAIL = -2;
|
||||
|
||||
|
||||
// Used to indicate that no template parameter packs were found.
|
||||
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
||||
|
||||
|
@ -1224,14 +1224,6 @@ public class CPPTemplates {
|
|||
if (tpar.isParameterPack()) {
|
||||
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
|
||||
if (args != null) {
|
||||
// The arguments could be dependent, so they could themselves
|
||||
// contain pack expansions.
|
||||
for (ICPPTemplateArgument arg : args) {
|
||||
if (arg.isPackExpansion()) {
|
||||
return PACK_SIZE_DEFER;
|
||||
}
|
||||
}
|
||||
|
||||
return args.length;
|
||||
}
|
||||
return PACK_SIZE_DEFER;
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||
|
@ -208,17 +210,9 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
|||
@Override
|
||||
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
|
||||
if (fOperator == op_sizeofParameterPack) {
|
||||
int packSize = determinePackSize(context.getParameterMap());
|
||||
if (packSize == CPPTemplates.PACK_SIZE_FAIL || packSize == CPPTemplates.PACK_SIZE_NOT_FOUND) {
|
||||
return EvalFixed.INCOMPLETE;
|
||||
} else if (packSize != CPPTemplates.PACK_SIZE_DEFER) {
|
||||
return new EvalFixed(getType(), getValueCategory(), IntegralValue.create(packSize));
|
||||
}
|
||||
return instantiateSizeofParameterPack(context);
|
||||
}
|
||||
IType type = CPPTemplates.instantiateType(fOrigType, context);
|
||||
if (type == fOrigType)
|
||||
return this;
|
||||
return new EvalUnaryTypeID(fOperator, type, getTemplateDefinition());
|
||||
return instantiateBySubstitution(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -235,4 +229,49 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
|||
public boolean referencesTemplateParameter() {
|
||||
return CPPTemplates.isDependentType(fOrigType);
|
||||
}
|
||||
|
||||
private ICPPEvaluation instantiateBySubstitution(InstantiationContext context) {
|
||||
IType type = CPPTemplates.instantiateType(fOrigType, context);
|
||||
if (type == fOrigType)
|
||||
return this;
|
||||
return new EvalUnaryTypeID(fOperator, type, getTemplateDefinition());
|
||||
}
|
||||
|
||||
private ICPPEvaluation instantiateSizeofParameterPack(InstantiationContext context) {
|
||||
if (fOrigType instanceof ICPPTemplateParameter) {
|
||||
ICPPTemplateParameter pack = (ICPPTemplateParameter) fOrigType;
|
||||
if (pack.isParameterPack()) {
|
||||
ICPPTemplateArgument[] args = context.getPackExpansion(pack);
|
||||
if (args == null) {
|
||||
return this;
|
||||
}
|
||||
int concreteArgCount = 0;
|
||||
boolean havePackExpansion = false;
|
||||
for (ICPPTemplateArgument arg : args) {
|
||||
if (arg.isPackExpansion()) {
|
||||
havePackExpansion = true;
|
||||
} else {
|
||||
concreteArgCount++;
|
||||
}
|
||||
}
|
||||
if (havePackExpansion) {
|
||||
// TODO(bug 530103):
|
||||
// This will only handle correctly the case where there is a single argument
|
||||
// which is a pack expansion, and no concrete arguments.
|
||||
// To correctly handle cases with multiple pack expansions, or a mixture
|
||||
// of concrete arguments and pack expansions, we need to do the following:
|
||||
// - For each pack expansion, find the parameter pack P which it's
|
||||
// expanding (if it's expanding multiple parameter packs, any one
|
||||
// should be sufficient), and construct an EvalUnaryTypeId representing
|
||||
// sizeof...(P).
|
||||
// - Construct an EvalBinary tree representing the sum of |concreteArgCount|
|
||||
// and the EvalUnaryTypeIds from the previous step.
|
||||
return instantiateBySubstitution(context);
|
||||
} else {
|
||||
return new EvalFixed(getType(), getValueCategory(), IntegralValue.create(concreteArgCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
return EvalFixed.INCOMPLETE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue