From 947aacd42b4da991ab9be0b046c0ffe234e427a4 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 27 Jul 2011 16:37:01 +0200 Subject: [PATCH] Bug 352859: Matching of template template parameters. --- .../parser/tests/ast2/AST2TemplateTests.java | 23 +++++++-- .../parser/cpp/semantics/CPPTemplates.java | 51 +++++++++++-------- 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 xa; // okay // X xb; // ill-formed: default arguments for the parameters of a template template argument are ignored // X xc; // ill-formed: a template parameter pack does not match a template parameter - // Y ya; // ill-formed: a template parameter pack does not match a template parameter - // Y yb; // ill-formed: a template parameter pack does not match a template parameter + // Y ya; // okay + // Y yb; // okay // Y yc; // okay public void testVariadicTemplateExamples_280909f() throws Exception { final String code= getAboveComment(); @@ -4541,8 +4541,8 @@ public class AST2TemplateTests extends AST2BaseTest { bh.assertNonProblem("X", 4); bh.assertProblem("X", 4); bh.assertProblem("X", 4); - bh.assertProblem("Y", 4); - bh.assertProblem("Y", 4); + bh.assertNonProblem("Y", 4); + bh.assertNonProblem("Y", 4); bh.assertNonProblem("Y", 4); } @@ -5439,4 +5439,19 @@ public class AST2TemplateTests extends AST2BaseTest { public void testTemplateParameterWithoutName_352266() throws Exception { parseAndCheckBindings(); } + + // template class T> struct CTTP{ }; + // + // template struct CT1{ }; + // template struct CT2{ }; + // template struct CT3{ }; + // template struct CT4{ }; + // + // typedef CTTP a; + // typedef CTTP b; + // typedef CTTP c; + // typedef CTTP 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; } /**