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:
parent
aa7ec888a1
commit
edca08b14f
4 changed files with 95 additions and 30 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue