Changeset 89be1c68
- Timestamp:
- Jul 17, 2017, 2:35:52 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 7ebaa56
- Parents:
- b46e3bd
- Location:
- src/ResolvExpr
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Alternative.cc
rb46e3bd r89be1c68 28 28 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {} 29 29 30 Alternative::Alternative( const Alternative &other ) { 31 initialize( other, *this ); 30 Alternative::Alternative( const Alternative &other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), env( other.env ) { 32 31 } 33 32 34 33 Alternative &Alternative::operator=( const Alternative &other ) { 35 34 if ( &other == this ) return *this; 36 initialize( other, *this ); 35 delete expr; 36 cost = other.cost; 37 cvtCost = other.cvtCost; 38 expr = maybeClone( other.expr ); 39 env = other.env; 37 40 return *this; 38 41 } … … 51 54 other.expr = nullptr; 52 55 return *this; 53 }54 55 void Alternative::initialize( const Alternative &src, Alternative &dest ) {56 dest.cost = src.cost;57 dest.cvtCost = src.cvtCost;58 dest.expr = maybeClone( src.expr );59 dest.env = src.env;60 56 } 61 57 -
src/ResolvExpr/Alternative.h
rb46e3bd r89be1c68 36 36 ~Alternative(); 37 37 38 void initialize( const Alternative &src, Alternative &dest );39 40 38 void print( std::ostream &os, int indent = 0 ) const; 41 39 -
src/ResolvExpr/AlternativeFinder.cc
rb46e3bd r89be1c68 67 67 68 68 Cost sumCost( const AltList &in ) { 69 Cost total ;69 Cost total = Cost::zero; 70 70 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { 71 71 total += i->cost; … … 218 218 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) { 219 219 NameExpr nameExpr( "" ); 220 addAggMembers( structInst, expr, alt.cost+Cost ( 0, 0, 1 ), alt.env, &nameExpr );220 addAggMembers( structInst, expr, alt.cost+Cost::safe, alt.env, &nameExpr ); 221 221 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) { 222 222 NameExpr nameExpr( "" ); 223 addAggMembers( unionInst, expr, alt.cost+Cost ( 0, 0, 1 ), alt.env, &nameExpr );223 addAggMembers( unionInst, expr, alt.cost+Cost::safe, alt.env, &nameExpr ); 224 224 } // if 225 225 } … … 277 277 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 278 278 279 Cost convCost ( 0, 0, 0 );279 Cost convCost = Cost::zero; 280 280 std::list< DeclarationWithType* >& formals = function->get_parameters(); 281 281 std::list< DeclarationWithType* >::iterator formal = formals.begin(); … … 290 290 actualType->print( std::cerr, 8 ); 291 291 ) 292 Cost actualCost ;292 Cost actualCost = Cost::zero; 293 293 if ( formal == formals.end() ) { 294 294 if ( function->get_isVarArgs() ) { 295 convCost += Cost( 1, 0, 0);295 convCost.incUnsafe(); 296 296 continue; 297 297 } else { … … 319 319 convCost += newCost; 320 320 actualCost += newCost; 321 if ( actualCost != Cost ( 0, 0, 0 )) {321 if ( actualCost != Cost::zero ) { 322 322 Type *newType = formalType->clone(); 323 323 alt.env.apply( newType ); 324 324 *actualExpr = new CastExpr( *actualExpr, newType ); 325 325 } 326 convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0);326 convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) ); 327 327 ++formal; // can't be in for-loop update because of the continue 328 328 } … … 346 346 } 347 347 convCost += newCost; 348 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0);348 convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) ); 349 349 } 350 350 … … 456 456 // match flattened actuals with formal parameters - actuals will be grouped to match 457 457 // with formals as appropriate 458 Cost cost ;458 Cost cost = Cost::zero; 459 459 std::list< Expression * > newExprs; 460 460 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); … … 668 668 UntypedExpr *vexpr = untypedExpr->clone(); 669 669 vexpr->set_result( pt.clone() ); 670 alternatives.push_back( Alternative( vexpr, env, Cost ()) );670 alternatives.push_back( Alternative( vexpr, env, Cost::zero) ); 671 671 return; 672 672 } … … 869 869 if ( thisCost != Cost::infinity ) { 870 870 // count one safe conversion for each value that is thrown away 871 thisCost += Cost( 0, 0,discardedValues );871 thisCost.incSafe( discardedValues ); 872 872 873 873 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); … … 916 916 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 917 917 VariableExpr newExpr( *i, nameExpr->get_argName() ); 918 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ()) );918 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 919 919 PRINT( 920 920 std::cerr << "decl is "; … … 1060 1060 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1061 1061 VariableExpr newExpr( *i ); 1062 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ()) );1062 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1063 1063 renameTypes( alternatives.back().expr ); 1064 1064 } // for … … 1233 1233 if ( thisCost != Cost::infinity ) { 1234 1234 // count one safe conversion for each value that is thrown away 1235 thisCost += Cost( 0, 0,discardedValues );1235 thisCost.incSafe( discardedValues ); 1236 1236 candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) ); 1237 1237 } -
src/ResolvExpr/CastCost.cc
rb46e3bd r89be1c68 46 46 assert( type ); 47 47 if ( type->get_base() ) { 48 return castCost( src, type->get_base(), indexer, env ) + Cost ( 0, 0, 1 );48 return castCost( src, type->get_base(), indexer, env ) + Cost::safe; 49 49 } // if 50 50 } // if 51 51 } // if 52 52 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 53 return Cost ( 0, 0, 0 );53 return Cost::zero; 54 54 } else if ( dynamic_cast< VoidType* >( dest ) ) { 55 return Cost ( 0, 0, 1 );55 return Cost::safe; 56 56 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 57 57 return convertToReferenceCost( src, refType, indexer, env ); … … 63 63 } else { 64 64 // xxx - why are we adding cost 0 here? 65 return converter.get_cost() + Cost ( 0, 0, 0 );65 return converter.get_cost() + Cost::zero; 66 66 } // if 67 67 } // if … … 76 76 if ( destAsPointer && basicType->isInteger() ) { 77 77 // necessary for, e.g. unsigned long => void* 78 cost = Cost ( 1, 0, 0 );78 cost = Cost::unsafe; 79 79 } else { 80 80 cost = conversionCost( basicType, dest, indexer, env ); … … 85 85 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 86 86 if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 87 cost = Cost ( 0, 0, 1 );87 cost = Cost::safe; 88 88 } else { 89 89 TypeEnvironment newEnv( env ); … … 92 92 int castResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer ); 93 93 if ( castResult > 0 ) { 94 cost = Cost ( 0, 0, 1 );94 cost = Cost::safe; 95 95 } else if ( castResult < 0 ) { 96 96 cost = Cost::infinity; … … 100 100 if ( destAsBasic->isInteger() ) { 101 101 // necessary for, e.g. void* => unsigned long 102 cost = Cost ( 1, 0, 0 );102 cost = Cost::unsafe; 103 103 } // if 104 104 } -
src/ResolvExpr/ConversionCost.cc
rb46e3bd r89be1c68 45 45 assert( type ); 46 46 if ( type->get_base() ) { 47 return conversionCost( src, type->get_base(), indexer, env ) + Cost ( 0, 0, 1 );47 return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe; 48 48 } // if 49 49 } // if … … 58 58 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 59 59 /// std::cout << "compatible!" << std::endl; 60 return Cost ( 0, 0, 0 );60 return Cost::zero; 61 61 } else if ( dynamic_cast< VoidType* >( dest ) ) { 62 return Cost ( 0, 0, 1 );62 return Cost::safe; 63 63 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 64 64 // std::cerr << "conversionCost: dest is reference" << std::endl; … … 70 70 return Cost::infinity; 71 71 } else { 72 return converter.get_cost() + Cost( 0, 0, 0 ); 73 } // if 74 } // if 75 } 76 77 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 78 // std::cerr << "convert to reference cost..." << std::endl; 79 if ( ReferenceType *srcAsRef = dynamic_cast< ReferenceType * >( src ) ) { // pointer-like conversions between references 80 // std::cerr << "converting between references" << std::endl; 81 if ( srcAsRef->get_base()->get_qualifiers() <= dest->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), dest->get_base(), indexer, env ) ) { 82 return Cost( 0, 0, 1 ); 83 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 84 int assignResult = ptrsAssignable( srcAsRef->get_base(), dest->get_base(), env ); 85 if ( assignResult < 0 ) { 86 return Cost( 0, 0, 1 ); 87 } else if ( assignResult > 0 ) { 88 return Cost( 1, 0, 0 ); 89 } // if 90 } // if 91 } else if ( typesCompatibleIgnoreQualifiers( src, dest->get_base(), indexer, env ) ) { 92 // std::cerr << "converting compatible base type" << std::endl; 93 if ( src->get_lvalue() ) { 94 // std::cerr << "lvalue to reference conversion" << std::endl; 95 // lvalue-to-reference conversion: cv lvalue T => cv T & 96 if ( src->get_qualifiers() == dest->get_base()->get_qualifiers() ) { 97 return Cost( 0, 0, 1 ); // cost needs to be non-zero to add cast 98 } if ( src->get_qualifiers() < dest->get_base()->get_qualifiers() ) { 99 return Cost( 0, 0, 2 ); // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 72 return converter.get_cost() + Cost::zero; 73 } // if 74 } // if 75 } 76 77 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 78 std::cerr << "convert to reference cost..." << std::endl; 79 if ( diff > 0 ) { 80 // TODO: document this 81 Cost cost = convertToReferenceCost( safe_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env ); 82 // TODO: increment reference cost 83 cost.incSafe(); 84 return cost; 85 } else if ( diff < -1 ) { 86 // TODO: document this 87 Cost cost = convertToReferenceCost( src, safe_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env ); 88 // TODO: increment reference cost 89 cost.incSafe(); 90 return cost; 91 } else if ( diff == 0 ) { 92 ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src ); 93 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 94 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 95 std::cerr << "converting between references" << std::endl; 96 if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) { 97 return Cost::safe; 98 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 99 int assignResult = ptrsAssignable( srcAsRef->get_base(), destAsRef->get_base(), env ); 100 if ( assignResult < 0 ) { 101 return Cost::safe; 102 } else if ( assignResult > 0 ) { 103 return Cost::unsafe; 104 } // if 105 } // if 106 } else { 107 std::cerr << "reference to rvalue conversion" << std::endl; 108 ConversionCost converter( dest, indexer, env ); 109 src->accept( converter ); 110 return converter.get_cost(); 111 } // if 112 } else { 113 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 114 assert( diff == -1 && destAsRef ); 115 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) { 116 std::cerr << "converting compatible base type" << std::endl; 117 if ( src->get_lvalue() ) { 118 std::cerr << "lvalue to reference conversion" << std::endl; 119 // lvalue-to-reference conversion: cv lvalue T => cv T & 120 if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) { 121 return Cost::safe; // cost needs to be non-zero to add cast 122 } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) { 123 return Cost::safe + Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 124 } else { 125 return Cost::unsafe; 126 } // if 127 } else if ( destAsRef->get_base()->get_const() ) { 128 std::cerr << "rvalue to const ref conversion" << std::endl; 129 // rvalue-to-const-reference conversion: T => const T & 130 return Cost::safe; 100 131 } else { 101 return Cost( 1, 0, 0 ); 102 } 103 } else if ( dest->get_base()->get_const() ) { 104 // std::cerr << "rvalue to const ref conversion" << std::endl; 105 // rvalue-to-const-reference conversion: T => const T & 106 return Cost( 0, 0, 1 ); 107 } else { 108 // std::cerr << "rvalue to non-const reference conversion" << std::endl; 109 // rvalue-to-reference conversion: T => T & 110 return Cost( 1, 0, 0 ); 111 } 112 } else { 113 // std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; 132 // std::cerr << "rvalue to non-const reference conversion" << std::endl; 133 // rvalue-to-reference conversion: T => T & 134 return Cost::unsafe; 135 } // if 136 } // if 137 std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; 114 138 } 115 139 return Cost::infinity; 140 } 141 142 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 143 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 144 return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env ); 116 145 } 117 146 … … 205 234 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ]; 206 235 if ( tableResult == -1 ) { 207 cost = Cost( 1, 0, 0 ); 208 } else { 209 cost = Cost( 0, 0, tableResult ); 236 cost = Cost::unsafe; 237 } else { 238 cost = Cost::zero; 239 cost.incSafe( tableResult ); 210 240 } // if 211 241 } else if ( dynamic_cast< EnumInstType *>( dest ) ) { 212 242 // xxx - not positive this is correct, but appears to allow casting int => enum 213 cost = Cost ( 1, 0, 0 );243 cost = Cost::unsafe; 214 244 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) { 215 cost = Cost ( 1, 0, 0 );245 cost = Cost::unsafe; 216 246 } // if 217 247 } … … 220 250 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 221 251 if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 222 cost = Cost ( 0, 0, 1 );252 cost = Cost::safe; 223 253 } else { // xxx - this discards pointer qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 224 254 int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env ); 225 255 if ( assignResult < 0 ) { 226 cost = Cost ( 0, 0, 1 );256 cost = Cost::safe; 227 257 } else if ( assignResult > 0 ) { 228 cost = Cost ( 1, 0, 0 );258 cost = Cost::unsafe; 229 259 } // if 230 260 } // if 231 261 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) { 232 cost = Cost ( 1, 0, 0 );262 cost = Cost::unsafe; 233 263 } // if 234 264 } … … 243 273 // cv can be safely dropped because of 'implicit dereference' behavior. 244 274 refType->get_base()->accept( *this ); 275 // TODO: increment reference cost 276 cost.incSafe(); 245 277 } 246 278 … … 267 299 static BasicType integer( q, BasicType::SignedInt ); 268 300 integer.accept( *this ); // safe if dest >= int 269 if ( cost < Cost ( 1, 0, 0 )) {301 if ( cost < Cost::unsafe ) { 270 302 cost.incSafe(); 271 303 } // if … … 289 321 assert( type ); 290 322 if ( type->get_base() ) { 291 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost ( 0, 0, 1 );323 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost::safe; 292 324 } // if 293 325 } // if … … 295 327 296 328 void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) { 297 Cost c ;329 Cost c = Cost::zero; 298 330 if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) { 299 331 std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); … … 327 359 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ]; 328 360 if ( tableResult == -1 ) { 329 cost = Cost( 1, 0, 0 ); 330 } else { 331 cost = Cost( 0, 0, tableResult + 1 ); 361 cost = Cost::unsafe; 362 } else { 363 cost = Cost::zero; 364 cost.incSafe( tableResult + 1 ); 332 365 } 333 366 } else if ( dynamic_cast< PointerType* >( dest ) ) { 334 cost = Cost ( 0, 0, 1 );367 cost = Cost::safe; 335 368 } 336 369 } … … 343 376 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ]; 344 377 if ( tableResult == -1 ) { 345 cost = Cost( 1, 0, 0 ); 346 } else { 347 cost = Cost( 0, 0, tableResult + 1 ); 378 cost = Cost::unsafe; 379 } else { 380 cost = Cost::zero; 381 cost.incSafe( tableResult + 1 ); 348 382 } 349 383 } -
src/ResolvExpr/Cost.h
rb46e3bd r89be1c68 21 21 namespace ResolvExpr { 22 22 class Cost { 23 public: 24 Cost(); 23 private: 25 24 Cost( int unsafeCost, int polyCost, int safeCost ); 26 25 27 void incUnsafe( int inc = 1 ); 28 void incPoly( int inc = 1 ); 29 void incSafe( int inc = 1 ); 26 public: 27 Cost & incUnsafe( int inc = 1 ); 28 Cost & incPoly( int inc = 1 ); 29 Cost & incSafe( int inc = 1 ); 30 30 31 31 Cost operator+( const Cost &other ) const; … … 50 50 }; 51 51 52 inline Cost::Cost() : unsafeCost( 0 ), polyCost( 0 ), safeCost( 0 ) {}53 54 52 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ) {} 55 53 56 inline voidCost::incUnsafe( int inc ) {54 inline Cost & Cost::incUnsafe( int inc ) { 57 55 unsafeCost += inc; 56 return *this; 58 57 } 59 58 60 inline voidCost::incPoly( int inc ) {59 inline Cost & Cost::incPoly( int inc ) { 61 60 polyCost += inc; 61 return *this; 62 62 } 63 63 64 inline voidCost::incSafe( int inc ) {64 inline Cost & Cost::incSafe( int inc ) { 65 65 safeCost += inc; 66 return *this; 66 67 } 67 68
Note: See TracChangeset
for help on using the changeset viewer.