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

Special cases in argument deduction for function templates, bug 293409.

This commit is contained in:
Markus Schorn 2009-10-27 10:03:06 +00:00
parent aa7ec888a1
commit edca08b14f
4 changed files with 95 additions and 30 deletions

View file

@ -4183,4 +4183,32 @@ public class AST2TemplateTests extends AST2BaseTest {
assertFalse(func instanceof ICPPUnknownBinding);
bh.assertProblem("n();", 1);
}
// template<class T> struct CT {};
// class D : public CT<char> {};
// template<typename S> void f1(const CT<S> &) {}
// template<typename S> void f2(const CT<S> *) {}
// template<typename S> void f3(CT<S> *) {}
// template<typename S> void f4(volatile S*) {}
// void t() {
// D d;
// const volatile int *i= 0;
// const D cd= *new D();
// f1(d);
// f2(&d);
// f2(&cd);
// f3(&d);
// f4(i);
// f3(&cd); // must be a problem, cd is const
// }
public void testArgumentDeduction_293409() throws Exception {
final String code = getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
bh.assertNonProblem("f1(d);", 2, ICPPFunction.class);
bh.assertNonProblem("f2(&d);", 2, ICPPFunction.class);
bh.assertNonProblem("f2(&cd);", 2, ICPPFunction.class);
bh.assertNonProblem("f3(&d);", 2, ICPPFunction.class);
bh.assertNonProblem("f4(i);", 2, ICPPFunction.class);
bh.assertProblem("f3(&cd);", 2);
}
}

View file

@ -550,31 +550,35 @@ public class CoreModelUtil {
*/
public static ITranslationUnit findTranslationUnitForLocation(IPath location, ICProject preferredProject) throws CModelException {
IFile[] files= ResourceLookup.findFilesForLocation(location);
boolean oneExisting= false;
if (files.length > 0) {
for (IFile file : files) {
ITranslationUnit tu= findTranslationUnit(file);
if (tu != null) {
return tu;
}
}
} else {
CoreModel coreModel = CoreModel.getDefault();
ITranslationUnit tu= null;
if (preferredProject != null) {
tu= coreModel.createTranslationUnitFrom(preferredProject, location);
}
if (tu == null) {
ICProject[] projects= coreModel.getCModel().getCProjects();
for (int i = 0; i < projects.length && tu == null; i++) {
ICProject project = projects[i];
if (!project.equals(preferredProject)) {
tu= coreModel.createTranslationUnitFrom(project, location);
if (file.exists()) {
oneExisting= true;
ITranslationUnit tu= findTranslationUnit(file);
if (tu != null) {
return tu;
}
}
}
return tu;
if (oneExisting)
return null;
}
CoreModel coreModel = CoreModel.getDefault();
ITranslationUnit tu= null;
if (preferredProject != null) {
tu= coreModel.createTranslationUnitFrom(preferredProject, location);
}
return null;
if (tu == null) {
ICProject[] projects= coreModel.getCModel().getCProjects();
for (int i = 0; i < projects.length && tu == null; i++) {
ICProject project = projects[i];
if (!project.equals(preferredProject)) {
tu= coreModel.createTranslationUnitFrom(project, location);
}
}
}
return tu;
}
/**

View file

@ -1478,13 +1478,40 @@ public class CPPTemplates {
par= getParameterTypeForDeduction(par, isReferenceType);
// 14.8.2.1.3
if (par instanceof ICPPTemplateInstance && !(par instanceof ICPPTemplateParameter) && arg instanceof ICPPClassType) {
ICPPTemplateInstance pInst = (ICPPTemplateInstance) par;
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
if (pTemplate != null) {
ICPPClassType aInst= findBaseInstance((ICPPClassType) arg, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
if (aInst != null) {
arg= aInst;
int cvPar= Conversions.getCVQualifier(par);
int cvArg= Conversions.getCVQualifier(arg);
if (cvPar == cvArg || (isReferenceType && (cvArg & ~cvPar) == 0)) {
IType pcheck= SemanticUtil.getNestedType(par, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
if (!(pcheck instanceof ICPPTemplateParameter)) {
par= pcheck;
arg= SemanticUtil.getNestedType(arg, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
IType argcheck= arg;
if (par instanceof IPointerType && arg instanceof IPointerType) {
pcheck= ((IPointerType) par).getType();
argcheck= ((IPointerType) arg).getType();
if (pcheck instanceof ICPPTemplateParameter) {
pcheck= null;
} else {
cvPar= Conversions.getCVQualifier(pcheck);
cvArg= Conversions.getCVQualifier(argcheck);
if ((cvArg & ~cvPar) == 0) {
pcheck= SemanticUtil.getNestedType(pcheck, SemanticUtil.CVQ);
argcheck= SemanticUtil.getNestedType(argcheck, SemanticUtil.CVQ);
} else {
pcheck= null;
}
}
}
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
if (pTemplate != null) {
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
if (aInst != null && aInst != argcheck) {
par= pcheck;
arg= aInst;
}
}
}
}
}
@ -1637,10 +1664,16 @@ public class CPPTemplates {
p = pa.getType();
a = aa.getType();
} else if (p instanceof IQualifierType) {
if (a instanceof IQualifierType) {
a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
IType uqp = SemanticUtil.getNestedType(p, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
IType uqa = SemanticUtil.getNestedType(a, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
if (uqp instanceof ICPPTemplateParameter) {
int remaining= Conversions.getCVQualifier(a) & ~Conversions.getCVQualifier(p);
if (remaining != 0) {
uqa= SemanticUtil.addQualifiers(uqa, (remaining & 1) != 0, (remaining & 2) != 0);
}
}
p = ((IQualifierType) p).getType();
a= uqa;
p= uqp;
} else if (p instanceof IFunctionType) {
if (!(a instanceof IFunctionType))
return false;

View file

@ -235,7 +235,7 @@ public class Conversions {
/**
* Returns 0 for no qualifier, 1 for const, 2 for volatile and 3 for const volatile.
*/
private static int getCVQualifier(IType t) {
static int getCVQualifier(IType t) {
if (t instanceof IQualifierType) {
int result= 0;
IQualifierType qt= (IQualifierType) t;