Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2018-01-22 03:52:53 +0000
committerNathan Ridge2018-01-28 23:37:12 +0000
commit1d9e549ae71109f97df38ded70dd548312b96023 (patch)
tree38a296e1644a055a213d86c00c84f839db093cb2 /core
parent5f9964098c21560cda659f4d81c01b57a648ad4f (diff)
downloadorg.eclipse.cdt-1d9e549ae71109f97df38ded70dd548312b96023.tar.gz
org.eclipse.cdt-1d9e549ae71109f97df38ded70dd548312b96023.tar.xz
org.eclipse.cdt-1d9e549ae71109f97df38ded70dd548312b96023.zip
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
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java59
3 files changed, 67 insertions, 20 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index fa80afde3a1..c1f8b07fbed 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -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();
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index b4915bb19c2..3ac22c11d96 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
index 41ff79f4ebe..2e3beb57384 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java
@@ -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;
+ }
}

Back to the top