1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-16 04:35:45 +02:00

Bug 363731: Call Hierarchy for address of overridden method.

This commit is contained in:
Markus Schorn 2011-11-28 09:35:33 +01:00
parent 93285e7f68
commit c83768bd6f
3 changed files with 60 additions and 6 deletions

View file

@ -288,6 +288,42 @@ public class IndexNamesTests extends BaseTestCase {
} }
} }
// class A {
// virtual void foo(){}
// template<typename C> 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 _i, ri, wi, rwi;
// int* rp; int* wp; int* rwp; // int* rp; int* wp; int* rwp;
// const int* cip= &ri; // const int* cip= &ri;

View file

@ -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.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; 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.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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
@ -110,6 +111,7 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return IIndexCPPBindingConstants.CPPMETHOD; return IIndexCPPBindingConstants.CPPMETHOD;
} }
@Override
public boolean isVirtual() { public boolean isVirtual() {
return getBit(getAnnotation1(), PDOMCPPAnnotation.VIRTUAL_OFFSET); return getBit(getAnnotation1(), PDOMCPPAnnotation.VIRTUAL_OFFSET);
} }
@ -120,10 +122,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return annotation1; return annotation1;
} }
@Override
public boolean isPureVirtual() { public boolean isPureVirtual() {
return getBit(getAnnotation1(), PDOMCPPAnnotation.PURE_VIRTUAL_OFFSET); return getBit(getAnnotation1(), PDOMCPPAnnotation.PURE_VIRTUAL_OFFSET);
} }
@Override
public boolean isDestructor() { public boolean isDestructor() {
return getBit(getAnnotation1(), PDOMCPPAnnotation.DESTRUCTOR_OFFSET); return getBit(getAnnotation1(), PDOMCPPAnnotation.DESTRUCTOR_OFFSET);
} }
@ -133,10 +137,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return false; return false;
} }
@Override
public boolean isImplicit() { public boolean isImplicit() {
return getBit(getAnnotation1(), PDOMCPPAnnotation.IMPLICIT_METHOD_OFFSET); return getBit(getAnnotation1(), PDOMCPPAnnotation.IMPLICIT_METHOD_OFFSET);
} }
@Override
public boolean isExplicit() { public boolean isExplicit() {
return getBit(getAnnotation1(), PDOMCPPAnnotation.EXPLICIT_METHOD_OFFSET); return getBit(getAnnotation1(), PDOMCPPAnnotation.EXPLICIT_METHOD_OFFSET);
} }
@ -169,10 +175,12 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return false; return false;
} }
@Override
public int getVisibility() { public int getVisibility() {
return PDOMCPPAnnotation.getVisibility(getAnnotation()); return PDOMCPPAnnotation.getVisibility(getAnnotation());
} }
@Override
public ICPPClassType getClassOwner() { public ICPPClassType getClassOwner() {
return (ICPPClassType) getOwner(); return (ICPPClassType) getOwner();
} }
@ -194,8 +202,19 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
public int getAdditionalNameFlags(int standardFlags, IASTName name) { public int getAdditionalNameFlags(int standardFlags, IASTName name) {
if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) {
IASTNode parent= name.getParent(); IASTNode parent= name.getParent();
if (parent instanceof ICPPASTFieldReference) { if (parent instanceof ICPPASTQualifiedName) {
// the name is not qualified // 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; ICPPASTFieldReference fr= (ICPPASTFieldReference) parent;
parent= parent.getParent(); parent= parent.getParent();
if (parent instanceof IASTFunctionCallExpression) { if (parent instanceof IASTFunctionCallExpression) {
@ -221,9 +240,8 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL;
} }
} }
} } else if (parent instanceof IASTIdExpression) {
// calling a member from within a member // Calling a member from within a member
else if (parent instanceof IASTIdExpression) {
if (parent.getParent() instanceof IASTFunctionCallExpression) { if (parent.getParent() instanceof IASTFunctionCallExpression) {
return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL;
} }

View file

@ -130,7 +130,7 @@ public class CHQueries {
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) { if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
while (true) { while (true) {
ICElement[] defs= null; ICElement[] defs= null;
if (binding instanceof ICPPMethod) { if (binding instanceof ICPPMethod && name.couldBePolymorphicMethodCall()) {
defs = findOverriders(index, (ICPPMethod) binding); defs = findOverriders(index, (ICPPMethod) binding);
} }
if (defs == null) { if (defs == null) {