diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 7bb7b366402..ecb1fff49e8 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -2615,5 +2615,41 @@ public class AST2CPPTests extends AST2BaseTest { assertInstances( col, g1, 1 ); assertInstances( col, g2, 2 ); } + + public void testBug86649() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class V { int f(); int x; }; \n"); //$NON-NLS-1$ + buffer.append("class W { int g(); int y; }; \n"); //$NON-NLS-1$ + buffer.append("class B : public virtual V, public W { \n"); //$NON-NLS-1$ + buffer.append(" int f(); int x; \n"); //$NON-NLS-1$ + buffer.append(" int g(); int y; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("class C : public virtual V, public W {}; \n"); //$NON-NLS-1$ + buffer.append("class D : public B, public C { \n"); //$NON-NLS-1$ + buffer.append(" void foo(); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("void D::foo(){ \n"); //$NON-NLS-1$ + buffer.append(" x++; \n"); //$NON-NLS-1$ + buffer.append(" f(); \n"); //$NON-NLS-1$ + buffer.append(" y++; \n"); //$NON-NLS-1$ + buffer.append(" g(); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP); + CPPNameCollector col = new CPPNameCollector(); + tu.getVisitor().visitTranslationUnit(col); + + ICPPField x = (ICPPField) col.getName(23).resolveBinding(); + ICPPMethod f = (ICPPMethod) col.getName(24).resolveBinding(); + + IProblemBinding y = (IProblemBinding) col.getName(25).resolveBinding(); + IProblemBinding g = (IProblemBinding) col.getName(26).resolveBinding(); + + assertEquals( y.getID(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP ); + assertEquals( g.getID(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP ); + + assertInstances( col, x, 2 ); + assertInstances( col, f, 2 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index d93b1fc0b06..0986c3ba67e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -746,6 +746,8 @@ public class CPPSemantics { if( inherited == null || inherited.length == 0 ){ inherited = lookupInParents( data, parent ); + } else { + visitVirtualBaseClasses( data, cls ); } } else { data.problem = new ProblemBinding( IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, bases[i].getName().toCharArray() ); @@ -775,6 +777,26 @@ public class CPPSemantics { return result; } + public static void visitVirtualBaseClasses( LookupData data, ICPPClassType cls ){ + ICPPBase [] bases = null; + try { + bases = cls.getBases(); + } catch ( DOMException e ) { + return; + } + for( int i = 0; i < bases.length; i++ ){ + try { + if( bases[i].isVirtual() ){ + if( data.visited == ObjectSet.EMPTY_SET ) + data.visited = new ObjectSet(2); + data.visited.put( bases[i].getBaseClass().getCompositeScope() ); + } else { + visitVirtualBaseClasses( data, bases[i].getBaseClass() ); + } + } catch ( DOMException e1 ) { + } + } + } private static boolean checkAmbiguity( IASTName n, IASTName []names ) throws DOMException{ names = (IASTName[]) ArrayUtil.trim( IASTName.class, names ); if( names.length == 0 )