From 994113f27459ef997584ada1563f3d8772f674c3 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Mon, 15 Sep 2003 21:50:00 +0000 Subject: [PATCH] Patch for Niefer Andrew Core: bug43106 - added getConditionalOperand to ParserSymbolTable Core.tests: added testGetConditionalOperand_bug43106 to ParserSymbolTableTests --- core/org.eclipse.cdt.core.tests/ChangeLog | 3 + .../parser/tests/ParserSymbolTableTest.java | 72 +++++++++++++++++++ core/org.eclipse.cdt.core/parser/ChangeLog | 3 + .../core/parser/pst/ParserSymbolTable.java | 59 ++++++++++++++- 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index b5873af72f0..3cdbecc73ac 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -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(). diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java index 4978f437299..0d16537a48a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -2624,5 +2624,77 @@ public class ParserSymbolTableTest extends TestCase { 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 + } + } + } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index d659209c5f3..9c41f834b75 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index 2d520f9bb71..47189b5db12 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -1303,7 +1303,7 @@ public class ParserSymbolTable { // 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 @@ public class ParserSymbolTable { 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 @@ public class ParserSymbolTable { 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