1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Function template ordering, bug 294539.

This commit is contained in:
Markus Schorn 2009-11-09 17:47:02 +00:00
parent 8d5a128bc4
commit 57150dcb15
3 changed files with 67 additions and 44 deletions

View file

@ -4227,4 +4227,22 @@ public class AST2TemplateTests extends AST2BaseTest {
final String code= getAboveComment(); final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP); parseAndCheckBindings(code, ParserLanguage.CPP);
} }
// template <typename T> void func(T* t) {};
// template <typename T> void func(T& t) {};
// void test() {
// int* a;
// func(a);
// }
//
// template <typename T> void func1(const T* const t) {};
// template <typename T> void func1(T* const t) {};
// void test2() {
// const int* a;
// func1 (a);
// }
public void testFunctionTemplateOrdering_294539() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
} }

View file

@ -653,7 +653,7 @@ public class CPPTemplates {
result[i]= tmplArg; result[i]= tmplArg;
} }
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map)) if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map, false))
return null; return null;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1456,7 +1456,8 @@ public class CPPTemplates {
* Deduces the mapping for the template parameters from the function parameters, * Deduces the mapping for the template parameters from the function parameters,
* returns <code>false</code> if there is no mapping. * returns <code>false</code> if there is no mapping.
*/ */
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException{ private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template,
IType[] fnArgs, CPPTemplateParameterMap map, boolean checkExactMatch) throws DOMException {
try { try {
IType[] fnPars = template.getType().getParameterTypes(); IType[] fnPars = template.getType().getParameterTypes();
if (fnPars.length == 0) if (fnPars.length == 0)
@ -1474,7 +1475,8 @@ public class CPPTemplates {
for (int j= 0; j < len; j++) { for (int j= 0; j < len; j++) {
IType par= instPars[j]; IType par= instPars[j];
if (isDependentType(par)) { boolean isDependentPar= isDependentType(par);
if (checkExactMatch || isDependentPar) {
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
par= SemanticUtil.adjustParameterType(par, false); par= SemanticUtil.adjustParameterType(par, false);
// 14.8.2.1.2 and 14.8.2.1.3 // 14.8.2.1.2 and 14.8.2.1.3
@ -1483,46 +1485,53 @@ public class CPPTemplates {
par= getParameterTypeForDeduction(par, isReferenceType); par= getParameterTypeForDeduction(par, isReferenceType);
// 14.8.2.1.3 // 14.8.2.1.3
CVQualifier cvPar= SemanticUtil.getCVQualifier(par); if (!checkExactMatch) {
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg); CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) { CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE); if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
if (!(pcheck instanceof ICPPTemplateParameter)) { IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
par= pcheck; if (!(pcheck instanceof ICPPTemplateParameter)) {
arg= SemanticUtil.getNestedType(arg, CVTYPE); par= pcheck;
IType argcheck= arg; arg= SemanticUtil.getNestedType(arg, CVTYPE);
if (par instanceof IPointerType && arg instanceof IPointerType) { IType argcheck= arg;
pcheck= ((IPointerType) par).getType(); if (par instanceof IPointerType && arg instanceof IPointerType) {
argcheck= ((IPointerType) arg).getType(); pcheck= ((IPointerType) par).getType();
if (pcheck instanceof ICPPTemplateParameter) { argcheck= ((IPointerType) arg).getType();
pcheck= null; if (pcheck instanceof ICPPTemplateParameter) {
} else {
cvPar= SemanticUtil.getCVQualifier(pcheck);
cvArg= SemanticUtil.getCVQualifier(argcheck);
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
} else {
pcheck= null; pcheck= null;
} else {
cvPar= SemanticUtil.getCVQualifier(pcheck);
cvArg= SemanticUtil.getCVQualifier(argcheck);
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
} else {
pcheck= null;
}
} }
} }
} if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) { ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck; ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); if (pTemplate != null) {
if (pTemplate != null) { ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH); if (aInst != null && aInst != argcheck) {
if (aInst != null && aInst != argcheck) { par= pcheck;
par= pcheck; arg= aInst;
arg= aInst; }
} }
} }
} }
} }
} }
if (!deduceTemplateParameterMap(par, arg, map)) { if (isDependentPar && !deduceTemplateParameterMap(par, arg, map)) {
return false; return false;
} }
if (checkExactMatch) {
IType instantiated= instantiateType(par, map, null);
if (!instantiated.isSameType(arg))
return false;
}
} }
} }
return true; return true;
@ -1844,7 +1853,7 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(2); CPPTemplateParameterMap map= new CPPTemplateParameterMap(2);
final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes(); final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes();
if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, map)) if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, map, true))
return false; return false;
final ICPPTemplateParameter[] tmplParams = f2.getTemplateParameters(); final ICPPTemplateParameter[] tmplParams = f2.getTemplateParameters();
@ -1854,15 +1863,6 @@ public class CPPTemplates {
return false; return false;
} }
// length can be different in case of varargs or default arguments
IType[] params= f2.getType().getParameterTypes();
final int len= Math.min(params.length, transferredParameterTypes.length);
for (int i = 0; i <len; i++) {
IType instantiated= instantiateType(params[i], map, null);
// we need to be able to compare class instances from different caches here
if (!instantiated.isSameType(transferredParameterTypes[i]))
return false;
}
return true; return true;
} }

View file

@ -390,12 +390,17 @@ public class Conversions {
continue; continue;
} }
} else { } else {
IType ptype= ptypes[0];
// We don't need to check the implicit conversion sequence it the type is void
if (ptype instanceof ICPPBasicType && ((ICPPBasicType) ptype).getKind() == Kind.eVoid)
continue;
if (ptypes.length > 1) { if (ptypes.length > 1) {
IParameter[] pars = ctor.getParameters(); IParameter[] pars = ctor.getParameters();
if (pars.length < 2 || !((ICPPParameter) pars[1]).hasDefaultValue()) if (pars.length < 2 || !((ICPPParameter) pars[1]).hasDefaultValue())
continue; continue;
} }
c1= checkImplicitConversionSequence(sourceIsLValue, source, ptypes[0], UDCMode.noUDC, false); c1= checkImplicitConversionSequence(sourceIsLValue, source, ptype, UDCMode.noUDC, false);
} }
int cmp= c1.compareTo(cost1); int cmp= c1.compareTo(cost1);
if (cmp <= 0) { if (cmp <= 0) {