[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Parser Symbol Table
|
(I meant to send this yesterday)
- Fix some NPEs in the parser Symbol table.
- add some comments and constants to help clarify ranking of conversion
sequences
-Andrew
Index: parser/ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/parser/ChangeLog,v
retrieving revision 1.118
diff -u -r1.118 ChangeLog
--- parser/ChangeLog 9 Sep 2003 18:02:40 -0000 1.118
+++ parser/ChangeLog 9 Sep 2003 19:22:05 -0000
@@ -1,3 +1,7 @@
+2003-09-09 Andrew Niefer
+ Fixed some NPEs in ParserSymbolTable.getFlatTypeInfo
+ Added some comments and created some constants to help clarify ranking of conversion sequences
+
2003-09-09 John Camelon
Updated ScannerException to be more precise and include more information.
Updated Parser to be more careful of how it handles particular Scanner errors in COMPLETE_PARSE mode.
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.17
diff -u -r1.17 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 8 Sep 2003 18:10:49 -0000 1.17
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 9 Sep 2003 19:22:06 -0000
@@ -738,13 +738,13 @@
target = ((ISymbol)targetParams.next()).getTypeInfo();
if( source.equals( target ) ){
cost = new Cost( source, target );
- cost.rank = 0; //exact match, no cost
+ cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
} else {
cost = checkStandardConversionSequence( source, target );
//12.3-4 At most one user-defined conversion is implicitly applied to
//a single value. (also prevents infinite loop)
- if( cost.rank == -1 && !data.forUserDefinedConversion ){
+ if( cost.rank == Cost.NO_MATCH_RANK && !data.forUserDefinedConversion ){
temp = checkUserDefinedConversionSequence( source, target );
if( temp != null ){
cost = temp;
@@ -758,7 +758,9 @@
hasWorse = false;
hasBetter = false;
-
+ //In order for this function to be better than the previous best, it must
+ //have at least one parameter match that is better that the corresponding
+ //match for the other function, and none that are worse.
for( int j = 0; j < numParams; j++ ){
if( currFnCost[ j ].rank < 0 ){
hasWorse = true;
@@ -766,6 +768,8 @@
break;
}
+ //an ambiguity in the user defined conversion sequence is only a problem
+ //if this function turns out to be the best.
currHasAmbiguousParam = ( currFnCost[ j ].userDefined == 1 );
if( bestFnCost != null ){
@@ -776,11 +780,15 @@
hasBetter = true;
}
}
-
+
+ //If function has a parameter match that is better than the current best,
+ //and another that is worse (or everything was just as good, neither better nor worse).
+ //then this is an ambiguity (unless we find something better than both later)
ambiguous |= ( hasWorse && hasBetter ) || ( !hasWorse && !hasBetter );
if( !hasWorse ){
if( hasBetter ){
+ //the new best function.
ambiguous = false;
bestFnCost = currFnCost;
bestHasAmbiguousParam = currHasAmbiguousParam;
@@ -1091,6 +1099,13 @@
}
Cost cost = new Cost( source, target );
+
+ //if either source or target is null here, then there was a problem
+ //with the parameters and we can't match them.
+ if( cost.source == null || cost.target == null ){
+ return cost;
+ }
+
TypeInfo.PtrOp op = null;
if( cost.source.hasPtrOperators() ){
@@ -1132,6 +1147,12 @@
return cost;
}
+ /**
+ * qualificationConversion
+ * @param cost
+ *
+ * see spec section 4.4 regarding qualification conversions
+ */
static private void qualificationConversion( Cost cost ){
int size = cost.source.hasPtrOperators() ? cost.source.getPtrOperators().size() : 0;
int size2 = cost.target.hasPtrOperators() ? cost.target.getPtrOperators().size() : 0;
@@ -1149,6 +1170,7 @@
op1 = (TypeInfo.PtrOp) iter1.next();
op2 = (TypeInfo.PtrOp) iter2.next();
+ //can only convert if op2 is more qualified
if( ( op1.isConst() && !op2.isConst() ) ||
( op1.isVolatile() && !op2.isVolatile() ) )
{
@@ -1166,7 +1188,7 @@
op1 = (TypeInfo.PtrOp) iter1.next();
op2 = (TypeInfo.PtrOp) iter2.next();
- //pointer types are similar
+ //pointer types must be similar
if( op1.getType() != op2.getType() ){
canConvert = false;
break;
@@ -1191,7 +1213,7 @@
if( canConvert == true ){
cost.qualification = 1;
- cost.rank = 0;
+ cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK;
} else {
cost.qualification = 0;
}
@@ -1235,7 +1257,7 @@
cost.promotion = 0;
}
- cost.rank = (cost.promotion > 0 ) ? 1 : -1;
+ cost.rank = (cost.promotion > 0 ) ? Cost.PROMOTION_RANK : Cost.NO_MATCH_RANK;
}
/**
@@ -1269,7 +1291,7 @@
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
//converted to an rvalue of type "pointer to cv void"
if( trg.isType( TypeInfo.t_void ) ){
- cost.rank = 2;
+ cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1;
cost.detail = 2;
return;
@@ -1281,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 = 2;
+ cost.rank = Cost.CONVERSION_RANK;
cost.conversion = ( temp > -1 ) ? temp : 0;
cost.detail = 1;
return;
@@ -1297,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 = 2;
+ cost.rank = Cost.CONVERSION_RANK;
cost.detail = 1;
cost.conversion = ( temp > -1 ) ? temp : 0;
return;
@@ -1313,7 +1335,7 @@
if( trg.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
trg.isType( TypeInfo.t_float, TypeInfo.t_double ) )
{
- cost.rank = 2;
+ cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1;
}
}
@@ -1323,8 +1345,12 @@
static private Cost checkStandardConversionSequence( TypeInfo source, TypeInfo target ){
Cost cost = lvalue_to_rvalue( source, target );
+ if( cost.source == null || cost.target == null ){
+ return cost;
+ }
+
if( cost.source.equals( cost.target ) ){
- cost.rank = 0;
+ cost.rank = Cost.IDENTITY_RANK;
return cost;
}
@@ -1384,7 +1410,7 @@
//conversion operators
if( source.getType() == TypeInfo.t_type ){
source = getFlatTypeInfo( source );
- sourceDecl = source.getTypeSymbol();
+ sourceDecl = ( source != null ) ? source.getTypeSymbol() : null;
if( sourceDecl != null && (sourceDecl instanceof IContainerSymbol) ){
String name = target.toString();
@@ -1409,21 +1435,21 @@
}
//if both are valid, then the conversion is ambiguous
- if( constructorCost != null && constructorCost.rank != -1 &&
- conversionCost != null && conversionCost.rank != -1 )
+ if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK &&
+ conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK )
{
cost = constructorCost;
- cost.userDefined = 1;
- cost.rank = 3;
+ cost.userDefined = Cost.AMBIGUOUS_USERDEFINED_CONVERSION;
+ cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
} else {
- if( constructorCost != null && constructorCost.rank != -1 ){
+ if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK ){
cost = constructorCost;
cost.userDefined = constructor.hashCode();
- cost.rank = 3;
- } else if( conversionCost != null && conversionCost.rank != -1 ){
+ cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
+ } else if( conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK ){
cost = conversionCost;
cost.userDefined = conversion.hashCode();
- cost.rank = 3;
+ cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
}
}
@@ -1442,12 +1468,12 @@
TypeInfo returnInfo = topInfo;
TypeInfo info = null;
- if( topInfo.getType() == TypeInfo.t_type ){
+ if( topInfo.getType() == TypeInfo.t_type && topInfo.getTypeSymbol() != null ){
returnInfo = (TypeInfo)new TypeInfo();
ISymbol typeSymbol = topInfo.getTypeSymbol();
- info = topInfo.getTypeSymbol().getTypeInfo();
+ info = typeSymbol.getTypeInfo();
while( info.getType() == TypeInfo.t_type || ( info.isForwardDeclaration() && info.getTypeSymbol() != null ) ){
typeSymbol = info.getTypeSymbol();
@@ -2038,6 +2064,16 @@
public int rank = -1;
public int detail;
+ //Some constants to help clarify things
+ public static final int AMBIGUOUS_USERDEFINED_CONVERSION = 1;
+
+ public static final int NO_MATCH_RANK = -1;
+ public static final int IDENTITY_RANK = 0;
+ public static final int LVALUE_OR_QUALIFICATION_RANK = 0;
+ public static final int PROMOTION_RANK = 1;
+ public static final int CONVERSION_RANK = 2;
+ public static final int USERDEFINED_CONVERSION_RANK = 3;
+
public int compare( Cost cost ){
int result = 0;
@@ -2049,7 +2085,7 @@
if( userDefined == 0 || cost.userDefined == 0 ){
return cost.userDefined - userDefined;
} else {
- if( (userDefined == 1 || cost.userDefined == 1) ||
+ if( (userDefined == AMBIGUOUS_USERDEFINED_CONVERSION || cost.userDefined == AMBIGUOUS_USERDEFINED_CONVERSION) ||
(userDefined != cost.userDefined ) )
{
return 0;
@@ -3132,6 +3168,10 @@
param = (TypeInfo) iter.next();
paramType = ParserSymbolTable.getFlatTypeInfo( param ).getTypeSymbol();
+ if( paramType == null ){
+ continue;
+ }
+
ParserSymbolTable.getAssociatedScopes( paramType, associated );
//if T is a pointer to a data member of class X, its associated namespaces and classes