diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java index 38eb0c788e7..10a0021dea4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java @@ -1068,7 +1068,7 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas // const int* q = p; // func(q); // } - public void _testOverloadedFunctionFromIndex_Bug256240() throws Exception { + public void testOverloadedFunctionFromIndex_Bug256240() throws Exception { getBindingFromASTName("func(q", 4, ICPPFunction.class); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index fa826455c59..c5dbe1b4505 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -229,28 +229,34 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope { final char[] c = name.getLookupKey(); IBinding[] result = null; - Object[] obj = null; + Object obj = null; if (prefixLookup) { Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; + ObjectSet all= new ObjectSet(16); for (int i = 0; i < keys.length; i++) { final char[] key = (char[]) keys[i]; if (CharArrayUtils.equals(key, 0, c.length, c, true)) { - obj = ArrayUtil.append(obj, bindings.get(key)); + obj= bindings.get(key); + if (obj instanceof ObjectSet) { + all.addAll((ObjectSet) obj); + } else if (obj != null) { + all.put(obj); + } } } + obj= all; } else { - obj = bindings != null ? new Object[] {bindings.get(c)} : null; + obj = bindings != null ? bindings.get(c) : null; } - obj = ArrayUtil.trim(Object.class, obj); - for (Object element : obj) { - if (element instanceof ObjectSet) { - ObjectSet os= (ObjectSet) element; + if (obj != null) { + if (obj instanceof ObjectSet) { + ObjectSet os= (ObjectSet) obj; for (int j = 0; j < os.size(); j++) { result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); } } else { - result = addCandidate(element, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); + result = addCandidate(obj, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); } } return (IBinding[]) ArrayUtil.trim(IBinding.class, result); 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 188f00f19a6..849d64789d5 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 @@ -1684,7 +1684,6 @@ public class CPPSemantics { IBinding type = null; IBinding obj = null; IBinding temp = null; - boolean fnsFromAST= false; Object[] items = (Object[]) data.foundItems; for (int i = 0; i < items.length && items[i] != null; i++) { @@ -1738,22 +1737,9 @@ public class CPPSemantics { if (!(temp instanceof IFunction)) continue; } - - IFunction function= (IFunction) temp; if (fns == ObjectSet.EMPTY_SET) fns = new ObjectSet(2); - if (isFromIndex(function)) { - // accept bindings from index only, in case we have none in the AST - if (!fnsFromAST) { - fns.put(function); - } - } else { - if (!fnsFromAST) { - fns.clear(); - fnsFromAST= true; - } - fns.put(function); - } + fns.put((IFunction) temp); } else if (temp instanceof IType) { // specializations are selected during instantiation if (temp instanceof ICPPClassTemplatePartialSpecialization) @@ -2083,6 +2069,16 @@ public class CPPSemantics { } } + // if we are ambiguous at this point prefer non-index bindings + if (hasBetter == hasWorse) { + final boolean bestIsFromIndex= isFromIndex(bestFn); + final boolean currIsFromIndex= isFromIndex(fn); + if (bestIsFromIndex != currIsFromIndex) { + hasBetter= bestIsFromIndex; + hasWorse= currIsFromIndex; + } + } + // If function has a parameter match that is better than the current best, // and another that is worse (or everything was just as good, neither better nor worse), // then this is an ambiguity (unless we find something better than both later). @@ -2232,6 +2228,19 @@ public class CPPSemantics { if (fns.length == 1) return fns[0]; + IBinding oneFromAST= null; + for (IBinding fn : fns) { + if (!isFromIndex(fn)) { + if (oneFromAST != null) { + oneFromAST= null; + break; + } + oneFromAST= fn; + } + } + if (oneFromAST != null) + return oneFromAST; + if (data.forAssociatedScopes) { return new CPPCompositeBinding(fns); } @@ -2263,7 +2272,11 @@ public class CPPSemantics { } if (type.isSameType(ft)) { if (result != null) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); + boolean fromIndex= isFromIndex(fn); + if (isFromIndex(result) == fromIndex) + return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); + if (!fromIndex) + result= fn; } result = fn; }