1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 14:55:41 +02:00

Consider overloaded functions from index, bug 265240

This commit is contained in:
Markus Schorn 2009-02-18 17:28:41 +00:00
parent a60fe2221f
commit 9a56d9a65d
3 changed files with 44 additions and 25 deletions

View file

@ -1068,7 +1068,7 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
// const int* q = p; // const int* q = p;
// func(q); // func(q);
// } // }
public void _testOverloadedFunctionFromIndex_Bug256240() throws Exception { public void testOverloadedFunctionFromIndex_Bug256240() throws Exception {
getBindingFromASTName("func(q", 4, ICPPFunction.class); getBindingFromASTName("func(q", 4, ICPPFunction.class);
} }

View file

@ -229,28 +229,34 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
final char[] c = name.getLookupKey(); final char[] c = name.getLookupKey();
IBinding[] result = null; IBinding[] result = null;
Object[] obj = null; Object obj = null;
if (prefixLookup) { if (prefixLookup) {
Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; Object[] keys = bindings != null ? bindings.keyArray() : new Object[0];
ObjectSet<Object> all= new ObjectSet<Object>(16);
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
final char[] key = (char[]) keys[i]; final char[] key = (char[]) keys[i];
if (CharArrayUtils.equals(key, 0, c.length, c, true)) { 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 { } else {
obj = bindings != null ? new Object[] {bindings.get(c)} : null; obj = bindings != null ? bindings.get(c) : null;
} }
obj = ArrayUtil.trim(Object.class, obj); if (obj != null) {
for (Object element : obj) { if (obj instanceof ObjectSet<?>) {
if (element instanceof ObjectSet<?>) { ObjectSet<?> os= (ObjectSet<?>) obj;
ObjectSet<?> os= (ObjectSet<?>) element;
for (int j = 0; j < os.size(); j++) { for (int j = 0; j < os.size(); j++) {
result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, expandUsingDirectives, result);
} }
} else { } else {
result = addCandidate(element, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); result = addCandidate(obj, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result);
} }
} }
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);

View file

@ -1684,7 +1684,6 @@ public class CPPSemantics {
IBinding type = null; IBinding type = null;
IBinding obj = null; IBinding obj = null;
IBinding temp = null; IBinding temp = null;
boolean fnsFromAST= false;
Object[] items = (Object[]) data.foundItems; Object[] items = (Object[]) data.foundItems;
for (int i = 0; i < items.length && items[i] != null; i++) { for (int i = 0; i < items.length && items[i] != null; i++) {
@ -1738,22 +1737,9 @@ public class CPPSemantics {
if (!(temp instanceof IFunction)) if (!(temp instanceof IFunction))
continue; continue;
} }
IFunction function= (IFunction) temp;
if (fns == ObjectSet.EMPTY_SET) if (fns == ObjectSet.EMPTY_SET)
fns = new ObjectSet<IFunction>(2); fns = new ObjectSet<IFunction>(2);
if (isFromIndex(function)) { fns.put((IFunction) temp);
// 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);
}
} else if (temp instanceof IType) { } else if (temp instanceof IType) {
// specializations are selected during instantiation // specializations are selected during instantiation
if (temp instanceof ICPPClassTemplatePartialSpecialization) 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, // 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), // 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). // then this is an ambiguity (unless we find something better than both later).
@ -2232,6 +2228,19 @@ public class CPPSemantics {
if (fns.length == 1) if (fns.length == 1)
return fns[0]; 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) { if (data.forAssociatedScopes) {
return new CPPCompositeBinding(fns); return new CPPCompositeBinding(fns);
} }
@ -2263,7 +2272,11 @@ public class CPPSemantics {
} }
if (type.isSameType(ft)) { if (type.isSameType(ft)) {
if (result != null) { 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; result = fn;
} }