Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2017-12-07 04:59:37 +0000
committerNathan Ridge2017-12-14 07:19:59 +0000
commitb07df3a4fc496f225fb1681a7dcd520962b6b258 (patch)
tree0665b0c06ad9e154ef9b02f4a4500db34e777275 /core
parente2c5592d9de0cd0d033a6a46defb8ef5910f31c5 (diff)
downloadorg.eclipse.cdt-b07df3a4fc496f225fb1681a7dcd520962b6b258.tar.gz
org.eclipse.cdt-b07df3a4fc496f225fb1681a7dcd520962b6b258.tar.xz
org.eclipse.cdt-b07df3a4fc496f225fb1681a7dcd520962b6b258.zip
Bug 527697 - Attempt deduction with all base classes of an argument type
Previously, we would only try the first base class whose primary template matched that of the parameter type. Change-Id: I0511e6a1ba1c7197887ff23bc37b70a2a820eb87
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java35
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 {

Back to the top