diff options
Diffstat (limited to 'core')
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 2a88223ceff..bf1f8b09d8f 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 cb5e1389025..aef3e512a70 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; } /** |