[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Parser Symbol Table Patch - user defined conversions by operator
|
patch_04.08.03(cdt.core).txt
user defined conversions by operator
patch_04.08.04(cdt.ui.tests).txt
added ParserSymbolTableTest::testUserDefinedConversionByOperator()
-Andrew
Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.22
diff -u -r1.22 ChangeLog
--- parser/ChangeLog 7 Apr 2003 21:43:01 -0000 1.22
+++ parser/ChangeLog 8 Apr 2003 14:02:54 -0000
@@ -1,3 +1,6 @@
+2003-04-08 Andrew Niefer
+ Added User defined conversions via operator
+
2003-04-06 Andrew Niefer
Added ParserSymbolTable::Cost and used it to fix up the conversion sequence ranking
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.9
diff -u -r1.9 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java 7 Apr 2003 21:43:01 -0000 1.9
+++ parser/org/eclipse/cdt/internal/core/parser/ParserSymbolTable.java 8 Apr 2003 14:02:55 -0000
@@ -1037,7 +1037,7 @@
}
static private Declaration ResolveFunction( LookupData data, LinkedList functions ) throws ParserSymbolTableException{
-
+
ReduceToViable( data, functions );
int numSourceParams = ( data.parameters == null ) ? 0 : data.parameters.size();
@@ -1073,10 +1073,12 @@
TypeInfo source = null;
TypeInfo target = null;
- boolean hasWorse;
- boolean hasBetter;
+ boolean hasWorse = false;
+ boolean hasBetter = false;
boolean ambiguous = false;
-
+ boolean currHasAmbiguousParam = false;
+ boolean bestHasAmbiguousParam = false;
+
for( int i = numFns; i > 0; i-- ){
currFn = (Declaration) iterFns.next();
@@ -1128,6 +1130,8 @@
break;
}
+ currHasAmbiguousParam = ( currFnCost[ j ].userDefined == 1 );
+
if( bestFnCost != null ){
comparison = currFnCost[ j ].compare( bestFnCost[ j ] );
hasWorse |= ( comparison < 0 );
@@ -1143,13 +1147,14 @@
if( hasBetter ){
ambiguous = false;
bestFnCost = currFnCost;
+ bestHasAmbiguousParam = currHasAmbiguousParam;
currFnCost = null;
bestFn = currFn;
}
}
}
- if( ambiguous ){
+ if( ambiguous || bestHasAmbiguousParam ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
}
@@ -1387,6 +1392,23 @@
source = getFlatTypeInfo( source );
}
+ String sourcePtr = source.getPtrOperator();
+ String targetPtr = target.getPtrOperator();
+
+ if( sourcePtr != null && sourcePtr.length() > 0 ){
+ char sourcePtrArray [] = sourcePtr.toCharArray();
+ if( sourcePtrArray[ 0 ] == '&' ){
+ source.setPtrOperator( new String(sourcePtrArray, 1, sourcePtr.length() - 1 ) );
+ }
+ }
+
+ if( targetPtr != null && targetPtr.length() > 0 ){
+ char targetPtrArray [] = targetPtr.toCharArray();
+ if( targetPtrArray[ 0 ] == '&' ){
+ target.setPtrOperator ( new String( targetPtrArray, 1, targetPtr.length() - 1 ) );
+ }
+ }
+
Cost cost = new Cost( source, target );
return cost;
@@ -1528,7 +1550,7 @@
Cost cost = lvalue_to_rvalue( source, target );
if( cost.source.equals( cost.target ) ){
- cost.rank = 1;
+ cost.rank = 0;
return cost;
}
@@ -1551,9 +1573,15 @@
static private Cost checkUserDefinedConversionSequence( TypeInfo source, TypeInfo target ) throws ParserSymbolTableException {
Cost cost = null;
+ Cost constructorCost = null;
+ Cost conversionCost = null;
+
Declaration targetDecl = null;
+ Declaration sourceDecl = null;
Declaration constructor = null;
+ Declaration conversion = null;
+ //constructors
if( target.getType() == TypeInfo.t_type ){
targetDecl = target.getTypeDeclaration();
if( targetDecl.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
@@ -1563,12 +1591,54 @@
data.parameters = params;
LookupInContained( data, targetDecl );
constructor = ResolveAmbiguities( data );
- if( constructor != null ){
- cost = checkStandardConversionSequence( new TypeInfo( TypeInfo.t_type, constructor._containingScope ), target );
- }
}
+ }
+
+ //conversion operators
+ if( source.getType() == TypeInfo.t_type ){
+ source = getFlatTypeInfo( source );
+ sourceDecl = source.getTypeDeclaration();
+ if( sourceDecl != null ){
+ String name = target.toString();
+
+ if( !name.equals("") ){
+ LookupData data = new LookupData( "operator " + name, TypeInfo.t_function );
+ LinkedList params = new LinkedList();
+ data.parameters = params;
+
+ LookupInContained( data, sourceDecl );
+ conversion = ResolveAmbiguities( data );
+ }
+ }
+ }
+
+ if( constructor != null ){
+ constructorCost = checkStandardConversionSequence( new TypeInfo( TypeInfo.t_type, constructor._containingScope ), target );
+ }
+ if( conversion != null ){
+ conversionCost = checkStandardConversionSequence( new TypeInfo( target.getType(), target.getTypeDeclaration() ), target );
+ }
+
+ //if both are valid, then the conversion is ambiguous
+ if( constructorCost != null && constructorCost.rank != -1 &&
+ conversionCost != null && conversionCost.rank != -1 )
+ {
+ cost = constructorCost;
+ cost.userDefined = 1;
+ cost.rank = 3;
+ } else {
+ if( constructorCost != null && constructorCost.rank != -1 ){
+ cost = constructorCost;
+ cost.userDefined = constructor.hashCode();
+ cost.rank = 3;
+ } else if( conversionCost != null && conversionCost.rank != -1 ){
+ cost = conversionCost;
+ cost.userDefined = conversion.hashCode();
+ cost.rank = 3;
+ }
}
+
return cost;
}
@@ -1667,13 +1737,31 @@
public int promotion;
public int conversion;
public int qualification;
-
+ public int userDefined;
public int rank = -1;
public int detail;
public int compare( Cost cost ){
int result = 0;
+ if( rank != cost.rank ){
+ return cost.rank - rank;
+ }
+
+ if( userDefined != 0 || cost.userDefined != 0 ){
+ if( userDefined == 0 || cost.userDefined == 0 ){
+ return cost.userDefined - userDefined;
+ } else {
+ if( (userDefined == 1 || cost.userDefined == 1) ||
+ (userDefined != cost.userDefined ) )
+ {
+ return 0;
+ }
+ // else they are the same constructor/conversion operator and are ranked
+ //on the standard conversion sequence
+ }
+ }
+
if( promotion > 0 || cost.promotion > 0 ){
result = cost.promotion - promotion;
}
@@ -1691,8 +1779,6 @@
return result;
}
-
-
}
-
+
}
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.3
diff -u -r1.3 TypeInfo.java
--- parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java 7 Apr 2003 21:43:01 -0000 1.3
+++ parser/org/eclipse/cdt/internal/core/parser/util/TypeInfo.java 8 Apr 2003 14:02:55 -0000
@@ -90,6 +90,23 @@
public static final int t_void = 14;
public static final int t_enumerator = 15;
+ private static final String _image[] = { "",
+ "",
+ "namespace",
+ "class",
+ "struct",
+ "union",
+ "enum",
+ "",
+ "bool",
+ "char",
+ "wchar_t",
+ "int",
+ "float",
+ "double",
+ "void",
+ ""
+ };
//Partial ordering :
// none < const
// none < volatile
@@ -334,6 +351,14 @@
return result;
}
+ public String toString(){
+ if( isType( t_type ) ){
+ return _typeDeclaration.getName();
+ } else {
+ return _image[ getType() ];
+ }
+ }
+
private int _typeInfo = 0;
private Declaration _typeDeclaration;
private int _cvQualifier = 0;
Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui.tests/ChangeLog,v
retrieving revision 1.21
diff -u -r1.21 ChangeLog
--- ChangeLog 7 Apr 2003 21:42:56 -0000 1.21
+++ ChangeLog 8 Apr 2003 14:03:26 -0000
@@ -1,3 +1,6 @@
+2003-04-08 Andrew Niefer
+ Added ParserSymbolTableTest::testUserDefinedConversionByOperator()
+
2003-04-06 Andrew Niefer
Added ParserSymbolTableTest::testOverloadRanking()
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.10
diff -u -r1.10 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 7 Apr 2003 21:42:56 -0000 1.10
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 8 Apr 2003 14:03:27 -0000
@@ -1902,5 +1902,108 @@
assertEquals( look, f1 );
}
+
+ /**
+ *
+ * @throws Exception
+ *
+ * class B;
+ * class A { A( B& ); };
+ * class B { operator A(); };
+ *
+ * void f(A){}
+ *
+ * B b;
+ * f( b ); //ambiguous because b->A via constructor or conversion
+ *
+ * class C { C( B& ); };
+ *
+ * void f(C){}
+ *
+ * f( b ); //ambiguous because b->C via constructor and b->a via constructor/conversion
+ *
+ * void f(B){}
+ *
+ * f( b ); //calls f(B)
+ */
+
+ public void testUserDefinedConversionByOperator() throws Exception{
+ newTable();
+
+ Declaration B = new Declaration( "B" );
+ B.setType( TypeInfo.t_class );
+
+ table.addDeclaration( B );
+
+ Declaration A = new Declaration( "A" );
+ A.setType( TypeInfo.t_class );
+ table.addDeclaration( A );
+
+ table.push( A );
+ Declaration constructA = new Declaration( "" );
+ constructA.setType( TypeInfo.t_function );
+ constructA.addParameter( B, 0, "&", false );
+ table.addDeclaration( constructA );
+ table.pop();
+
+ table.push( B );
+ Declaration operator = new Declaration( "operator A" );
+ operator.setType( TypeInfo.t_function );
+ table.addDeclaration( operator );
+ table.pop();
+
+ Declaration f1 = new Declaration( "f" );
+ f1.setType( TypeInfo.t_function );
+ f1.addParameter( A, 0, null, false );
+ table.addDeclaration( f1 );
+
+ Declaration b = new Declaration( "b" );
+ b.setType( TypeInfo.t_type );
+ b.setTypeDeclaration( B );
+
+ LinkedList params = new LinkedList();
+ TypeInfo p1 = new TypeInfo( TypeInfo.t_type, b, 0, null, false );
+ params.add( p1 );
+
+ Declaration look = null;
+
+ try{
+ look = table.UnqualifiedFunctionLookup( "f", params );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
+ }
+
+ Declaration C = new Declaration("C");
+ C.setType( TypeInfo.t_class );
+ table.addDeclaration( C );
+
+ table.push( C );
+ Declaration constructC = new Declaration("");
+ constructC.setType( TypeInfo.t_function );
+ constructC.addParameter( B, 0, "&", false );
+ table.addDeclaration( constructC );
+ table.pop();
+
+ Declaration f2 = new Declaration( "f" );
+ f2.setType( TypeInfo.t_function );
+ f2.addParameter( C, 0, null, false );
+ table.addDeclaration( f2 );
+
+ try{
+ look = table.UnqualifiedFunctionLookup( "f", params );
+ assertTrue( false );
+ } catch( ParserSymbolTableException e ){
+ assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
+ }
+
+ Declaration f3 = new Declaration( "f" );
+ f3.setType( TypeInfo.t_function );
+ f3.addParameter( B, 0, null, false );
+ table.addDeclaration( f3 );
+
+ look = table.UnqualifiedFunctionLookup( "f", params );
+ assertEquals( look, f3 );
+ }
}