Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMarkus Schorn2011-07-20 06:05:13 -0400
committerMarkus Schorn2011-07-20 06:05:49 -0400
commit34fdfb11964bdd89930641b0bff118f089fdb126 (patch)
treefb7581975c772876993a4b40537c586df96d2987 /core
parent9d9efe8e9d73583167fd33ac7b696403bbccfebc (diff)
downloadorg.eclipse.cdt-34fdfb11964bdd89930641b0bff118f089fdb126.tar.gz
org.eclipse.cdt-34fdfb11964bdd89930641b0bff118f089fdb126.tar.xz
org.eclipse.cdt-34fdfb11964bdd89930641b0bff118f089fdb126.zip
Bug 351547: Resolution of delete expressions.
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java34
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java131
2 files changed, 107 insertions, 58 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
index 70f6b939bc..40ddef7549 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
@@ -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.IASTNodeSelector;
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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@@ -367,8 +368,8 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
// struct X {
// ~X();
- // void operator delete();
- // void operator delete[]();
+ // void operator delete(void *);
+ // void operator delete[](void *);
// };
//
// int test(X* x) {
@@ -393,11 +394,38 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
names = ba.getImplicitNames("delete[] x;", 6);
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);
}
+ // 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 {}
// int test(X* x) {
// X* xs = new X[5];
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 822b794a9c..dfa676eeb5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -2962,14 +2962,14 @@ public class CPPSemantics {
}
}
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) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
IType classType = getNestedClassType(exp);
- IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType)};
- return findOverloadedOperator(exp, args, classType, op, LookupMode.ALL_GLOBALS);
+ IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType), exp.getOperand()};
+ return findOverloadedOperator(exp, args, classType, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
}
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);
}
- 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,
OverloadableOperator operator, LookupMode mode) {
ICPPClassType callToObjectOfClassType= null;
@@ -3281,43 +3281,64 @@ public class CPPSemantics {
funcName.setParent(parent);
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
LookupData funcData = new LookupData(funcName);
+ if (operator == OverloadableOperator.DELETE || operator == OverloadableOperator.DELETE_ARRAY) {
+ args= ArrayUtil.removeFirst(args);
+ }
funcData.setFunctionArguments(true, args);
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 {
- if (mode != LookupMode.NO_GLOBALS) {
- IScope scope = CPPVisitor.getContainingScope(parent);
- if (scope == null)
- return null;
- lookup(funcData, scope);
- try {
- doKoenigLookup(funcData);
- } catch (DOMException e) {
- }
- // Filter with file-set
- IASTTranslationUnit tu= parent.getTranslationUnit();
- if (tu != null && funcData.foundItems instanceof Object[]) {
- final IIndexFileSet fileSet = tu.getIndexFileSet();
- if (fileSet != null) {
- int j=0;
- final Object[] items= (Object[]) funcData.foundItems;
- for (int i = 0; i < items.length; i++) {
- Object item = items[i];
- items[i]= null;
- if (item instanceof IIndexBinding) {
- if (!fileSet.containsDeclaration((IIndexBinding) item)) {
- continue;
- }
+ IScope scope = CPPVisitor.getContainingScope(parent);
+ if (scope == null)
+ return null;
+ lookup(funcData, scope);
+ try {
+ doKoenigLookup(funcData);
+ } catch (DOMException e) {
+ }
+ // Filter with file-set
+ IASTTranslationUnit tu= parent.getTranslationUnit();
+ if (tu != null && funcData.foundItems instanceof Object[]) {
+ final IIndexFileSet fileSet = tu.getIndexFileSet();
+ if (fileSet != null) {
+ int j=0;
+ final Object[] items= (Object[]) funcData.foundItems;
+ for (int i = 0; i < items.length; i++) {
+ Object item = items[i];
+ items[i]= null;
+ if (item instanceof IIndexBinding) {
+ if (!fileSet.containsDeclaration((IIndexBinding) item)) {
+ continue;
}
- items[j++]= item;
}
+ items[j++]= item;
}
}
}
} catch (DOMException e) {
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
// However, if no operand type has class type, only those non-member functions ...
if (mode == LookupMode.LIMITED_GLOBALS) {
@@ -3348,31 +3369,31 @@ public class CPPSemantics {
}
}
}
-
- if (callToObjectOfClassType != null) {
- try {
- // 13.3.1.1.2 call to object of class type
- ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType);
- for (ICPPMethod op : ops) {
- if (op.isExplicit())
- continue;
- IFunctionType ft= op.getType();
- if (ft != null) {
- IType rt= SemanticUtil.getNestedType(ft.getReturnType(), SemanticUtil.TDEF);
- if (rt instanceof IPointerType) {
- IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF);
- if (ptt instanceof IFunctionType) {
- IFunctionType ft2= (IFunctionType) ptt;
- IBinding sf= createSurrogateCallFunction(parent.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes());
- mergeResults(funcData, sf, false);
- }
- }
- }
- }
- } catch (DOMException e) {
- return null;
- }
- }
+ }
+
+ if (callToObjectOfClassType != null) {
+ try {
+ // 13.3.1.1.2 call to object of class type
+ ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType);
+ for (ICPPMethod op : ops) {
+ if (op.isExplicit())
+ continue;
+ IFunctionType ft= op.getType();
+ if (ft != null) {
+ IType rt= SemanticUtil.getNestedType(ft.getReturnType(), SemanticUtil.TDEF);
+ if (rt instanceof IPointerType) {
+ IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF);
+ if (ptt instanceof IFunctionType) {
+ IFunctionType ft2= (IFunctionType) ptt;
+ IBinding sf= createSurrogateCallFunction(parent.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes());
+ mergeResults(funcData, sf, false);
+ }
+ }
+ }
+ }
+ } catch (DOMException e) {
+ return null;
+ }
}
if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) {

Back to the top