mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Bug 245049. Also fixed test14_8_2_4s7.
This commit is contained in:
parent
bc2382f2ca
commit
e9629b194e
4 changed files with 105 additions and 58 deletions
|
@ -163,16 +163,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<class T> void f(const T*) {}
|
|
||||||
// int *p;
|
|
||||||
// void s()
|
|
||||||
// {
|
|
||||||
// f(p); // f(const int *)
|
|
||||||
// }
|
|
||||||
public void _test14_8_2_4s7() throws Exception {
|
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// template <class T> struct B { };
|
// template <class T> struct B { };
|
||||||
// template <class T> struct D : public B<T> {};
|
// template <class T> struct D : public B<T> {};
|
||||||
// struct D2 : public B<int> {};
|
// struct D2 : public B<int> {};
|
||||||
|
|
|
@ -5482,6 +5482,16 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<class T> void f(const T*) {}
|
||||||
|
// int *p;
|
||||||
|
// void s()
|
||||||
|
// {
|
||||||
|
// f(p); // f(const int *)
|
||||||
|
// }
|
||||||
|
public void test14_8_2_4s7() throws Exception {
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// template<class T, T i> void f(double a[10][i]);
|
// template<class T, T i> void f(double a[10][i]);
|
||||||
// int v[10][20];
|
// int v[10][20];
|
||||||
// int foo() {
|
// int foo() {
|
||||||
|
|
|
@ -2160,8 +2160,8 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
|
|
||||||
// struct A {};
|
// struct A {};
|
||||||
//
|
//
|
||||||
// template <class T>
|
// template <class T1>
|
||||||
// void func(const T& p) {
|
// void func(const T1& p) {
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// void test() {
|
// void test() {
|
||||||
|
@ -2170,12 +2170,35 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// func(a1);
|
// func(a1);
|
||||||
// func(a2);
|
// func(a2);
|
||||||
// }
|
// }
|
||||||
public void _testFunctionTemplate_245049() throws Exception {
|
public void testFunctionTemplate_245049_1() throws Exception {
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
ICPPFunction b0= bh.assertNonProblem("func(a1)", 4, ICPPFunction.class);
|
ICPPFunction b0= bh.assertNonProblem("func(a1)", 4, ICPPFunction.class);
|
||||||
assertInstance(b0, ICPPTemplateInstance.class);
|
assertInstance(b0, ICPPTemplateInstance.class);
|
||||||
ICPPFunction b1= bh.assertNonProblem("func(a2)", 4, ICPPFunction.class);
|
ICPPFunction b1= bh.assertNonProblem("func(a2)", 4, ICPPFunction.class);
|
||||||
assertEquals(b0, b1);
|
assertSame(b0, b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct A {};
|
||||||
|
//
|
||||||
|
// template <class T1>
|
||||||
|
// void func(const T1& p) {
|
||||||
|
// }
|
||||||
|
// template <class T2>
|
||||||
|
// void func(T2& p) {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// A a1;
|
||||||
|
// const A a2;
|
||||||
|
// func(a1);
|
||||||
|
// func(a2);
|
||||||
|
// }
|
||||||
|
public void testFunctionTemplate_245049_2() throws Exception {
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ICPPFunction b0= bh.assertNonProblem("func(a1)", 4, ICPPFunction.class);
|
||||||
|
assertInstance(b0, ICPPTemplateInstance.class);
|
||||||
|
ICPPFunction b1= bh.assertNonProblem("func(a2)", 4, ICPPFunction.class);
|
||||||
|
assertNotSame(b0, b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// namespace ns {
|
// namespace ns {
|
||||||
|
|
|
@ -174,8 +174,8 @@ public class CPPTemplates {
|
||||||
|
|
||||||
ICPPTemplateParameter[] params= partialSpec.getTemplateParameters();
|
ICPPTemplateParameter[] params= partialSpec.getTemplateParameters();
|
||||||
int numParams = params.length;
|
int numParams = params.length;
|
||||||
for( int i = 0; i < numParams; i++ ){
|
for (int i = 0; i < numParams; i++) {
|
||||||
if( params[i] instanceof IType && !argMap.containsKey(params[i]))
|
if (params[i] instanceof IType && !argMap.containsKey(params[i]))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1133,7 +1133,7 @@ public class CPPTemplates {
|
||||||
IType[] args = ((ICPPTemplateInstance) binding).getArguments();
|
IType[] args = ((ICPPTemplateInstance) binding).getArguments();
|
||||||
for (IType arg : args) {
|
for (IType arg : args) {
|
||||||
if (arg instanceof IBinding) {
|
if (arg instanceof IBinding) {
|
||||||
if(bindings.containsKey((IBinding)arg)) {
|
if (bindings.containsKey((IBinding)arg)) {
|
||||||
clear = true;
|
clear = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1245,17 +1245,17 @@ public class CPPTemplates {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// special case treatment for non-type integral parameters
|
// special case treatment for non-type integral parameters
|
||||||
if(argA instanceof ICPPBasicType && argB instanceof ICPPBasicType) {
|
if (argA instanceof ICPPBasicType && argB instanceof ICPPBasicType) {
|
||||||
try {
|
try {
|
||||||
IASTExpression eA= ((ICPPBasicType) argA).getValue();
|
IASTExpression eA= ((ICPPBasicType) argA).getValue();
|
||||||
IASTExpression eB= ((ICPPBasicType) argB).getValue();
|
IASTExpression eB= ((ICPPBasicType) argB).getValue();
|
||||||
if(eA != null && eB != null) {
|
if (eA != null && eB != null) {
|
||||||
// TODO - we should normalize template arguments
|
// TODO - we should normalize template arguments
|
||||||
// rather than check their original expressions
|
// rather than check their original expressions
|
||||||
// are equivalent.
|
// are equivalent.
|
||||||
return isNonTypeArgumentConvertible(argA, argB) && expressionsEquivalent(eA, eB);
|
return isNonTypeArgumentConvertible(argA, argB) && expressionsEquivalent(eA, eB);
|
||||||
}
|
}
|
||||||
} catch(DOMException de) {
|
} catch (DOMException de) {
|
||||||
CCorePlugin.log(de);
|
CCorePlugin.log(de);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1271,7 +1271,7 @@ public class CPPTemplates {
|
||||||
*/
|
*/
|
||||||
static public IType[] createTemplateArgumentArray(ICPPASTTemplateId id) {
|
static public IType[] createTemplateArgumentArray(ICPPASTTemplateId id) {
|
||||||
IType[] result= IType.EMPTY_TYPE_ARRAY;
|
IType[] result= IType.EMPTY_TYPE_ARRAY;
|
||||||
if(id != null) {
|
if (id != null) {
|
||||||
IASTNode[] params= id.getTemplateArguments();
|
IASTNode[] params= id.getTemplateArguments();
|
||||||
result = new IType[params.length];
|
result = new IType[params.length];
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
@ -1281,7 +1281,7 @@ public class CPPTemplates {
|
||||||
* modeled by the type of the initialized expression (which
|
* modeled by the type of the initialized expression (which
|
||||||
* will include its value)
|
* will include its value)
|
||||||
*/
|
*/
|
||||||
if(param instanceof IASTIdExpression) {
|
if (param instanceof IASTIdExpression) {
|
||||||
param= CPPVisitor.reverseConstantPropogationLookup((IASTIdExpression)param);
|
param= CPPVisitor.reverseConstantPropogationLookup((IASTIdExpression)param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1454,7 +1454,7 @@ public class CPPTemplates {
|
||||||
if (!deduceTemplateArgument(map, specArgs[j], args[j])) {
|
if (!deduceTemplateArgument(map, specArgs[j], args[j])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch(DOMException de) {
|
} catch (DOMException de) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1530,12 +1530,12 @@ public class CPPTemplates {
|
||||||
IType t1= e1.getExpressionType();
|
IType t1= e1.getExpressionType();
|
||||||
IType t2= e2.getExpressionType();
|
IType t2= e2.getExpressionType();
|
||||||
try {
|
try {
|
||||||
if(t1 instanceof ICPPBasicType && t2 instanceof ICPPBasicType) {
|
if (t1 instanceof ICPPBasicType && t2 instanceof ICPPBasicType) {
|
||||||
BigInteger i1= CPPVisitor.parseIntegral(e1.toString());
|
BigInteger i1= CPPVisitor.parseIntegral(e1.toString());
|
||||||
BigInteger i2= CPPVisitor.parseIntegral(e2.toString());
|
BigInteger i2= CPPVisitor.parseIntegral(e2.toString());
|
||||||
return i1.equals(i2);
|
return i1.equals(i2);
|
||||||
}
|
}
|
||||||
} catch(NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
/* fall through */
|
/* fall through */
|
||||||
}
|
}
|
||||||
return e1.toString().equals(e2.toString());
|
return e1.toString().equals(e2.toString());
|
||||||
|
@ -1549,11 +1549,12 @@ public class CPPTemplates {
|
||||||
a = getArgumentTypeForDeduction(a, pIsAReferenceType);
|
a = getArgumentTypeForDeduction(a, pIsAReferenceType);
|
||||||
|
|
||||||
if (p instanceof IBasicType) {
|
if (p instanceof IBasicType) {
|
||||||
if(a instanceof IBasicType) {
|
if (a instanceof IBasicType) {
|
||||||
IBasicType pbt= (IBasicType) p, abt= (IBasicType) a;
|
IBasicType pbt= (IBasicType) p;
|
||||||
|
IBasicType abt= (IBasicType) a;
|
||||||
|
|
||||||
// non-type argument comparison
|
// non-type argument comparison
|
||||||
if(pbt.getValue() != null && abt.getValue() != null) {
|
if (pbt.getValue() != null && abt.getValue() != null) {
|
||||||
return isNonTypeArgumentConvertible(p, a)
|
return isNonTypeArgumentConvertible(p, a)
|
||||||
&& expressionsEquivalent(pbt.getValue(), abt.getValue());
|
&& expressionsEquivalent(pbt.getValue(), abt.getValue());
|
||||||
}
|
}
|
||||||
|
@ -1570,10 +1571,10 @@ public class CPPTemplates {
|
||||||
} else if (p instanceof ICPPPointerToMemberType) {
|
} else if (p instanceof ICPPPointerToMemberType) {
|
||||||
if (!(a instanceof ICPPPointerToMemberType))
|
if (!(a instanceof ICPPPointerToMemberType))
|
||||||
return false;
|
return false;
|
||||||
|
if (!deduceTemplateArgument(map, ((ICPPPointerToMemberType) p).getMemberOfClass(),
|
||||||
if (!deduceTemplateArgument(map, ((ICPPPointerToMemberType) p).getMemberOfClass(), ((ICPPPointerToMemberType) a).getMemberOfClass()))
|
((ICPPPointerToMemberType) a).getMemberOfClass())) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
p = ((ICPPPointerToMemberType) p).getType();
|
p = ((ICPPPointerToMemberType) p).getType();
|
||||||
a = ((ICPPPointerToMemberType) a).getType();
|
a = ((ICPPPointerToMemberType) a).getType();
|
||||||
} else if (p instanceof IPointerType) {
|
} else if (p instanceof IPointerType) {
|
||||||
|
@ -1583,15 +1584,17 @@ public class CPPTemplates {
|
||||||
p = ((IPointerType) p).getType();
|
p = ((IPointerType) p).getType();
|
||||||
a = ((IPointerType) a).getType();
|
a = ((IPointerType) a).getType();
|
||||||
} else if (p instanceof IQualifierType) {
|
} else if (p instanceof IQualifierType) {
|
||||||
if (!(a instanceof IQualifierType))
|
if (a instanceof IQualifierType) {
|
||||||
return false;
|
a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
|
||||||
a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
|
}
|
||||||
p = ((IQualifierType) p).getType();
|
p = ((IQualifierType) p).getType();
|
||||||
} else if (p instanceof IFunctionType) {
|
} else if (p instanceof IFunctionType) {
|
||||||
if (!(a instanceof IFunctionType))
|
if (!(a instanceof IFunctionType))
|
||||||
return false;
|
return false;
|
||||||
if (!deduceTemplateArgument(map, ((IFunctionType) p).getReturnType(), ((IFunctionType) a).getReturnType()))
|
if (!deduceTemplateArgument(map, ((IFunctionType) p).getReturnType(),
|
||||||
|
((IFunctionType) a).getReturnType())) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
IType[] pParams = ((IFunctionType) p).getParameterTypes();
|
IType[] pParams = ((IFunctionType) p).getParameterTypes();
|
||||||
IType[] aParams = ((IFunctionType) a).getParameterTypes();
|
IType[] aParams = ((IFunctionType) a).getParameterTypes();
|
||||||
if (pParams.length != aParams.length)
|
if (pParams.length != aParams.length)
|
||||||
|
@ -1653,7 +1656,7 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transform a function template for use in partial ordering, as described in the
|
* Transforms a function template for use in partial ordering, as described in the
|
||||||
* spec 14.5.5.2-3
|
* spec 14.5.5.2-3
|
||||||
* @param template
|
* @param template
|
||||||
* @return
|
* @return
|
||||||
|
@ -1665,7 +1668,8 @@ public class CPPTemplates {
|
||||||
* for each occurrence of that parameter in the function parameter list
|
* for each occurrence of that parameter in the function parameter list
|
||||||
* @throws DOMException
|
* @throws DOMException
|
||||||
*/
|
*/
|
||||||
static private IType[] createArgsForFunctionTemplateOrdering(ICPPFunctionTemplate template) throws DOMException{
|
static private IType[] createArgsForFunctionTemplateOrdering(ICPPFunctionTemplate template)
|
||||||
|
throws DOMException{
|
||||||
ICPPTemplateParameter[] paramList = template.getTemplateParameters();
|
ICPPTemplateParameter[] paramList = template.getTemplateParameters();
|
||||||
int size = paramList.length;
|
int size = paramList.length;
|
||||||
IType[] args = new IType[size];
|
IType[] args = new IType[size];
|
||||||
|
@ -1687,11 +1691,11 @@ public class CPPTemplates {
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected int orderTemplateFunctions(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2) throws DOMException {
|
static protected int orderTemplateFunctions(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2)
|
||||||
//Using the transformed parameter list, perform argument deduction against the other
|
throws DOMException {
|
||||||
//function template
|
// Using the transformed parameter list, perform argument deduction against the other
|
||||||
|
// function template
|
||||||
ObjectMap m1 = null;
|
ObjectMap m1 = null;
|
||||||
ObjectMap m2 = null;
|
|
||||||
if (f1 != null) {
|
if (f1 != null) {
|
||||||
IType[] args = createArgsForFunctionTemplateOrdering(f1);
|
IType[] args = createArgsForFunctionTemplateOrdering(f1);
|
||||||
IBinding function = instantiate(f1, args);
|
IBinding function = instantiate(f1, args);
|
||||||
|
@ -1699,6 +1703,7 @@ public class CPPTemplates {
|
||||||
m1 = deduceTemplateArguments(f2, ((ICPPFunction) function).getType().getParameterTypes());
|
m1 = deduceTemplateArguments(f2, ((ICPPFunction) function).getType().getParameterTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectMap m2 = null;
|
||||||
if (f2 != null) {
|
if (f2 != null) {
|
||||||
IType[] args = createArgsForFunctionTemplateOrdering(f2);
|
IType[] args = createArgsForFunctionTemplateOrdering(f2);
|
||||||
IBinding function = instantiate(f2, args);
|
IBinding function = instantiate(f2, args);
|
||||||
|
@ -1706,22 +1711,41 @@ public class CPPTemplates {
|
||||||
if (function instanceof ICPPFunction)
|
if (function instanceof ICPPFunction)
|
||||||
m2 = deduceTemplateArguments(f1, ((ICPPFunction) function).getType().getParameterTypes());
|
m2 = deduceTemplateArguments(f1, ((ICPPFunction) function).getType().getParameterTypes());
|
||||||
}
|
}
|
||||||
//The transformed template is at least as specialized as the other iff the deduction
|
// The transformed template is at least as specialized as the other iff the deduction
|
||||||
//succeeds and the deduced parameter types are an exact match
|
// succeeds and the deduced parameter types are an exact match.
|
||||||
//A template is more specialized than another iff it is at least as specialized as the
|
// A template is more specialized than another iff it is at least as specialized as the
|
||||||
//other template and that template is not at least as specialized as the first.
|
// other template and that template is not at least as specialized as the first.
|
||||||
boolean d1 = (m1 != null);
|
if (m1 == null) {
|
||||||
boolean d2 = (m2 != null);
|
if (m2 == null) {
|
||||||
|
return 0;
|
||||||
if (d1 && d2 || !d1 && !d2)
|
} else {
|
||||||
return 0;
|
return -1;
|
||||||
else if (d1 && !d2)
|
}
|
||||||
return 1;
|
} else {
|
||||||
else
|
if (m2 == null) {
|
||||||
return -1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
// Count the number of cv-qualifications. The function with a lower number
|
||||||
|
// of cv-qualifications is more specialized.
|
||||||
|
int d1 = 0;
|
||||||
|
for (int i = 0; i < m1.size(); i++) {
|
||||||
|
if (m1.getAt(i) instanceof IQualifierType) {
|
||||||
|
d1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int d2 = 0;
|
||||||
|
for (int i = 0; i < m2.size(); i++) {
|
||||||
|
if (m2.getAt(i) instanceof IQualifierType) {
|
||||||
|
d2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d1 - d2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public ICPPTemplateDefinition selectSpecialization(ICPPClassTemplate template, IType[] args) throws DOMException{
|
static public ICPPTemplateDefinition selectSpecialization(ICPPClassTemplate template, IType[] args)
|
||||||
|
throws DOMException {
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1902,7 +1926,7 @@ public class CPPTemplates {
|
||||||
pType = (IType) map.get(pType);
|
pType = (IType) map.get(pType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isNonTypeArgumentConvertible(pType, argument)) {
|
if (!isNonTypeArgumentConvertible(pType, argument)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -1943,8 +1967,8 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsDependentArg(ObjectMap argMap) {
|
public static boolean containsDependentArg(ObjectMap argMap) {
|
||||||
for(Object arg : argMap.valueArray()) {
|
for (Object arg : argMap.valueArray()) {
|
||||||
if(isDependentType((IType)arg))
|
if (isDependentType((IType)arg))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue