Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] bug43106 - Symbol Table support for Conditional expression

Core: 
bug43106 - added getConditionalOperand to ParserSymbolTable

Core.tests:
added testGetConditionalOperand_bug43106 to ParserSymbolTableTests

-Andrew

Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.126
diff -u -r1.126 ChangeLog
--- parser/ChangeLog	15 Sep 2003 19:04:44 -0000	1.126
+++ parser/ChangeLog	15 Sep 2003 19:30:38 -0000
@@ -1,3 +1,6 @@
+2003-09-15 Andrew Niefer
+	bug43106 - added getConditionalOperand to ParserSymbolTable
+
 2003-09-15 John Camelon
 	Partially fixed Bug 42979 : Cannot search for operator overloaders 
 
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java,v
retrieving revision 1.19
diff -u -r1.19 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	12 Sep 2003 15:08:40 -0000	1.19
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	15 Sep 2003 19:30:39 -0000
@@ -1303,7 +1303,7 @@
 				// to an rvalue of type "pointer to cv B", where B is a base class of D.
 				if( (srcDecl instanceof IDerivableContainerSymbol) && trgDecl.isType( srcDecl.getType() ) ){
 					temp = hasBaseClass( (IDerivableContainerSymbol) srcDecl, (IDerivableContainerSymbol) trgDecl );
-					cost.rank = Cost.CONVERSION_RANK;
+					cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
 					cost.conversion = ( temp > -1 ) ? temp : 0;
 					cost.detail = 1;
 					return;
@@ -1319,7 +1319,7 @@
 				TypeInfo.PtrOp srcPtr =  trg.hasPtrOperators() ? (TypeInfo.PtrOp)trg.getPtrOperators().getFirst() : null;
 				if( trgDecl.isType( srcDecl.getType() ) && srcPtr != null && srcPtr.getType() == TypeInfo.PtrOp.t_memberPointer ){
 					temp = hasBaseClass( (IDerivableContainerSymbol)ptr.getMemberOf(), (IDerivableContainerSymbol)srcPtr.getMemberOf() );
-					cost.rank = Cost.CONVERSION_RANK;
+					cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
 					cost.detail = 1;
 					cost.conversion = ( temp > -1 ) ? temp : 0;
 					return; 
@@ -1456,6 +1456,61 @@
 		return cost;
 	}
 
+	/**
+	 *	Determine the type of a conditional operator based on the second and third operands 
+	 * @param secondOp
+	 * @param thirdOp
+	 * @return
+	 * Spec 5.16
+	 * Determine if the second operand can be converted to match the third operand, and vice versa.
+	 * - If both can be converted, or one can be converted but the conversion is ambiguous, the program
+	 * is illformed  (throw ParserSymbolTableException)
+	 * - If neither can be converted, further checking must be done (return null)
+	 * - If exactly one conversion is possible, that conversion is applied ( return the other TypeInfo )
+	 */
+	static public TypeInfo getConditionalOperand( TypeInfo secondOp, TypeInfo thirdOp ) throws ParserSymbolTableException{
+		
+		//can secondOp convert to thirdOp ?
+		Cost secondCost = checkStandardConversionSequence( secondOp, getFlatTypeInfo( thirdOp ) );
+
+		if( secondCost.rank == Cost.NO_MATCH_RANK ){
+			secondCost = checkUserDefinedConversionSequence( secondOp, getFlatTypeInfo( thirdOp ) );
+		}
+		
+		Cost thirdCost = checkStandardConversionSequence( thirdOp, getFlatTypeInfo( secondOp ) );
+		if( thirdCost.rank == Cost.NO_MATCH_RANK ){
+			thirdCost = checkUserDefinedConversionSequence( thirdOp, getFlatTypeInfo( secondOp ) );
+		}
+		
+		
+		boolean canConvertSecond = ( secondCost != null && secondCost.rank != Cost.NO_MATCH_RANK );
+		boolean canConvertThird  = ( thirdCost  != null && thirdCost.rank  != Cost.NO_MATCH_RANK );
+
+		if( !canConvertSecond && !canConvertThird ){
+			//neither can be converted
+			return null;
+		} else if ( canConvertSecond && canConvertThird ){
+			//both can be converted -> illformed
+			throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+		} else {
+			if( canConvertSecond ){
+				if( secondCost.userDefined == Cost.AMBIGUOUS_USERDEFINED_CONVERSION ){
+					//conversion is ambiguous -> ill-formed
+					throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+				} else {
+					return thirdOp;
+				}
+			} else {
+				if( thirdCost.userDefined == Cost.AMBIGUOUS_USERDEFINED_CONVERSION ){
+					//conversion is ambiguous -> ill-formed
+					throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+				} else {
+					return secondOp;
+				}
+			}
+		}
+	}
+	
 	/**
 	 * 
 	 * @param decl
Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core.tests/ChangeLog,v
retrieving revision 1.96
diff -u -r1.96 ChangeLog
--- ChangeLog	15 Sep 2003 19:04:48 -0000	1.96
+++ ChangeLog	15 Sep 2003 19:31:05 -0000
@@ -1,3 +1,6 @@
+2003-09-15 Andrew Niefer
+	added testGetConditionalOperand_bug43106 to ParserSymbolTableTests
+
 2003-09-15 John Camelon
 	Added CompleteParseASTTest::testBug42979().
 	Updated CompleteParseASTTest::testAndrewsExample(). 
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java,v
retrieving revision 1.17
diff -u -r1.17 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	12 Sep 2003 15:08:35 -0000	1.17
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java	15 Sep 2003 19:31:07 -0000
@@ -2624,5 +2624,77 @@
 		
 		assertEquals( look, null );
 	}
+	
+	/**
+	 * class A {
+	 *    A ( C ) {};
+	 * } a;
+	 * class B : public A {} b;
+	 * class C {
+	 *    C ( A ) {};
+	 * } c;
+	 * 
+	 * isTrue ? &a : &b;	//expect type = 2nd operand ( A )
+	 * isTrue ? &a : &c;	//expect null, neither converts
+	 * isTrue ? a : c;		//expect exception, both convert 
+	 * 
+	 * @throws Exception
+	 */
+	public void testGetConditionalOperand_bug43106() throws Exception{
+		newTable();
+		
+		IDerivableContainerSymbol clsA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
+		IDerivableContainerSymbol clsB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
+		
+		clsB.addParent( clsA );
+		
+		table.getCompilationUnit().addSymbol( clsA );
+		table.getCompilationUnit().addSymbol( clsB );
+		
+		ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
+		a.setTypeSymbol( clsA );
+		
+		ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
+		b.setTypeSymbol( clsB );
+		
+		table.getCompilationUnit().addSymbol( a );
+		table.getCompilationUnit().addSymbol( b );
+		
+		TypeInfo secondOp = new TypeInfo( TypeInfo.t_type, 0, a, new PtrOp( PtrOp.t_reference ), false );
+		TypeInfo thirdOp = new TypeInfo( TypeInfo.t_type, 0, b, new PtrOp( PtrOp.t_reference ), false );
+		
+		TypeInfo returned = ParserSymbolTable.getConditionalOperand( secondOp, thirdOp );
+		assertEquals( returned, secondOp );
+		
+		IDerivableContainerSymbol clsC = table.newDerivableContainerSymbol( "C", TypeInfo.t_class );
+		table.getCompilationUnit().addSymbol( clsC );
+		ISymbol c = table.newSymbol( "c", TypeInfo.t_type );
+		c.setTypeSymbol( clsC );
+		table.getCompilationUnit().addSymbol( c );
+		
+		TypeInfo anotherOp = new TypeInfo( TypeInfo.t_type, 0, c, new PtrOp( PtrOp.t_reference ), false );
+		
+		returned = ParserSymbolTable.getConditionalOperand( secondOp, anotherOp );
+		assertEquals( returned, null );
+		
+		IParameterizedSymbol constructorA = table.newParameterizedSymbol( "A", TypeInfo.t_constructor );
+		constructorA.addParameter( clsC, null, false );
+		clsA.addConstructor( constructorA );
+		
+		IParameterizedSymbol constructorC = table.newParameterizedSymbol( "C", TypeInfo.t_constructor );
+		constructorC.addParameter( clsA, null, false );
+		clsC.addConstructor( constructorC );
+		
+		secondOp.getPtrOperators().clear();
+		anotherOp.getPtrOperators().clear();
+		try{
+			
+			returned = ParserSymbolTable.getConditionalOperand( secondOp, anotherOp );
+			assertTrue( false );
+		} catch ( ParserSymbolTableException e ){
+			//good
+		}
+	}
+	
 }
 

Back to the top