mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Bug 299101: Perform ADL even if unqualified lookup was successful.
This commit is contained in:
parent
ac54f0829b
commit
8476012b32
4 changed files with 86 additions and 69 deletions
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7985,5 +7985,30 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
String code= getAboveComment();
|
String code= getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -53,9 +53,12 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
abstract public class CPPScope implements ICPPASTInternalScope {
|
abstract public class CPPScope implements ICPPASTInternalScope {
|
||||||
protected static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
protected static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
||||||
private static final IProgressMonitor NPM = new NullProgressMonitor();
|
private static final IProgressMonitor NPM = new NullProgressMonitor();
|
||||||
|
private static final ICPPNamespace UNINITIALIZED = new CPPNamespace.CPPNamespaceProblem(null, 0, null);
|
||||||
|
|
||||||
private IASTNode physicalNode;
|
private IASTNode physicalNode;
|
||||||
private boolean isCached = false;
|
private boolean isCached = false;
|
||||||
protected CharArrayObjectMap bindings = null;
|
protected CharArrayObjectMap bindings = null;
|
||||||
|
private ICPPNamespace fIndexNamespace= UNINITIALIZED;
|
||||||
|
|
||||||
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
|
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
|
||||||
public CPPScopeProblem(IASTNode node, int id, char[] arg) {
|
public CPPScopeProblem(IASTNode node, int id, char[] arg) {
|
||||||
|
@ -162,14 +165,9 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
} else if (physicalNode instanceof ICPPASTNamespaceDefinition) {
|
} else if (physicalNode instanceof ICPPASTNamespaceDefinition) {
|
||||||
ICPPASTNamespaceDefinition nsdef = (ICPPASTNamespaceDefinition)physicalNode;
|
ICPPNamespace nsbinding= getNamespaceIndexBinding((ICPPASTNamespaceDefinition)physicalNode, index);
|
||||||
IASTName nsname = nsdef.getName();
|
if (nsbinding != null) {
|
||||||
IBinding nsbinding= nsname.resolveBinding();
|
return nsbinding.getNamespaceScope().getBinding(name, forceResolve, fileSet);
|
||||||
if (nsbinding instanceof ICPPNamespace) {
|
|
||||||
ICPPNamespace nsbindingAdapted = (ICPPNamespace) index.adaptBinding(nsbinding);
|
|
||||||
if (nsbindingAdapted!=null) {
|
|
||||||
return nsbindingAdapted.getNamespaceScope().getBinding(name, forceResolve, fileSet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,6 +175,18 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
||||||
return binding;
|
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 {
|
public IBinding getBindingInAST(IASTName name, boolean forceResolve) throws DOMException {
|
||||||
IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, true);
|
IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, true);
|
||||||
return CPPSemantics.resolveAmbiguities(name, bs);
|
return CPPSemantics.resolveAmbiguities(name, bs);
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -230,14 +230,19 @@ public class CPPSemantics {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 2: lookup
|
// 2: lookup
|
||||||
lookup(data, name);
|
lookup(data, null);
|
||||||
|
|
||||||
|
// Perform argument dependent lookup
|
||||||
|
if (data.checkAssociatedScopes() && !data.hasTypeOrMemberFunctionResult()) {
|
||||||
|
doKoenigLookup(data);
|
||||||
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
data.problem = (ProblemBinding) e.getProblem();
|
data.problem = (ProblemBinding) e.getProblem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.problem != null)
|
if (data.problem != null)
|
||||||
return data.problem;
|
return data.problem;
|
||||||
|
|
||||||
|
|
||||||
// 3: resolve ambiguities
|
// 3: resolve ambiguities
|
||||||
IBinding binding;
|
IBinding binding;
|
||||||
try {
|
try {
|
||||||
|
@ -263,29 +268,6 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding postResolution(IBinding binding, LookupData data) {
|
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)
|
if (binding instanceof IProblemBinding)
|
||||||
return binding;
|
return binding;
|
||||||
|
|
||||||
|
@ -508,9 +490,9 @@ public class CPPSemantics {
|
||||||
private static void doKoenigLookup(LookupData data) throws DOMException {
|
private static void doKoenigLookup(LookupData data) throws DOMException {
|
||||||
data.ignoreUsingDirectives = true;
|
data.ignoreUsingDirectives = true;
|
||||||
data.forceQualified = true;
|
data.forceQualified = true;
|
||||||
ObjectSet<IScope> associated = getAssociatedScopes(data);
|
ObjectSet<ICPPScope> associated = getAssociatedScopes(data);
|
||||||
for (int i = 0; i < associated.size(); i++) {
|
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)) {
|
if (!data.visited.containsKey(scope)) {
|
||||||
lookup(data, scope);
|
lookup(data, scope);
|
||||||
}
|
}
|
||||||
|
@ -602,12 +584,12 @@ public class CPPSemantics {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private ObjectSet<IScope> getAssociatedScopes(LookupData data) {
|
static private ObjectSet<ICPPScope> getAssociatedScopes(LookupData data) {
|
||||||
if (!data.hasArgumentTypes())
|
if (!data.hasArgumentTypes())
|
||||||
return ObjectSet.emptySet();
|
return ObjectSet.emptySet();
|
||||||
|
|
||||||
IType[] ps = data.getFunctionArgumentTypes();
|
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);
|
ObjectSet<ICPPClassType> classes = new ObjectSet<ICPPClassType>(2);
|
||||||
for (IType p : ps) {
|
for (IType p : ps) {
|
||||||
p = getUltimateType(p, true);
|
p = getUltimateType(p, true);
|
||||||
|
@ -619,14 +601,14 @@ public class CPPSemantics {
|
||||||
return namespaces;
|
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 {
|
ObjectSet<ICPPClassType> classes, CPPASTTranslationUnit tu) throws DOMException {
|
||||||
// 3.4.2-2
|
// 3.4.2-2
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
ICPPClassType ct= (ICPPClassType) t;
|
ICPPClassType ct= (ICPPClassType) t;
|
||||||
if (!classes.containsKey(ct)) {
|
if (!classes.containsKey(ct)) {
|
||||||
classes.put(ct);
|
classes.put(ct);
|
||||||
IScope scope = getContainingNamespaceScope((IBinding) t, tu);
|
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
|
||||||
if (scope != null)
|
if (scope != null)
|
||||||
namespaces.put(scope);
|
namespaces.put(scope);
|
||||||
|
|
||||||
|
@ -641,7 +623,7 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (t instanceof IEnumeration) {
|
} else if (t instanceof IEnumeration) {
|
||||||
IScope scope = getContainingNamespaceScope((IBinding) t, tu);
|
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
|
||||||
if (scope!=null)
|
if (scope!=null)
|
||||||
namespaces.put(scope);
|
namespaces.put(scope);
|
||||||
} else if (t instanceof IFunctionType) {
|
} else if (t instanceof IFunctionType) {
|
||||||
|
@ -780,16 +762,30 @@ public class CPPSemantics {
|
||||||
* @param data the lookup data created off a name
|
* @param data the lookup data created off a name
|
||||||
* @param start either a scope or 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);
|
final IIndexFileSet fileSet= getIndexFileSet(data);
|
||||||
if (data.astName == null)
|
if (data.astName == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ICPPScope nextScope= null;
|
ICPPScope nextScope= null;
|
||||||
|
ICPPTemplateScope nextTmplScope= null;
|
||||||
if (start instanceof ICPPScope) {
|
if (start instanceof ICPPScope) {
|
||||||
nextScope= (ICPPScope) start;
|
nextScope= (ICPPScope) start;
|
||||||
} else if (start instanceof IASTName) {
|
} else {
|
||||||
nextScope= getLookupScope((IASTName) start, data);
|
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)
|
if (nextScope == null)
|
||||||
return;
|
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) {
|
while (nextScope != null || nextTmplScope != null) {
|
||||||
// when the non-template scope is no longer contained within the first template scope,
|
// when the non-template scope is no longer contained within the first template scope,
|
||||||
// we use the template scope for the next iteration.
|
// 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 still not found, loop and check our containing scope
|
||||||
if (data.qualified() && !(scope instanceof ICPPTemplateScope)) {
|
if (data.qualified() && !(scope instanceof ICPPTemplateScope)) {
|
||||||
if (data.usingDirectives.isEmpty())
|
if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty())
|
||||||
break;
|
break;
|
||||||
data.usingDirectivesOnly = true;
|
data.usingDirectivesOnly = true;
|
||||||
}
|
}
|
||||||
|
@ -2470,7 +2452,7 @@ public class CPPSemantics {
|
||||||
IASTName name = idExp.getName();
|
IASTName name = idExp.getName();
|
||||||
LookupData data = createLookupData(name, false);
|
LookupData data = createLookupData(name, false);
|
||||||
try {
|
try {
|
||||||
lookup(data, name);
|
lookup(data, null);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2957,10 +2939,10 @@ public class CPPSemantics {
|
||||||
data.prefixLookup = prefixLookup;
|
data.prefixLookup = prefixLookup;
|
||||||
data.foundItems = new CharArrayObjectMap(2);
|
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 {
|
try {
|
||||||
lookup(data, start);
|
lookup(data, start);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -2999,7 +2981,7 @@ public class CPPSemantics {
|
||||||
return ArrayUtil.trim(result);
|
return ArrayUtil.trim(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding[] standardLookup(LookupData data, Object start) {
|
private static IBinding[] standardLookup(LookupData data, IScope start) {
|
||||||
try {
|
try {
|
||||||
lookup(data, start);
|
lookup(data, start);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -374,12 +374,12 @@ public class LookupData {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasMemberFunctionResult() {
|
public boolean hasTypeOrMemberFunctionResult() {
|
||||||
if(foundItems == null)
|
if(foundItems == null)
|
||||||
return false;
|
return false;
|
||||||
if(foundItems instanceof Object[]) {
|
if(foundItems instanceof Object[]) {
|
||||||
for(Object item : (Object[])foundItems) {
|
for(Object item : (Object[])foundItems) {
|
||||||
if(item instanceof ICPPMethod) {
|
if(item instanceof ICPPMethod || item instanceof IType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue