Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java23
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java51
2 files changed, 49 insertions, 25 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 2a88223cef..bf1f8b09d8 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
@@ -4532,8 +4532,8 @@ public class AST2TemplateTests extends AST2BaseTest {
// X<A> xa; // okay
// X<B> xb; // ill-formed: default arguments for the parameters of a template template argument are ignored
// X<C> xc; // ill-formed: a template parameter pack does not match a template parameter
- // Y<A> ya; // ill-formed: a template parameter pack does not match a template parameter
- // Y<B> yb; // ill-formed: a template parameter pack does not match a template parameter
+ // Y<A> ya; // okay
+ // Y<B> yb; // okay
// Y<C> yc; // okay
public void testVariadicTemplateExamples_280909f() throws Exception {
final String code= getAboveComment();
@@ -4541,8 +4541,8 @@ public class AST2TemplateTests extends AST2BaseTest {
bh.assertNonProblem("X<A>", 4);
bh.assertProblem("X<B>", 4);
bh.assertProblem("X<C>", 4);
- bh.assertProblem("Y<A>", 4);
- bh.assertProblem("Y<B>", 4);
+ bh.assertNonProblem("Y<A>", 4);
+ bh.assertNonProblem("Y<B>", 4);
bh.assertNonProblem("Y<C>", 4);
}
@@ -5439,4 +5439,19 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testTemplateParameterWithoutName_352266() throws Exception {
parseAndCheckBindings();
}
+
+ // template<template<typename, typename...> class T> struct CTTP{ };
+ //
+ // template<typename T> struct CT1{ };
+ // template<typename T1, typename T2> struct CT2{ };
+ // template<typename T1, typename T2, typename T3> struct CT3{ };
+ // template<typename T1, typename T2, typename T3, typename... T4> struct CT4{ };
+ //
+ // typedef CTTP<CT1> a;
+ // typedef CTTP<CT2> b;
+ // typedef CTTP<CT3> c;
+ // typedef CTTP<CT4> d;
+ public void testTemplateTemplateParameterMatching_352859() 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 cb5e138902..aef3e512a7 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
@@ -1981,7 +1981,7 @@ public class CPPTemplates {
try {
pParams = ((ICPPTemplateTemplateParameter) param).getTemplateParameters();
aParams = ((ICPPTemplateDefinition) t).getTemplateParameters();
- if (!compareTemplateParameters(pParams, aParams))
+ if (!matchTemplateTemplateParameters(pParams, aParams))
return null;
} catch (DOMException e) {
return null;
@@ -2015,48 +2015,57 @@ public class CPPTemplates {
return null;
}
- private static boolean compareTemplateParameters(ICPPTemplateParameter[] params1,
- ICPPTemplateParameter[] params2) throws DOMException {
- int size = params1.length;
- if (params2.length != size) {
- return false;
- }
-
- for (int i = 0; i < size; i++) {
- final ICPPTemplateParameter p1 = params1[i];
- final ICPPTemplateParameter p2 = params2[i];
- if (p1.isParameterPack() != p2.isParameterPack())
+ private static boolean matchTemplateTemplateParameters(ICPPTemplateParameter[] pParams,
+ ICPPTemplateParameter[] aParams) throws DOMException {
+ int pi=0;
+ int ai=0;
+ while (pi < pParams.length && ai < aParams.length) {
+ final ICPPTemplateParameter pp = pParams[pi];
+ final ICPPTemplateParameter ap = aParams[ai];
+
+ // A parameter pack does not match a regular template parameter.
+ if (ap.isParameterPack() && !pp.isParameterPack())
return false;
- boolean pb= p1 instanceof ICPPTemplateTypeParameter;
- boolean ab= p2 instanceof ICPPTemplateTypeParameter;
+
+ boolean pb= pp instanceof ICPPTemplateTypeParameter;
+ boolean ab= ap instanceof ICPPTemplateTypeParameter;
if (pb != ab)
return false;
if (pb) {
// Both are template type parameters
} else {
- pb= p1 instanceof ICPPTemplateNonTypeParameter;
- ab= p2 instanceof ICPPTemplateNonTypeParameter;
+ pb= pp instanceof ICPPTemplateNonTypeParameter;
+ ab= ap instanceof ICPPTemplateNonTypeParameter;
if (pb != ab)
return false;
if (pb) {
// Both are non-type parameters
} else {
- if (!(p1 instanceof ICPPTemplateTemplateParameter) ||
- !(p2 instanceof ICPPTemplateTemplateParameter)) {
+ if (!(pp instanceof ICPPTemplateTemplateParameter) ||
+ !(ap instanceof ICPPTemplateTemplateParameter)) {
assert false;
return false;
}
- if (!compareTemplateParameters(((ICPPTemplateTemplateParameter) p1).getTemplateParameters(),
- ((ICPPTemplateTemplateParameter) p2).getTemplateParameters()) )
+ if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(),
+ ((ICPPTemplateTemplateParameter) ap).getTemplateParameters()) )
return false;
}
}
+ if (!pp.isParameterPack())
+ pi++;
+ ai++;
}
- return true;
+ if (pi < pParams.length) {
+ if (pi == pParams.length - 1 && pParams[pi].isParameterPack())
+ return true;
+ return false;
+ }
+
+ return ai == aParams.length;
}
/**

Back to the top