Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Parser Symbol Table updates

patch_04.01.03(cdt.core).txt
Modified lookup with respect to resolving ambiguous names, reducing the
number of temporary lists/sets.  Modified adding using declarations to
properly support overloaded functions.  Added initial support for user
defined conversion sequences when resolving overloaded functions.

patch_04.01.03(cdt.ui.tests).txt
Modifications to using declaration tests to reflect changes in the symbol
table.  Also added testUserDefinedConversionSequences()

-Andrew

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/ChangeLog,v
retrieving revision 1.16
diff -u -r1.16 ChangeLog
--- ChangeLog	1 Apr 2003 18:54:16 -0000	1.16
+++ ChangeLog	1 Apr 2003 23:20:48 -0000
@@ -1,3 +1,7 @@
+2003-04-01 Andrew Niefer
+	ParserSymbolTableTest. modifications to using declaration tests to reflect changes in the
+	symbol table.  Also added testUserDefinedConversionSequences()
+
 2003-03-31 John Camelon
 	Added testStruct() to DOMTests.  
 	Added test35892()to ScannerTest. 
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java,v
retrieving revision 1.8
diff -u -r1.8 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	31 Mar 2003 20:43:02 -0000	1.8
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	1 Apr 2003 23:20:49 -0000
@@ -1146,34 +1146,19 @@
 		
 		Declaration lookB = table.LookupNestedNameSpecifier("B");
 		assertEquals( lookB, B );
-		table.push( lookB );
-		look = table.QualifiedLookup( "f" );
-		table.pop();
-		
-		assertEquals( look, f );
-		table.addUsingDeclaration( look );
+
+		table.addUsingDeclaration( "f", lookB );
 		
-		table.push( lookB );
-		look = table.QualifiedLookup( "e" );
-		table.pop();
-		assertEquals( look, e );
-		table.addUsingDeclaration( look );
+		table.addUsingDeclaration( "e", lookB );
 		  
 		//TBD anonymous union
-		//table.push( lookB );
-		//look = table.QualifiedLookup( "x")
-		//table.pop();
-		//table.addUsingDeclaration( look );
+		//table.addUsingDeclaration( "x", lookB );
 		
 		look = table.LookupNestedNameSpecifier("C");
 		assertEquals( look, C );
-		table.push( look );
-		look = table.QualifiedLookup("g");
-		table.pop();
-		assertEquals( look, g );
 		
 		try{
-			table.addUsingDeclaration( look );
+			table.addUsingDeclaration( "g", look );
 			assertTrue( false );
 		}
 		catch ( ParserSymbolTableException exception ){
@@ -1204,10 +1189,6 @@
 	 * 	  using A::f;
 	 * 	  f('a');    //calls f( char );
 	 * }	
-	 *
-	 * TBD: we need to support using declarations for overloaded functions.
-	 * TBD: function overload resolution is not done yet, so the call to f in
-	 * bar() can't be tested yet.
 	 */
 	public void testUsingDeclaration_2() throws Exception{
 		newTable();
@@ -1228,12 +1209,8 @@
 		
 		Declaration look = table.LookupNestedNameSpecifier("A");
 		assertEquals( look, A );
-		table.push( A );
-		look = table.QualifiedLookup("f");
-		assertEquals( look, f1 );
-		table.pop();
 		
-		Declaration usingF = table.addUsingDeclaration( look );
+		Declaration usingF = table.addUsingDeclaration( "f", look );
 		
 		look = table.Lookup("A");
 		assertEquals( look, A );
@@ -1258,7 +1235,23 @@
 		
 		look = table.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, usingF );
+		assertTrue( look.hasSameParameters( f1 ) );
+		
+		Declaration bar = new Declaration( "bar" );
+		bar.setType( TypeInfo.t_function );
+		bar.addParameter( TypeInfo.t_char, 0, null, false );
+		table.addDeclaration( bar );
+		table.push( bar );
+		
+		look = table.LookupNestedNameSpecifier( "A" );
+		assertEquals( look, A );
+		table.addUsingDeclaration( "f", A );
 		
+		look = table.UnqualifiedFunctionLookup( "f", paramList );
+		assertTrue( look != null );
+		assertTrue( look.hasSameParameters( f2 ) );
+		
+		table.pop();
 	}
 	
 	/**
@@ -1389,8 +1382,8 @@
 		LinkedList paramList = new LinkedList();
 		look = table.Lookup( "parm" );
 		assertEquals( look, param );
-		
-		paramList.add( look.getTypeInfo() );
+		TypeInfo p = new TypeInfo( TypeInfo.t_type, look, 0, null, false );
+		paramList.add( p );
 		
 		look = table.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f );
@@ -1764,6 +1757,61 @@
 		look = table.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f1 );
 		
+	}
+	
+	/**
+	 * 
+	 * @throws Exception
+	 *
+	 *  class A {};
+	 *
+	 *	class B
+	 *	{
+	 *	   B( A a ){ };
+	 *	};
+	 *	
+	 *	void f( B b ){};
+	 *	
+	 *  A a;
+	 *	f( a );
+	 */
+	public void testUserDefinedConversionSequences() throws Exception{
+		newTable();
+		
+		Declaration A = new Declaration( "A" );
+		A.setType( TypeInfo.t_class );
+		table.addDeclaration( A );
+		
+		Declaration B = new Declaration( "B" );
+		B.setType( TypeInfo.t_class );
+		table.addDeclaration( B );
+		
+		table.push( B );
+		
+		//12.1-1 "Constructors do not have names"
+		Declaration constructor = new Declaration("");
+		constructor.setType( TypeInfo.t_function );
+		constructor.addParameter( A, 0, null, false );
+		table.addDeclaration( constructor );
+		
+		table.pop();
+		
+		Declaration f = new Declaration( "f" );
+		f.setType( TypeInfo.t_function );
+		f.addParameter( B, 0, null, false );
+		table.addDeclaration( f );
+		
+		Declaration a = new Declaration( "a" );
+		a.setType( TypeInfo.t_type );
+		a.setTypeDeclaration( A );
+		table.addDeclaration( a );
+		
+		LinkedList paramList = new LinkedList();
+		TypeInfo p = new TypeInfo( TypeInfo.t_type, a, 0, null, false );
+		paramList.add( p );
+		
+		Declaration look = table.UnqualifiedFunctionLookup( "f", paramList );
+		assertEquals( look, f );	
 	}
 }
 
Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.15
diff -u -r1.15 ChangeLog
--- parser/ChangeLog	1 Apr 2003 18:52:37 -0000	1.15
+++ parser/ChangeLog	1 Apr 2003 23:21:11 -0000
@@ -1,3 +1,9 @@
+2003-04-01 Andrew Niefer
+	Parser Symbol Table, modified lookup with respect to resolving ambiguous names,
+	reducing the number of temporary lists/sets.  Modified adding using declarations
+	to properly support overloaded functions.  Added initial support for user defined
+	conversion sequences when resolving overloaded functions.
+
 2003-03-31 John Camelon
 	Fixed unsigned short SimpleDeclarations not showing up in the outline view.  
 	Fixed default visibilities for structs in outline view.  
Index: parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java,v
retrieving revision 1.7
diff -u -r1.7 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java	31 Mar 2003 20:43:07 -0000	1.7
+++ parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java	1 Apr 2003 23:21:11 -0000
@@ -72,12 +72,18 @@
 		
 	public Declaration Lookup( String name ) throws ParserSymbolTableException {
 		LookupData data = new LookupData( name, -1 );
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		
+		Lookup( data, (Declaration) _contextStack.peek() );
+		
+		return ResolveAmbiguities( data ); 
 	}
 	
 	public Declaration ElaboratedLookup( int type, String name ) throws ParserSymbolTableException{
 		LookupData data = new LookupData( name, type );
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		
+		Lookup( data, (Declaration) _contextStack.peek() );
+		
+		return ResolveAmbiguities( data ); 
 	}
 
 	/**
@@ -101,8 +107,12 @@
 		LookupData data = new LookupData( name, TypeInfo.t_namespace );
 		data.upperType = TypeInfo.t_union;
 		
-		foundDeclaration = LookupInContained( data, inDeclaration );
-			
+		LookupInContained( data, inDeclaration );
+		
+		if( data.foundItems != null ){
+			foundDeclaration = ResolveAmbiguities( data );//, data.foundItems );
+		}
+				
 		if( foundDeclaration == null && inDeclaration._containingScope != null ){
 			foundDeclaration = LookupNestedNameSpecifier( name, inDeclaration._containingScope );
 		}
@@ -142,7 +152,9 @@
 		LookupData data = new LookupData( name, -1 );
 		data.qualified = true;
 	
-		return LookupInContained( data, (Declaration) _contextStack.peek() );
+		LookupInContained( data, (Declaration) _contextStack.peek() );
+		
+		return ResolveAmbiguities( data );
 	}
 	
 	/**
@@ -155,7 +167,9 @@
 	public Declaration QualifiedLookup( String name ) throws ParserSymbolTableException{
 		LookupData data = new LookupData( name, -1 );
 		data.qualified = true;
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		Lookup( data, (Declaration) _contextStack.peek() );
+		
+		return ResolveAmbiguities( data ); 
 	}
 	
 	/**
@@ -168,9 +182,13 @@
 	public Declaration QualifiedFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{
 		LookupData data = new LookupData( name, TypeInfo.t_function );
 		data.qualified = true;
-		data.parameters = parameters;
+		//if parameters == null, thats no parameters, but we need to distinguish that from
+		//no parameter information at all, so make an empty list.
+		data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
+		
+		Lookup( data, (Declaration) _contextStack.peek() );
 		
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		return ResolveAmbiguities( data ); 
 	}
 	
 	/**
@@ -185,9 +203,12 @@
 	 */
 	public Declaration MemberFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{
 		LookupData data = new LookupData( name, TypeInfo.t_function );
-		data.parameters = parameters;
+		//if parameters == null, thats no parameters, but we need to distinguish that from
+		//no parameter information at all, so make an empty list.
+		data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
 			
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		Lookup( data, (Declaration) _contextStack.peek() );
+		return ResolveAmbiguities( data ); 
 	}
 	
 	/**
@@ -216,16 +237,19 @@
 		//figure out the set of associated scopes first, so we can remove those that are searched
 		//during the normal lookup to avoid doing them twice
 		HashSet associated = new HashSet();
+		
 		//collect associated namespaces & classes.
 		int size = ( parameters == null ) ? 0 : parameters.size();
 		Iterator iter = ( parameters == null ) ? null : parameters.iterator();
+		
 		TypeInfo param = null;
 		Declaration paramType = null;
 		for( int i = size; i > 0; i-- ){
 			param = (TypeInfo) iter.next();
-			paramType = param.getTypeDeclaration();
+			paramType = getFlatTypeInfo( param ).getTypeDeclaration();
 			
 			getAssociatedScopes( paramType, associated );
+			
 			//if T is a pointer to a data member of class X, its associated namespaces and classes
 			//are those associated with the member type together with those associated with X
 			if( param.getPtrOperator() != null && 
@@ -237,21 +261,22 @@
 		}
 		
 		LookupData data = new LookupData( name, TypeInfo.t_function );
-		data.parameters = parameters;
+		//if parameters == null, thats no parameters, but we need to distinguish that from
+		//no parameter information at all, so make an empty list.
+		data.parameters = ( parameters == null ) ? new LinkedList() : parameters;
 		data.associated = associated;
 		
-		Declaration found = Lookup( data, (Declaration) _contextStack.peek() );
+		Lookup( data, (Declaration) _contextStack.peek() );
+		
+		Declaration found = ResolveAmbiguities( data );
 		
 		//if we haven't found anything, or what we found is not a class member, consider the 
 		//associated scopes
 		if( found == null || found._containingScope.getType() != TypeInfo.t_class ){
-			HashSet foundSet = new HashSet();
-			
 			if( found != null ){
-				foundSet.add( found );
+				data.foundItems.add( found );
 			}
-			
-						
+									
 			Declaration decl;
 			Declaration temp;
 
@@ -267,14 +292,11 @@
 				if( associated.contains( decl ) ){
 					data.qualified = true;
 					data.ignoreUsingDirectives = true;
-					temp = Lookup( data, decl );
-					if( temp != null ){
-						foundSet.add( temp );
-					}	
+					Lookup( data, decl );
 				}
 			}
 			
-			found = ResolveAmbiguities( data, foundSet );
+			found = ResolveAmbiguities( data );
 		}
 		
 		return found;
@@ -307,7 +329,9 @@
 
 		data.stopAt = enclosing;
 		
-		return Lookup( data, (Declaration) _contextStack.peek() );
+		Lookup( data, (Declaration) _contextStack.peek() );
+		
+		return ResolveAmbiguities( data ); 
 	}
 		
 	public void addUsingDirective( Declaration namespace ) throws ParserSymbolTableException{
@@ -340,38 +364,48 @@
 	 * class being defined, or shall refer to an enumerator for an enumeration
 	 * type that is a member of a base class of the class being defined.
 	 */
-	public Declaration addUsingDeclaration( Declaration obj ) throws ParserSymbolTableException{
-		Declaration clone = null;
-		Declaration context = (Declaration) _contextStack.peek();
-		boolean okToAdd = false;
+	public Declaration addUsingDeclaration( String name ) throws ParserSymbolTableException {
+		return addUsingDeclaration( name, null );
+	}
+	
+	public Declaration addUsingDeclaration( String name, Declaration declContext ) throws ParserSymbolTableException{
+		LookupData data = new LookupData( name, -1 );
 		
-		//7.3.3-4
-		if( context.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
-			//a member of a base class
-			if( obj.getContainingScope().getType() == context.getType() ){
-				okToAdd = ( hasBaseClass( context, obj.getContainingScope() ) > 0 );		
-			} 
-			//TBD : a member of an _anonymous_ union
-			else if ( obj.getContainingScope().getType() == TypeInfo.t_union ) {
-				Declaration union = obj.getContainingScope();
-				okToAdd = ( hasBaseClass( context, union.getContainingScope() ) > 0 ); 
-			}
-			//an enumerator for an enumeration
-			else if ( obj.getType() == TypeInfo.t_enumerator ){
-				Declaration enumeration = obj.getContainingScope();
-				okToAdd = ( hasBaseClass( context, enumeration.getContainingScope() ) > 0 );
-			}
+		if( declContext != null ){				
+			push( declContext );
+			data.qualified = true;
+			Lookup( data, (Declaration) _contextStack.peek() );
+			pop();
 		} else {
-			okToAdd = true;
+			Lookup( data, (Declaration) _contextStack.peek() );
 		}
 		
-		if( okToAdd ){
-			clone = (Declaration) obj.clone(); //7.3.3-9
-			addDeclaration( clone );
-		} else {
-			throw new ParserSymbolTableException();
+		//figure out which declaration we are talking about, if it is a set of functions,
+		//then they will be in data.foundItems (since we provided no parameter info);
+		Declaration obj = ResolveAmbiguities( data );
+		
+		if( data.foundItems == null ){
+			throw new ParserSymbolTableException();				
 		}
-		return clone;
+
+		Declaration clone = null;
+
+		//if obj != null, then that is the only object to consider, so size is 1,
+		//otherwise we consider the foundItems set				
+		int size = ( obj == null ) ? data.foundItems.size() : 1;
+		Iterator iter = data.foundItems.iterator();
+		for( int i = size; i > 0; i-- ){
+			obj = ( obj != null && size == 1 ) ? obj : (Declaration) iter.next();
+			
+			if( okToAddUsingDeclaration( obj, (Declaration) _contextStack.peek() ) ){
+				clone = (Declaration) obj.clone(); //7.3.3-9
+				addDeclaration( clone );
+			} else {
+				throw new ParserSymbolTableException();
+			}
+		}
+		
+		return ( size == 1 ) ? clone : null;
 	}
 	
 	public void addDeclaration( Declaration obj ) throws ParserSymbolTableException{
@@ -500,7 +534,10 @@
 			//check to see if there is already a this object, since using declarations
 			//of function will have them from the original declaration
 			LookupData data = new LookupData( "this", -1 );
-			if( LookupInContained( data, obj ) == null ){
+			LookupInContained( data, obj );
+			//if we didn't find "this" then foundItems will still be null, no need to actually
+			//check its contents 
+			if( data.foundItems == null ){
 				Declaration thisObj = new Declaration("this");
 				thisObj.setType( TypeInfo.t_type );
 				thisObj.setTypeDeclaration( obj._containingScope );
@@ -521,24 +558,18 @@
 	 * @return Declaration
 	 * @throws ParserSymbolTableException
 	 */
-	static private Declaration Lookup( LookupData data, Declaration inDeclaration ) throws ParserSymbolTableException
+	static private void Lookup( LookupData data, Declaration inDeclaration ) throws ParserSymbolTableException
 	{
 		if( data.type != -1 && data.type < TypeInfo.t_class && data.upperType > TypeInfo.t_union ){
 			throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
 		}
 		
 		Declaration decl = null;					//the return value
-		LinkedList tempList = null;
-		LinkedList foundNames = new LinkedList();	//list of names found
 		LinkedList transitives = new LinkedList();	//list of transitive using directives
 		
-		
 		//if this name define in this scope?
-		decl = LookupInContained( data, inDeclaration );
-		if( decl != null ){
-			foundNames.add( decl );		 
-		}
-			
+		LookupInContained( data, inDeclaration );
+		
 		if( !data.ignoreUsingDirectives ){
 			//check nominated namespaces
 			//the transitives list is populated in LookupInNominated, and then 
@@ -546,15 +577,11 @@
 			
 			data.visited.clear(); //each namesapce is searched at most once, so keep track
 			
-			tempList = LookupInNominated( data, inDeclaration, transitives );
-					
-			if( tempList != null ){
-				foundNames.addAll( tempList );
-			}
-				
+			LookupInNominated( data, inDeclaration, transitives );
+
 			//if we are doing a qualified lookup, only process using directives if
 			//we haven't found the name yet (and if we aren't ignoring them). 
-			if( !data.qualified || foundNames.size() == 0 ){
+			if( !data.qualified || data.foundItems == null ){
 				ProcessDirectives( inDeclaration, data, transitives );
 				
 				if( inDeclaration._usingDirectives != null ){
@@ -564,34 +591,36 @@
 				while( data.usingDirectives != null && data.usingDirectives.get( inDeclaration ) != null ){
 					transitives.clear();
 					
-					tempList = LookupInNominated( data, inDeclaration, transitives );
-					
-					if( tempList != null ){
-						foundNames.addAll( tempList );
-					}
+					LookupInNominated( data, inDeclaration, transitives );
 	
-					if( !data.qualified || foundNames.size() == 0 ){
+					if( !data.qualified || data.foundItems == null ){
 						ProcessDirectives( inDeclaration, data, transitives );
 					}
 				}
 			}
 		}
 		
-		decl = ResolveAmbiguities( data, new HashSet( foundNames ) );
-		if( decl != null || data.stopAt == inDeclaration ){
-			return decl;
+		if( data.foundItems != null || data.stopAt == inDeclaration ){
+			return;
 		}
 			
 		//if we still havn't found it, check any parents we have
 		data.visited.clear();	//each virtual base class is searched at most once	
-		decl = LookupInParents( data, inDeclaration );	
+		decl = LookupInParents( data, inDeclaration );
+		
+		//there is a resolveAmbiguities inside LookupInParents, which means if we found
+		//something the foundItems set will be non-null, but empty.  So, add the decl into
+		//the foundItems set
+		if( decl != null ){
+			data.foundItems.add( decl );	
+		}
 					
 		//if still not found, check our containing scope.			
-		if( decl == null && inDeclaration._containingScope != null ){ 
-			decl = Lookup( data, inDeclaration._containingScope );
+		if( data.foundItems == null && inDeclaration._containingScope != null ){ 
+			Lookup( data, inDeclaration._containingScope );
 		}
 
-		return decl;
+		return;
 	}
 	
 	/**
@@ -613,29 +642,28 @@
 	 * directives, the effect is as if the using-directives from the second
 	 * namespace also appeared in the first.
 	 */
-	static private LinkedList LookupInNominated( LookupData data, Declaration declaration, LinkedList transitiveDirectives ) throws ParserSymbolTableException{
+	static private void LookupInNominated( LookupData data, Declaration declaration, LinkedList transitiveDirectives ) throws ParserSymbolTableException{
 		//if the data.usingDirectives is empty, there is nothing to do.
 		if( data.usingDirectives == null ){
-			return null;
+			return;
 		}
 			
-		LinkedList found = null;	//list of found names to return
-		
 		//local variables
-		LinkedList  list = null;
+		LinkedList  directives = null; //using directives association with declaration
 		Iterator    iter = null;
 		Declaration decl = null;
-		Declaration temp = null;
+		
+		boolean foundSomething = false;
 		int size = 0;
 		
-		list = (LinkedList) data.usingDirectives.remove( declaration );
+		directives = (LinkedList) data.usingDirectives.remove( declaration );
 		
-		if( list == null ){
-			return null;
+		if( directives == null ){
+			return;
 		}
 		
-		iter = list.iterator();
-		size = list.size();
+		iter = directives.iterator();
+		size = directives.size();
 		for( int i = size; i > 0; i-- ){
 			decl = (Declaration) iter.next();
 
@@ -643,26 +671,18 @@
 			if( !data.visited.contains( decl ) ){
 				data.visited.add( decl );
 				
-				temp = LookupInContained( data, decl );
-										
-				//if we found something, add it to the list of found names
-				if( temp != null ){
-					if( found == null ){ 
-						found = new LinkedList();
-					}
-					found.add( temp );
-				}	
-				
+				foundSomething = LookupInContained( data, decl );
+													
 				//only consider the transitive using directives if we are an unqualified
 				//lookup, or we didn't find the name in decl
-				if( (!data.qualified || temp == null) && decl._usingDirectives != null ){
+				if( (!data.qualified || !foundSomething ) && decl._usingDirectives != null ){
 					//name wasn't found, add transitive using directives for later consideration
 					transitiveDirectives.addAll( decl._usingDirectives );
 				}
 			}
 		}
 		
-		return found;
+		return;
 	}
 	
 	/**
@@ -673,8 +693,8 @@
 	 * 
 	 * Look for data.name in our collection _containedDeclarations
 	 */
-	private static Declaration LookupInContained( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{
-		HashSet found = null;
+	private static boolean LookupInContained( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{
+		boolean foundSomething = false;
 		Declaration temp  = null;
 		Object obj = null;
 	
@@ -685,24 +705,27 @@
 		
 		Map declarations = lookIn.getContainedDeclarations();
 		if( declarations == null )
-			return null;
+			return foundSomething;
 		
 		obj = declarations.get( data.name );
 	
 		if( obj == null ){
 			//not found
-			return null;
+			return foundSomething;
 		}
-					
+		
 	 	//the contained declarations map either to a Declaration object, or to a list
 	 	//of declaration objects.
 		if( obj.getClass() == Declaration.class ){	
 			if( ((Declaration)obj).isType( data.type, data.upperType ) ){
-				return (Declaration) obj;
+				if( data.foundItems == null ){
+					data.foundItems = new HashSet();
+				}
+				data.foundItems.add( obj );
+				foundSomething = true;
 			}
 		} else {
-			found = new HashSet();
-			
+			//we have to filter on type so can't just add the list whole to the fount set
 			LinkedList objList = (LinkedList)obj;
 			Iterator iter  = objList.iterator();
 			int size = objList.size();
@@ -711,17 +734,16 @@
 				temp = (Declaration) iter.next();
 		
 				if( temp.isType( data.type, data.upperType ) ){
-					found.add(temp);
+					if( data.foundItems == null ){
+						data.foundItems = new HashSet();
+					}
+					data.foundItems.add(temp);
+					foundSomething = true;
 				} 
 			}
 		}
 
-		//if none of the found items made it through the type filtering, just
-		//return null instead of an empty list.
-		if( found == null || found.size() == 0 )			
-			return null;
-		
-		return ResolveAmbiguities( data, found );
+		return foundSomething;
 	}
 	
 	/**
@@ -733,6 +755,7 @@
 	 */
 	private static Declaration LookupInParents( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{
 		LinkedList scopes = lookIn.getParentScopes();
+		boolean foundSomething = false;
 		Declaration temp = null;
 		Declaration decl = null;
 		
@@ -764,8 +787,8 @@
 				//is circular inheritance
 				if( ! data.inheritanceChain.contains( wrapper.parent ) ){
 					//is this name define in this scope?
-					temp =  LookupInContained( data, wrapper.parent );
-					
+					LookupInContained( data, wrapper.parent );
+					temp = ResolveAmbiguities( data );
 					if( temp == null ){
 						temp = LookupInParents( data, wrapper.parent );
 					}
@@ -880,86 +903,137 @@
 		return true;
 	}
 	
-	static private Declaration ResolveAmbiguities( LookupData data, HashSet items ) throws ParserSymbolTableException{
-		int size = items.size(); 
-		Iterator iter = items.iterator();
+	/**
+	 * 
+	 * @param data
+	 * @return Declaration
+	 * @throws ParserSymbolTableException
+	 * 
+	 * Resolve the foundItems set down to one declaration and return that
+	 * declaration.  
+	 * If we successfully resolve, then the data.foundItems list will be
+	 * cleared.  If however, we were not able to completely resolve the set,
+	 * then the data.foundItems set will be left with those items that
+	 * survived the partial resolution and we will return null.  (currently,
+	 * this case applies to when we have overloaded functions and no parameter
+	 * information)
+	 * 
+	 * NOTE: data.parameters == null means there is no parameter information at
+	 * all, when looking for functions with no parameters, an empty list must be
+	 * provided in data.parameters.
+	 */
+	static private Declaration ResolveAmbiguities( LookupData data ) throws ParserSymbolTableException{
+		Declaration decl = null;
+		Declaration obj	= null;
+		Declaration cls = null;
+		
+		if( data.foundItems == null ){
+			return null;
+		}
+		
+		int size = data.foundItems.size(); 
+		Iterator iter = data.foundItems.iterator();
+		
+		boolean needDecl = true;
 		
 		if( size == 0){
 			return null;
 		} else if (size == 1) {
-			return (Declaration) iter.next();
-		} else	{
-			LinkedList functionList = null;	
-
-			Declaration decl = null;
-			Declaration obj	= null;
-			Declaration cls = null;
-			
-			for( int i = size; i > 0; i-- ){
+			decl = (Declaration) iter.next();
+			//if it is a function we need to check its parameters
+			if( !decl.isType( TypeInfo.t_function ) ){
+				data.foundItems.clear();
+				return decl;
+			}
+			needDecl = false;
+		} 
+		
+		LinkedList functionList = null;	
+
+		for( int i = size; i > 0; i-- ){
+			//if we
+			if( needDecl ){
 				decl = (Declaration) iter.next();
-				
-				if( decl.isType( TypeInfo.t_function ) ){
-					if( functionList == null){
-						functionList = new LinkedList();
+			} else {
+				needDecl = true;
+			}
+			
+			if( decl.isType( TypeInfo.t_function ) ){
+				if( functionList == null){
+					functionList = new LinkedList();
+				}
+				functionList.add( decl );
+			} else {
+				//if this is a class-name, other stuff hides it
+				if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
+					if( cls == null ) {
+						cls = decl;
+					} else {
+						throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); 
 					}
-					functionList.add( decl );
 				} else {
-					//if this is a class-name, other stuff hides it
-					if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
-						if( cls == null ) {
-							cls = decl;
-						} else {
-							throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); 
-						}
+					//an object, can only have one of these
+					if( obj == null ){
+						obj = decl;	
 					} else {
-						//an object, can only have one of these
-						if( obj == null ){
-							obj = decl;	
-						} else {
-							throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); 
-						}
+						throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); 
 					}
 				}
 			}
-		
-			int numFunctions = ( functionList == null ) ? 0 : functionList.size();
-			
-			boolean ambiguous = false;
 			
-			if( cls != null ){
-				//the class is only hidden by other stuff if they are from the same scope
-				if( obj != null && cls._containingScope != obj._containingScope ){
-					ambiguous = true;	
-				}
-				if( functionList != null ){
-					Iterator fnIter = functionList.iterator();
-					Declaration fn = null;
-					for( int i = numFunctions; i > 0; i-- ){
-						fn = (Declaration) fnIter.next();
-						if( cls._containingScope != fn._containingScope ){
-							ambiguous = true;
-							break;
-						}
+			decl = null;
+		}
+	
+		data.foundItems.clear();
+		
+		int numFunctions = ( functionList == null ) ? 0 : functionList.size();
+		
+		boolean ambiguous = false;
+		
+		if( cls != null ){
+			//the class is only hidden by other stuff if they are from the same scope
+			if( obj != null && cls._containingScope != obj._containingScope ){
+				ambiguous = true;	
+			}
+			if( functionList != null ){
+				Iterator fnIter = functionList.iterator();
+				Declaration fn = null;
+				for( int i = numFunctions; i > 0; i-- ){
+					fn = (Declaration) fnIter.next();
+					if( cls._containingScope != fn._containingScope ){
+						ambiguous = true;
+						break;
 					}
 				}
 			}
-			
-			if( obj != null && !ambiguous ){
-				if( numFunctions > 0 ){
-					ambiguous = true;
+		}
+		
+		if( obj != null && !ambiguous ){
+			if( numFunctions > 0 ){
+				ambiguous = true;
+			} else {
+				return obj;
+			}
+		} else if( numFunctions > 0 ) {
+			if( data.parameters == null ){
+				//we have no parameter information, if we only have one function, return
+				//that, otherwise we can't decide between them
+				if( numFunctions == 1){
+					return (Declaration) functionList.getFirst();
 				} else {
-					return obj;
+					data.foundItems.addAll( functionList );
+					return null;
 				}
-			} else if( numFunctions > 0 ) {
-				return ResolveFunction( data, functionList );
-			}
-			
-			if( ambiguous ){
-				throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
 			} else {
-				return cls;
+				return ResolveFunction( data, functionList );
 			}
 		}
+		
+		if( ambiguous ){
+			throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
+		} else {
+			return cls;
+		}
 	}
 
 	static private Declaration ResolveFunction( LookupData data, LinkedList functions ) throws ParserSymbolTableException{
@@ -1023,15 +1097,10 @@
 				if( source.equals( target ) ){
 					cost = 0;	//exact match, no cost
 				} else {
-					if( !canDoQualificationConversion( source, target ) ){
-						//matching qualification is at no cost, but not matching is a failure 
-						cost = -1;	
-					} else if( (temp = canPromote( source, target )) >= 0 ){
-						cost = temp;	
-					} else if( (temp = canConvert( source, target )) >= 0 ){
-						cost = temp;	//cost for conversion has to do with "distance" between source and target
-					} else {
-						cost = -1;		//failure
+					cost = checkStandardConversionSequence( source, target );
+					
+					if( cost == -1){
+						cost = checkUserDefinedConversionSequence( source, target );
 					}
 				}
 				
@@ -1269,6 +1338,32 @@
 		}
 	}
 
+	static private boolean okToAddUsingDeclaration( Declaration obj, Declaration context ){
+		boolean okToAdd = false;
+			
+		//7.3.3-4
+		if( context.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
+			//a member of a base class
+			if( obj.getContainingScope().getType() == context.getType() ){
+				okToAdd = ( hasBaseClass( context, obj.getContainingScope() ) > 0 );		
+			} 
+			//TBD : a member of an _anonymous_ union
+			else if ( obj.getContainingScope().getType() == TypeInfo.t_union ) {
+				Declaration union = obj.getContainingScope();
+				okToAdd = ( hasBaseClass( context, union.getContainingScope() ) > 0 ); 
+			}
+			//an enumerator for an enumeration
+			else if ( obj.getType() == TypeInfo.t_enumerator ){
+				Declaration enumeration = obj.getContainingScope();
+				okToAdd = ( hasBaseClass( context, enumeration.getContainingScope() ) > 0 );
+			}
+		} else {
+			okToAdd = true;
+		}	
+		
+		return okToAdd;
+	}
+	
 	/**
 	 * 
 	 * @param source
@@ -1391,6 +1486,50 @@
 		return -1;
 	}
 	
+	static private int checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
+		int cost = -1;
+		int temp = 0;
+		
+		if( !canDoQualificationConversion( source, target ) ){
+			//matching qualification is at no cost, but not matching is a failure 
+			cost = -1;	
+		} else if( (temp = canPromote( source, target )) >= 0 ){
+			cost = temp;	
+		} else if( (temp = canConvert( source, target )) >= 0 ){
+			cost = temp;	//cost for conversion has to do with "distance" between source and target
+		} else {
+			cost = -1;		//failure
+		}
+		
+		return cost;	
+	}
+	
+	static private int checkUserDefinedConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
+		int cost = -1;
+		Declaration targetDecl = null;
+		Declaration constructor = null;
+		
+		if( target.getType() == TypeInfo.t_type ){
+			targetDecl = target.getTypeDeclaration();
+			if( targetDecl.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
+				LookupData data = new LookupData( "", TypeInfo.t_function );
+				LinkedList params = new LinkedList();
+				params.add( source );
+				data.parameters = params;
+				LookupInContained( data, targetDecl );
+				constructor = ResolveAmbiguities( data );
+				if( constructor != null ){
+					cost = checkStandardConversionSequence( new TypeInfo( TypeInfo.t_type, constructor._containingScope ), target );
+					if( cost != -1 ){
+						cost++;	
+					}
+				}
+			}
+			
+		}
+		return cost;
+	}
+	
 	static private boolean canDoQualificationConversion( TypeInfo source, TypeInfo target ){
 		return (  source.getCVQualifier() == source.getCVQualifier() ||
 		 		  (source.getCVQualifier() - source.getCVQualifier()) > 1 );	
@@ -1411,7 +1550,7 @@
 		if( topInfo.getType() == TypeInfo.t_type ){
 			returnInfo = new TypeInfo();
 			
-			Declaration typeDecl = null;
+			Declaration typeDecl = topInfo.getTypeDeclaration();
 			
 			info = topInfo.getTypeDeclaration().getTypeInfo();
 			
@@ -1441,7 +1580,7 @@
 	private Stack _contextStack = new Stack();
 	private Declaration _compilationUnit;
 	
-	private class LookupData
+	static private class LookupData
 	{
 		
 		public String name;
@@ -1459,6 +1598,8 @@
 		public boolean qualified = false;
 		public boolean ignoreUsingDirectives = false;
 
+		public HashSet foundItems = null;
+		
 		public LookupData( String n, int t ){
 			name = n;
 			type = t;

Back to the top