mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
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
This commit is contained in:
parent
58e2f34bfc
commit
6ef70ba044
2 changed files with 39 additions and 12 deletions
|
@ -9054,6 +9054,22 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
|||
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 {};
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue