- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r6c3a988f r722617d 267 267 std::list< Expression* >& actuals = appExpr->get_args(); 268 268 269 std::list< Type * > formalTypes; 270 std::list< Type * >::iterator formalType = formalTypes.end(); 271 269 272 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 270 Type * actualType = (*actualExpr)->get_result(); 273 271 274 PRINT( 272 275 std::cerr << "actual expression:" << std::endl; 273 276 (*actualExpr)->print( std::cerr, 8 ); 274 277 std::cerr << "--- results are" << std::endl; 275 actualType->print( std::cerr, 8 ); 276 ) 278 (*actualExpr)->get_result()->print( std::cerr, 8 ); 279 ) 280 std::list< DeclarationWithType* >::iterator startFormal = formal; 277 281 Cost actualCost; 278 if ( formal == formals.end() ) { 279 if ( function->get_isVarArgs() ) { 280 convCost += Cost( 1, 0, 0 ); 281 continue; 282 std::list< Type * > flatActualTypes; 283 flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) ); 284 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) { 285 286 287 // tuple handling code 288 if ( formalType == formalTypes.end() ) { 289 // the type of the formal parameter may be a tuple type. To make this easier to work with, 290 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 291 // iterator once its types have been extracted. Once a particular formal parameter's type has 292 // been exhausted load the next formal parameter's type. 293 if ( formal == formals.end() ) { 294 if ( function->get_isVarArgs() ) { 295 convCost += Cost( 1, 0, 0 ); 296 break; 297 } else { 298 return Cost::infinity; 299 } 300 } 301 formalTypes.clear(); 302 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 303 formalType = formalTypes.begin(); 304 ++formal; 305 } 306 307 PRINT( 308 std::cerr << std::endl << "converting "; 309 (*actualType)->print( std::cerr, 8 ); 310 std::cerr << std::endl << " to "; 311 (*formalType)->print( std::cerr, 8 ); 312 ) 313 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env ); 314 PRINT( 315 std::cerr << std::endl << "cost is" << newCost << std::endl; 316 ) 317 318 if ( newCost == Cost::infinity ) { 319 return newCost; 320 } 321 convCost += newCost; 322 actualCost += newCost; 323 324 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 ); 325 326 formalType++; 327 } 328 if ( actualCost != Cost( 0, 0, 0 ) ) { 329 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal; 330 startFormalPlusOne++; 331 if ( formal == startFormalPlusOne ) { 332 // not a tuple type 333 Type *newType = (*startFormal)->get_type()->clone(); 334 alt.env.apply( newType ); 335 *actualExpr = new CastExpr( *actualExpr, newType ); 282 336 } else { 283 return Cost::infinity; 337 TupleType *newType = new TupleType( Type::Qualifiers() ); 338 for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) { 339 newType->get_types().push_back( (*i)->get_type()->clone() ); 340 } 341 alt.env.apply( newType ); 342 *actualExpr = new CastExpr( *actualExpr, newType ); 284 343 } 285 344 } 286 Type * formalType = (*formal)->get_type(); 287 PRINT( 288 std::cerr << std::endl << "converting "; 289 actualType->print( std::cerr, 8 ); 290 std::cerr << std::endl << " to "; 291 formalType->print( std::cerr, 8 ); 292 ) 293 Cost newCost = conversionCost( actualType, formalType, indexer, alt.env ); 294 PRINT( 295 std::cerr << std::endl << "cost is" << newCost << std::endl; 296 ) 297 298 if ( newCost == Cost::infinity ) { 299 return newCost; 300 } 301 convCost += newCost; 302 actualCost += newCost; 303 if ( actualCost != Cost( 0, 0, 0 ) ) { 304 Type *newType = formalType->clone(); 305 alt.env.apply( newType ); 306 *actualExpr = new CastExpr( *actualExpr, newType ); 307 } 308 convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 ); 309 ++formal; // can't be in for-loop update because of the continue 345 310 346 } 311 347 if ( formal != formals.end() ) { … … 328 364 } 329 365 convCost += newCost; 366 330 367 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 ); 331 368 } … … 339 376 unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar }; 340 377 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { 341 needAssertions[ *assert ] .isUsed= true;378 needAssertions[ *assert ] = true; 342 379 } 343 380 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); … … 351 388 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 352 389 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 353 std::list< Expression * > exprs;390 TupleExpr * tupleExpr = new TupleExpr(); 354 391 for ( Type * type : *tupleType ) { 355 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs) ) ) {356 delete All( exprs );392 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) { 393 delete tupleExpr; 357 394 return false; 358 395 } 359 396 } 360 *out++ = new TupleExpr( exprs ); 361 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) { 362 // xxx - mixing default arguments with variadic?? 363 std::list< Expression * > exprs; 364 for ( ; actualIt != actualEnd; ++actualIt ) { 365 exprs.push_back( actualIt->expr->clone() ); 366 cost += actualIt->cost; 367 } 368 Expression * arg = nullptr; 369 if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) { 370 // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes 371 // xxx - what if passing multiple arguments, last of which is ttype? 372 // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below. 373 arg = exprs.front(); 374 } else { 375 arg = new TupleExpr( exprs ); 376 } 377 assert( arg && arg->get_result() ); 378 if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 379 return false; 380 } 381 *out++ = arg; 397 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 398 *out++ = tupleExpr; 382 399 } else if ( actualIt != actualEnd ) { 383 400 // both actualType and formalType are atomic (non-tuple) types - if they unify … … 466 483 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 467 484 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 468 if ( i->second .isUsed) {485 if ( i->second == true ) { 469 486 i->first->accept( indexer ); 470 487 } … … 477 494 if ( begin == end ) { 478 495 if ( newNeed.empty() ) { 479 PRINT(480 std::cerr << "all assertions satisfied, output alternative: ";481 newAlt.print( std::cerr );482 std::cerr << std::endl;483 );484 496 *out++ = newAlt; 485 497 return; … … 498 510 499 511 ForwardIterator cur = begin++; 500 if ( ! cur->second .isUsed) {512 if ( ! cur->second ) { 501 513 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out ); 502 514 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be … … 542 554 assert( (*candidate)->get_uniqueId() ); 543 555 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 544 545 // everything with an empty idChain was pulled in by the current assertion.546 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.547 for ( auto & a : newerNeed ) {548 if ( a.second.idChain.empty() ) {549 a.second.idChain = cur->second.idChain;550 a.second.idChain.push_back( curDecl->get_uniqueId() );551 }552 }553 554 556 //AssertionParentSet newNeedParents( needParents ); 555 557 // skip repeatingly-self-recursive assertion satisfaction … … 567 569 ) 568 570 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr ); 569 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).570 InferredParams * inferParameters = &appExpr->get_inferParams();571 for ( UniqueId id : cur->second.idChain ) {572 inferParameters = (*inferParameters)[ id ].inferParams.get();573 }574 571 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 575 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );572 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 576 573 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 577 574 } else { … … 612 609 makeUnifiableVars( funcType, openVars, resultNeed ); 613 610 AltList instantiatedActuals; // filled by instantiate function 614 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty()) {611 if ( targetType && ! targetType->isVoid() ) { 615 612 // attempt to narrow based on expected target type 616 613 Type * returnType = funcType->get_returnVals().front()->get_type(); … … 1078 1075 } 1079 1076 1080 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {1077 void AlternativeFinder::visit( TupleExpr *tupleExpr ) { 1081 1078 std::list< AlternativeFinder > subExprAlternatives; 1082 1079 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) ); … … 1084 1081 combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) ); 1085 1082 for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) { 1086 std::list< Expression * > exprs; 1087 makeExprList( *i, exprs ); 1083 TupleExpr *newExpr = new TupleExpr; 1084 makeExprList( *i, newExpr->get_exprs() ); 1085 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1088 1086 1089 1087 TypeEnvironment compositeEnv; 1090 1088 simpleCombineEnvironments( i->begin(), i->end(), compositeEnv ); 1091 alternatives.push_back( Alternative( new TupleExpr( exprs ), compositeEnv, sumCost( *i ) ) );1089 alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) ); 1092 1090 } // for 1093 }1094 1095 void AlternativeFinder::visit( TupleExpr *tupleExpr ) {1096 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );1097 1091 } 1098 1092
Note:
See TracChangeset
for help on using the changeset viewer.