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 + // struct get_from_variadic_pack { + // template + // static constexpr int apply(First first, Accessors... args) { + // return get_from_variadic_pack::apply(args...); + // } + // }; + // + // template<> + // struct get_from_variadic_pack<0> { + // template + // static constexpr int apply(First first, Accessors ... args) { + // return first; + // } + // }; + // + // template + // struct static_int{ + // static constexpr int value = N; + // }; + // + // constexpr int tmp = get_from_variadic_pack<1>::apply(1,2); + // constexpr int result = static_int::value; + public void testInstantiationOfPackInNestedTemplate_540758() throws Exception { + parseAndCheckBindings(); + } + // // A metafunction that loops infinitely on odd inputs. // template // 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];