diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EnclosingNamesTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EnclosingNamesTest.java
new file mode 100644
index 00000000000..737ead8c376
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EnclosingNamesTest.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.index.tests;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMManager;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexName;
+import org.eclipse.cdt.core.index.IndexFilter;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.core.testplugin.CTestPlugin;
+import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
+import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
+import org.eclipse.cdt.internal.core.CCoreInternals;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+public class EnclosingNamesTest extends BaseTestCase {
+ private static final IProgressMonitor NPM = new NullProgressMonitor();
+ private ICProject fCProject;
+ protected IIndex fIndex;
+
+ public EnclosingNamesTest(String name) {
+ super(name);
+ }
+
+ public static TestSuite suite() {
+ return suite(EnclosingNamesTest.class);
+ }
+
+ protected void setUp() throws CoreException {
+ fCProject= CProjectHelper.createCCProject("__encNamesTest__", "bin", IPDOMManager.ID_FAST_INDEXER);
+ CCoreInternals.getPDOMManager().reindex(fCProject);
+ fIndex= CCorePlugin.getIndexManager().getIndex(fCProject);
+ }
+
+ protected void tearDown() throws CoreException {
+ if (fCProject != null) {
+ CProjectHelper.delete(fCProject);
+ }
+ }
+
+ protected IProject getProject() {
+ return fCProject.getProject();
+ }
+
+ protected StringBuffer[] getContentsForTest(int blocks) throws IOException {
+ return TestSourceReader.getContentsForTest(
+ CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), blocks);
+ }
+
+ protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {
+ return TestSourceReader.createFile(container, new Path(fileName), contents);
+ }
+
+ protected void waitForIndexer() {
+ assertTrue(CCorePlugin.getIndexManager().joinIndexer(10000, NPM));
+ }
+
+ protected Pattern[] getPattern(String qname) {
+ String[] parts= qname.split("::");
+ Pattern[] result= new Pattern[parts.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i]= Pattern.compile(parts[i]);
+ }
+ return result;
+ }
+
+ protected void waitUntilFileIsIndexed(IFile file, int time) throws Exception {
+ TestSourceReader.waitUntilFileIsIndexed(fIndex, file, time);
+ }
+
+ // void func();
+ // int var;
+ //
+ // void main() {
+ // func();
+ // var=1;
+ // };
+ public void testNestingWithFunction() throws Exception {
+ waitForIndexer();
+ String content= getContentsForTest(1)[0].toString();
+ IFile file= createFile(getProject().getProject(), "test.cpp", content);
+ waitUntilFileIsIndexed(file, 4000);
+
+ fIndex.acquireReadLock();
+ try {
+ IIndexBinding[] mainBS= fIndex.findBindings(getPattern("main"), true, IndexFilter.ALL, NPM);
+ assertLength(1, mainBS);
+ IIndexBinding mainB= mainBS[0];
+
+ IIndexName[] names= fIndex.findDefinitions(mainB);
+ assertLength(1, names);
+ IIndexName main= names[0];
+
+ assertNull(main.getEnclosingDefinition());
+ IIndexName[] enclosed= main.getEnclosedNames();
+ assertLength(2, enclosed);
+ assertName("func", enclosed[0]);
+ assertName("var", enclosed[1]);
+
+ IIndexName enclosing= enclosed[0].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("main", enclosing);
+
+ enclosing= enclosed[1].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("main", enclosing);
+ }
+ finally {
+ fIndex.releaseReadLock();
+ }
+ }
+
+ private void assertName(String name, IIndexName iname) {
+ assertEquals(name, new String(iname.toCharArray()));
+ }
+
+ private void assertLength(int length, Object[] array) {
+ assertNotNull(array);
+ assertEquals(length, array.length);
+ }
+
+ // class C {
+ // public:
+ // void func();
+ // int var;
+ // };
+ //
+ // void main() {
+ // C c;
+ // c.func();
+ // c.var=1;
+ // };
+ // void C::func() {
+ // func();
+ // var=1;
+ // };
+
+
+ public void testNestingWithMethod() throws Exception {
+ waitForIndexer();
+ String content= getContentsForTest(1)[0].toString();
+ IFile file= createFile(getProject().getProject(), "test.cpp", content);
+ waitUntilFileIsIndexed(file, 4000);
+
+ fIndex.acquireReadLock();
+ try {
+ IIndexBinding[] mainBS= fIndex.findBindings(getPattern("main"), true, IndexFilter.ALL, NPM);
+ assertLength(1, mainBS);
+ IIndexBinding mainB= mainBS[0];
+
+ IIndexName[] names= fIndex.findDefinitions(mainB);
+ assertLength(1, names);
+ IIndexName main= names[0];
+
+ assertNull(main.getEnclosingDefinition());
+ IIndexName[] enclosed= main.getEnclosedNames();
+ assertLength(3, enclosed);
+ assertName("C", enclosed[0]);
+ assertName("func", enclosed[1]);
+ assertName("var", enclosed[2]);
+
+ IIndexName enclosing= enclosed[0].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("main", enclosing);
+
+ enclosing= enclosed[1].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("main", enclosing);
+
+ enclosing= enclosed[2].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("main", enclosing);
+
+ IIndexBinding funcB= fIndex.findBinding(enclosed[1]);
+ assertNotNull(funcB);
+ names= fIndex.findDefinitions(funcB);
+ assertLength(1, names);
+ IIndexName funcdef= names[0];
+
+ assertNull(funcdef.getEnclosingDefinition());
+ enclosed= funcdef.getEnclosedNames();
+ assertLength(3, enclosed);
+ assertName("C", enclosed[0]);
+ assertName("func", enclosed[1]);
+ assertName("var", enclosed[2]);
+
+ enclosing= enclosed[0].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("func", enclosing);
+
+ enclosing= enclosed[1].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("func", enclosing);
+
+ enclosing= enclosed[2].getEnclosingDefinition();
+ assertNotNull(enclosing);
+ assertName("func", enclosing);
+ }
+ finally {
+ fIndex.releaseReadLock();
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
index f3e90ee0dec..37a5d28d69c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java
@@ -74,8 +74,9 @@ public class IndexBugsTests extends BaseTestCase {
return fCProject.getProject();
}
- protected String readTaggedComment(final String tag) throws IOException {
- return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "parser", getClass(), tag);
+ protected StringBuffer[] getContentsForTest(int blocks) throws IOException {
+ return TestSourceReader.getContentsForTest(
+ CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), blocks);
}
protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {
@@ -99,7 +100,6 @@ public class IndexBugsTests extends BaseTestCase {
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, time);
}
- // {bug162011}
// namespace ns162011 {
// class Class162011 {
// friend void function162011(Class162011);
@@ -107,7 +107,7 @@ public class IndexBugsTests extends BaseTestCase {
// void function162011(Class162011 x){};
// }
public void testBug162011() throws Exception {
- String content = readTaggedComment("bug162011");
+ String content = getContentsForTest(1)[0].toString();
String fileName = "bug162011.cpp";
String funcName = "function162011";
String nsName = "ns162011";
@@ -247,13 +247,12 @@ public class IndexBugsTests extends BaseTestCase {
}
}
- // {test164500}
// #define macro164500 1
// #undef macro164500
// #define macro164500 2
public void test164500() throws Exception {
waitForIndexer();
- String content= readTaggedComment("test164500");
+ String content= getContentsForTest(1)[0].toString();
IFile file= TestSourceReader.createFile(fCProject.getProject(), "test164500.cpp", content);
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, 4000);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
index 813fef12e04..719daa4c9ba 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -108,4 +109,12 @@ public interface IASTNode {
*/
public String getRawSignature();
+ /**
+ * Returns whether this node contains the given one. The decision is made
+ * purly on location information and therefore the method is fast.
+ * @param node the node to check
+ * @return whether this node contains the given one.
+ * @since 4.0
+ */
+ public boolean contains(IASTNode node);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexName.java
index 36b24b179a0..7c6b79fa1fd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexName.java
@@ -51,4 +51,20 @@ public interface IIndexName extends IName {
* Returns the length of the name.
*/
public int getNodeLength();
+
+ /**
+ * Returns the name of the definition that contains this name.
+ * May return null
.
+ * Currently this is implemented for function and method definitions, only.
+ */
+ public IIndexName getEnclosingDefinition() throws CoreException;
+
+ /**
+ * Returns the names of the references contained in this definition.
+ * Returns null
, if the name is not a definition.
+ *
+ * Currently the method works with function definitions, only.
+ */
+ public IIndexName[] getEnclosedNames() throws CoreException;
+
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
index 9f2d687e3af..209e9cba88a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@@ -112,4 +113,12 @@ public abstract class ASTNode implements IASTNode {
return true;
}
+ public boolean contains(IASTNode node) {
+ if (node instanceof ASTNode) {
+ ASTNode astNode= (ASTNode) node;
+ return offset <= astNode.offset &&
+ astNode.offset+astNode.length <= offset+length;
+ }
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
index e6f1c54b6e3..0b1ba63822a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java
@@ -35,7 +35,7 @@ public interface IWritableIndex extends IIndex {
*/
void setFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes,
- IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException;
+ IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException;
/**
* Clears the entire index.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
index f17787f1d1b..091cfaa3a2e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java
@@ -41,7 +41,7 @@ public interface IWritableIndexFragment extends IIndexFragment {
*/
void addFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles,
- IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException;
+ IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException;
/**
* Acquires a write lock, while giving up a certain amount of read locks.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
index 27a290d472c..dd43f620d71 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java
@@ -57,7 +57,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
public void setFileContent(IIndexFragmentFile file,
IASTPreprocessorIncludeStatement[] includes,
- IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException {
+ IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException {
IIndexFragment indexFragment = file.getIndexFragment();
assert isWritableFragment(indexFragment);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 50fbf929165..0eff27a8552 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -64,7 +64,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private Database db;
- public static final int VERSION = 16;
+ public static final int VERSION = 17;
// 0 - the beginning of it all
// 1 - first change to kick off upgrades
// 2 - added file inclusions
@@ -82,6 +82,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
// 14 - added timestamps for files (bug 149571)
// 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540).
// 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing
+ // 17 - use single linked list for names in file, adds a link to enclosing defintion name.
public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;
@@ -460,7 +461,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
}
}
- public void releaseWriteLock() {
+ final public void releaseWriteLock() {
releaseWriteLock(0);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index 39f849286a1..797c1375bcf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.core.runtime.CoreException;
@@ -35,22 +36,14 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void addFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles,
- IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException {
+ IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException {
assert sourceFile.getIndexFragment() == this;
+ assert includes.length == destFiles.length;
PDOMFile pdomFile = (PDOMFile) sourceFile;
pdomFile.addIncludesTo(destFiles, includes);
pdomFile.addMacros(macros);
- for (int i = 0; i < names.length; i++) {
- IASTName name= names[i];
- PDOMLinkage linkage= createLinkage(name.getLinkage().getID());
- if (linkage == null) {
- CCorePlugin.log(MessageFormat.format(Messages.WritablePDOM_error_unknownLinkage, new Object[]{name.getLinkage()}));
- }
- else {
- linkage.addName(name, pdomFile);
- }
- }
+ pdomFile.addNames(names);
}
public void clearFile(IIndexFragmentFile file) throws CoreException {
@@ -61,4 +54,16 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void clear() throws CoreException {
super.clear();
}
+
+ public PDOMBinding addBinding(IASTName name) throws CoreException {
+ PDOMBinding result= null;
+ PDOMLinkage linkage= createLinkage(name.getLinkage().getID());
+ if (linkage == null) {
+ CCorePlugin.log(MessageFormat.format(Messages.WritablePDOM_error_unknownLinkage, new Object[]{name.getLinkage()}));
+ }
+ else {
+ result= linkage.addBinding(name);
+ }
+ return result;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
index 10304ebf51f..918137bfa47 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
@@ -12,8 +12,10 @@
package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.index.IIndexInclude;
@@ -22,6 +24,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@@ -149,15 +152,6 @@ public class PDOMFile implements IIndexFragmentFile {
pdom.getDB().putInt(record + FIRST_NAME, namerec);
}
- public void addName(PDOMName name) throws CoreException {
- PDOMName firstName = getFirstName();
- if (firstName != null) {
- name.setNextInFile(firstName);
- firstName.setPrevInFile(name);
- }
- setFirstName(name);
- }
-
public PDOMInclude getFirstInclude() throws CoreException {
int increc = pdom.getDB().getInt(record + FIRST_INCLUDE);
return increc != 0 ? new PDOMInclude(pdom, increc) : null;
@@ -205,6 +199,36 @@ public class PDOMFile implements IIndexFragmentFile {
}
}
+ public void addNames(IASTName[][] names) throws CoreException {
+ assert getFirstName() == null;
+ HashMap nameCache= new HashMap();
+ PDOMName lastName= null;
+ for (int i = 0; i < names.length; i++) {
+ IASTName[] name = names[i];
+ PDOMName caller= (PDOMName) nameCache.get(name[1]);
+ PDOMName pdomName = createPDOMName(name[0], caller);
+ if (pdomName != null) {
+ nameCache.put(name[0], pdomName);
+ if (lastName == null) {
+ setFirstName(pdomName);
+ }
+ else {
+ lastName.setNextInFile(pdomName);
+ }
+ lastName= pdomName;
+ }
+ }
+ }
+
+ private PDOMName createPDOMName(IASTName name, PDOMName caller) throws CoreException {
+ PDOMName result= null;
+ PDOMBinding binding= ((WritablePDOM) pdom).addBinding(name);
+ if (binding != null) {
+ result= new PDOMName(pdom, name, this, binding, caller);
+ }
+ return result;
+ }
+
public void clear() throws CoreException {
// Remove the includes
PDOMInclude include = getFirstInclude();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
index e8ed93c983e..27fd71cd875 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
@@ -168,7 +168,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IBindingIdent
};
}
- public abstract PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException;
+ public abstract PDOMBinding addBinding(IASTName name) throws CoreException;
public abstract PDOMBinding adaptBinding(IBinding binding) throws CoreException;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
index 6b613d21fba..e7427d6393c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java
@@ -11,10 +11,13 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
+import java.util.ArrayList;
+
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.index.IIndexFile;
+import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IIndexProxyBinding;
@@ -32,23 +35,23 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
private final int record;
private static final int FILE_REC_OFFSET = 0;
- private static final int FILE_PREV_OFFSET = 4;
- private static final int FILE_NEXT_OFFSET = 8;
+ private static final int FILE_NEXT_OFFSET = 4;
+ private static final int CALLER_REC_OFFSET = 8;
private static final int BINDING_REC_OFFSET = 12;
private static final int BINDING_PREV_OFFSET = 16;
private static final int BINDING_NEXT_OFFSET = 20;
private static final int NODE_OFFSET_OFFSET = 24;
- private static final int NODE_LENGTH_OFFSET = 28;
- private static final int FLAGS = 32;
+ private static final int NODE_LENGTH_OFFSET = 28; // short
+ private static final int FLAGS = 30; // byte
- private static final int RECORD_SIZE = 33;
+ private static final int RECORD_SIZE = 31;
private static final int IS_DECLARATION = 1;
private static final int IS_DEFINITION = 2;
private static final int IS_REFERENCE = 3;
- public PDOMName(PDOM pdom, IASTName name, PDOMFile file, PDOMBinding binding) throws CoreException {
+ public PDOMName(PDOM pdom, IASTName name, PDOMFile file, PDOMBinding binding, PDOMName caller) throws CoreException {
this.pdom = pdom;
Database db = pdom.getDB();
record = db.malloc(RECORD_SIZE);
@@ -80,14 +83,15 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
db.putInt(record + BINDING_REC_OFFSET, binding.getRecord());
}
- // Hook us up the the liked name list from file
db.putInt(record + FILE_REC_OFFSET, file.getRecord());
- file.addName(this);
+ if (caller != null) {
+ db.putInt(record + CALLER_REC_OFFSET, caller.getRecord());
+ }
// Record our location in the file
IASTFileLocation fileloc = name.getFileLocation();
db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset());
- db.putInt(record + NODE_LENGTH_OFFSET, fileloc.getNodeLength());
+ db.putShort(record + NODE_LENGTH_OFFSET, (short) fileloc.getNodeLength());
}
public PDOMName(PDOM pdom, int nameRecord) {
@@ -147,6 +151,15 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
int filerec = pdom.getDB().getInt(record + FILE_REC_OFFSET);
return filerec != 0 ? new PDOMFile(pdom, filerec) : null;
}
+
+ public IIndexName getEnclosingDefinition() throws CoreException {
+ int namerec = getEnclosingDefinitionRecord();
+ return namerec != 0 ? new PDOMName(pdom, namerec) : null;
+ }
+
+ private int getEnclosingDefinitionRecord() throws CoreException {
+ return pdom.getDB().getInt(record + CALLER_REC_OFFSET);
+ }
public PDOMName getNextInFile() throws CoreException {
return getNameField(FILE_NEXT_OFFSET);
@@ -155,15 +168,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public void setNextInFile(PDOMName name) throws CoreException {
setNameField(FILE_NEXT_OFFSET, name);
}
-
- public PDOMName getPrevInFile() throws CoreException {
- return getNameField(FILE_PREV_OFFSET);
- }
-
- public void setPrevInFile(PDOMName name) throws CoreException {
- setNameField(FILE_PREV_OFFSET, name);
- }
-
+
public PDOMBinding resolveBinding() {
try {
int bindingRecord = pdom.getDB().getInt(record + BINDING_REC_OFFSET);
@@ -248,7 +253,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public int getNodeLength() {
try {
- return pdom.getDB().getInt(record + NODE_LENGTH_OFFSET);
+ return pdom.getDB().getShort(record + NODE_LENGTH_OFFSET);
} catch (CoreException e) {
CCorePlugin.log(e);
return 0;
@@ -298,4 +303,16 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public IIndexProxyBinding getBinding() throws CoreException {
return getPDOMBinding();
}
+
+ public IIndexName[] getEnclosedNames() throws CoreException {
+ ArrayList result= new ArrayList();
+ PDOMName name= getNextInFile();
+ while (name != null) {
+ if (name.getEnclosingDefinitionRecord() == record) {
+ result.add(name);
+ }
+ name= name.getNextInFile();
+ }
+ return (IIndexName[]) result.toArray(new IIndexName[result.size()]);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
index ab671442e13..7f0cee55d42 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
@@ -43,9 +43,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.FindBindingByLinkageConstant;
import org.eclipse.cdt.internal.core.pdom.dom.FindEquivalentBinding;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
-import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
-import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
@@ -85,9 +83,7 @@ class PDOMCLinkage extends PDOMLinkage {
return new GCCLanguage();
}
-
-
- public PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException {
+ public PDOMBinding addBinding(IASTName name) throws CoreException {
if (name == null)
return null;
@@ -149,10 +145,6 @@ class PDOMCLinkage extends PDOMLinkage {
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
-
- if (pdomBinding != null)
- new PDOMName(pdom, name, file, pdomBinding);
-
return pdomBinding;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java
index 78af27ff078..087ebee6362 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java
@@ -316,7 +316,9 @@ ICPPClassScope, IPDOMMemberOwner {
}
}
- public void addChild(PDOMNode member) throws CoreException {addMember(member);}
+ public void addChild(PDOMNode member) throws CoreException {
+ addMember(member);
+ }
public ICPPConstructor[] getConstructors() throws DOMException {
// TODO
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index b54ac41eefc..df0c7e16fb0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
-import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@@ -69,9 +68,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.FindBindingByLinkageConstant;
import org.eclipse.cdt.internal.core.pdom.dom.FindEquivalentBinding;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
-import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
-import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException;
@@ -120,8 +117,7 @@ class PDOMCPPLinkage extends PDOMLinkage {
return new GPPLanguage();
}
-
- public PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException {
+ public PDOMBinding addBinding(IASTName name) throws CoreException {
if (name == null || name instanceof ICPPASTQualifiedName)
return null;
@@ -198,9 +194,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
// final processing
if (pdomBinding != null) {
- // Add in the name
- new PDOMName(pdom, name, file, pdomBinding);
-
// Check if is a base specifier
if (pdomBinding instanceof ICPPClassType && name.getParent() instanceof ICPPASTBaseSpecifier) {
ICPPASTBaseSpecifier baseNode = (ICPPASTBaseSpecifier)name.getParent();
@@ -297,8 +290,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
}
private PDOMBinding _resolveBinding(IASTName name) throws CoreException, DOMException {
- // mstodo revisit
-
IBinding origBinding = name.getBinding();
if (origBinding != null)
return adaptBinding(origBinding);
@@ -398,7 +389,7 @@ class PDOMCPPLinkage extends PDOMLinkage {
PDOMBinding pdomFOB = adaptBinding( (ICompositeType) type);
FindBindingByLinkageConstant visitor = new FindBindingByLinkageConstant(this, name.toCharArray(), PDOMCPPLinkage.CPPFIELD);
try {
- ((PDOMBinding)pdomFOB).accept(visitor);
+ pdomFOB.accept(visitor);
} catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS)) {
return visitor.getResult();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java
new file mode 100644
index 00000000000..bfb1ad253c8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core.pdom.indexer;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
+
+abstract public class IndexerASTVisitor extends ASTVisitor {
+ private IASTName fDefinitionName;
+ private IASTNode fDefinition;
+
+ public IndexerASTVisitor() {
+ shouldVisitNames = true;
+ shouldVisitDeclarations = true;
+ }
+
+ abstract public void visit(IASTName name, IASTName definitionName);
+
+ final public int visit(IASTName name) {
+ if (!(name instanceof ICPPASTQualifiedName)) {
+ if (fDefinition != null) {
+ if (!fDefinition.contains(name)) {
+ fDefinition= null;
+ fDefinitionName= null;
+ }
+ }
+ if (name != fDefinitionName) {
+ visit(name, fDefinitionName);
+ }
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ public int visit(IASTDeclaration decl) {
+ if (decl instanceof IASTFunctionDefinition) {
+ IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
+ fDefinition= decl;
+ fDefinitionName= fdef.getDeclarator().getName();
+ if (fDefinitionName instanceof ICPPASTQualifiedName) {
+ fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
+ }
+ visit(fDefinitionName, null);
+ }
+ return PROCESS_CONTINUE;
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
index f00b1630a7d..db7afcf2603 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
@@ -14,15 +14,21 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexInclude;
@@ -240,7 +246,90 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
return fCompletedSources;
}
- protected IIndexFragmentFile addToIndex(IWritableIndex index, String location, ArrayList[] lists) throws CoreException {
+ /**
+ * Extracts a map of names from the ast and returns an array defining the order in
+ * which the symbols should be added to the index.
+ * @since 4.0
+ */
+ protected String[] extractSymbols(IASTTranslationUnit ast, Set legalPaths, final LinkedHashMap symbolMap) {
+ // includes
+ final String astFilePath = ast.getFilePath();
+ IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
+ for (int i = includes.length-1; i >= 0; --i) {
+ IASTPreprocessorIncludeStatement include = includes[i];
+ IASTFileLocation sourceLoc = include.getFileLocation();
+ String path= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
+ if (legalPaths.contains(path)) {
+ prepareInMap(symbolMap, path);
+ addToMap(symbolMap, 0, path, include);
+ }
+ path= include.getPath();
+ if (legalPaths.contains(path)) {
+ prepareInMap(symbolMap, path);
+ }
+ }
+ if (legalPaths.contains(astFilePath)) {
+ prepareInMap(symbolMap, ast.getFilePath());
+ }
+
+ // macros
+ IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
+ for (int i = 0; i < macros.length; ++i) {
+ IASTPreprocessorMacroDefinition macro = macros[i];
+ IASTFileLocation sourceLoc = macro.getFileLocation();
+ if (sourceLoc != null) { // skip built-ins and command line macros
+ String path = sourceLoc.getFileName();
+ addToMap(symbolMap, 1, path, macro);
+ }
+ }
+
+ // names
+ ast.accept(new IndexerASTVisitor() {
+ public void visit(IASTName name, IASTName caller) {
+ IASTFileLocation nameLoc = name.getFileLocation();
+ if (nameLoc != null) {
+ addToMap(symbolMap, 2, nameLoc.getFileName(), new IASTName[]{name, caller});
+ }
+ }
+ });
+
+ Collection temp= symbolMap.keySet();
+ int size= temp.size();
+ String[] result= new String[temp.size()];
+ for (Iterator iter = temp.iterator(); iter.hasNext();) {
+ result[--size]= (String) iter.next();
+ }
+ return result;
+ }
+
+ private void addToMap(HashMap map, int idx, String path, Object thing) {
+ List[] lists= (List[]) map.get(path);
+ if (lists != null)
+ lists[idx].add(thing);
+ }
+
+ private boolean prepareInMap(Map map, String path) {
+ if (map.get(path) == null) {
+ Object lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
+ map.put(path, lists);
+ }
+ return false;
+ }
+
+ protected void prepareIndexInsertion(String path, Map symbolMap) {
+ ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
+
+ // reverse the includes
+ Collections.reverse(arrayLists[0]);
+
+ // resolve the names
+ ArrayList names= arrayLists[2];
+ for (int j=0; j MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE;
- }
- }
- });
-
- for (Iterator iter = symbolMap.entrySet().iterator(); iter.hasNext();) {
- Map.Entry entry = (Map.Entry) iter.next();
+ for (int i=0; i MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE;
- }
- }
- });
-
- for (Iterator iter = symbolMap.values().iterator(); iter.hasNext();) {
+ for (int i=0; i