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

Bug 354585: Resolution of overloaded new

This commit is contained in:
Markus Schorn 2011-08-17 09:55:06 +02:00
parent 7a6df79277
commit 2ae5b10cae
2 changed files with 64 additions and 30 deletions

View file

@ -418,14 +418,41 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
IBinding f= bh.assertNonProblem("operator delete(void * b)", 15);
IASTImplicitName[] names = bh.getImplicitNames("delete a;", 6);
assertEquals(2, names.length);
assertEquals(2, names.length);
assertTrue(((ICPPMethod) names[0].resolveBinding()).isDestructor());
assertSame(m, names[1].resolveBinding());
names = bh.getImplicitNames("delete b;", 6);
assertEquals(2, names.length);
assertTrue(((ICPPMethod) names[0].resolveBinding()).isDestructor());
assertEquals(2, names.length);
assertSame(f, names[1].resolveBinding());
}
// typedef int size_t;
// struct A {
// void* operator new(size_t a);
// };
// struct B {};
// void* operator new(size_t b);
//
// void test() {
// A *a = new A;
// B* b = new B;
// }
public void testOverloadedNew_Bug354585() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
IBinding m= bh.assertNonProblem("operator new(size_t a)", 12);
IBinding f= bh.assertNonProblem("operator new(size_t b)", 12);
IASTImplicitName[] names = bh.getImplicitNames("new A;", 3);
assertEquals(1, names.length);
assertSame(m, names[0].resolveBinding());
names = bh.getImplicitNames("new B;", 3);
assertEquals(1, names.length);
assertSame(f, names[0].resolveBinding());
}
// struct X {}
// int test(X* x) {
// X* xs = new X[5];

View file

@ -3005,20 +3005,19 @@ public class CPPSemantics {
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
}
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
IType type = exp.getExpressionType();
if (!(type instanceof IPointerType))
return null;
type = ((IPointerType) type).getType();
IASTTypeId typeId = exp.getTypeId().copy();
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
sizeExpression.setParent(exp);
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression expr) {
OverloadableOperator op = OverloadableOperator.fromNewExpression(expr);
IType type = getTypeOfPointer(expr.getExpressionType());
if (type == null)
return null;
IASTInitializerClause[] placement = exp.getPlacementArguments();
IASTTypeId typeId = expr.getTypeId().copy();
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
sizeExpression.setParent(expr);
IASTInitializerClause[] placement = expr.getPlacementArguments();
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
args.add(createArgForType(expr, type));
args.add(sizeExpression);
if (placement != null) {
for (IASTInitializerClause p : placement) {
@ -3026,23 +3025,23 @@ public class CPPSemantics {
}
}
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]);
return findOverloadedOperator(exp, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
return findOverloadedOperator(expr, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
}
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
IType classType = getNestedClassType(exp);
IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType), exp.getOperand()};
return findOverloadedOperator(exp, args, classType, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression expr) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(expr);
IType type = getTypeOfPointer(expr.getOperand().getExpressionType());
if (type == null)
return null;
IASTExpression[] args = {createArgForType(expr, type), expr.getOperand()};
return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
}
private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
IType type = exp.getOperand().getExpressionType();
type = SemanticUtil.getUltimateTypeUptoPointers(type);
private static IType getTypeOfPointer(IType type) {
type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF | SemanticUtil.REF | SemanticUtil.CVTYPE);
if (type instanceof IPointerType) {
IType classType = ((IPointerType) type).getType();
if (classType instanceof ICPPClassType)
return (ICPPClassType) classType;
return getNestedType(((IPointerType) type).getType(), TDEF | REF | CVTYPE);
}
return null;
}
@ -3165,10 +3164,11 @@ public class CPPSemantics {
}
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
ICPPClassType cls = getNestedClassType(expr);
if (cls == null)
IType t = getTypeOfPointer(expr.getOperand().getExpressionType());
if (!(t instanceof ICPPClassType))
return null;
ICPPClassType cls = (ICPPClassType) t;
IScope scope = cls.getCompositeScope();
if (scope == null)
return null;
@ -3337,8 +3337,15 @@ public class CPPSemantics {
funcName.setParent(parent);
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
LookupData funcData = new LookupData(funcName);
if (operator == OverloadableOperator.DELETE || operator == OverloadableOperator.DELETE_ARRAY) {
// Global new and delete operators do not take an argument for the this pointer.
switch (operator) {
case DELETE: case DELETE_ARRAY:
case NEW: case NEW_ARRAY:
args= ArrayUtil.removeFirst(args);
break;
default:
break;
}
funcData.setFunctionArguments(true, args);
funcData.ignoreMembers = true; // (13.3.1.2.3)