1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

Bug 299101: Perform ADL even if unqualified lookup was successful.

This commit is contained in:
Markus Schorn 2010-01-08 14:33:35 +00:00
parent ac54f0829b
commit 8476012b32
4 changed files with 86 additions and 69 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation 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
@ -7985,5 +7985,30 @@ public class AST2CPPTests extends AST2BaseTest {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// namespace ns {
// struct A{};
// void f(ns::A, char) {}
// }
// void f(ns::A, int) {}
//
// ns::A a;
// void test() {
// f(a, '1'); // calls ns::f(ns::A, char)
// f(a, 1); // calls ns::f(ns::A, char)
// }
public void testADL_299101() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction inns= bh.assertNonProblem("f(ns::A, char)", 1);
IFunction glob= bh.assertNonProblem("f(ns::A, int)", 1);
IBinding b= bh.assertNonProblem("f(a, '1')", 1);
assertSame(b, inns);
b= bh.assertNonProblem("f(a, 1)", 1);
assertSame(b, glob);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation 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
@ -53,9 +53,12 @@ import org.eclipse.core.runtime.NullProgressMonitor;
abstract public class CPPScope implements ICPPASTInternalScope {
protected static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
private static final IProgressMonitor NPM = new NullProgressMonitor();
private static final ICPPNamespace UNINITIALIZED = new CPPNamespace.CPPNamespaceProblem(null, 0, null);
private IASTNode physicalNode;
private boolean isCached = false;
protected CharArrayObjectMap bindings = null;
private ICPPNamespace fIndexNamespace= UNINITIALIZED;
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
public CPPScopeProblem(IASTNode node, int id, char[] arg) {
@ -162,14 +165,9 @@ abstract public class CPPScope implements ICPPASTInternalScope {
CCorePlugin.log(e);
}
} else if (physicalNode instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition nsdef = (ICPPASTNamespaceDefinition)physicalNode;
IASTName nsname = nsdef.getName();
IBinding nsbinding= nsname.resolveBinding();
if (nsbinding instanceof ICPPNamespace) {
ICPPNamespace nsbindingAdapted = (ICPPNamespace) index.adaptBinding(nsbinding);
if (nsbindingAdapted!=null) {
return nsbindingAdapted.getNamespaceScope().getBinding(name, forceResolve, fileSet);
}
ICPPNamespace nsbinding= getNamespaceIndexBinding((ICPPASTNamespaceDefinition)physicalNode, index);
if (nsbinding != null) {
return nsbinding.getNamespaceScope().getBinding(name, forceResolve, fileSet);
}
}
}
@ -177,6 +175,18 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return binding;
}
private ICPPNamespace getNamespaceIndexBinding(ICPPASTNamespaceDefinition nsdef, IIndex index) {
if (fIndexNamespace == UNINITIALIZED) {
fIndexNamespace= null;
IASTName nsname = nsdef.getName();
IBinding nsbinding= nsname.resolveBinding();
if (nsbinding != null) {
fIndexNamespace= (ICPPNamespace) index.adaptBinding(nsbinding);
}
}
return fIndexNamespace;
}
public IBinding getBindingInAST(IASTName name, boolean forceResolve) throws DOMException {
IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, true);
return CPPSemantics.resolveAmbiguities(name, bs);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation 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
@ -230,14 +230,19 @@ public class CPPSemantics {
try {
// 2: lookup
lookup(data, name);
lookup(data, null);
// Perform argument dependent lookup
if (data.checkAssociatedScopes() && !data.hasTypeOrMemberFunctionResult()) {
doKoenigLookup(data);
}
} catch (DOMException e) {
data.problem = (ProblemBinding) e.getProblem();
}
if (data.problem != null)
return data.problem;
// 3: resolve ambiguities
IBinding binding;
try {
@ -263,29 +268,6 @@ public class CPPSemantics {
}
private static IBinding postResolution(IBinding binding, LookupData data) {
// If the normal lookup of the unqualified name finds a class member function, then ADL does not occur
if (data.checkAssociatedScopes() && !data.hasMemberFunctionResult()) {
// 3.4.2 argument dependent name lookup, aka Koenig lookup
try {
boolean doKoenig= true;
if (binding != null) {
if (binding.getOwner() instanceof ICPPClassType)
doKoenig= false;
else if (binding instanceof ICPPClassType && data.considerConstructors)
doKoenig= false;
}
if (doKoenig) {
int count= data.getFoundItemCount();
doKoenigLookup(data);
if (data.getFoundItemCount() > count) {
binding = resolveAmbiguities(data, data.astName);
}
}
} catch (DOMException e) {
binding = e.getProblem();
}
}
if (binding instanceof IProblemBinding)
return binding;
@ -508,9 +490,9 @@ public class CPPSemantics {
private static void doKoenigLookup(LookupData data) throws DOMException {
data.ignoreUsingDirectives = true;
data.forceQualified = true;
ObjectSet<IScope> associated = getAssociatedScopes(data);
ObjectSet<ICPPScope> associated = getAssociatedScopes(data);
for (int i = 0; i < associated.size(); i++) {
final IScope scope = associated.keyAt(i);
final ICPPScope scope = associated.keyAt(i);
if (!data.visited.containsKey(scope)) {
lookup(data, scope);
}
@ -602,12 +584,12 @@ public class CPPSemantics {
return data;
}
static private ObjectSet<IScope> getAssociatedScopes(LookupData data) {
static private ObjectSet<ICPPScope> getAssociatedScopes(LookupData data) {
if (!data.hasArgumentTypes())
return ObjectSet.emptySet();
IType[] ps = data.getFunctionArgumentTypes();
ObjectSet<IScope> namespaces = new ObjectSet<IScope>(2);
ObjectSet<ICPPScope> namespaces = new ObjectSet<ICPPScope>(2);
ObjectSet<ICPPClassType> classes = new ObjectSet<ICPPClassType>(2);
for (IType p : ps) {
p = getUltimateType(p, true);
@ -619,14 +601,14 @@ public class CPPSemantics {
return namespaces;
}
static private void getAssociatedScopes(IType t, ObjectSet<IScope> namespaces,
static private void getAssociatedScopes(IType t, ObjectSet<ICPPScope> namespaces,
ObjectSet<ICPPClassType> classes, CPPASTTranslationUnit tu) throws DOMException {
// 3.4.2-2
if (t instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) t;
if (!classes.containsKey(ct)) {
classes.put(ct);
IScope scope = getContainingNamespaceScope((IBinding) t, tu);
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
if (scope != null)
namespaces.put(scope);
@ -641,7 +623,7 @@ public class CPPSemantics {
}
}
} else if (t instanceof IEnumeration) {
IScope scope = getContainingNamespaceScope((IBinding) t, tu);
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
if (scope!=null)
namespaces.put(scope);
} else if (t instanceof IFunctionType) {
@ -780,16 +762,30 @@ public class CPPSemantics {
* @param data the lookup data created off a name
* @param start either a scope or a name.
*/
static protected void lookup(LookupData data, Object start) throws DOMException {
static protected void lookup(LookupData data, IScope start) throws DOMException {
final IIndexFileSet fileSet= getIndexFileSet(data);
if (data.astName == null)
return;
ICPPScope nextScope= null;
ICPPTemplateScope nextTmplScope= null;
if (start instanceof ICPPScope) {
nextScope= (ICPPScope) start;
} else if (start instanceof IASTName) {
nextScope= getLookupScope((IASTName) start, data);
} else {
nextScope= getLookupScope(data.astName, data);
if (nextScope instanceof ICPPTemplateScope) {
nextTmplScope= (ICPPTemplateScope) nextScope;
nextScope= getParentScope(nextScope, data.tu);
} else {
nextTmplScope= enclosingTemplateScope(data.astName);
}
if (!data.usesEnclosingScope && nextTmplScope != null) {
nextTmplScope= null;
if (dependsOnTemplateFieldReference(data.astName)) {
data.checkPointOfDecl= false;
}
}
}
if (nextScope == null)
return;
@ -803,20 +799,6 @@ public class CPPSemantics {
}
}
ICPPTemplateScope nextTmplScope;
if (nextScope instanceof ICPPTemplateScope) {
nextTmplScope= (ICPPTemplateScope) nextScope;
nextScope= getParentScope(nextScope, data.tu);
} else {
nextTmplScope= enclosingTemplateScope(data.astName);
}
if (!data.usesEnclosingScope && nextTmplScope != null) {
nextTmplScope= null;
if (dependsOnTemplateFieldReference(data.astName)) {
data.checkPointOfDecl= false;
}
}
while (nextScope != null || nextTmplScope != null) {
// when the non-template scope is no longer contained within the first template scope,
// we use the template scope for the next iteration.
@ -884,7 +866,7 @@ public class CPPSemantics {
// if still not found, loop and check our containing scope
if (data.qualified() && !(scope instanceof ICPPTemplateScope)) {
if (data.usingDirectives.isEmpty())
if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty())
break;
data.usingDirectivesOnly = true;
}
@ -2470,7 +2452,7 @@ public class CPPSemantics {
IASTName name = idExp.getName();
LookupData data = createLookupData(name, false);
try {
lookup(data, name);
lookup(data, null);
} catch (DOMException e) {
return null;
}
@ -2957,10 +2939,10 @@ public class CPPSemantics {
data.prefixLookup = prefixLookup;
data.foundItems = new CharArrayObjectMap(2);
return contentAssistLookup(data, name);
return contentAssistLookup(data, null);
}
private static IBinding[] contentAssistLookup(LookupData data, Object start) {
private static IBinding[] contentAssistLookup(LookupData data, IScope start) {
try {
lookup(data, start);
} catch (DOMException e) {
@ -2999,7 +2981,7 @@ public class CPPSemantics {
return ArrayUtil.trim(result);
}
private static IBinding[] standardLookup(LookupData data, Object start) {
private static IBinding[] standardLookup(LookupData data, IScope start) {
try {
lookup(data, start);
} catch (DOMException e) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation 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
@ -374,12 +374,12 @@ public class LookupData {
return false;
}
public boolean hasMemberFunctionResult() {
public boolean hasTypeOrMemberFunctionResult() {
if(foundItems == null)
return false;
if(foundItems instanceof Object[]) {
for(Object item : (Object[])foundItems) {
if(item instanceof ICPPMethod) {
if(item instanceof ICPPMethod || item instanceof IType) {
return true;
}
}