1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Niefer Andrew

Core: 
bug43106 - added getConditionalOperand to ParserSymbolTable

Core.tests:
added testGetConditionalOperand_bug43106 to ParserSymbolTableTests
This commit is contained in:
John Camelon 2003-09-15 21:50:00 +00:00
parent 7b35a1a68b
commit 994113f274
4 changed files with 135 additions and 2 deletions

View file

@ -1,3 +1,6 @@
2003-09-15 Andrew Niefer
added testGetConditionalOperand_bug43106 to ParserSymbolTableTests
2003-09-15 John Camelon 2003-09-15 John Camelon
Added CompleteParseASTTest::testBug42979(). Added CompleteParseASTTest::testBug42979().
Updated CompleteParseASTTest::testAndrewsExample(). Updated CompleteParseASTTest::testAndrewsExample().

View file

@ -2624,5 +2624,77 @@ public class ParserSymbolTableTest extends TestCase {
assertEquals( look, null ); 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
}
}
} }

View file

@ -1,3 +1,6 @@
2003-09-15 Andrew Niefer
bug43106 - added getConditionalOperand to ParserSymbolTable
2003-09-15 John Camelon 2003-09-15 John Camelon
Partially fixed Bug 42979 : Cannot search for operator overloaders Partially fixed Bug 42979 : Cannot search for operator overloaders

View file

@ -1303,7 +1303,7 @@ public class ParserSymbolTable {
// to an rvalue of type "pointer to cv B", where B is a base class of D. // 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() ) ){ if( (srcDecl instanceof IDerivableContainerSymbol) && trgDecl.isType( srcDecl.getType() ) ){
temp = hasBaseClass( (IDerivableContainerSymbol) srcDecl, (IDerivableContainerSymbol) trgDecl ); 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.conversion = ( temp > -1 ) ? temp : 0;
cost.detail = 1; cost.detail = 1;
return; return;
@ -1319,7 +1319,7 @@ public class ParserSymbolTable {
TypeInfo.PtrOp srcPtr = trg.hasPtrOperators() ? (TypeInfo.PtrOp)trg.getPtrOperators().getFirst() : null; TypeInfo.PtrOp srcPtr = trg.hasPtrOperators() ? (TypeInfo.PtrOp)trg.getPtrOperators().getFirst() : null;
if( trgDecl.isType( srcDecl.getType() ) && srcPtr != null && srcPtr.getType() == TypeInfo.PtrOp.t_memberPointer ){ if( trgDecl.isType( srcDecl.getType() ) && srcPtr != null && srcPtr.getType() == TypeInfo.PtrOp.t_memberPointer ){
temp = hasBaseClass( (IDerivableContainerSymbol)ptr.getMemberOf(), (IDerivableContainerSymbol)srcPtr.getMemberOf() ); 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.detail = 1;
cost.conversion = ( temp > -1 ) ? temp : 0; cost.conversion = ( temp > -1 ) ? temp : 0;
return; return;
@ -1456,6 +1456,61 @@ public class ParserSymbolTable {
return cost; 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 * @param decl