diff options
2 files changed, 45 insertions, 6 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 fb687f073fc..789af2f3408 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 @@ -4841,6 +4841,25 @@ public class AST2TemplateTests extends AST2TestBase { ub= bh.assertNonProblem("f(h(args...) + args...)", 1); } + // template <typename... Args> + // struct contains_waldo; + // template <> + // struct contains_waldo<> { + // static const bool value = false; + // }; + // template <typename First, typename... Rest> + // struct contains_waldo<First, Rest...> { + // static const bool value = contains_waldo<Rest...>::value; + // }; + // int main() { + // bool b1 = contains_waldo<int>::value; + // bool b2 = contains_waldo<int, int>::value; + // bool b2 = contains_waldo<int, int, int>::value; + // } + public void testRecursiveVariadicTemplate_397828() throws Exception { + parseAndCheckBindings(); + } + // struct Test { // void Update() {} // }; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 8f8328cffa2..eeafbef7f77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -37,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; @@ -607,15 +606,36 @@ public class TemplateArgumentDeduction { final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map, IASTNode point) throws DOMException { TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(pars, null, map, 0); - final int len= a.length; - if (p == null || p.length != len) { + if (p == null) { return false; } - for (int j= 0; j < len; j++) { - if (!deduct.fromTemplateArgument(p[j], a[j], point)) { - return false; + boolean containsPackExpansion= false; + for (int j= 0; j < p.length; j++) { + if (p[j].isPackExpansion()) { + deduct = new TemplateArgumentDeduction(deduct, a.length - j); + containsPackExpansion= true; + if (j != p.length - 1) { + return false; // A pack expansion must be the last argument to the specialization. + } + ICPPTemplateArgument pattern = p[j].getExpansionPattern(); + for (int i= j; i < a.length; i++) { + if (!deduct.fromTemplateArgument(pattern, a[i], point)) { + return false; + } + deduct.incPackOffset(); + } + break; + } else { + if (j >= a.length) { + return false; // Not enough arguments. + } + if (!deduct.fromTemplateArgument(p[j], a[j], point)) { + return false; + } } } + if (!containsPackExpansion && p.length < a.length) + return false; // Too many arguments. return verifyDeduction(pars, map, false, point); } |