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:
parent
7a6df79277
commit
2ae5b10cae
2 changed files with 64 additions and 30 deletions
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue