diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index de66c6f4451..91f24327b8a 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,16 @@ +2003-12-03 Andrew Niefer + -modified FailedCompleteParseASTTest.testPMDotStarPointerToMemberFunction_Bug43242 + .testPMArrowStarPointerToMemberFunction_Bug43242 + .testPMDotStar_bug43579 + .testPMArrowStar_bug43579 + -created: FailedCompleteParseASTTest.testBug47926 + CompleteParseASTTest.testQualifiedLookup + ParserSymbolTableTest.testPrefixLookup_Ambiguities + ParserSymbolTableTest.testQualifiedUnqualifiedLookup + -modified resources/search/classDecl.cpp & include.h + -created FunctionMethodPatternTests.testLookupForDefinition + + 2003-11-27 Andrew Niefer tests for Symbol table prefix lookup ParserSymbolTableTest.testBug46882 diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java index fcfafca2fd4..d8cc9031a22 100644 --- a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java @@ -45,35 +45,47 @@ public class FailedCompleteParseASTTest extends CompleteParseBaseTest public void testPMDotStarPointerToMemberFunction_Bug43242() throws Exception { - Iterator i = parse ("class A { int m(int); }; \n A a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a.*pm)(5));").getDeclarations(); - IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - Iterator members = getDeclarations(cl); - IASTMethod method = (IASTMethod)members.next(); - IASTVariable a = (IASTVariable) i.next(); - IASTVariable pm = (IASTVariable) i.next(); - IASTFunction f1 = (IASTFunction) i.next(); - IASTFunction f2 = (IASTFunction) i.next(); - IASTVariable x = (IASTVariable) i.next(); - - assertAllReferences( 5 /* should be 8 */, - createTaskList( new Task( cl, 2 /* should be 3 */ ), new Task( method ), new Task( a ), new Task( pm ) /* should be ,new Task( f2 ) */ - )); + //parse no longer passes + try{ + parse ("class A { int m(int); }; \n A a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a.*pm)(5));"); + } catch ( ParserException e ){ + assertTrue( e.getMessage().equals( "FAILURE" ) ); + } +// Iterator i = parse ("class A { int m(int); }; \n A a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a.*pm)(5));").getDeclarations(); +// IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); +// Iterator members = getDeclarations(cl); +// IASTMethod method = (IASTMethod)members.next(); +// IASTVariable a = (IASTVariable) i.next(); +// IASTVariable pm = (IASTVariable) i.next(); +// IASTFunction f1 = (IASTFunction) i.next(); +// IASTFunction f2 = (IASTFunction) i.next(); +// IASTVariable x = (IASTVariable) i.next(); +// +// assertAllReferences( 5 /* should be 8 */, +// createTaskList( new Task( cl, 2 /* should be 3 */ ), new Task( method ), new Task( a ), new Task( pm ) /* should be ,new Task( f2 ) */ +// )); } public void testPMArrowStarPointerToMemberFunction_Bug43242() throws Exception { - Iterator i = parse ("class A { int m(int); }; \n A * a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a->*pm)(5));").getDeclarations(); - IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - Iterator members = getDeclarations(cl); - IASTMethod method = (IASTMethod)members.next(); - IASTVariable a = (IASTVariable) i.next(); - IASTVariable pm = (IASTVariable) i.next(); - IASTFunction f1 = (IASTFunction) i.next(); - IASTFunction f2 = (IASTFunction) i.next(); - IASTVariable x = (IASTVariable) i.next(); - - assertAllReferences( 5 /* should be more */, - createTaskList( new Task( cl, 2 ), new Task( method ), new Task( a /*, 2 */), new Task( pm )/* ,new Task( f2 )*/)); - + //parse no longer passes + try{ + parse ("class A { int m(int); }; \n A * a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a->*pm)(5));"); + } catch ( ParserException e ){ + assertTrue( e.getMessage().equals( "FAILURE" ) ); + } +// Iterator i = parse ("class A { int m(int); }; \n A * a; int A::*pm = &A::m; \n int f(){} \n int f(int); \n int x = f((a->*pm)(5));").getDeclarations(); +// IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); +// Iterator members = getDeclarations(cl); +// IASTMethod method = (IASTMethod)members.next(); +// IASTVariable a = (IASTVariable) i.next(); +// IASTVariable pm = (IASTVariable) i.next(); +// IASTFunction f1 = (IASTFunction) i.next(); +// IASTFunction f2 = (IASTFunction) i.next(); +// IASTVariable x = (IASTVariable) i.next(); +// +// assertAllReferences( 5 /* should be more */, +// createTaskList( new Task( cl, 2 ), new Task( method ), new Task( a /*, 2 */), new Task( pm )/* ,new Task( f2 )*/)); +// } public void testUnaryStarCastexpressionPointerToFunction_Bug43241() throws Exception { @@ -93,29 +105,41 @@ public class FailedCompleteParseASTTest extends CompleteParseBaseTest // Kind PM_DOTSTAR public void testPMDotStar_bug43579() throws Exception { - Iterator i = parse ("class A { int m; }; \n A a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a.*pm);").getDeclarations(); - IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - IASTVariable a = (IASTVariable) i.next(); - IASTVariable pm = (IASTVariable) i.next(); - IASTFunction f1 = (IASTFunction) i.next(); - IASTFunction f2 = (IASTFunction) i.next(); - IASTVariable x = (IASTVariable) i.next(); - assertFalse( i.hasNext() ); - assertAllReferences( 4 /*should be 5 */, createTaskList( new Task( cl /* , 2 */ ), new Task( a), new Task( pm), new Task( f2))); + //parse no longer passes + try{ + parse ( "class A { int m; }; \n A a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a.*pm);" ); + } catch ( ParserException e ){ + assertTrue( e.getMessage().equals( "FAILURE" ) ); + } +// Iterator i = parse ("class A { int m; }; \n A a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a.*pm);").getDeclarations(); +// IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); +// IASTVariable a = (IASTVariable) i.next(); +// IASTVariable pm = (IASTVariable) i.next(); +// IASTFunction f1 = (IASTFunction) i.next(); +// IASTFunction f2 = (IASTFunction) i.next(); +// IASTVariable x = (IASTVariable) i.next(); +// assertFalse( i.hasNext() ); +// assertAllReferences( 4 /*should be 5 */, createTaskList( new Task( cl /* , 2 */ ), new Task( a), new Task( pm), new Task( f2))); } // Kind PM_ARROWSTAR public void testPMArrowStar_bug43579() throws Exception { - Iterator i = parse ("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);").getDeclarations(); - IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - IASTVariable a = (IASTVariable) i.next(); - IASTVariable pm = (IASTVariable) i.next(); - IASTFunction f1 = (IASTFunction) i.next(); - IASTFunction f2 = (IASTFunction) i.next(); - IASTVariable x = (IASTVariable) i.next(); - assertFalse( i.hasNext() ); - assertAllReferences( 4 /*should be 5 */, createTaskList( new Task( cl /* , 2 */ ), new Task( a), new Task( pm), new Task( f2))); + //parse no longer passes + try{ + parse ("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);"); + } catch ( ParserException e ){ + assertTrue( e.getMessage().equals( "FAILURE" ) ); + } +// Iterator i = parse ("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);").getDeclarations(); +// IASTClassSpecifier cl = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); +// IASTVariable a = (IASTVariable) i.next(); +// IASTVariable pm = (IASTVariable) i.next(); +// IASTFunction f1 = (IASTFunction) i.next(); +// IASTFunction f2 = (IASTFunction) i.next(); +// IASTVariable x = (IASTVariable) i.next(); +// assertFalse( i.hasNext() ); +// assertAllReferences( 4 /*should be 5 */, createTaskList( new Task( cl /* , 2 */ ), new Task( a), new Task( pm), new Task( f2))); } public void testErrorHandling_1() throws Exception @@ -150,4 +174,25 @@ public class FailedCompleteParseASTTest extends CompleteParseBaseTest } + + public void testBug47926() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "void f () {} \n" ); + buffer.append( "class A { }; \n" ); + buffer.append( "void main() { A * a = new A(); a->f(); } "); + + Iterator i = parse( buffer.toString() ).getDeclarations(); + + IASTFunction f = (IASTFunction) i.next(); + IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); + + IASTFunction main = (IASTFunction) i.next(); + + Iterator fnIter = getDeclarations( main ); + IASTVariable a = (IASTVariable) fnIter.next(); + + //there should be no reference to f, but there is + //assertAllReferences( 3, createTaskList( new Task( classA, 2 ), new Task( a ) ) ); + assertAllReferences( 4, createTaskList( new Task( classA, 2 ), new Task( a ), new Task( f ) ) ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index 4a7462d542f..a9502d6e806 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -1074,4 +1074,32 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertAllReferences( 1, createTaskList( new Task( structS ) ) ); assertFalse( i.hasNext() ); } + + public void testQualifiedLookup() throws Exception{ + //this is meant to test that on a->f, the lookup for f is qualified + //the namespace is necessary because of bug 47926 + StringBuffer buffer = new StringBuffer(); + buffer.append( "namespace N {" ); + buffer.append( " void f () {} \n" ); + buffer.append( " class A { }; \n" ); + buffer.append( "}" ); + buffer.append( "void main() { N::A * a = new N::A(); a->f(); } "); + + Iterator i = parse( buffer.toString() ).getDeclarations(); + + IASTNamespaceDefinition namespace = (IASTNamespaceDefinition) i.next(); + Iterator nsIter = getDeclarations( namespace ); + + IASTFunction f = (IASTFunction) nsIter.next(); + IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)nsIter.next()).getTypeSpecifier(); + + assertFalse( nsIter.hasNext() ); + + IASTFunction main = (IASTFunction) i.next(); + + Iterator fnIter = getDeclarations( main ); + IASTVariable a = (IASTVariable) fnIter.next(); + + assertAllReferences( 5, createTaskList( new Task( namespace, 2 ), new Task( classA, 2 ), new Task( a ) ) ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java index 13ce26a1dbc..a9c3bb075e6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -1950,10 +1950,10 @@ public class ParserSymbolTableTest extends TestCase { B.setType( TypeInfo.t_namespace ); mark = table.setMark(); - A.addUsingDirective( B ); - assertEquals( A.getUsingDirectives().size(), 1 ); + C.addUsingDirective( B ); + assertEquals( C.getUsingDirectives().size(), 1 ); table.rollBack( mark ); - assertEquals( A.getUsingDirectives().size(), 0 ); + assertEquals( C.getUsingDirectives().size(), 0 ); } /** @@ -3107,5 +3107,93 @@ public class ParserSymbolTableTest extends TestCase { assertTrue( results.contains( af2 ) ); } + /** + * int aa; + * namespace { + * namespace U { + * int a; + * } + * namespace V{ + * int a; + * } + * namespace W{ + * int a; + * } + * + * void f(){ + * using namespace U; + * using namespace V; + * using namespace W; + * a(CTRL+SPACE) + * } + * } + * + * @throws Exception + */ + public void testPrefixLookup_Ambiguities() throws Exception{ + newTable(); + + ISymbol aa = table.newSymbol( "aa", TypeInfo.t_int ); + table.getCompilationUnit().addSymbol( aa ); + + IContainerSymbol ns = table.newContainerSymbol( "", TypeInfo.t_namespace ); + table.getCompilationUnit().addSymbol( ns ); + + IContainerSymbol U = table.newContainerSymbol( "U", TypeInfo.t_namespace ); + ns.addSymbol( U ); + ISymbol a1 = table.newSymbol( "a", TypeInfo.t_int ); + U.addSymbol( a1 ); + + IContainerSymbol V = table.newContainerSymbol( "V", TypeInfo.t_namespace ); + ns.addSymbol( V ); + ISymbol a2 = table.newSymbol( "a", TypeInfo.t_int ); + V.addSymbol( a2 ); + + IContainerSymbol W = table.newContainerSymbol( "W", TypeInfo.t_namespace ); + ns.addSymbol( W ); + ISymbol a3 = table.newSymbol( "a", TypeInfo.t_int ); + W.addSymbol( a3 ); + + IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + ns.addSymbol( f ); + + f.addUsingDirective( U ); + f.addUsingDirective( V ); + f.addUsingDirective( W ); + + List results = f.prefixLookup( TypeInfo.t_any, "a", false ); + + assertTrue( results != null ); + assertEquals( results.size(), 1 ); + assertTrue( results.contains( aa ) ); + } + + /** + * int i; + * class A { + * void g(){ + * A a; + * a.i++; //fail qualified lookup, no i in A + * i++; //success unqualified lookup + * } + * }; + * + * @throws Exception + */ + public void testQualifiedUnqualifiedLookup() throws Exception{ + newTable(); + + ISymbol i = table.newSymbol( "i", TypeInfo.t_int ); + table.getCompilationUnit().addSymbol( i ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( A ); + + IParameterizedSymbol g = table.newParameterizedSymbol( "g", TypeInfo.t_function ); + A.addSymbol( g ); + + assertEquals( null, A.qualifiedLookup( "i" ) ); + assertEquals( i, g.lookup( "i" ) ); + } } diff --git a/core/org.eclipse.cdt.core.tests/resources/search/classDecl.cpp b/core/org.eclipse.cdt.core.tests/resources/search/classDecl.cpp index 52bd74045a8..50954fd50b8 100644 --- a/core/org.eclipse.cdt.core.tests/resources/search/classDecl.cpp +++ b/core/org.eclipse.cdt.core.tests/resources/search/classDecl.cpp @@ -28,9 +28,13 @@ namespace NS { Three }; - using namespace NS2; + void f(){ + using namespace NS2; + a aStruct; + } - a aStruct; + + AA anotherStruct; }; union u{ } ; diff --git a/core/org.eclipse.cdt.core.tests/resources/search/include.h b/core/org.eclipse.cdt.core.tests/resources/search/include.h index 7cbb5f838f5..1df7c093c2f 100644 --- a/core/org.eclipse.cdt.core.tests/resources/search/include.h +++ b/core/org.eclipse.cdt.core.tests/resources/search/include.h @@ -25,4 +25,10 @@ class DeclsAndDefns{ void forwardFunction(); +class Direction{ + void turn(); +}; +class Right : public Direction { + void turn() { } +}; #endif \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java b/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java index 3818b1519e7..16f094cb8ee 100644 --- a/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java +++ b/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java @@ -191,4 +191,16 @@ public class FunctionMethodPatternTests extends BaseSearchTest { matches = resultCollector.getSearchResults(); assertEquals( matches.size(), 1 ); } + + public void testLookupForDefinition(){ + ICSearchPattern pattern = SearchEngine.createSearchPattern( "turn", METHOD, DECLARATIONS, true ); + search( workspace, pattern, scope, resultCollector ); + Set matches = resultCollector.getSearchResults(); + assertEquals( matches.size(), 2 ); + + pattern = SearchEngine.createSearchPattern( "Direction::turn", METHOD, DEFINITIONS, true ); + search( workspace, pattern, scope, resultCollector ); + matches = resultCollector.getSearchResults(); + assertEquals( matches.size(), 0 ); + } } diff --git a/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java b/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java index d61833ca13f..faea9bf7be9 100644 --- a/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java +++ b/core/org.eclipse.cdt.core.tests/search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java @@ -148,7 +148,7 @@ public class OtherPatternTests extends BaseSearchTest { search( workspace, pattern, scope, resultCollector ); Set matches = resultCollector.getSearchResults(); - assertEquals( matches.size(), 2 ); + assertEquals( matches.size(), 1 ); IMatch match = (IMatch) matches.iterator().next(); assertTrue( match.getParentName().equals( "NS::B" ) ); @@ -185,7 +185,7 @@ public class OtherPatternTests extends BaseSearchTest { search( workspace, orPattern, scope, resultCollector ); matches = resultCollector.getSearchResults(); - assertEquals( matches.size(), 6 ); + assertEquals( matches.size(), 5 ); } public void testMacroPattern(){ diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index ce871b1560f..aec42466e39 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -1,3 +1,11 @@ +2003-12-03 Andrew Niefer + - Symbol table - modify prefix lookup handling of ambiguities + - fix up qualified lookup + - add IContainerSymbol.lookupMethodForDefinition + - Parser - modify Complete parse AST factory to use the correct lookups in different situations + - Created a LookupType enum to specify what kind of lookup is needed (Qualified, unqualified, for definition) + + 2003-11-27 Andrew Niefer fix bug 47264: Parse fails when using struct s foo; and int s; in function bodies diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index 1909745e98e..b7216021df3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -16,6 +16,7 @@ import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.cdt.core.parser.Enum; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParserLanguage; @@ -101,6 +102,17 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto SUBSCRIPT.add( TypeInfo.OperatorExpression.subscript ); } + static private class LookupType extends Enum { + public static final LookupType QUALIFIED = new LookupType( 1 ); + public static final LookupType UNQUALIFIED = new LookupType( 2 ); + public static final LookupType FORDEFINITION = new LookupType( 3 ); + + private LookupType( int constant) + { + super( constant ); + } + } + public CompleteParseASTFactory( ParserLanguage language ) { super(); @@ -146,7 +158,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto return true; } - private ISymbol lookupElement (IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters) throws ParserSymbolTableException{ + private ISymbol lookupElement (IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, LookupType lookupType ) throws ParserSymbolTableException{ ISymbol result = null; try { if((type == TypeInfo.t_function) || (type == TypeInfo.t_constructor)){ @@ -156,13 +168,24 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto IDerivableContainerSymbol startingDerivableScope = (IDerivableContainerSymbol) startingScope; result = startingDerivableScope.lookupConstructor( new LinkedList(parameters)); } - else - result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters)); + else { + if( lookupType == LookupType.QUALIFIED ) + result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters)); + else if( lookupType == LookupType.UNQUALIFIED ) + result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) ); + else + result = startingScope.lookupMethodForDefinition( name, new LinkedList( parameters ) ); + } else result = null; }else{ // looking for something else - result = startingScope.qualifiedLookup(name, type); + if( lookupType == LookupType.QUALIFIED ) + result = startingScope.qualifiedLookup(name, type); + else if( lookupType == LookupType.UNQUALIFIED ) + result = startingScope.elaboratedLookup( type, name ); + else + result = startingScope.lookupMemberForDefinition( name ); } } catch (ParserSymbolTableException e) { if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ) @@ -171,11 +194,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto return result; } - protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, List references, boolean throwOnError ) throws ASTSemanticException{ - return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, 0, references, throwOnError); + protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException{ + return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, 0, references, throwOnError, lookup ); } - protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, int offset, List references, boolean throwOnError ) throws ASTSemanticException + protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, int offset, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException { ISymbol result = null; try @@ -183,7 +206,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( name == null ) throw new ASTSemanticException(); try { - result = lookupElement(startingScope, name, type, parameters); + result = lookupElement(startingScope, name, type, parameters, lookup); if( result != null ) addReference(references, createReference( result, name, offset )); else @@ -206,10 +229,16 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, List references, boolean throwOnError ) throws ASTSemanticException{ - return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, references, throwOnError); + return lookupQualifiedName(startingScope, name, references, throwOnError, LookupType.UNQUALIFIED); } - - protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, TypeInfo.eType type, List parameters, List references, boolean throwOnError ) throws ASTSemanticException + protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException{ + return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, references, throwOnError, lookup ); + } + protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, TypeInfo.eType type, List parameters, List references, boolean throwOnError ) throws ASTSemanticException{ + return lookupQualifiedName( startingScope, name, type, parameters, references, throwOnError, LookupType.UNQUALIFIED ); + } + + protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, TypeInfo.eType type, List parameters, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException { ISymbol result = null; IToken firstSymbol = null; @@ -226,7 +255,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto firstSymbol = name.getFirstToken(); try { - result = lookupElement(startingScope, firstSymbol.getImage(), type, parameters); + result = lookupElement(startingScope, firstSymbol.getImage(), type, parameters, lookup ); if( result != null ) addReference( references, createReference( result, firstSymbol.getImage(), firstSymbol.getOffset() )); else @@ -252,7 +281,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto try { if( t == name.getLastToken() ) - result = lookupElement((IContainerSymbol)result, t.getImage(), type, parameters); + result = lookupElement((IContainerSymbol)result, t.getImage(), type, parameters, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED ); else result = ((IContainerSymbol)result).lookupNestedNameSpecifier( t.getImage() ); addReference( references, createReference( result, t.getImage(), t.getOffset() )); @@ -814,7 +843,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto // If the expression is lookup symbol if it is in the scope of a type after a "." or an "->" IContainerSymbol searchScope = getSearchScope(kind, lhs, startingScope); if (!searchScope.equals(startingScope)) - symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false); + symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false, LookupType.QUALIFIED ); // get symbol if it is the "this" pointer // go up the scope until you hit a class @@ -839,7 +868,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto parameters = new ArrayList(); parameters.add(expResult.getResult()); } - symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false); + if( functionScope.equals( startingScope ) ) + symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false); + else + symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false, LookupType.QUALIFIED ); } return symbol; @@ -1634,7 +1666,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto IParameterizedSymbol functionDeclaration = null; functionDeclaration = - (IParameterizedSymbol) lookupQualifiedName(ownerScope, name.getLastToken().getImage(), TypeInfo.t_function, functionParameters, 0, new ArrayList(), false); + (IParameterizedSymbol) lookupQualifiedName(ownerScope, name.getLastToken().getImage(), TypeInfo.t_function, functionParameters, 0, new ArrayList(), false, LookupType.UNQUALIFIED ); if( functionDeclaration != null ) { @@ -1935,8 +1967,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto List functionReferences = new ArrayList(); functionDeclaration = - (IParameterizedSymbol) lookupQualifiedName(ownerScope, name, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false); - + (IParameterizedSymbol) lookupQualifiedName(ownerScope, name, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION ); + if( functionDeclaration != null ) { previouslyDeclared = true; @@ -1994,7 +2026,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto ASTConstructorMemberInitializer realInitializer = ((ASTConstructorMemberInitializer)initializer); try { - lookupQualifiedName( symbol, initializer.getName(), realInitializer.getNameOffset(), realInitializer.getReferences(), false ); + IDerivableContainerSymbol container = (IDerivableContainerSymbol) symbol.getContainingSymbol(); + lookupQualifiedName(container, initializer.getName(), TypeInfo.t_any, null, realInitializer.getNameOffset(), realInitializer.getReferences(), false, LookupType.QUALIFIED); } catch( ASTSemanticException ase ) { @@ -2009,19 +2042,6 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } - /** - * @param symbol - * @param string - * @param i - * @param list - * @param b - * @return - */ - protected ISymbol lookupQualifiedName(IParameterizedSymbol startingScope, String name, int nameOffset, List references, boolean throwOnError) throws ASTSemanticException - { - return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, nameOffset, references, throwOnError); - } - /** * @param symbol * @param isConst @@ -2080,17 +2100,16 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto Iterator i = tokens.iterator(); while (i.hasNext() && (numOfTokens++) < tokens.size()){ String token = (String) i.next(); - IContainerSymbol parentSymbol = - (IContainerSymbol) lookupQualifiedName(parentScope, token, TypeInfo.t_class, null, offset, references, false); - if(parentSymbol == null){ - parentSymbol = (IContainerSymbol) lookupQualifiedName(parentScope, token, TypeInfo.t_namespace, null, offset, references, false); - } - if(parentSymbol == null){ - parentSymbol = (IContainerSymbol) lookupQualifiedName(parentScope, token, TypeInfo.t_struct, null, offset, references, false); - } - if(parentSymbol == null){ - parentSymbol = (IContainerSymbol) lookupQualifiedName(parentScope, token, TypeInfo.t_union, null, offset, references, false); + + IContainerSymbol parentSymbol = null; + try { + parentSymbol = (IContainerSymbol) parentScope.lookupNestedNameSpecifier( token ); + if( parentSymbol != null ) + addReference( references, createReference( parentSymbol, name, offset )); + } catch (ParserSymbolTableException e1) { + //do nothing } + if(parentSymbol == null) break; else { @@ -2124,7 +2143,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto newSymbol.setIsForwardDeclaration(isStatic); boolean previouslyDeclared = false; if(!isStatic){ - ISymbol variableDeclaration = (ISymbol) lookupQualifiedName(ownerScope, name, new ArrayList(), false); + ISymbol variableDeclaration = (ISymbol) lookupQualifiedName(ownerScope, name, new ArrayList(), false, LookupType.UNQUALIFIED); if( variableDeclaration != null ) { @@ -2331,7 +2350,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto boolean previouslyDeclared = false; if(!isStatic){ List fieldReferences = new ArrayList(); - ISymbol fieldDeclaration = lookupQualifiedName(ownerScope, name, fieldReferences, false); + ISymbol fieldDeclaration = lookupQualifiedName(ownerScope, name, fieldReferences, false, LookupType.FORDEFINITION); if( fieldDeclaration != null ) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index ca5af515945..7651b5a0646 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -158,6 +158,10 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { if( namespace.getType() != TypeInfo.t_namespace ){ throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing ); } + //7.3.4 A using-directive shall not appear in class scope + if( isType( TypeInfo.t_class, TypeInfo.t_union ) ){ + throw new ParserSymbolTableException( ParserSymbolTableException.r_InvalidUsing ); + } //handle namespace aliasing ISymbol alias = namespace.getTypeSymbol(); @@ -334,6 +338,26 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { return ParserSymbolTable.resolveAmbiguities( data ); } + public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException{ + LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() ); + data.qualified = true; + data.parameters = ( parameters == null ) ? new LinkedList() : parameters; + + IContainerSymbol container = this; + + //handle namespace aliases + if( container.isType( TypeInfo.t_namespace ) ){ + ISymbol symbol = container.getTypeSymbol(); + if( symbol != null && symbol.isType( TypeInfo.t_namespace ) ){ + container = (IContainerSymbol) symbol; + } + } + + data.foundItems = ParserSymbolTable.lookupInContained( data, container ); + + ISymbol symbol = ParserSymbolTable.resolveAmbiguities( data ); + return (IParameterizedSymbol) (( symbol instanceof IParameterizedSymbol ) ? symbol : null); + } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupNestedNameSpecifier(java.lang.String) */ @@ -479,6 +503,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { if( associated.contains( associatedScope ) ){ data.qualified = true; data.ignoreUsingDirectives = true; + data.usingDirectivesOnly = false; ParserSymbolTable.lookup( data, associatedScope ); } } @@ -556,6 +581,14 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { if( data.foundItems == null || data.foundItems.isEmpty() ){ return null; } else { + //remove any ambiguous symbols + if( data.ambiguities != null && !data.ambiguities.isEmpty() ){ + Iterator iter = data.ambiguities.iterator(); + while( iter.hasNext() ){ + data.foundItems.remove( iter.next() ); + } + } + List list = new LinkedList(); Iterator iter = data.foundItems.keySet().iterator(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java index d936bb02886..1fd74524864 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java @@ -44,6 +44,7 @@ public interface IContainerSymbol extends ISymbol { public ISymbol elaboratedLookup( TypeInfo.eType type, String name ) throws ParserSymbolTableException; public ISymbol lookup( String name ) throws ParserSymbolTableException; public ISymbol lookupMemberForDefinition( String name ) throws ParserSymbolTableException; + public IParameterizedSymbol lookupMethodForDefinition( String name, List parameters ) throws ParserSymbolTableException; public IContainerSymbol lookupNestedNameSpecifier( String name ) throws ParserSymbolTableException; public ISymbol qualifiedLookup( String name ) throws ParserSymbolTableException; public ISymbol qualifiedLookup( String name, TypeInfo.eType t ) throws ParserSymbolTableException; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index a0a08373a19..94283fd05bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -106,11 +106,14 @@ public class ParserSymbolTable { LinkedList transitives = new LinkedList(); //list of transitive using directives //if this name define in this scope? - Map map = lookupInContained( data, inSymbol ); - if( data.foundItems == null || data.foundItems.isEmpty() ){ - data.foundItems = map; - } else { - mergeResults( data, data.foundItems, map ); + Map map = null; + if( !data.usingDirectivesOnly ){ + map = lookupInContained( data, inSymbol ); + if( data.foundItems == null || data.foundItems.isEmpty() ){ + data.foundItems = map; + } else { + mergeResults( data, data.foundItems, map ); + } } if( inSymbol.getSymbolTable().getLanguage() == ParserLanguage.CPP && @@ -149,7 +152,7 @@ public class ParserSymbolTable { return; } - if( inSymbol instanceof IDerivableContainerSymbol ){ + if( !data.usingDirectivesOnly && inSymbol instanceof IDerivableContainerSymbol ){ //if we still havn't found it, check any parents we have data.visited.clear(); //each virtual base class is searched at most once map = lookupInParents( data, (IDerivableContainerSymbol)inSymbol ); @@ -162,10 +165,19 @@ public class ParserSymbolTable { } //if still not found, check our containing scope. - if( ( data.foundItems == null || data.foundItems.isEmpty() || ( data.mode == LookupMode.PREFIX && !data.qualified ) ) + if( ( data.foundItems == null || data.foundItems.isEmpty() || data.mode == LookupMode.PREFIX ) && inSymbol.getContainingSymbol() != null ) { - lookup( data, inSymbol.getContainingSymbol() ); + if( data.qualified ){ + if( data.usingDirectives != null && !data.usingDirectives.isEmpty() ){ + data.usingDirectivesOnly = true; + lookup( data, inSymbol.getContainingSymbol() ); + + } + } else { + lookup( data, inSymbol.getContainingSymbol() ); + } + } return; @@ -393,7 +405,14 @@ public class ParserSymbolTable { } else if( foundSymbol.getTypeInfo().isForwardDeclaration() && foundSymbol.getTypeSymbol() == cls ){ //decl is a forward declaration of cls, we already have what we want (cls) } else { - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + if( data.mode == LookupMode.PREFIX ){ + if( data.ambiguities == null ){ + data.ambiguities = new HashSet(); + } + data.ambiguities.add( foundSymbol.getName() ); + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + } } } } else { @@ -401,7 +420,14 @@ public class ParserSymbolTable { if( obj == null ){ obj = foundSymbol; } else { - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + if( data.mode == LookupMode.PREFIX ){ + if( data.ambiguities == null ){ + data.ambiguities = new HashSet(); + } + data.ambiguities.add( foundSymbol.getName() ); + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + } } } } @@ -447,10 +473,17 @@ public class ParserSymbolTable { } if( ambiguous ){ - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); - } else { - return cls; - } + if( data.mode == LookupMode.PREFIX ){ + if( data.ambiguities == null ){ + data.ambiguities = new HashSet(); + } + data.ambiguities.add( foundSymbol.getName() ); + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + } + } + + return cls; } /** * @@ -546,7 +579,17 @@ public class ParserSymbolTable { while( iter.hasNext() ){ key = iter.next(); if( symbol.containsKey( key ) ){ - checkAmbiguity( symbol.get( key ), temp.get( key ) ); + ISymbol sym = (ISymbol) symbol.get( key ); + if( !checkAmbiguity( sym, temp.get( key ) ) ){ + if( data.mode == LookupMode.PREFIX ){ + if( data.ambiguities == null ){ + data.ambiguities = new HashSet(); + } + data.ambiguities.add( sym.getName() ); + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + } + } } else { symbol.put( key, temp.get( key ) ); } @@ -562,7 +605,7 @@ public class ParserSymbolTable { return symbol; } - private static void checkAmbiguity( Object obj1, Object obj2 ) throws ParserSymbolTableException{ + private static boolean checkAmbiguity( Object obj1, Object obj2 ) throws ParserSymbolTableException{ //it is not ambiguous if they are the same thing and it is static or an enumerator if( obj1 == obj2 ){ @@ -571,7 +614,7 @@ public class ParserSymbolTable { while( symbol != null ) { TypeInfo type = ((ISymbol)obj1).getTypeInfo(); if( !type.checkBit( TypeInfo.isStatic ) && !type.isType( TypeInfo.t_enumerator ) ){ - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + return false; } if( iter != null && iter.hasNext() ){ @@ -580,9 +623,9 @@ public class ParserSymbolTable { symbol = null; } } - return; + return true; } - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + return false; } /** @@ -1160,6 +1203,7 @@ public class ParserSymbolTable { //if( symbol.getType() == TypeInfo.t_class ){ if( symbol instanceof IDerivableContainerSymbol ){ associated.add( symbol ); + associated.add( symbol.getContainingSymbol() ); getBaseClassesAndContainingNamespaces( (IDerivableContainerSymbol) symbol, associated ); } //if T is a union or enumeration type, its associated namespace is the namespace in @@ -2188,6 +2232,7 @@ public class ParserSymbolTable { static protected class LookupData { + public Set ambiguities; public String name; public Map usingDirectives; public Set visited = new HashSet(); //used to ensure we don't visit things more than once @@ -2202,6 +2247,7 @@ public class ParserSymbolTable { public TypeInfo.eType upperType = TypeInfo.t_undef; public boolean qualified = false; public boolean ignoreUsingDirectives = false; + public boolean usingDirectivesOnly = false; public boolean forUserDefinedConversion = false; public Map foundItems = null;