diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java index 1f781263bf8..80827a35d2e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java @@ -354,4 +354,64 @@ public class CallHierarchyBugs extends CallHierarchyBaseTest { chTree= checkTreeNode(ch, 0, "call(int)").getParent(); ti= checkTreeNode(chTree, 0, 0, "PREFIX_Test(char *, char *)"); } + + // void shared_func(); + + // #include "260262.h" + + // void call() { + // shared_func(); + // } + public void testMultiLanguageWithPrototype_260262() throws Exception { + final StringBuffer[] contents = getContentsForTest(3); + final String hcontent = contents[0].toString(); + final String content_inc = contents[1].toString(); + final String content_full = content_inc + contents[2].toString(); + IFile header= createFile(getProject(), "260262.h", hcontent); + IFile f1= createFile(getProject(), "260262.c", content_full); + IFile f2= createFile(getProject(), "260262.cpp", content_inc); + waitForIndexer(fIndex, f2, CallHierarchyBaseTest.INDEXER_WAIT_TIME); + + final CHViewPart ch= (CHViewPart) activateView(CUIPlugin.ID_CALL_HIERARCHY); + + // open editor, check outline + CEditor editor= openEditor(header); + int idx = hcontent.indexOf("shared_func()"); + editor.selectAndReveal(idx, 0); + openCallHierarchy(editor, true); + + Tree chTree= checkTreeNode(ch, 0, "shared_func()").getParent(); + TreeItem ti= checkTreeNode(chTree, 0, 0, "call()"); + checkTreeNode(chTree, 0, 1, null); + } + + // inline void shared_func() {} + + // #include "260262.h" + + // void call() { + // shared_func(); + // } + public void testMultiLanguageWithInlinedfunc_260262() throws Exception { + final StringBuffer[] contents = getContentsForTest(3); + final String hcontent = contents[0].toString(); + final String content_inc = contents[1].toString(); + final String content_full = content_inc + contents[2].toString(); + IFile header= createFile(getProject(), "260262.h", hcontent); + IFile f1= createFile(getProject(), "260262.c", content_full); + IFile f2= createFile(getProject(), "260262.cpp", content_inc); + waitForIndexer(fIndex, f2, CallHierarchyBaseTest.INDEXER_WAIT_TIME); + + final CHViewPart ch= (CHViewPart) activateView(CUIPlugin.ID_CALL_HIERARCHY); + + // open editor, check outline + CEditor editor= openEditor(header); + int idx = hcontent.indexOf("shared_func()"); + editor.selectAndReveal(idx, 0); + openCallHierarchy(editor, true); + + Tree chTree= checkTreeNode(ch, 0, "shared_func()").getParent(); + TreeItem ti= checkTreeNode(chTree, 0, 0, "call()"); + checkTreeNode(chTree, 0, 1, null); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHContentProvider.java index 2153d7bc54c..d9e8f257e93 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHContentProvider.java @@ -20,6 +20,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; @@ -129,7 +130,7 @@ public class CHContentProvider extends AsyncTreeContentProvider { }); } ITranslationUnit tu= CModelUtil.getTranslationUnit(element); - return new Object[] { new CHNode(null, tu, 0, element) }; + return new Object[] { new CHNode(null, tu, 0, element, -1) }; } finally { index.releaseReadLock(); @@ -193,7 +194,8 @@ public class CHContentProvider extends AsyncTreeContentProvider { private CHNode createRefbyNode(CHNode parent, ICElement element, IIndexName[] refs) throws CoreException { ITranslationUnit tu= CModelUtil.getTranslationUnit(element); - CHNode node= new CHNode(parent, tu, refs[0].getFile().getTimestamp(), element); + final IIndexFile file = refs[0].getFile(); + CHNode node= new CHNode(parent, tu, file.getTimestamp(), element, file.getLinkageID()); if (element instanceof IVariable || element instanceof IEnumerator) { node.setInitializer(true); } @@ -231,14 +233,15 @@ public class CHContentProvider extends AsyncTreeContentProvider { private CHNode createReftoNode(CHNode parent, ITranslationUnit tu, ICElement[] elements, IIndexName[] references) throws CoreException { assert elements.length > 0; - CHNode node; - long timestamp= references[0].getFile().getTimestamp(); + final IIndexFile file = references[0].getFile(); + final long timestamp= file.getTimestamp(); + final int linkageID= file.getLinkageID(); + CHNode node; if (elements.length == 1) { - node= new CHNode(parent, tu, timestamp, elements[0]); - } - else { - node= new CHMultiDefNode(parent, tu, timestamp, elements); + node= new CHNode(parent, tu, timestamp, elements[0], linkageID); + } else { + node= new CHMultiDefNode(parent, tu, timestamp, elements, linkageID); } boolean readAccess= false; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefChildNode.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefChildNode.java index d5905bfeaf9..5fafc58c0b4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefChildNode.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefChildNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,22 +8,18 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.callhierarchy; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; /** - * Represents a node in the include browser + * Represents a child of a node with multiple definitions. */ public class CHMultiDefChildNode extends CHNode { - /** - * Creates a new node for the include browser - */ - public CHMultiDefChildNode(CHMultiDefNode parent, ITranslationUnit fileOfReferences, long timestamp, ICElement decl) { - super(parent, fileOfReferences, timestamp, decl); + public CHMultiDefChildNode(CHMultiDefNode parent, ITranslationUnit fileOfReferences, long timestamp, ICElement decl, int linkageID) { + super(parent, fileOfReferences, timestamp, decl, linkageID); } @Override diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefNode.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefNode.java index 422eed6288d..5c6821c1dd8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefNode.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMultiDefNode.java @@ -19,8 +19,8 @@ public class CHMultiDefNode extends CHNode { private CHNode[] fChildren; - public CHMultiDefNode(CHNode parent, ITranslationUnit tu, long timestamp, ICElement[] elements) { - super(parent, tu, timestamp, null); + public CHMultiDefNode(CHNode parent, ITranslationUnit tu, long timestamp, ICElement[] elements, int linkageID) { + super(parent, tu, timestamp, null, linkageID); if (elements.length == 0) { throw new IllegalArgumentException(); } @@ -28,7 +28,7 @@ public class CHMultiDefNode extends CHNode { fChildren= new CHNode[elements.length]; for (int i = 0; i < elements.length; i++) { ICElement element = elements[i]; - fChildren[i]= new CHMultiDefChildNode(this, tu, timestamp, element); + fChildren[i]= new CHMultiDefChildNode(this, tu, timestamp, element, linkageID); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHNode.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHNode.java index 8191a0c8829..2676cb33bf6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHNode.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHNode.java @@ -39,11 +39,12 @@ public class CHNode implements IAdaptable { private boolean fIsInitializer; private boolean fIsReadAccess; private boolean fIsWriteAccess; + private final int fLinkageID; /** * Creates a new node for the include browser */ - public CHNode(CHNode parent, ITranslationUnit fileOfReferences, long timestamp, ICElement decl) { + public CHNode(CHNode parent, ITranslationUnit fileOfReferences, long timestamp, ICElement decl, int linkageID) { fParent= parent; fFileOfReferences= fileOfReferences; fReferences= Collections.emptyList(); @@ -51,6 +52,7 @@ public class CHNode implements IAdaptable { fIsRecursive= computeIsRecursive(fParent, decl); fHashCode= computeHashCode(); fTimestamp= timestamp; + fLinkageID= linkageID; } private int computeHashCode() { @@ -100,6 +102,9 @@ public class CHNode implements IAdaptable { return fParent; } + public int getLinkageID() { + return fLinkageID; + } public boolean isRecursive() { return fIsRecursive; 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 6d3616220b1..deb3e155ffe 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 @@ -16,6 +16,8 @@ import java.util.Arrays; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -51,8 +53,27 @@ public class CHQueries { if (! (callee instanceof ISourceReference)) { return EMPTY_NODES; } + boolean done= false; + int linkageID= node.getLinkageID(); + if (linkageID == -1) { + final String ct = ((ISourceReference) callee).getTranslationUnit().getContentTypeId(); + if (ct.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER)) { + // bug 260262: in a header file we need to consider c and c++ + findCalledBy(callee, ILinkage.C_LINKAGE_ID, index, result); + findCalledBy(callee, ILinkage.CPP_LINKAGE_ID, index, result); + done= true; + } + } + if (!done) { + findCalledBy(callee, linkageID, index, result); + } + return cp.createNodes(node, result); + } + + private static void findCalledBy(ICElement callee, int linkageID, IIndex index, CalledByResult result) + throws CoreException { final ICProject project = callee.getCProject(); - IIndexBinding calleeBinding= IndexUI.elementToBinding(index, callee); + IIndexBinding calleeBinding= IndexUI.elementToBinding(index, callee, linkageID); if (calleeBinding != null) { findCalledBy(index, calleeBinding, true, project, result); if (calleeBinding instanceof ICPPMethod) { @@ -66,7 +87,6 @@ public class CHQueries { } } } - return cp.createNodes(node, result); } private static void findCalledBy(IIndex index, IBinding callee, boolean includeOrdinaryCalls, ICProject project, CalledByResult result) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java index f1747bac1ef..ad21cb90d06 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java @@ -91,11 +91,15 @@ public class IndexUI { private static final ICElementHandle[] EMPTY_ELEMENTS = new ICElementHandle[0]; public static IIndexBinding elementToBinding(IIndex index, ICElement element) throws CoreException { + return elementToBinding(index, element, -1); + } + + public static IIndexBinding elementToBinding(IIndex index, ICElement element, int linkageID) throws CoreException { if (element instanceof ISourceReference) { ISourceReference sf = ((ISourceReference)element); ISourceRange range= sf.getSourceRange(); if (range.getIdLength() != 0) { - IIndexName name= elementToName(index, element); + IIndexName name= elementToName(index, element, linkageID); if (name != null) { return index.findBinding(name); } @@ -172,6 +176,10 @@ public class IndexUI { } public static IIndexName elementToName(IIndex index, ICElement element) throws CoreException { + return elementToName(index, element, -1); + } + + public static IIndexName elementToName(IIndex index, ICElement element, int linkageID) throws CoreException { if (element instanceof ISourceReference) { ISourceReference sf = ((ISourceReference)element); ITranslationUnit tu= sf.getTranslationUnit(); @@ -181,15 +189,17 @@ public class IndexUI { IIndexFile[] files= index.getFiles(location); for (int i = 0; i < files.length; i++) { IIndexFile file = files[i]; - String elementName= element.getElementName(); - int idx= elementName.lastIndexOf(":")+1; //$NON-NLS-1$ - ISourceRange pos= sf.getSourceRange(); - IRegion region = getConvertedRegion(tu, file, pos.getIdStartPos()+idx, pos.getIdLength()-idx); - IIndexName[] names= file.findNames(region.getOffset(), region.getLength()); - for (int j = 0; j < names.length; j++) { - IIndexName name = names[j]; - if (!name.isReference() && elementName.endsWith(new String(name.getSimpleID()))) { - return name; + if (linkageID == -1 || file.getLinkageID() == linkageID) { + String elementName= element.getElementName(); + int idx= elementName.lastIndexOf(":")+1; //$NON-NLS-1$ + ISourceRange pos= sf.getSourceRange(); + IRegion region = getConvertedRegion(tu, file, pos.getIdStartPos()+idx, pos.getIdLength()-idx); + IIndexName[] names= file.findNames(region.getOffset(), region.getLength()); + for (int j = 0; j < names.length; j++) { + IIndexName name = names[j]; + if (!name.isReference() && elementName.endsWith(new String(name.getSimpleID()))) { + return name; + } } } }