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 0a413efe432..a82af57671c 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2010 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 @@ -2169,4 +2169,44 @@ public class IndexBugsTests extends BaseTestCase { } } + // // a.h + // struct Error{}; + + // // b.h + // void Error(int errCode) {} + + // // source1.cpp + // #include "a.h" + // Error d; + + // // source2.cpp + // Error d; // Problem, without inclusion we need to prefer the function. + public void testDisambiguateObjectVsType_304479() throws Exception { + waitForIndexer(); + String[] testData = getContentsForTest(4); + TestSourceReader.createFile(fCProject.getProject(), "a.h", testData[0]); + TestSourceReader.createFile(fCProject.getProject(), "b.h", testData[1]); + IFile s1= TestSourceReader.createFile(fCProject.getProject(), "s1.cpp", testData[2]); + IFile s2= TestSourceReader.createFile(fCProject.getProject(), "s2.cpp", testData[3]); + final IIndexManager indexManager = CCorePlugin.getIndexManager(); + indexManager.reindex(fCProject); + waitForIndexer(); + IIndex index= indexManager.getIndex(fCProject); + index.acquireReadLock(); + try { + IASTTranslationUnit tu = TestSourceReader.createIndexBasedAST(index, fCProject, s1); + IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IVariable var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding(); + assertFalse(var.getType() instanceof IProblemBinding); + assertTrue(var.getType() instanceof ICPPClassType); + + tu = TestSourceReader.createIndexBasedAST(index, fCProject, s2); + sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0]; + var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding(); + assertTrue(var.getType() instanceof IProblemBinding); + } finally { + index.releaseReadLock(); + } + } + } \ No newline at end of file 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 ecb3909ec76..8a4e9386b34 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 @@ -1765,40 +1765,45 @@ public class CPPSemantics { ICPPUsingDeclaration composite = new CPPUsingDeclaration(data.astName, bindings); return composite; } - - if (data.typesOnly) { - if (type != null) { - if (obj instanceof ICPPNamespace && compareByRelevance(data, type, obj) < 0) { - return obj; - } - return type; + + if (obj != null && type != null) { + if (obj instanceof ICPPNamespace) { + if (compareByRelevance(data, type, obj) >= 0) { + obj= null; + } + } else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) { + obj= null; } + } + + if (data.typesOnly) { if (obj instanceof ICPPNamespace) return obj; - return null; + return type; } + if (fns.size() > 0) { final IFunction[] fnArray = fns.keyArray(IFunction.class); + if (type != null && overrulesByRelevance(data, type, fnArray)) { + return type; + } + if (obj != null) { int cmp= compareByRelevance(data, obj, fnArray); if (cmp == 0) { return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } - if (cmp > 0) + if (cmp > 0) { return obj; + } } return resolveFunction(data, fnArray, true); } if (obj != null) { - if (type != null && obj instanceof ICPPNamespace) { - if (compareByRelevance(data, type, obj) >= 0) { - return type; - } - } return obj; } return type; @@ -1834,6 +1839,47 @@ public class CPPSemantics { return 0; } + /** + * Compares two bindings for relevance in the context of an AST. Type bindings are + * considered to overrule object bindings when the former is reachable but the + * latter is not. + */ + static boolean overrulesByRelevance(LookupData data, IBinding type, IBinding b2) { + if (data != null && data.tu != null) { + return !isReachableFromAst(data.tu, b2) && isReachableFromAst(data.tu, type); + } + return false; + } + + /** + * Compares a binding with a list of function candidates for relevance in the + * context of an AST. Types are considered to overrule object bindings when + * the former is reachable but none of the functions are. + */ + static boolean overrulesByRelevance(LookupData data, IBinding type, IFunction[] fns) { + if (data == null || data.tu == null) { + return false; + } + + for (int i = 0; i < fns.length; i++) { + if (!isFromIndex(fns[i])) { + return false; // function from ast + } + } + + if (!isReachableFromAst(data.tu, type)) { + return false; + } + + for (IFunction fn : fns) { + if (isReachableFromAst(data.tu, fn)) { + return false; // function from ast + } + } + return true; + } + + /** * Compares two bindings 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, @@ -1901,7 +1947,7 @@ public class CPPSemantics { } return 1; // only obj is from ast. } - + private static boolean isFromIndex(IBinding binding) { if (binding instanceof IIndexBinding) { return true;