Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Parser Symbol Table Patch - fix conversion sequence r anking

Rewrote the conversion sequence ranking to better handle all cases.
Added ParserSymbolTableTest::testOverloadRanking (whose initial failure
prompted the ranking rewrite).

files:
patch_04.06.03(cdt.core).txt
patch_04.06.03(cdt.ui.tests).txt

-Andrew

Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.21
diff -u -r1.21 ChangeLog
--- parser/ChangeLog	6 Apr 2003 03:06:16 -0000	1.21
+++ parser/ChangeLog	6 Apr 2003 18:41:18 -0000
@@ -1,3 +1,6 @@
+2003-04-06 Andrew Niefer
+	Added ParserSymbolTable::Cost and used it to fix up the conversion sequence ranking
+
 2003-04-04 John Camelon
 	Fixed defect 36073.
 	Fixed error handling for unterminated strings in Scanner.
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.8
diff -u -r1.8 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java	2 Apr 2003 13:18:50 -0000	1.8
+++ parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java	6 Apr 2003 18:41:18 -0000
@@ -810,7 +810,7 @@
 					if( decl == temp && ( type.checkBit( TypeInfo.isStatic ) || type.isType( TypeInfo.t_enumerator ) ) ){
 						temp = null;
 					} else {
-						throw( new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ) );
+						throw( new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ) );
 					}
 	
 				}
@@ -969,14 +969,14 @@
 					if( cls == null ) {
 						cls = decl;
 					} else {
-						throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); 
+						throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); 
 					}
 				} 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_Ambiguous ); 
 					}
 				}
 			}
@@ -1030,7 +1030,7 @@
 		}
 		
 		if( ambiguous ){
-			throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
+			throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
 		} else {
 			return cls;
 		}
@@ -1051,14 +1051,14 @@
 			} else if ( numFns == 1 ){
 				return (Declaration)functions.getFirst();
 			} else{
-				throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
+				throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
 			}
 		}
 		
 		Declaration bestFn = null;				//the best function
 		Declaration currFn = null;				//the function currently under consideration
-		int [] bestFnCost = null;				//the cost of the best function
-		int [] currFnCost = null;				//the cost for the current function
+		Cost [] bestFnCost = null;				//the cost of the best function
+		Cost [] currFnCost = null;				//the cost for the current function
 				
 		Iterator iterFns = functions.iterator();
 		Iterator sourceParams = null;
@@ -1066,11 +1066,17 @@
 		
 		int numTargetParams = 0;
 		int numParams = 0;
-		int cost, temp, comparison;
+		int comparison;
+		Cost cost = null;
+		Cost temp = null;
 		
 		TypeInfo source = null;
 		TypeInfo target = null;
 		 
+		boolean hasWorse;
+		boolean hasBetter;
+		boolean ambiguous = false;
+		
 		for( int i = numFns; i > 0; i-- ){
 			currFn = (Declaration) iterFns.next();
 			
@@ -1086,7 +1092,7 @@
 			numParams = ( numTargetParams < numSourceParams ) ? numTargetParams : numSourceParams;
 			
 			if( currFnCost == null ){
-				currFnCost = new int [ numParams ];	
+				currFnCost = new Cost [ numParams ];	
 			}
 			
 			comparison = 0;
@@ -1095,47 +1101,58 @@
 				source = ( TypeInfo )sourceParams.next();
 				target = ( TypeInfo )targetParams.next();
 				if( source.equals( target ) ){
-					cost = 0;	//exact match, no cost
+					cost = new Cost( source, target );
+					cost.rank = 0;	//exact match, no cost
 				} else {
 					cost = checkStandardConversionSequence( source, target );
 					
-					if( cost == -1){
-						cost = checkUserDefinedConversionSequence( source, target );
+					if( cost.rank == -1){
+						temp = checkUserDefinedConversionSequence( source, target );
+						if( temp != null ){
+							cost = temp;
+						}
 					}
 				}
 				
 				currFnCost[ j ] = cost;
+			}
+			
+			
+			hasWorse = false;
+			hasBetter = false;
+			
+			for( int j = 0; j < numParams; j++ ){ 
+				if( currFnCost[ j ].rank < 0 ){
+					hasWorse = true;
+					hasBetter = false;
+					break;
+				}
 				
-				//compare successes against the best function
-				//comparison = (-1 = worse, 0 = same, 1 = better ) 
-				if( cost >= 0 ){
-					if( bestFnCost != null ){
-						if( cost < bestFnCost[ j ] ){
-							comparison = 1;		//better
-						} else if ( cost > bestFnCost[ j ] ){
-							comparison = -1;	//worse
-							break;				//don't bother continuing if worse
-						}
-						
-					} else {
-						comparison = 1;
-					}
+				if( bestFnCost != null ){
+					comparison = currFnCost[ j ].compare( bestFnCost[ j ] );
+					hasWorse |= ( comparison < 0 );
+					hasBetter |= ( comparison > 0 );
 				} else {
-					comparison = -1;
+					hasBetter = true;
 				}
 			}
+				
+			ambiguous |= ( hasWorse && hasBetter ) || ( !hasWorse && !hasBetter );
 			
-			if( comparison > 0){
-				//the current function is better than the previous best
-				bestFnCost = currFnCost;
-				currFnCost = null;
-				bestFn = currFn;
-			} else if( comparison == 0 ){
-				//this is just as good as the best one, which means the best one isn't the best
-				bestFn = null;
+			if( !hasWorse ){
+				if( hasBetter ){
+					ambiguous = false;
+					bestFnCost = currFnCost;
+					currFnCost = null;
+					bestFn = currFn;
+				}				
 			}
 		}
-				
+
+		if( ambiguous ){
+			throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+		}
+						
 		return bestFn;
 	}
 	
@@ -1363,7 +1380,29 @@
 		
 		return okToAdd;
 	}
+
+	static private Cost lvalue_to_rvalue( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
+		//lvalues will have type t_type
+		if( source.isType( TypeInfo.t_type ) ){
+			source = getFlatTypeInfo( source );
+		}
+	
+		Cost cost = new Cost( source, target );
+	
+		return cost;
+	}
 	
+	static private void qualificationConversion( Cost cost ){
+		if(  cost.source.getCVQualifier() == cost.target.getCVQualifier() || 
+			( cost.target.getCVQualifier() - cost.source.getCVQualifier()) > 1 )
+		{
+			cost.qualification = cost.target.getCVQualifier() + 1;
+			cost.rank = 0;
+		} else {
+			cost.qualification = 0;
+		}
+	}
+		
 	/**
 	 * 
 	 * @param source
@@ -1378,27 +1417,31 @@
 	 * 4.5-4 bool can be promoted to int 
 	 * 4.6 float can be promoted to double
 	 */
-	static private int canPromote( TypeInfo source, TypeInfo target ){
-
-		//if they are the same, no promotion is necessary
-		if( ( source.isType( TypeInfo.t_bool, TypeInfo.t_double ) || 
-		      source.isType( TypeInfo.t_enumeration ) ) 		   && 
-			  source.getType() == target.getType() )
+	static private void promotion( Cost cost ){
+		TypeInfo src = cost.source;
+		TypeInfo trg = cost.target;
+		 
+		int mask = TypeInfo.isShort | TypeInfo.isLong | TypeInfo.isUnsigned;
+		
+		if( (src.isType( TypeInfo.t_bool, TypeInfo.t_float ) || src.isType( TypeInfo.t_enumeration )) &&
+			(trg.isType( TypeInfo.t_int ) || trg.isType( TypeInfo.t_double )) )
 		{
-			return 0;
-		}
-	   
-		if( source.isType( TypeInfo.t_enumeration ) || source.isType( TypeInfo.t_bool, TypeInfo.t_int ) ){
-			if( target.isType( TypeInfo.t_int ) && target.canHold( source ) ){
-				return 1;
-			}
-		} else if( source.isType( TypeInfo.t_float ) ){
-			if( target.isType( TypeInfo.t_double ) ){
-				return 1; 
+			if( src.getType() == trg.getType() && (( src.getTypeInfo() & mask) == (trg.getTypeInfo() & mask)) ){
+				//same, no promotion needed
+				return;	
+			}
+			
+			if( src.isType( TypeInfo.t_float ) ){ 
+				cost.promotion = trg.isType( TypeInfo.t_double ) ? 1 : 0;
+			} else {
+				cost.promotion = ( trg.isType( TypeInfo.t_int ) && trg.canHold( src ) ) ? 1 : 0;
 			}
+			
+		} else {
+			cost.promotion = 0;
 		}
 		
-		return -1;
+		cost.rank = (cost.promotion > 0 ) ? 1 : -1;
 	}
 	
 	/**
@@ -1408,104 +1451,106 @@
 	 * @return int
 	 * 
 	 */
-	static private int canConvert(TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
-		int temp = 0;
+	static private void conversion( Cost cost ){
+		TypeInfo src = cost.source;
+		TypeInfo trg = cost.target;
 		
-		source = getFlatTypeInfo( source );
+		int temp;
 		
-		String sourcePtr = source.getPtrOperator();
-		String targetPtr = target.getPtrOperator();
+		String tempStr = src.getPtrOperator();
+		String srcPtr = ( tempStr == null ) ? new String("") : tempStr;
 		
-		if( sourcePtr != null && sourcePtr.equals("") ){
-			sourcePtr = null;
-		}
-		if( targetPtr != null && targetPtr.equals("") ){
-			targetPtr = null;
-		}
+		tempStr = trg.getPtrOperator();
+		String trgPtr = ( tempStr == null ) ? new String("") : tempStr;
 		
-		boolean samePtrOp = ( ( sourcePtr == targetPtr ) ||
-							  ( sourcePtr != null && targetPtr != null && sourcePtr.equals( targetPtr ) ) );
-		//are they the same?
-		if( source.getType() == target.getType() &&
-			source.getTypeDeclaration() == target.getTypeDeclaration() &&
-			samePtrOp  )
-		{
-			return 0;
-		}
+		cost.conversion = 0;
+		cost.detail = 0;
 		
-		//no go if they have different pointer qualification
-		if( !samePtrOp )
-		{					
-			return -1;
-		}
-		
-		//TBD, do a better check on the kind of ptrOperator
-		if( sourcePtr == null || !sourcePtr.equals("*") ){
-			//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.  
-			//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
-			if( source.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
-				source.isType( TypeInfo.t_float, TypeInfo.t_double ) ||
-				source.isType( TypeInfo.t_enumeration ) )
-			{
-				if( target.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
-					target.isType( TypeInfo.t_float, TypeInfo.t_double ) )
-				{
-					return 2;	
-				}
-			}
-		} else /*pointers*/ {
-			Declaration sourceDecl = source.getTypeDeclaration();
-			Declaration targetDecl = target.getTypeDeclaration();
+		if( !srcPtr.equals( trgPtr ) ){
+			return;
+		} 
+		if( srcPtr.equals("*") ){
+			Declaration srcDecl = src.isType( TypeInfo.t_type ) ? src.getTypeDeclaration() : null;
+			Declaration trgDecl = trg.isType( TypeInfo.t_type ) ? trg.getTypeDeclaration() : null;
 
+			if( srcDecl == null || (trgDecl == null && !trg.isType( TypeInfo.t_void )) ){
+				return;	
+			}
+			
 			//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
 			//converted to an rvalue of type "pointer to cv void"
-			if( source.isType( TypeInfo.t_type ) && target.isType( TypeInfo.t_void ) ){
-				//use cost of MAX_VALUE since conversion to any base class, no matter how
-				//far away, would be better than conversion to void
-				return Integer.MAX_VALUE;	
-			}			
+			if( trg.isType( TypeInfo.t_void ) ){
+				cost.rank = 2;
+				cost.conversion = 1;
+				cost.detail = 2;
+				return;	
+			}
+			
+			cost.detail = 1;
+			
 			//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
 			// to an rvalue of type "pointer to cv B", where B is a base class of D.
-			else if( source.isType( TypeInfo.t_type ) && sourceDecl.isType( TypeInfo.t_class ) &&
-					  target.isType( TypeInfo.t_type ) && targetDecl.isType( TypeInfo.t_class ) )
-			{
-				temp = hasBaseClass( sourceDecl, targetDecl );
-				return ( temp > -1 ) ? 1 + temp : -1;
+			if( srcDecl.isType( TypeInfo.t_class ) && trgDecl.isType( TypeInfo.t_class ) ){
+				temp = hasBaseClass( srcDecl, trgDecl );
+				cost.rank = 2;
+				cost.conversion = ( temp > -1 ) ? temp : 0;
+				cost.detail = 1;
+				return;
 			}
+			
 			//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type, 
 			//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
 			//derived class of B
-			else if( (	source.isType( TypeInfo.t_type ) && sourceDecl._containingScope.isType( TypeInfo.t_class ) ) || 
-			 		  (	target.isType( TypeInfo.t_type ) && targetDecl._containingScope.isType( TypeInfo.t_class ) ) )
+			if( srcDecl._containingScope.isType( TypeInfo.t_class ) && trgDecl._containingScope.isType( TypeInfo.t_class ) ){
+				temp = hasBaseClass( trgDecl._containingScope, srcDecl._containingScope );
+				cost.rank = 2;
+				cost.conversion = ( temp > -1 ) ? temp : 0;
+				return;
+			}
+		} else {
+			//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.  
+			//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
+			if( src.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
+				src.isType( TypeInfo.t_float, TypeInfo.t_double ) ||
+				src.isType( TypeInfo.t_enumeration ) )
 			{
-				temp = hasBaseClass( targetDecl._containingScope, sourceDecl._containingScope );
-				return ( temp > -1 ) ? 1 + temp : -1; 	
+				if( trg.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
+					trg.isType( TypeInfo.t_float, TypeInfo.t_double ) )
+				{
+					cost.rank = 2;
+					cost.conversion = 1;	
+				}
 			}
 		}
-		
-		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
+	static private Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
+		Cost cost = lvalue_to_rvalue( source, target );
+		
+		if( cost.source.equals( cost.target ) ){
+			cost.rank = 1;
+			return cost;
 		}
+	
+		qualificationConversion( cost );
+		
+		//if we can't convert the qualifications, then we can't do anything
+		if( cost.qualification == 0 ){
+			return cost;
+		}
+		
+		promotion( cost );
+		if( cost.promotion > 0 || cost.rank > -1 ){
+			return cost;
+		}
+		
+		conversion( cost );
 		
 		return cost;	
 	}
 	
-	static private int checkUserDefinedConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
-		int cost = -1;
+	static private Cost checkUserDefinedConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
+		Cost cost = null;
 		Declaration targetDecl = null;
 		Declaration constructor = null;
 		
@@ -1520,21 +1565,13 @@
 				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 );	
-	}
-	
+
 	/**
 	 * 
 	 * @param decl
@@ -1563,8 +1600,13 @@
 				info = info.getTypeDeclaration().getTypeInfo();
 			}
 			
-			returnInfo.setType( TypeInfo.t_type );
-			returnInfo.setTypeDeclaration( typeDecl );
+			if( info.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
+				returnInfo.setType( TypeInfo.t_type );
+				returnInfo.setTypeDeclaration( typeDecl );
+			} else {
+				returnInfo.setTypeInfo( info.getTypeInfo() );
+				returnInfo.setTypeDeclaration( null );
+			}
 			
 			String ptrOp = returnInfo.getPtrOperator();
 			returnInfo.setPtrOperator( topInfo.getInvertedPtrOperator() );
@@ -1572,11 +1614,16 @@
 			if( ptrOp != null ){
 				returnInfo.addPtrOperator( ptrOp );
 			}
+			
+			returnInfo.setCVQualifier( info.getCVQualifier() );
+			returnInfo.addCVQualifier( topInfo.getCVQualifier() );
 		}
 		
 		return returnInfo;	
 	}
+
 	
+		
 	private Stack _contextStack = new Stack();
 	private Declaration _compilationUnit;
 	
@@ -1605,4 +1652,47 @@
 			type = t;
 		}
 	}
+	
+	static private class Cost
+	{
+		public Cost( TypeInfo s, TypeInfo t ){
+			source = s;
+			target = t;
+		}
+		
+		public TypeInfo source;
+		public TypeInfo target;
+		
+		public int lvalue;
+		public int promotion;
+		public int conversion;
+		public int qualification;
+		
+		public int rank = -1;
+		public int detail;
+		
+		public int compare( Cost cost ){
+			int result = 0;
+			
+			if( promotion > 0 || cost.promotion > 0 ){
+				result = cost.promotion - promotion;
+			}
+			if( conversion > 0 || cost.conversion > 0 ){
+				if( detail == cost.detail ){
+					result = cost.conversion - conversion;
+				} else {
+					result = cost.detail - detail;
+				}
+			}
+			
+			if( result == 0 ){
+				result = cost.qualification - qualification;
+			}
+			 
+			return result;
+		}
+		
+		
+	}
+	
 }
Index: parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTableException.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTableException.java,v
retrieving revision 1.4
diff -u -r1.4 ParserSymbolTableException.java
--- parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTableException.java	23 Mar 2003 13:59:57 -0000	1.4
+++ parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTableException.java	6 Apr 2003 18:41:18 -0000
@@ -37,7 +37,7 @@
 	}
 
 	public static final int r_Unspecified   			= -1;
-	public static final int r_AmbiguousName 			=  0;
+	public static final int r_Ambiguous 			=  0;
 	public static final int r_BadTypeInfo   			=  1;
 	public static final int r_CircularInheritance	=  2;
 	public static final int r_InvalidOverload		=  3;
Index: parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java,v
retrieving revision 1.2
diff -u -r1.2 TypeInfo.java
--- parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java	31 Mar 2003 20:43:07 -0000	1.2
+++ parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java	6 Apr 2003 18:41:18 -0000
@@ -96,9 +96,9 @@
 	// none		< const volatile
 	// const	< const volatile
 	// volatile < const volatile
-	public static final int cvConst 			= 1;
-	public static final int cvVolatile 		= 2;
-	public static final int cvConstVolatile 	= 4;
+	public static final int cvConst 			= 2;
+	public static final int cvVolatile 		= 3;
+	public static final int cvConstVolatile 	= 5;
 	
 		// Convenience methods
 	public void setBit(boolean b, int mask){
@@ -130,6 +130,14 @@
 		return isType( type, 0 ); 
 	}
 	
+	public int getTypeInfo(){
+		return _typeInfo;
+	}
+	
+	public void setTypeInfo( int typeInfo ){
+		_typeInfo = typeInfo;
+	}
+	
 	/**
 	 * 
 	 * @param type
@@ -306,6 +314,24 @@
 	 */
 	public boolean canHold( TypeInfo type ){
 		return getType() >= type.getType();	
+	}
+	
+	public boolean equals( Object t ){
+		if( t == null || !(t instanceof TypeInfo) ){
+			return false;
+		}
+		
+		TypeInfo type = (TypeInfo)t;
+		
+		boolean result = ( _typeInfo == type._typeInfo );
+		result &= ( _typeDeclaration == type._typeDeclaration );
+		result &= ( _cvQualifier == type._cvQualifier );
+		
+		String op1 = ( _ptrOperator != null && _ptrOperator.equals("") ) ? null : _ptrOperator;
+		String op2 = ( type._ptrOperator != null && type._ptrOperator.equals("") ) ? null : type._ptrOperator;
+		result &= (( op1 != null && op2 != null && op1.equals( op2 ) ) || op1 == op2 );
+		
+		return result;
 	}
 	
 	private int 		 _typeInfo = 0;
Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/ChangeLog,v
retrieving revision 1.20
diff -u -r1.20 ChangeLog
--- ChangeLog	6 Apr 2003 00:33:54 -0000	1.20
+++ ChangeLog	6 Apr 2003 18:41:49 -0000
@@ -1,3 +1,6 @@
+2003-04-06 Andrew Niefer
+	Added ParserSymbolTableTest::testOverloadRanking()
+
 2003-04-04 Alain Magloire
 	* src/org/eclipse/cdt/testplugin/util/VerifyDialog.java:
 	Remove some warnings.
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.9
diff -u -r1.9 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	2 Apr 2003 13:18:54 -0000	1.9
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	6 Apr 2003 18:41:50 -0000
@@ -349,7 +349,7 @@
 			assertTrue( false );
 		}
 		catch( ParserSymbolTableException e){
-			assertEquals( e.reason, ParserSymbolTableException.r_AmbiguousName );
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
 		}
 	}
 	
@@ -426,7 +426,7 @@
 			assertTrue( false );	
 		}
 		catch ( ParserSymbolTableException e){
-			assertEquals( e.reason, ParserSymbolTableException.r_AmbiguousName );
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
 		}
 	}
 	
@@ -645,7 +645,7 @@
 		catch ( ParserSymbolTableException e )
 		{
 			//ambiguous B::C::i and A::i
-			assertEquals( e.reason, ParserSymbolTableException.r_AmbiguousName );
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
 		}
 		table.pop(); //end f2
 		table.pop(); //end nsD
@@ -729,7 +729,7 @@
 		catch ( ParserSymbolTableException e )
 		{
 			//ambiguous, both M::i and N::i are visible.
-			assertEquals( e.reason, ParserSymbolTableException.r_AmbiguousName );
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
 		}
 		
 		look = table.LookupNestedNameSpecifier("N");
@@ -1023,7 +1023,7 @@
 			look = table.QualifiedLookup( "y" );
 			assertTrue(false);
 		} catch ( ParserSymbolTableException e ) {
-			assertEquals( e.reason, ParserSymbolTableException.r_AmbiguousName );
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
 		}
 	}
 	
@@ -1812,6 +1812,95 @@
 		
 		Declaration look = table.UnqualifiedFunctionLookup( "f", paramList );
 		assertEquals( look, f );	
+	}
+	
+	/**
+	 * 
+	 * @throws Exception
+	 *
+	 * void f( const int *, short );
+	 * void f( int *, int );
+	 * 
+	 * int i;
+	 * short s;
+	 *
+	 * void main() {
+	 * 	  f( &i, s );		//ambiguous because &i->int* is better than &i->const int *
+	 * 	  					//but s-> short is better than s->int
+	 * 	  f( &i, 1L );		//calls f(int *, int) because &i->int* is better than &i->const int *
+	 * 	  					//and 1L->short and 1L->int are indistinguishable
+	 * 	  f( &i, 'c' );		//calls f( int*, int) because &i->int * is better than &i->const int *
+	 * 	  					//and c->int is better than c->short
+	 * 	  f( (const)&i, 1L ); //calls f(const int *, short ) because const &i->int* is better than &i->int *
+	 * 	  					   //and 1L->short and 1L->int are indistinguishable
+	 * }
+	 */
+	public void testOverloadRanking() throws Exception{
+		newTable();
+		
+		Declaration f1 = new Declaration( "f" );
+		f1.setType( TypeInfo.t_function );
+		f1.addParameter( TypeInfo.t_int, TypeInfo.cvConst, "*", false );
+		f1.addParameter( TypeInfo.t_int | TypeInfo.isShort, 0, null, false );
+		
+		table.addDeclaration( f1 );
+		
+		Declaration f2 = new Declaration( "f" );
+		f2.setType( TypeInfo.t_function );
+		f2.addParameter( TypeInfo.t_int, 0, "*", false );
+		f2.addParameter( TypeInfo.t_int, 0, null, false );
+		table.addDeclaration( f2 );
+		
+		Declaration i = new Declaration( "i" );
+		i.setType( TypeInfo.t_int );
+		table.addDeclaration( i );
+		
+		Declaration s = new Declaration( "s" );
+		s.setType( TypeInfo.t_int );
+		s.getTypeInfo().setBit( true, TypeInfo.isShort );
+		table.addDeclaration( s );
+		
+		Declaration main = new Declaration( "main" );
+		main.setType( TypeInfo.t_function );
+		table.addDeclaration( main );
+		table.push( main );
+		
+		LinkedList params = new LinkedList();
+		TypeInfo p1 = new TypeInfo( TypeInfo.t_type, i, 0, "&", false );
+		TypeInfo p2 = new TypeInfo( TypeInfo.t_type, s, 0, null, false );
+		params.add( p1 );
+		params.add( p2 );
+		
+		Declaration look = null;
+		
+		try{
+			look = table.UnqualifiedFunctionLookup( "f", params );
+			assertTrue( false );
+		} catch ( ParserSymbolTableException e ){
+			assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
+		}
+		
+		params.clear();
+		TypeInfo p3 = new TypeInfo( TypeInfo.t_int | TypeInfo.isLong, null, 0, null, false );
+		params.add( p1 );
+		params.add( p3 );
+		look = table.UnqualifiedFunctionLookup( "f", params );
+		assertEquals( look, f2 );
+		
+		params.clear();
+		TypeInfo p4 = new TypeInfo( TypeInfo.t_char, null, 0, null, false );
+		params.add( p1 );
+		params.add( p4 );
+		look = table.UnqualifiedFunctionLookup( "f", params );
+		assertEquals( look, f2 );
+		
+		params.clear();
+		p1.setCVQualifier( TypeInfo.cvConst );
+		params.add( p1 );
+		params.add( p3 );
+		look = table.UnqualifiedFunctionLookup( "f", params );
+		assertEquals( look, f1 );
+		
 	}
 }
 

Back to the top