diff options
2 files changed, 39 insertions, 12 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 24de5150d1a..1e9b3073fc6 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 @@ -9053,6 +9053,22 @@ public class AST2TemplateTests extends AST2CPPTestBase { ITypedef waldo = helper.assertNonProblem("Waldo"); assertSameType(CommonCPPTypes.int_, waldo); } + + // template <int, class> + // struct A {}; + // + // struct B : A<0, int>, A<1, int> {}; + // + // template <class T> + // void waldo(A<1, T>); + // + // void foo() { + // B b; + // waldo(b); + // } + public void testTemplateArgumentDeduction_MultipleInheritance_527697() throws Exception { + parseAndCheckBindings(); + } // template <typename T> // struct A {}; 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 7f9a1930721..d8c34552128 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 @@ -58,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; @@ -301,10 +302,20 @@ public class TemplateArgumentDeduction { ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck; ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); if (pTemplate != null) { - ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate); - if (aInst != null && aInst != argcheck) { - par= pcheck; - arg= aInst; + ICPPClassType[] aInstances = findBaseInstances((ICPPClassType) argcheck, pTemplate); + boolean attempted = false; + for (ICPPClassType aInst : aInstances) { + if (aInst != null && aInst != argcheck) { + par= pcheck; + arg= aInst; + attempted = true; + if (deduct.fromType(par, arg, true, false)) { + return true; + } + } + } + if (attempted) { + return false; } } } @@ -631,29 +642,29 @@ public class TemplateArgumentDeduction { * 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of * the deduced A. */ - private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate) throws DOMException { - return findBaseInstance(a, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<>()); + private static ICPPClassType[] findBaseInstances(ICPPClassType a, ICPPClassTemplate pTemplate) throws DOMException { + return findBaseInstances(a, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<>()); } - private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth, + private static ICPPClassType[] findBaseInstances(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth, HashSet<Object> handled) throws DOMException { if (a instanceof ICPPTemplateInstance) { ICPPTemplateInstance inst = (ICPPTemplateInstance) a; ICPPClassTemplate tmpl= getPrimaryTemplate(inst); if (pTemplate.isSameType(tmpl)) - return a; + return new ICPPClassType[] { a }; } + ICPPClassType[] results = ICPPClassType.EMPTY_CLASS_ARRAY; if (maxdepth-- > 0) { for (ICPPBase cppBase : a.getBases()) { IBinding base= cppBase.getBaseClass(); if (base instanceof ICPPClassType && handled.add(base)) { - final ICPPClassType inst= findBaseInstance((ICPPClassType) base, pTemplate, maxdepth, handled); - if (inst != null) - return inst; + ICPPClassType[] inst= findBaseInstances((ICPPClassType) base, pTemplate, maxdepth, handled); + results = ArrayUtil.addAll(results, inst); } } } - return null; + return ArrayUtil.trim(results); } private static ICPPClassTemplate getPrimaryTemplate(ICPPTemplateInstance inst) throws DOMException { |