Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMarkus Schorn2009-07-20 05:58:39 -0400
committerMarkus Schorn2009-07-20 05:58:39 -0400
commit1c3fa59e415cb1e6fb48069e0e236b015a22484f (patch)
tree4b40782e6cf633060fff977e69f797197d4788dd /core
parent2002d38a54e5e192513f57752955b2c342da5e94 (diff)
downloadorg.eclipse.cdt-1c3fa59e415cb1e6fb48069e0e236b015a22484f.tar.gz
org.eclipse.cdt-1c3fa59e415cb1e6fb48069e0e236b015a22484f.tar.xz
org.eclipse.cdt-1c3fa59e415cb1e6fb48069e0e236b015a22484f.zip
Further disambiguation of bindings from index, bug 268704.
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java37
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java70
2 files changed, 95 insertions, 12 deletions
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 8bfe8fb40b..ac9f1e5c40 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
@@ -1866,8 +1866,7 @@ public class IndexBugsTests extends BaseTestCase {
IName[] decls= ast.getDeclarations(var);
assertEquals(2, decls.length);
int check= 0;
- for (int i = 0; i < decls.length; i++) {
- IName name = decls[i];
+ for (IName name : decls) {
assert name instanceof IIndexName;
IIndexName iName= (IIndexName) name;
if (iName.getFileLocation().getFileName().endsWith("a.h")) {
@@ -1976,6 +1975,40 @@ public class IndexBugsTests extends BaseTestCase {
}
}
+ // // a.h
+ // int xx;
+
+ // #include "a.h"
+ // int yy= xx;
+
+ // // b.h
+ // int xx();
+
+ // #include "b.h"
+ // void test() {
+ // xx();
+ // }
+ public void testDisambiguationByReachability_268704_3() throws Exception {
+ String[] testData = getContentsForTest(4);
+ TestSourceReader.createFile(fCProject.getProject(), "a.h", testData[0]);
+ IFile a = TestSourceReader.createFile(fCProject.getProject(), "a.cpp", testData[1]);
+ TestSourceReader.createFile(fCProject.getProject(), "b.h", testData[2]);
+ IFile b = TestSourceReader.createFile(fCProject.getProject(), "b.cpp", testData[3]);
+ final IIndexManager indexManager = CCorePlugin.getIndexManager();
+ indexManager.reindex(fCProject);
+ waitForIndexer();
+ IIndex index= indexManager.getIndex(fCProject);
+ index.acquireReadLock();
+ try {
+ BindingAssertionHelper aHelper = new BindingAssertionHelper(a, testData[1], index);
+ IVariable b1 = aHelper.assertNonProblem("xx;", 2, IVariable.class);
+ BindingAssertionHelper bHelper = new BindingAssertionHelper(b, testData[3], index);
+ IFunction f = bHelper.assertNonProblem("xx();", 2, IFunction.class);
+ } finally {
+ index.releaseReadLock();
+ }
+ }
+
// // header.h
// template<class T>
// struct A {
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 0c45f6087a..24fc887d7e 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
@@ -1883,17 +1883,24 @@ public class CPPSemantics {
}
}
if (data.forUsingDeclaration()) {
- IBinding[] bindings = null;
+ int cmp= -1;
if (obj != null) {
+ cmp= 1;
if (fns.size() > 0) {
- return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
- data.getFoundBindings());
+ IFunction[] fnArray= fns.keyArray(IFunction.class);
+ cmp= compareByRelevance(data, obj, fnArray);
+ if (cmp == 0) {
+ return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
+ data.getFoundBindings());
+ }
}
-// if (type == null) return obj;
+ }
+
+ IBinding[] bindings = null;
+ if (cmp > 0) {
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, obj);
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
} else {
-// if (fns == null) return type;
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
bindings = (IBinding[]) ArrayUtil.addAll(IBinding.class, bindings, fns.keyArray());
}
@@ -1910,13 +1917,18 @@ public class CPPSemantics {
return null;
}
- int numFns = fns.size();
- if (numFns > 0) {
+ if (fns.size() > 0) {
+ final IFunction[] fnArray = fns.keyArray(IFunction.class);
if (obj != null) {
- return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
- data.getFoundBindings());
+ int cmp= compareByRelevance(data, obj, fnArray);
+ if (cmp == 0) {
+ return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
+ data.getFoundBindings());
+ }
+ if (cmp > 0)
+ return obj;
}
- return resolveFunction(data, fns.keyArray(IFunction.class), true);
+ return resolveFunction(data, fnArray, true);
}
if (obj != null) {
@@ -1955,6 +1967,44 @@ public class CPPSemantics {
return 0;
}
+ /**
+ * Compares a binding with a list of function candidates for relevance in the context of an AST. AST bindings are
+ * considered more relevant than index ones since the index may be out of date,
+ * built for a different configuration, etc. Index bindings reachable through includes
+ * are more relevant than unreachable ones.
+ * @return 1 if binding <code>obj</code> is more relevant than the function candidates; 0 if
+ * the they have the same relevance; -1 if <code>obj</code> is less relevant than
+ * the function candidates.
+ */
+ static int compareByRelevance(LookupData data, IBinding obj, IFunction[] fns) {
+ if (isFromIndex(obj)) {
+ for (int i = 0; i < fns.length; i++) {
+ if (!isFromIndex(fns[i])) {
+ return -1; // function from ast
+ }
+ }
+ // everything is from the index
+ if (!isReachableFromAst(data.tu, obj)) {
+ return -1; // obj not reachable
+ }
+
+ for (IFunction fn : fns) {
+ if (isReachableFromAst(data.tu, fn)) {
+ return 0; // obj reachable, 1 function reachable
+ }
+ }
+ return 1; // no function is reachable
+ }
+
+ // obj is not from the index
+ for (int i = 0; i < fns.length; i++) {
+ if (!isFromIndex(fns[i])) {
+ return 0; // obj and function from ast
+ }
+ }
+ return 1; // only obj is from ast.
+ }
+
private static boolean isFromIndex(IBinding binding) {
if (binding instanceof IIndexBinding) {
return true;

Back to the top