diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java index 3906978ad9d..cfabc25b857 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -1393,7 +1394,19 @@ public class CompleteParser2Tests extends TestCase { buffer.append( "void f ( int s ) { \n" ); //$NON-NLS-1$ buffer.append( " struct s sInstance; \n" ); //$NON-NLS-1$ buffer.append( "}\n"); //$NON-NLS-1$ - parse( buffer.toString() ); + IASTTranslationUnit tu = parse( buffer.toString() ); + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 5 ); + ICPPClassType s = (ICPPClassType) col.getName(0).resolveBinding(); + IParameter s2 = (IParameter) col.getName(2).resolveBinding(); + IVariable instance = (IVariable) col.getName(4).resolveBinding(); + + assertInstances( col, s, 2 ); + assertInstances( col, s2, 1 ); + assertSame( instance.getType(), s ); } public void testQualifiedLookup() throws Exception{ @@ -1405,7 +1418,22 @@ public class CompleteParser2Tests extends TestCase { buffer.append( " class A { }; \n" ); //$NON-NLS-1$ buffer.append( "}" ); //$NON-NLS-1$ buffer.append( "void main() { N::A * a = new N::A(); a->f(); } "); //$NON-NLS-1$ - parse( buffer.toString() ); + IASTTranslationUnit tu = parse( buffer.toString() ); + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 13 ); + ICPPNamespace N = (ICPPNamespace) col.getName(0).resolveBinding(); + IFunction f = (IFunction) col.getName(1).resolveBinding(); + ICPPClassType A = (ICPPClassType) col.getName(2).resolveBinding(); + + ICPPConstructor ctor = A.getConstructors()[0]; + + assertInstances( col, N, 3 ); + assertInstances( col, f, 2 ); + assertInstances( col, A, 3 ); + assertInstances( col, ctor, 2 ); } public void testBug43110() throws Exception @@ -1414,7 +1442,18 @@ public class CompleteParser2Tests extends TestCase { buffer.append("void x( int y, ... );\n"); //$NON-NLS-1$ buffer.append("void y( int x... );\n"); //$NON-NLS-1$ buffer.append("void z(...);"); //$NON-NLS-1$ - parse(buffer.toString() ); + IASTTranslationUnit tu = parse( buffer.toString() ); + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 5 ); + IFunction x = (IFunction) col.getName(0).resolveBinding(); + IFunction y = (IFunction) col.getName(2).resolveBinding(); + IFunction z = (IFunction) col.getName(4).resolveBinding(); + assertNotNull(x); + assertNotNull(y); + assertNotNull(z); } public void testBug43110_XRef() throws Exception @@ -1423,17 +1462,50 @@ public class CompleteParser2Tests extends TestCase { buffer.append( "void foo( ... ) {}\n" ); //$NON-NLS-1$ buffer.append( "void main( ){ foo( 1 ); }\n" ); //$NON-NLS-1$ - parse( buffer.toString() ); + IASTTranslationUnit tu = parse( buffer.toString() ); + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 3 ); + IFunction foo = (IFunction) col.getName(0).resolveBinding(); + assertInstances( col, foo, 2 ); } public void testErrorHandling_1() throws Exception { - parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ); //$NON-NLS-1$ + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 9 ); + IProblemBinding p = (IProblemBinding) col.getName(0).resolveBinding(); + IVariable anA = (IVariable) col.getName(1).resolveBinding(); + assertNotNull( col.getName(2).resolveBinding() ); + IProblemBinding p2 = (IProblemBinding) col.getName(3).resolveBinding(); + ICPPClassType A = (ICPPClassType) col.getName(4).resolveBinding(); + + assertInstances( col, anA, 2 ); + assertInstances( col, A, 2 ); + + assertNotNull( p ); + assertNotNull( p2 ); + + assertSame( anA.getType(), p ); } public void testBug44340() throws Exception { // inline function with reference to variables declared after them - parse ("class A{ int getX() {return x[1];} int x[10];};", false ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse ("class A{ int getX() {return x[1];} int x[10];};"); //$NON-NLS-1$ + + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 4 ); + + ICPPField x = (ICPPField) col.getName(2).resolveBinding(); + assertInstances( col, x, 2 ); } public void testBug47628() throws Exception @@ -1451,7 +1523,17 @@ public class CompleteParser2Tests extends TestCase { Writer writer = new StringWriter(); writer.write( "void f( char [] ); \n" ); //$NON-NLS-1$ writer.write( "void f( char * ){} \n" ); //$NON-NLS-1$ - parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 4 ); + IFunction f1 = (IFunction) col.getName(0).resolveBinding(); + IParameter p1 = (IParameter)col.getName(1).resolveBinding(); + IFunction f2 = (IFunction) col.getName(2).resolveBinding(); + IParameter p2 = (IParameter)col.getName(3).resolveBinding(); + assertSame( f1, f2 ); + assertSame( p1, p2 ); } public void testBug45697() throws Exception @@ -1460,7 +1542,18 @@ public class CompleteParser2Tests extends TestCase { writer.write( " int f( bool ); \n"); //$NON-NLS-1$ writer.write( " int f( char ){ } "); //$NON-NLS-1$ - parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 4 ); + IFunction f1 = (IFunction) col.getName(0).resolveBinding(); + IParameter p1 = (IParameter)col.getName(1).resolveBinding(); + IFunction f2 = (IFunction) col.getName(2).resolveBinding(); + IParameter p2 = (IParameter)col.getName(3).resolveBinding(); + + assertNotSame( f1, f2 ); + assertNotSame( p1, p2 ); } public void testBug54639() throws Exception @@ -1468,7 +1561,20 @@ public class CompleteParser2Tests extends TestCase { Writer writer = new StringWriter(); writer.write( "typedef enum _A { } A, *pA; " ); //$NON-NLS-1$ - parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 3 ); + + IEnumeration _A = (IEnumeration) col.getName(0).resolveBinding(); + ITypedef A = (ITypedef) col.getName(1).resolveBinding(); + ITypedef pA = (ITypedef)col.getName(2).resolveBinding(); + + assertNotNull( _A ); + assertSame( A.getType(), _A ); + assertTrue( pA.getType() instanceof IPointerType ); + assertSame( ((IPointerType)pA.getType()).getType(), _A ); } public void testBug55163() throws Exception @@ -1480,13 +1586,34 @@ public class CompleteParser2Tests extends TestCase { writer.write( " for( i = n - 1, di = (double)( i + i ); i > 0; i-- ){ } \n"); //$NON-NLS-1$ writer.write( "}\n"); //$NON-NLS-1$ - parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 11 ); + IVariable i = (IVariable)col.getName(1).resolveBinding(); + IVariable n = (IVariable)col.getName(2).resolveBinding(); + IVariable di = (IVariable)col.getName(3).resolveBinding(); + + assertInstances( col, i, 6 ); + assertInstances( col, n, 2 ); + assertInstances( col, di, 2 ); } public void testBug55673() throws Exception{ Writer writer = new StringWriter(); writer.write( "struct Example { int i; int ( * pfi ) ( int ); }; "); //$NON-NLS-1$ parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 5 ); + ICPPField pfi = (ICPPField)col.getName(3).resolveBinding(); + + assertNotNull( pfi ); + assertTrue( pfi.getType() instanceof IPointerType ); + assertTrue( ((IPointerType)pfi.getType()).getType() instanceof IFunctionType ); } public void testBug54531() throws Exception @@ -1496,7 +1623,15 @@ public class CompleteParser2Tests extends TestCase { public void testBug56516() throws Exception { - parse( "typedef struct blah sb;"); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( "typedef struct blah sb;"); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 2 ); + + IProblemBinding blah = (IProblemBinding) col.getName(0).resolveBinding(); + ITypedef sb = (ITypedef) col.getName(1).resolveBinding(); + assertSame( sb.getType(), blah ); } public void testBug53786() throws Exception @@ -1530,7 +1665,18 @@ public class CompleteParser2Tests extends TestCase { writer.write( " void f( T ); " ); //$NON-NLS-1$ writer.write( "}; " ); //$NON-NLS-1$ writer.write( "void X::f( T ) { } " ); //$NON-NLS-1$ - parse( writer.toString() ); + IASTTranslationUnit tu = parse( writer.toString() ); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 10 ); + ICPPClassType X = (ICPPClassType) col.getName(0).resolveBinding(); + ITypedef T = (ITypedef) col.getName(1).resolveBinding(); + ICPPMethod f = (ICPPMethod) col.getName(2).resolveBinding(); + + assertInstances( col, X, 2 ); + assertInstances( col, T, 3 ); + assertInstances( col, f, 3 ); } public void testBug57800() throws Exception diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 5ac8da36e24..b8f203dbb90 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -19,13 +19,14 @@ import java.text.MessageFormat; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; import org.eclipse.cdt.internal.core.parser.ParserMessages; /** * @author aniefer */ -public class ProblemBinding implements IProblemBinding { +public class ProblemBinding implements IProblemBinding, IType { private final int id; private final char [] arg; @@ -111,4 +112,8 @@ public class ProblemBinding implements IProblemBinding { return null; } + public Object clone(){ + //don't clone problems + return this; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index f254deeb90e..79f3ee923f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.ICPPConstructor; @@ -170,7 +171,11 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { private boolean isConstructorReference( IASTName name ){ IASTNode node = name.getParent(); - + if( node instanceof ICPPASTQualifiedName ){ + IASTName [] ns = ((ICPPASTQualifiedName)node).getNames(); + if( ns[ ns.length - 1 ] == name ) + node = node.getParent(); + } if( node instanceof IASTDeclSpecifier ){ IASTNode parent = node.getParent(); if( parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression ) 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 502ef134054..dba89966b56 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 @@ -98,25 +98,71 @@ public class CPPSemantics { static protected class LookupData { + private IASTName astName; public char[] name; public ObjectMap usingDirectives = ObjectMap.EMPTY_MAP; public ObjectSet visited = ObjectSet.EMPTY_SET; //used to ensure we don't visit things more than once public ObjectSet inheritanceChain; //used to detect circular inheritance - public boolean qualified = false; public boolean ignoreUsingDirectives = false; public boolean usingDirectivesOnly = false; - public boolean forDefinition = false; - public boolean typesOnly = false; public List foundItems = null; public Object [] functionParameters; public boolean forUserDefinedConversion; - public boolean forUsingDeclaration; public ProblemBinding problem; - public boolean considerConstructors; - public LookupData( char[] n ){ - name = n; + public LookupData( IASTName n ){ + astName = n; + this.name = n.toCharArray(); + } + public LookupData( char [] n ){ + astName = null; + this.name = n; + } + public boolean typesOnly(){ + if( astName == null ) return false; + IASTNode parent = astName.getParent(); + return ( parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTElaboratedTypeSpecifier); + } + public boolean forUsingDeclaration(){ + if( astName == null ) return false; + IASTNode p1 = astName.getParent(); + IASTNode p2 = p1.getParent(); + return ( ( p1 instanceof ICPPASTUsingDeclaration ) || + ( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTUsingDeclaration ) ); + } + public boolean forDefinition(){ + if( astName == null ) return false; + IASTNode p1 = astName.getParent(); + IASTNode p2 = p1.getParent(); + + return ( ( p1 instanceof ICPPASTQualifiedName && p2 instanceof IASTDeclarator ) || + ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) ); + } + public boolean considerConstructors(){ + if( astName == null ) return false; + IASTNode p1 = astName.getParent(); + IASTNode p2 = p1.getParent(); + + if( p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId ) + return p2.getParent() instanceof ICPPASTNewExpression; + else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTFunctionDeclarator ){ + IASTName[] names = ((ICPPASTQualifiedName)p1).getNames(); + if( names.length >= 2 && names[ names.length - 1 ] == astName ) + return CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) p2 ); + } else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTNamedTypeSpecifier ){ + IASTNode p3 = p2.getParent(); + return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression; + } + return false; + } + public boolean qualified(){ + if( astName == null ) return false; + IASTNode p1 = astName.getParent(); + if( p1 instanceof ICPPASTQualifiedName ){ + return ((ICPPASTQualifiedName)p1).getNames()[0] != astName; + } + return p1 instanceof ICPPASTFieldReference; } } @@ -271,33 +317,28 @@ public class CPPSemantics { IBinding binding = resolveAmbiguities( data, name ); //4: post processing - if( data.considerConstructors && binding instanceof ICPPClassType ){ + if( binding instanceof ICPPClassType && data.considerConstructors() ){ ICPPClassType cls = (ICPPClassType) binding; //force resolution of constructor bindings cls.getConstructors(); //then use the class scope to resolve which one. binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( name ); } - if( binding != null && data.forDefinition && !( binding instanceof IProblemBinding ) ){ + if( binding != null && data.forDefinition() && !( binding instanceof IProblemBinding ) ){ addDefinition( binding, name ); } + if( binding == null ) + binding = new ProblemBinding(IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray() ); return binding; } static private CPPSemantics.LookupData createLookupData( IASTName name ){ - CPPSemantics.LookupData data = new CPPSemantics.LookupData( name.toCharArray() ); + CPPSemantics.LookupData data = new CPPSemantics.LookupData( name ); IASTNode parent = name.getParent(); if( parent instanceof ICPPASTQualifiedName ){ - IASTName[] names = ((ICPPASTQualifiedName)parent).getNames(); - data.qualified = names[0] != name; parent = parent.getParent(); - if( parent instanceof IASTDeclarator ){ - data.forDefinition = true; - if( parent instanceof ICPPASTFunctionDeclarator ){ - data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); - if( names.length >= 2 && names[ names.length - 1 ] == name ) - data.considerConstructors = CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) parent ); - } + if( parent instanceof ICPPASTFunctionDeclarator ){ + data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); } else if( parent instanceof IASTIdExpression ){ parent = parent.getParent(); if( parent instanceof IASTFunctionCallExpression ){ @@ -309,19 +350,9 @@ public class CPPSemantics { else data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; } - } else if( parent instanceof ICPPASTUsingDeclaration ){ - data.forUsingDeclaration = true; } - } else if( parent instanceof IASTDeclarator ){ - if( parent.getParent() instanceof IASTSimpleDeclaration ) - data.forDefinition = true; - if( parent instanceof ICPPASTFunctionDeclarator ){ - data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); - } - } else if ( parent instanceof ICPPASTBaseSpecifier || - parent instanceof ICPPASTElaboratedTypeSpecifier) - { - data.typesOnly = true; + } else if( parent instanceof ICPPASTFunctionDeclarator ){ + data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); } else if( parent instanceof IASTIdExpression ){ parent = parent.getParent(); if( parent instanceof IASTFunctionCallExpression ){ @@ -333,31 +364,20 @@ public class CPPSemantics { else data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; } - } else if( parent instanceof ICPPASTFieldReference ){ - data.qualified = true; - - if( parent.getParent() instanceof IASTFunctionCallExpression ){ - IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression(); - if( exp instanceof IASTExpressionList ) - data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); - else if( exp != null ) - data.functionParameters = new IASTExpression [] { exp }; - else - data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; - } - } else if( parent instanceof ICPPASTUsingDeclaration ){ - data.forUsingDeclaration = true; - } else if( parent instanceof ICPPASTNamedTypeSpecifier ){ - if( parent.getParent() instanceof IASTTypeId ){ - IASTTypeId typeId = (IASTTypeId) parent.getParent(); - if( typeId.getAbstractDeclarator() instanceof IASTFunctionDeclarator ){ - ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) typeId.getAbstractDeclarator(); - data.functionParameters = fdtor.getParameters(); - } - if( typeId.getParent() instanceof ICPPASTNewExpression ){ - data.considerConstructors = true; - } - } + } else if( parent instanceof ICPPASTFieldReference && parent.getParent() instanceof IASTFunctionCallExpression ){ + IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression(); + if( exp instanceof IASTExpressionList ) + data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); + else if( exp != null ) + data.functionParameters = new IASTExpression [] { exp }; + else + data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; + } else if( parent instanceof ICPPASTNamedTypeSpecifier && parent.getParent() instanceof IASTTypeId ){ + IASTTypeId typeId = (IASTTypeId) parent.getParent(); + if( typeId.getAbstractDeclarator() instanceof IASTFunctionDeclarator ){ + ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) typeId.getAbstractDeclarator(); + data.functionParameters = fdtor.getParameters(); + } } return data; } @@ -365,13 +385,7 @@ public class CPPSemantics { static private ICPPScope getLookupScope( IASTName name ){ IASTNode parent = name.getParent(); - if( parent instanceof IASTDeclSpecifier ){ - IASTNode node = parent.getParent(); - if( node instanceof IASTParameterDeclaration ){ - IASTNode n = CPPVisitor.getContainingBlockItem( parent ); - return (ICPPScope) CPPVisitor.getContainingScope( n ); - } - } else if( parent instanceof ICPPASTBaseSpecifier ) { + if( parent instanceof ICPPASTBaseSpecifier ) { IASTNode n = CPPVisitor.getContainingBlockItem( parent ); return (ICPPScope) CPPVisitor.getContainingScope( n ); } else if( parent instanceof ICPPASTConstructorChainInitializer ){ @@ -419,7 +433,7 @@ public class CPPSemantics { transitives.clear(); transitives = lookupInNominated( data, scope, transitives ); - if( !data.qualified || data.foundItems == null ){ + if( !data.qualified() || data.foundItems == null ){ processDirectives( data, scope, transitives ); } } @@ -437,7 +451,7 @@ public class CPPSemantics { return; //if still not found, loop and check our containing scope - if( data.qualified && !data.usingDirectives.isEmpty() ) + if( data.qualified() && !data.usingDirectives.isEmpty() ) data.usingDirectivesOnly = true; if( blockItem != null ) @@ -623,6 +637,10 @@ public class CPPSemantics { namespaceIdx = -1; } + if( scope instanceof ICPPClassScope ){ + blockItem = null; + } + int idx = -1; IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent ); @@ -695,7 +713,7 @@ public class CPPSemantics { //only consider the transitive using directives if we are an unqualified //lookup, or we didn't find the name in decl - if( usings != null && usings.size() > 0 && (!data.qualified || found == null ) ){ + if( usings != null && usings.size() > 0 && (!data.qualified() || found == null ) ){ if( transitives == null ) transitives = new ArrayList(2); transitives.addAll( usings ); @@ -719,11 +737,11 @@ public class CPPSemantics { if( declaration instanceof IASTSimpleDeclaration ){ IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; - if( !data.typesOnly ) { + if( !data.typesOnly() ) { IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); for( int i = 0; i < declarators.length; i++ ){ IASTDeclarator declarator = declarators[i]; - if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){ + if( data.considerConstructors() || !CPPVisitor.isConstructor( scope, declarator ) ){ IASTName declaratorName = declarator.getName(); if( CharArrayUtils.equals( declaratorName.toCharArray(), data.name ) ){ return declaratorName; @@ -750,7 +768,7 @@ public class CPPSemantics { if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){ return eName; } - if( !data.typesOnly ) { + if( !data.typesOnly() ) { //check enumerators too IASTEnumerator [] list = enumeration.getEnumerators(); for( int i = 0; i < list.length; i++ ) { @@ -775,7 +793,7 @@ public class CPPSemantics { } } - if( data.typesOnly ) + if( data.typesOnly() ) return null; if( declaration instanceof IASTFunctionDefinition ){ @@ -784,7 +802,7 @@ public class CPPSemantics { //check the function itself IASTName declName = declarator.getName(); - if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){ + if( data.considerConstructors() || !CPPVisitor.isConstructor( scope, declarator ) ){ if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){ return declName; } @@ -897,7 +915,7 @@ public class CPPSemantics { } if( type != null ) { - if( data.typesOnly || (obj == null && fns == null) ) + if( data.typesOnly() || (obj == null && fns == null) ) return type; IScope typeScope = type.getScope(); if( obj != null && obj.getScope() != typeScope ){ @@ -960,7 +978,7 @@ public class CPPSemantics { //if there are m arguments in the list, all candidate functions having m parameters //are viable if( num == numParameters ){ - if( data.forDefinition && !functionHasParameters( fName, (IASTParameterDeclaration[]) data.functionParameters ) ){ + if( data.forDefinition() && !functionHasParameters( fName, (IASTParameterDeclaration[]) data.functionParameters ) ){ functions.remove( i-- ); size--; } @@ -1024,7 +1042,7 @@ public class CPPSemantics { return null; } static private IBinding resolveFunction( CPPSemantics.LookupData data, List fns ){ - if( data.forUsingDeclaration ){ + if( data.forUsingDeclaration() ){ if( fns.size() == 1 ) return (IBinding) fns.get( 0 ); return new CPPCompositeBinding( fns ); @@ -1140,7 +1158,7 @@ public class CPPSemantics { //In order for this function to be better than the previous best, it must //have at least one parameter match that is better that the corresponding //match for the other function, and none that are worse. - for( int j = 0; j < numSourceParams; j++ ){ + for( int j = 0; j < numSourceParams || j == 0; j++ ){ if( currFnCost[ j ].rank < 0 ){ hasWorse = true; hasBetter = false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 5070dc84e68..c3c6858a94f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -73,6 +73,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; @@ -127,17 +128,22 @@ public class CPPVisitor { */ public static IBinding createBinding(IASTName name) { IASTNode parent = name.getParent(); + IBinding binding = null; if( parent instanceof IASTNamedTypeSpecifier || parent instanceof ICPPASTQualifiedName || parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTConstructorChainInitializer ) { - IBinding binding = CPPSemantics.resolveBinding( name ); - if( binding == null && parent instanceof ICPPASTQualifiedName ){ - binding = createBinding( (IASTName) parent ); + binding = CPPSemantics.resolveBinding( name ); + if( binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName ){ + if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND ){ + parent = parent.getParent(); + } + } else { + return binding; } - return binding; - } else if( parent instanceof IASTIdExpression ){ + } + if( parent instanceof IASTIdExpression ){ return resolveBinding( parent ); } else if( parent instanceof ICPPASTFieldReference ){ return resolveBinding( parent ); @@ -497,20 +503,14 @@ public class CPPVisitor { * @return */ public static IScope getContainingScope(IASTParameterDeclaration parameterDeclaration) { - IASTNode parent = parameterDeclaration.getParent(); - if( parent instanceof IASTStandardFunctionDeclarator ){ - IASTStandardFunctionDeclarator functionDeclarator = (IASTStandardFunctionDeclarator) parent; - if( functionDeclarator.getNestedDeclarator() != null ){ - return getContainingScope( functionDeclarator ); - } - IASTName fnName = functionDeclarator.getName(); - IBinding binding = fnName.resolveBinding(); - if( binding instanceof IFunction ) - return ((IFunction)binding).getFunctionScope(); - return binding.getScope(); - } - - return null; + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parameterDeclaration.getParent(); + IASTName name = dtor.getName(); + if( name instanceof ICPPASTQualifiedName ) { + IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); + if( ns.length > 0 ) + return getContainingScope( ns [ ns.length - 1 ] ); + } + return getContainingScope( dtor ); } public static IASTNode getContainingBlockItem( IASTNode node ){ @@ -1285,6 +1285,10 @@ public class CPPVisitor { IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); if( binding instanceof IType ) type = (IType) binding; + } else if( declSpec instanceof IASTEnumerationSpecifier ){ + IBinding binding = ((IASTEnumerationSpecifier)declSpec).getName().resolveBinding(); + if( binding instanceof IType ) + type = (IType) binding; } else if( declSpec instanceof ICPPASTSimpleDeclSpecifier ){ ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) &