[
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
+ }
+ }
+
}