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
|
@ -419,13 +419,40 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
|
|
||||||
IASTImplicitName[] names = bh.getImplicitNames("delete a;", 6);
|
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());
|
assertSame(m, names[1].resolveBinding());
|
||||||
|
|
||||||
names = bh.getImplicitNames("delete b;", 6);
|
names = bh.getImplicitNames("delete b;", 6);
|
||||||
|
assertTrue(((ICPPMethod) names[0].resolveBinding()).isDestructor());
|
||||||
assertEquals(2, names.length);
|
assertEquals(2, names.length);
|
||||||
assertSame(f, names[1].resolveBinding());
|
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 {}
|
// struct X {}
|
||||||
// int test(X* x) {
|
// int test(X* x) {
|
||||||
// X* xs = new X[5];
|
// X* xs = new X[5];
|
||||||
|
|
|
@ -3005,20 +3005,19 @@ public class CPPSemantics {
|
||||||
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
|
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression expr) {
|
||||||
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromNewExpression(expr);
|
||||||
|
IType type = getTypeOfPointer(expr.getExpressionType());
|
||||||
IType type = exp.getExpressionType();
|
if (type == null)
|
||||||
if (!(type instanceof IPointerType))
|
|
||||||
return null;
|
return null;
|
||||||
type = ((IPointerType) type).getType();
|
|
||||||
|
|
||||||
IASTTypeId typeId = exp.getTypeId().copy();
|
IASTTypeId typeId = expr.getTypeId().copy();
|
||||||
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
||||||
sizeExpression.setParent(exp);
|
sizeExpression.setParent(expr);
|
||||||
|
|
||||||
IASTInitializerClause[] placement = exp.getPlacementArguments();
|
IASTInitializerClause[] placement = expr.getPlacementArguments();
|
||||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||||
|
args.add(createArgForType(expr, type));
|
||||||
args.add(sizeExpression);
|
args.add(sizeExpression);
|
||||||
if (placement != null) {
|
if (placement != null) {
|
||||||
for (IASTInitializerClause p : placement) {
|
for (IASTInitializerClause p : placement) {
|
||||||
|
@ -3026,23 +3025,23 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]);
|
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) {
|
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression expr) {
|
||||||
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(expr);
|
||||||
IType classType = getNestedClassType(exp);
|
IType type = getTypeOfPointer(expr.getOperand().getExpressionType());
|
||||||
IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType), exp.getOperand()};
|
if (type == null)
|
||||||
return findOverloadedOperator(exp, args, classType, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
|
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) {
|
private static IType getTypeOfPointer(IType type) {
|
||||||
IType type = exp.getOperand().getExpressionType();
|
type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF | SemanticUtil.REF | SemanticUtil.CVTYPE);
|
||||||
type = SemanticUtil.getUltimateTypeUptoPointers(type);
|
|
||||||
if (type instanceof IPointerType) {
|
if (type instanceof IPointerType) {
|
||||||
IType classType = ((IPointerType) type).getType();
|
return getNestedType(((IPointerType) type).getType(), TDEF | REF | CVTYPE);
|
||||||
if (classType instanceof ICPPClassType)
|
|
||||||
return (ICPPClassType) classType;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -3165,10 +3164,11 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
||||||
ICPPClassType cls = getNestedClassType(expr);
|
IType t = getTypeOfPointer(expr.getOperand().getExpressionType());
|
||||||
if (cls == null)
|
if (!(t instanceof ICPPClassType))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
ICPPClassType cls = (ICPPClassType) t;
|
||||||
IScope scope = cls.getCompositeScope();
|
IScope scope = cls.getCompositeScope();
|
||||||
if (scope == null)
|
if (scope == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -3337,8 +3337,15 @@ public class CPPSemantics {
|
||||||
funcName.setParent(parent);
|
funcName.setParent(parent);
|
||||||
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
LookupData funcData = new LookupData(funcName);
|
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);
|
args= ArrayUtil.removeFirst(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
funcData.setFunctionArguments(true, args);
|
funcData.setFunctionArguments(true, args);
|
||||||
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
||||||
|
|
Loading…
Add table
Reference in a new issue