1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 356268 - Name resolution problem with 'using' declaration inside a

class. Fix and test case.
This commit is contained in:
Sergey Prigogin 2011-09-01 12:31:04 -07:00
parent 9cf0293460
commit e6d138a358
2 changed files with 52 additions and 41 deletions

View file

@ -9481,14 +9481,35 @@ public class AST2CPPTests extends AST2BaseTest {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct A {
// void method(A);
// };
//
// struct B : A {
// void method(B);
// using A::method;
// };
//
// struct C : B {
// };
//
// void test() {
// B b;
// C c;
// c.method(b);
// }
public void testAmbiguityResolution_Bug356268() throws Exception {
parseAndCheckBindings();
}
// void (g)(char); // void (g)(char);
// void (g )(int); // void (g)(int); //1
// void (g )(int); // void (g)(int); //2
public void testFunctionRedeclarations() throws Exception { public void testFunctionRedeclarations() throws Exception {
BindingAssertionHelper bh= getAssertionHelper(); BindingAssertionHelper bh= getAssertionHelper();
IFunction g1= bh.assertNonProblem("g)", 1); IFunction g1= bh.assertNonProblem("g)(char)", 1);
IFunction g2= bh.assertNonProblem("g )", 1); IFunction g2= bh.assertNonProblem("g)(int); //1", 1);
IFunction g3= bh.assertNonProblem("g )", 1); IFunction g3= bh.assertNonProblem("g)(int); //2", 1);
assertNotSame(g1, g2); assertNotSame(g1, g2);
assertSame(g2, g3); assertSame(g2, g3);
} }

View file

@ -22,7 +22,6 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -56,8 +55,13 @@ class BaseClassLookup {
rootInfo.collectResultForContentAssist(data); rootInfo.collectResultForContentAssist(data);
} else { } else {
hideVirtualBases(rootInfo, infoMap); hideVirtualBases(rootInfo, infoMap);
IBinding[] result= rootInfo.collectResult(data, true, null); IBinding[] result= rootInfo.collectResult(data, true, IBinding.EMPTY_BINDING_ARRAY);
verifyResult(data, result); if (data.problem == null) {
data.foundItems = ArrayUtil.addAll((Object[]) data.foundItems, result);
} else if (result.length > 0) {
data.problem.setCandidateBindings(result);
}
// verifyResult(data, result);
} }
} }
@ -323,7 +327,7 @@ class BaseClassLookup {
} }
} }
public IBinding[] collectResult(LookupData data, boolean asVirtualBase, IBinding[] result) { private IBinding[] collectResult(LookupData data, boolean asVirtualBase, IBinding[] result) {
if (asVirtualBase) { if (asVirtualBase) {
if (fHiddenAsVirtualBase) if (fHiddenAsVirtualBase)
return result; return result;
@ -338,40 +342,26 @@ class BaseClassLookup {
return result; return result;
fCollected= true; fCollected= true;
result= (IBinding[]) ArrayUtil.addAll(IBinding.class, result, fBindings); int numBindingsToAdd = 0;
for (int i = 0; i < fBindings.length; i++) {
IBinding binding = fBindings[i];
if (binding == null)
break;
if (!ArrayUtil.contains(result, binding))
fBindings[numBindingsToAdd++] = binding;
}
if (numBindingsToAdd < fBindings.length)
fBindings[numBindingsToAdd] = null;
if (result.length > 0 && numBindingsToAdd > 0 && data.problem == null) {
// Matches are found in more than one base class - this is an indication of ambiguity.
data.problem= new ProblemBinding(data.astName,
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, result);
}
result= ArrayUtil.addAll(result, fBindings);
for (int i= 0; i < fChildren.size(); i++) { for (int i= 0; i < fChildren.size(); i++) {
BaseClassLookup child = fChildren.get(i); BaseClassLookup child = fChildren.get(i);
result= child.collectResult(data, fVirtual.get(i), result); result= child.collectResult(data, fVirtual.get(i), result);
} }
return result; return result;
} }
static void verifyResult(LookupData data, IBinding[] bindings) {
bindings= (IBinding[]) ArrayUtil.trim(IBinding.class, bindings);
if (bindings.length == 0)
return;
if (data.problem != null) {
data.problem.setCandidateBindings(bindings);
} else {
ICPPClassType uniqueOwner= null;
for (IBinding b : bindings) {
if (!(b instanceof IType)) {
IBinding owner= b.getOwner();
if (owner instanceof ICPPClassType) {
final ICPPClassType classOwner = (ICPPClassType) owner;
if (uniqueOwner == null) {
uniqueOwner= classOwner;
} else if (!uniqueOwner.isSameType(classOwner)) {
data.problem= new ProblemBinding(data.astName,
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, bindings);
return;
}
}
}
}
}
data.foundItems = ArrayUtil.addAll(Object.class, (Object[]) data.foundItems, bindings);
}
} }