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

Bug 351547: Resolution of delete expressions.

This commit is contained in:
Markus Schorn 2011-07-20 12:05:13 +02:00
parent 9d9efe8e9d
commit 34fdfb1196
2 changed files with 107 additions and 58 deletions

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -367,8 +368,8 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
// struct X { // struct X {
// ~X(); // ~X();
// void operator delete(); // void operator delete(void *);
// void operator delete[](); // void operator delete[](void *);
// }; // };
// //
// int test(X* x) { // int test(X* x) {
@ -393,11 +394,38 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
names = ba.getImplicitNames("delete[] x;", 6); names = ba.getImplicitNames("delete[] x;", 6);
assertEquals(1, names.length); assertEquals(1, names.length);
assertSame(col.getName(3).resolveBinding(), names[0].resolveBinding()); assertSame(col.getName(4).resolveBinding(), names[0].resolveBinding());
ba.assertNoImplicitName("delete 1;", 6); ba.assertNoImplicitName("delete 1;", 6);
} }
// struct A {
// void operator delete(void * a);
// };
// struct B {};
// void operator delete(void * b);
//
// void test() {
// A *a = new A;
// delete a;
//
// B* b = new B;
// delete b;
// }
public void testOverloadedDelete_Bug351547() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
IBinding m= bh.assertNonProblem("operator delete(void * a)", 15);
IBinding f= bh.assertNonProblem("operator delete(void * b)", 15);
IASTImplicitName[] names = bh.getImplicitNames("delete a;", 6);
assertEquals(2, names.length);
assertSame(m, names[1].resolveBinding());
names = bh.getImplicitNames("delete b;", 6);
assertEquals(2, names.length);
assertSame(f, names[1].resolveBinding());
}
// struct X {} // struct X {}
// int test(X* x) { // int test(X* x) {
// X* xs = new X[5]; // X* xs = new X[5];

View file

@ -2962,14 +2962,14 @@ 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.ALL_GLOBALS); return findOverloadedOperator(exp, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
} }
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) { public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp); OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
IType classType = getNestedClassType(exp); IType classType = getNestedClassType(exp);
IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType)}; IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType), exp.getOperand()};
return findOverloadedOperator(exp, args, classType, op, LookupMode.ALL_GLOBALS); return findOverloadedOperator(exp, args, classType, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
} }
private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) { private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
@ -3228,7 +3228,7 @@ public class CPPSemantics {
return findOverloadedOperator(fieldRef, new IASTExpression[] {arg}, classType, OverloadableOperator.ARROW, LookupMode.NO_GLOBALS); return findOverloadedOperator(fieldRef, new IASTExpression[] {arg}, classType, OverloadableOperator.ARROW, LookupMode.NO_GLOBALS);
} }
private static enum LookupMode {NO_GLOBALS, LIMITED_GLOBALS, ALL_GLOBALS} private static enum LookupMode {NO_GLOBALS, GLOBALS_IF_NO_MEMBERS, LIMITED_GLOBALS, ALL_GLOBALS}
private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTInitializerClause[] args, IType methodLookupType, private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTInitializerClause[] args, IType methodLookupType,
OverloadableOperator operator, LookupMode mode) { OverloadableOperator operator, LookupMode mode) {
ICPPClassType callToObjectOfClassType= null; ICPPClassType callToObjectOfClassType= null;
@ -3281,36 +3281,39 @@ 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) {
args= ArrayUtil.removeFirst(args);
}
funcData.setFunctionArguments(true, args); funcData.setFunctionArguments(true, args);
funcData.ignoreMembers = true; // (13.3.1.2.3) funcData.ignoreMembers = true; // (13.3.1.2.3)
if (mode != LookupMode.NO_GLOBALS || callToObjectOfClassType != null) { boolean haveMembers= methodData != null && methodData.hasResults();
if (mode == LookupMode.ALL_GLOBALS || mode == LookupMode.LIMITED_GLOBALS
|| (mode == LookupMode.GLOBALS_IF_NO_MEMBERS && !haveMembers)) {
try { try {
if (mode != LookupMode.NO_GLOBALS) { IScope scope = CPPVisitor.getContainingScope(parent);
IScope scope = CPPVisitor.getContainingScope(parent); if (scope == null)
if (scope == null) return null;
return null; lookup(funcData, scope);
lookup(funcData, scope); try {
try { doKoenigLookup(funcData);
doKoenigLookup(funcData); } catch (DOMException e) {
} catch (DOMException e) { }
} // Filter with file-set
// Filter with file-set IASTTranslationUnit tu= parent.getTranslationUnit();
IASTTranslationUnit tu= parent.getTranslationUnit(); if (tu != null && funcData.foundItems instanceof Object[]) {
if (tu != null && funcData.foundItems instanceof Object[]) { final IIndexFileSet fileSet = tu.getIndexFileSet();
final IIndexFileSet fileSet = tu.getIndexFileSet(); if (fileSet != null) {
if (fileSet != null) { int j=0;
int j=0; final Object[] items= (Object[]) funcData.foundItems;
final Object[] items= (Object[]) funcData.foundItems; for (int i = 0; i < items.length; i++) {
for (int i = 0; i < items.length; i++) { Object item = items[i];
Object item = items[i]; items[i]= null;
items[i]= null; if (item instanceof IIndexBinding) {
if (item instanceof IIndexBinding) { if (!fileSet.containsDeclaration((IIndexBinding) item)) {
if (!fileSet.containsDeclaration((IIndexBinding) item)) { continue;
continue;
}
} }
items[j++]= item;
} }
items[j++]= item;
} }
} }
} }
@ -3318,6 +3321,24 @@ public class CPPSemantics {
return null; return null;
} }
if (operator == OverloadableOperator.NEW || operator == OverloadableOperator.DELETE
|| operator == OverloadableOperator.NEW_ARRAY || operator == OverloadableOperator.DELETE_ARRAY) {
// Those operators replace the built-in operator
Object[] items= (Object[]) funcData.foundItems;
int j= 0;
for (Object object : items) {
if (object instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) object;
if (!(func instanceof CPPImplicitFunction))
items[j++]= func;
}
}
if (j>0) {
while (j < items.length)
items[j++]= null;
}
}
// 13.3.1.2.3 // 13.3.1.2.3
// However, if no operand type has class type, only those non-member functions ... // However, if no operand type has class type, only those non-member functions ...
if (mode == LookupMode.LIMITED_GLOBALS) { if (mode == LookupMode.LIMITED_GLOBALS) {
@ -3348,31 +3369,31 @@ public class CPPSemantics {
} }
} }
} }
}
if (callToObjectOfClassType != null) { if (callToObjectOfClassType != null) {
try { try {
// 13.3.1.1.2 call to object of class type // 13.3.1.1.2 call to object of class type
ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType); ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType);
for (ICPPMethod op : ops) { for (ICPPMethod op : ops) {
if (op.isExplicit()) if (op.isExplicit())
continue; continue;
IFunctionType ft= op.getType(); IFunctionType ft= op.getType();
if (ft != null) { if (ft != null) {
IType rt= SemanticUtil.getNestedType(ft.getReturnType(), SemanticUtil.TDEF); IType rt= SemanticUtil.getNestedType(ft.getReturnType(), SemanticUtil.TDEF);
if (rt instanceof IPointerType) { if (rt instanceof IPointerType) {
IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF); IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF);
if (ptt instanceof IFunctionType) { if (ptt instanceof IFunctionType) {
IFunctionType ft2= (IFunctionType) ptt; IFunctionType ft2= (IFunctionType) ptt;
IBinding sf= createSurrogateCallFunction(parent.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes()); IBinding sf= createSurrogateCallFunction(parent.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes());
mergeResults(funcData, sf, false); mergeResults(funcData, sf, false);
} }
} }
} }
} }
} catch (DOMException e) { } catch (DOMException e) {
return null; return null;
} }
}
} }
if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) { if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) {