1
0
Fork 0
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:
Sergey Prigogin 2008-08-25 00:39:02 +00:00
parent bc2382f2ca
commit e9629b194e
4 changed files with 105 additions and 58 deletions

View file

@ -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> {};

View file

@ -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() {

View file

@ -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 {

View file

@ -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) {
if (d1 && d2 || !d1 && !d2)
return 0; return 0;
else if (d1 && !d2) } else {
return 1;
else
return -1; return -1;
} }
} else {
if (m2 == null) {
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;