From c83768bd6f1b5629264a817b75e6f0eab15857ad Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 28 Nov 2011 09:35:33 +0100 Subject: [PATCH] Bug 363731: Call Hierarchy for address of overridden method. --- .../internal/index/tests/IndexNamesTests.java | 36 +++++++++++++++++++ .../core/pdom/dom/cpp/PDOMCPPMethod.java | 28 ++++++++++++--- .../internal/ui/callhierarchy/CHQueries.java | 2 +- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexNamesTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexNamesTests.java index 69ae8c4a08d..2b690924beb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexNamesTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexNamesTests.java @@ -287,6 +287,42 @@ public class IndexNamesTests extends BaseTestCase { fIndex.releaseReadLock(); } } + + // class A { + // virtual void foo(){} + // template void SetCallback(C callback){} + // void InitCallback() { + // SetCallback(&A::foo); // Can be A::foo or B::foo + // } + // }; + // class B: public A { + // virtual void foo(){} + // }; + public void testAddressOfPolymorphicMethod_Bug363731() throws Exception { + waitForIndexer(); + String content= getComment(); + IFile file= createFile(getProject().getProject(), "test.cpp", content); + waitUntilFileIsIndexed(file, 4000); + + fIndex.acquireReadLock(); + try { + IIndexFile ifile= getIndexFile(ILinkage.CPP_LINKAGE_ID, file); + IIndexName[] names= ifile.findNames(0, content.length()); + int j= 0; + for (IIndexName indexName : names) { + if (indexName.isReference() && indexName.toString().equals("foo")) { + assertEquals(true, indexName.couldBePolymorphicMethodCall()); + assertEquals("A", CPPVisitor.getQualifiedName(fIndex.findBinding(indexName))[0]); + j++; + } else { + assertEquals(false, indexName.couldBePolymorphicMethodCall()); + } + } + assertEquals(1, j); + } finally { + fIndex.releaseReadLock(); + } + } // int _i, ri, wi, rwi; // int* rp; int* wp; int* rwp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java index 9262f137782..df9d4578aa9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; @@ -110,6 +111,7 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { return IIndexCPPBindingConstants.CPPMETHOD; } + @Override public boolean isVirtual() { return getBit(getAnnotation1(), PDOMCPPAnnotation.VIRTUAL_OFFSET); } @@ -120,10 +122,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { return annotation1; } + @Override public boolean isPureVirtual() { return getBit(getAnnotation1(), PDOMCPPAnnotation.PURE_VIRTUAL_OFFSET); } + @Override public boolean isDestructor() { return getBit(getAnnotation1(), PDOMCPPAnnotation.DESTRUCTOR_OFFSET); } @@ -133,10 +137,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { return false; } + @Override public boolean isImplicit() { return getBit(getAnnotation1(), PDOMCPPAnnotation.IMPLICIT_METHOD_OFFSET); } + @Override public boolean isExplicit() { return getBit(getAnnotation1(), PDOMCPPAnnotation.EXPLICIT_METHOD_OFFSET); } @@ -169,10 +175,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { return false; } + @Override public int getVisibility() { return PDOMCPPAnnotation.getVisibility(getAnnotation()); } + @Override public ICPPClassType getClassOwner() { return (ICPPClassType) getOwner(); } @@ -194,8 +202,19 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { IASTNode parent= name.getParent(); - if (parent instanceof ICPPASTFieldReference) { - // the name is not qualified + if (parent instanceof ICPPASTQualifiedName) { + // When taking the address of a method it will be called without suppressing + // the virtual mechanism + parent= parent.getParent(); + if (parent instanceof IASTIdExpression) { + parent= parent.getParent(); + if (parent instanceof IASTUnaryExpression) { + if (((IASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_amper) + return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; + } + } + } else if (parent instanceof ICPPASTFieldReference) { + // The name is not qualified ICPPASTFieldReference fr= (ICPPASTFieldReference) parent; parent= parent.getParent(); if (parent instanceof IASTFunctionCallExpression) { @@ -221,9 +240,8 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod { return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } } - } - // calling a member from within a member - else if (parent instanceof IASTIdExpression) { + } else if (parent instanceof IASTIdExpression) { + // Calling a member from within a member if (parent.getParent() instanceof IASTFunctionCallExpression) { return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java index c72ba3b6a43..ecf68a72717 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java @@ -130,7 +130,7 @@ public class CHQueries { if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) { while (true) { ICElement[] defs= null; - if (binding instanceof ICPPMethod) { + if (binding instanceof ICPPMethod && name.couldBePolymorphicMethodCall()) { defs = findOverriders(index, (ICPPMethod) binding); } if (defs == null) {