Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java19
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java32
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);
}

Back to the top