Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2018-11-22 05:29:26 +0000
committerNathan Ridge2018-11-29 22:25:43 +0000
commit9e44f3634abf8e22f1950e7e10e464ccc2adbe86 (patch)
tree718c9f192baaa8ea65a195d154e88649da4de9dc
parent1a8b9a9628cccc3fdff7c097f4c78cc9157f0d7e (diff)
downloadorg.eclipse.cdt-9e44f3634abf8e22f1950e7e10e464ccc2adbe86.tar.gz
org.eclipse.cdt-9e44f3634abf8e22f1950e7e10e464ccc2adbe86.tar.xz
org.eclipse.cdt-9e44f3634abf8e22f1950e7e10e464ccc2adbe86.zip
Bug 540758 - Substitution of enclosing template parameters into expansion pattern
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java27
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java13
3 files changed, 41 insertions, 3 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 c5cc8440506..06641c1293a 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
@@ -10703,6 +10703,33 @@ public class AST2TemplateTests extends AST2CPPTestBase {
parseAndCheckBindings();
}
+ // template<int Idx>
+ // struct get_from_variadic_pack {
+ // template<typename First, typename ... Accessors>
+ // static constexpr int apply(First first, Accessors... args) {
+ // return get_from_variadic_pack<Idx - 1>::apply(args...);
+ // }
+ // };
+ //
+ // template<>
+ // struct get_from_variadic_pack<0> {
+ // template<typename First, typename ... Accessors>
+ // static constexpr int apply(First first, Accessors ... args) {
+ // return first;
+ // }
+ // };
+ //
+ // template<int N>
+ // struct static_int{
+ // static constexpr int value = N;
+ // };
+ //
+ // constexpr int tmp = get_from_variadic_pack<1>::apply(1,2);
+ // constexpr int result = static_int<tmp>::value;
+ public void testInstantiationOfPackInNestedTemplate_540758() throws Exception {
+ parseAndCheckBindings();
+ }
+
// // A metafunction that loops infinitely on odd inputs.
// template <int N>
// struct meta {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java
index 7bf07930382..952e08d75ce 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java
@@ -124,7 +124,9 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
if (packSize == CPPTemplates.PACK_SIZE_FAIL || packSize == CPPTemplates.PACK_SIZE_NOT_FOUND) {
newEval = EvalFixed.INCOMPLETE;
} else if (packSize == CPPTemplates.PACK_SIZE_DEFER) {
- newEval = origEval;
+ // We're not expanding the pack, but arguments for template parameters of
+ // enclosing templates may still need to be substituted into the expansion pattern.
+ newEval = origEval.instantiate(context, maxDepth);
} else {
int shift = packSize - 1;
ICPPEvaluation[] newResult = new ICPPEvaluation[subexpressions.length + resultShift + shift];
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 157107f088e..a2b17c0e9fd 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
@@ -1334,7 +1334,9 @@ public class CPPTemplates {
IProblemBinding.SEMANTIC_INVALID_TYPE,
types[i] instanceof IBinding ? ((IBinding) types[i]).getNameCharArray() : null);
} else if (packSize == PACK_SIZE_DEFER) {
- newType = origType;
+ // We're not expanding the pack, but arguments for template parameters of
+ // enclosing templates may still need to be substituted into the expansion pattern.
+ newType = instantiateType(origType, context);
} else {
IType[] newResult = new IType[result.length + packSize - 1];
System.arraycopy(result, 0, newResult, 0, j);
@@ -1395,7 +1397,14 @@ public class CPPTemplates {
throw new DOMException(new ProblemBinding(CPPSemantics.getCurrentLookupPoint(),
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null));
} else if (packSize == PACK_SIZE_DEFER) {
- newArg = origArg;
+ // We're not expanding the pack, but arguments for template parameters of
+ // enclosing templates may still need to be substituted into the expansion pattern.
+ newArg = instantiateArgument(origArg, context);
+ if (!isValidArgument(newArg)) {
+ if (strict)
+ return null;
+ newArg = origArg;
+ }
} else {
int shift = packSize - 1;
ICPPTemplateArgument[] newResult = new ICPPTemplateArgument[args.length + resultShift + shift];

Back to the top