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);
|
assertFalse(func instanceof ICPPUnknownBinding);
|
||||||
bh.assertProblem("n();", 1);
|
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 {
|
public static ITranslationUnit findTranslationUnitForLocation(IPath location, ICProject preferredProject) throws CModelException {
|
||||||
IFile[] files= ResourceLookup.findFilesForLocation(location);
|
IFile[] files= ResourceLookup.findFilesForLocation(location);
|
||||||
|
boolean oneExisting= false;
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
for (IFile file : files) {
|
for (IFile file : files) {
|
||||||
ITranslationUnit tu= findTranslationUnit(file);
|
if (file.exists()) {
|
||||||
if (tu != null) {
|
oneExisting= true;
|
||||||
return tu;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tu;
|
if (oneExisting)
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1478,13 +1478,40 @@ public class CPPTemplates {
|
||||||
par= getParameterTypeForDeduction(par, isReferenceType);
|
par= getParameterTypeForDeduction(par, isReferenceType);
|
||||||
|
|
||||||
// 14.8.2.1.3
|
// 14.8.2.1.3
|
||||||
if (par instanceof ICPPTemplateInstance && !(par instanceof ICPPTemplateParameter) && arg instanceof ICPPClassType) {
|
int cvPar= Conversions.getCVQualifier(par);
|
||||||
ICPPTemplateInstance pInst = (ICPPTemplateInstance) par;
|
int cvArg= Conversions.getCVQualifier(arg);
|
||||||
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
|
if (cvPar == cvArg || (isReferenceType && (cvArg & ~cvPar) == 0)) {
|
||||||
if (pTemplate != null) {
|
IType pcheck= SemanticUtil.getNestedType(par, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
|
||||||
ICPPClassType aInst= findBaseInstance((ICPPClassType) arg, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
|
if (!(pcheck instanceof ICPPTemplateParameter)) {
|
||||||
if (aInst != null) {
|
par= pcheck;
|
||||||
arg= aInst;
|
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();
|
p = pa.getType();
|
||||||
a = aa.getType();
|
a = aa.getType();
|
||||||
} else if (p instanceof IQualifierType) {
|
} else if (p instanceof IQualifierType) {
|
||||||
if (a instanceof IQualifierType) {
|
IType uqp = SemanticUtil.getNestedType(p, SemanticUtil.CVQ | SemanticUtil.PTR_CVQ);
|
||||||
a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
|
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) {
|
} else if (p instanceof IFunctionType) {
|
||||||
if (!(a instanceof IFunctionType))
|
if (!(a instanceof IFunctionType))
|
||||||
return false;
|
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.
|
* 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) {
|
if (t instanceof IQualifierType) {
|
||||||
int result= 0;
|
int result= 0;
|
||||||
IQualifierType qt= (IQualifierType) t;
|
IQualifierType qt= (IQualifierType) t;
|
||||||
|
|
Loading…
Add table
Reference in a new issue