Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Symbol Table & Complete Parse patch

This patch changes the handling of ambiguities during prefix lookup.
It also addresses problems in the symbol table to do with qualified 
lookup.  Fixing these revealed problems caused by the 
CompleteParseASTFactory not always using the correct lookup functions.  So 
the factory has been modified to call the appropriate lookups.

The following tests have been created:
        FailedCompleteParseASTTest.testBug47926
        CompleteParseASTTest.testQualifiedLookup
        ParserSymbolTableTest.testPrefixLookup_Ambiguities
        ParserSymbolTableTest.testQualifiedUnqualifiedLookup
        FunctionMethodPatternTests.testLookupForDefinition

-Andrew

Index: parser/ChangeLog
===================================================================
retrieving revision 1.164
diff -u -r1.164 ChangeLog
--- parser/ChangeLog	28 Nov 2003 05:07:21 -0000	1.164
+++ parser/ChangeLog	3 Dec 2003 19:06:09 -0000
@@ -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
 
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java
===================================================================
retrieving revision 1.58
diff -u -r1.58 CompleteParseASTFactory.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java	28 Nov 2003 05:07:21 -0000	1.58
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java	3 Dec 2003 19:06:11 -0000
@@ -16,6 +16,7 @@
 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 @@
     	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 @@
 		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 @@
 						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 @@
 		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 @@
 			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 @@
 	}
 
 	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 @@
 						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 @@
 							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 @@
 		// 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 @@
 				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 @@
 			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 @@
 
 			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 @@
 					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 )
 					{
@@ -2010,19 +2043,6 @@
 	}
 
 	/**
-	 * @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
      * @param isVolatile
@@ -2080,17 +2100,16 @@
 			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 @@
 		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 @@
 		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 )
 			{
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java
===================================================================
retrieving revision 1.2
diff -u -r1.2 ContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java	28 Nov 2003 04:57:50 -0000	1.2
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java	3 Dec 2003 19:06:13 -0000
@@ -158,6 +158,10 @@
 		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 @@
 		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 @@
 				if( associated.contains( associatedScope ) ){
 					data.qualified = true;
 					data.ignoreUsingDirectives = true;
+					data.usingDirectivesOnly = false;
 					ParserSymbolTable.lookup( data, associatedScope );
 				}
 			}
@@ -556,6 +581,14 @@
 		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();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java
===================================================================
retrieving revision 1.8
diff -u -r1.8 IContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java	28 Nov 2003 04:57:50 -0000	1.8
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IContainerSymbol.java	3 Dec 2003 19:06:13 -0000
@@ -44,6 +44,7 @@
 	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;
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
===================================================================
retrieving revision 1.27
diff -u -r1.27 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	28 Nov 2003 04:57:50 -0000	1.27
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	3 Dec 2003 19:06:14 -0000
@@ -106,11 +106,14 @@
 		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 @@
 			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 @@
 		}
 					
 		//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 @@
 							} 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 @@
 						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 @@
 		}
 		
 		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 @@
 					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 @@
 		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 @@
 			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 @@
 					symbol = null;
 				}
 			}
-			return;
+			return true;
 		} 
-		throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+		return false;
 	}
 	
 	/**
@@ -1160,6 +1203,7 @@
 		//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 @@
 	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 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;
Index: ChangeLog
===================================================================
retrieving revision 1.146
diff -u -r1.146 ChangeLog
--- ChangeLog	28 Nov 2003 05:07:26 -0000	1.146
+++ ChangeLog	3 Dec 2003 19:05:43 -0000
@@ -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
Index: failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java
===================================================================
retrieving revision 1.3
diff -u -r1.3 FailedCompleteParseASTTest.java
--- failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java	13 Nov 2003 19:27:29 -0000	1.3
+++ failures/org/eclipse/cdt/core/parser/failedTests/FailedCompleteParseASTTest.java	3 Dec 2003 19:05:44 -0000
@@ -45,35 +45,47 @@
 	
 	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 @@
 	// 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
@@ -149,5 +173,26 @@
 	  }
 		
 		
+	}
+	
+	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 ) ) );
 	}
 }
Index: parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java
===================================================================
retrieving revision 1.43
diff -u -r1.43 CompleteParseASTTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java	28 Nov 2003 05:07:26 -0000	1.43
+++ parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java	3 Dec 2003 19:05:47 -0000
@@ -1074,4 +1074,32 @@
 		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 ) ) );
+	}
 }
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
retrieving revision 1.25
diff -u -r1.25 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	28 Nov 2003 04:58:00 -0000	1.25
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	3 Dec 2003 19:05:49 -0000
@@ -1950,10 +1950,10 @@
 		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 @@
 		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" ) );
+	}
 }
 
Index: resources/search/classDecl.cpp
===================================================================
retrieving revision 1.13
diff -u -r1.13 classDecl.cpp
--- resources/search/classDecl.cpp	30 Sep 2003 13:42:44 -0000	1.13
+++ resources/search/classDecl.cpp	3 Dec 2003 19:05:50 -0000
@@ -28,9 +28,13 @@
 			Three
 		};
 		
-		using namespace NS2;
+		void f(){
+			using namespace NS2;
+			a aStruct;
+		}
 		
-		a aStruct;
+		
+
 		AA anotherStruct;
 	};
 	union u{ } ;
Index: resources/search/include.h
===================================================================
retrieving revision 1.5
diff -u -r1.5 include.h
--- resources/search/include.h	13 Nov 2003 19:27:29 -0000	1.5
+++ resources/search/include.h	3 Dec 2003 19:05:50 -0000
@@ -25,4 +25,10 @@
 void forwardFunction();
 
 
+class Direction{
+   void turn();
+};
+class Right : public Direction  {
+   void turn() { }
+};
 #endif
Index: search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java
===================================================================
retrieving revision 1.11
diff -u -r1.11 FunctionMethodPatternTests.java
--- search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java	30 Sep 2003 13:42:44 -0000	1.11
+++ search/org/eclipse/cdt/core/search/tests/FunctionMethodPatternTests.java	3 Dec 2003 19:05:51 -0000
@@ -191,4 +191,16 @@
 		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 );
+	}
 }
Index: search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java
===================================================================
retrieving revision 1.20
diff -u -r1.20 OtherPatternTests.java
--- search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java	10 Nov 2003 19:37:02 -0000	1.20
+++ search/org/eclipse/cdt/core/search/tests/OtherPatternTests.java	3 Dec 2003 19:05:51 -0000
@@ -148,7 +148,7 @@
 		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 @@
 		
 		search( workspace, orPattern, scope, resultCollector );
 		matches = resultCollector.getSearchResults();
-		assertEquals( matches.size(), 6 );
+		assertEquals( matches.size(), 5 );
 	}
 
 	public void testMacroPattern(){

Back to the top