Changeset 2162c2c for src/ResolvExpr/AlternativeFinder.cc
- Timestamp:
- Jan 11, 2017, 4:11:02 PM (9 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:
- 075734f
- Parents:
- bb82c03 (diff), d3a85240 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rbb82c03 r2162c2c 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 272 269 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 273 270 Type * actualType = (*actualExpr)->get_result(); 274 271 PRINT( 275 272 std::cerr << "actual expression:" << std::endl; 276 273 (*actualExpr)->print( std::cerr, 8 ); 277 274 std::cerr << "--- results are" << std::endl; 278 (*actualExpr)->get_result()->print( std::cerr, 8 ); 279 ) 280 std::list< DeclarationWithType* >::iterator startFormal = formal; 275 actualType->print( std::cerr, 8 ); 276 ) 281 277 Cost actualCost; 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; 278 if ( formal == formals.end() ) { 279 if ( function->get_isVarArgs() ) { 280 convCost += Cost( 1, 0, 0 ); 281 continue; 282 } else { 283 return Cost::infinity; 305 284 } 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 } 285 } 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; 328 303 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 ); 336 } else { 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 ); 343 } 344 } 345 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 346 310 } 347 311 if ( formal != formals.end() ) { … … 364 328 } 365 329 convCost += newCost; 366 367 330 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 ); 368 331 } … … 376 339 unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar }; 377 340 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { 378 needAssertions[ *assert ] = true;341 needAssertions[ *assert ].isUsed = true; 379 342 } 380 343 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); … … 388 351 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 389 352 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 390 TupleExpr * tupleExpr = new TupleExpr();353 std::list< Expression * > exprs; 391 354 for ( Type * type : *tupleType ) { 392 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs()) ) ) {393 delete tupleExpr;355 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) { 356 deleteAll( exprs ); 394 357 return false; 395 358 } 396 359 } 397 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 398 *out++ = tupleExpr; 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; 399 382 } else if ( actualIt != actualEnd ) { 400 383 // both actualType and formalType are atomic (non-tuple) types - if they unify … … 483 466 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 484 467 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 485 if ( i->second == true) {468 if ( i->second.isUsed ) { 486 469 i->first->accept( indexer ); 487 470 } … … 494 477 if ( begin == end ) { 495 478 if ( newNeed.empty() ) { 479 PRINT( 480 std::cerr << "all assertions satisfied, output alternative: "; 481 newAlt.print( std::cerr ); 482 std::cerr << std::endl; 483 ); 496 484 *out++ = newAlt; 497 485 return; … … 510 498 511 499 ForwardIterator cur = begin++; 512 if ( ! cur->second ) {500 if ( ! cur->second.isUsed ) { 513 501 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out ); 514 502 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be … … 554 542 assert( (*candidate)->get_uniqueId() ); 555 543 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 556 554 //AssertionParentSet newNeedParents( needParents ); 557 555 // skip repeatingly-self-recursive assertion satisfaction … … 569 567 ) 570 568 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 } 571 574 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 572 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );575 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 573 576 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 574 577 } else { … … 609 612 makeUnifiableVars( funcType, openVars, resultNeed ); 610 613 AltList instantiatedActuals; // filled by instantiate function 611 if ( targetType && ! targetType->isVoid() ) {614 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 612 615 // attempt to narrow based on expected target type 613 616 Type * returnType = funcType->get_returnVals().front()->get_type(); … … 1075 1078 } 1076 1079 1077 void AlternativeFinder::visit( TupleExpr *tupleExpr ) {1080 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) { 1078 1081 std::list< AlternativeFinder > subExprAlternatives; 1079 1082 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) ); … … 1081 1084 combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) ); 1082 1085 for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) { 1083 TupleExpr *newExpr = new TupleExpr; 1084 makeExprList( *i, newExpr->get_exprs() ); 1085 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1086 std::list< Expression * > exprs; 1087 makeExprList( *i, exprs ); 1086 1088 1087 1089 TypeEnvironment compositeEnv; 1088 1090 simpleCombineEnvironments( i->begin(), i->end(), compositeEnv ); 1089 alternatives.push_back( Alternative( new Expr, compositeEnv, sumCost( *i ) ) );1091 alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) ); 1090 1092 } // for 1093 } 1094 1095 void AlternativeFinder::visit( TupleExpr *tupleExpr ) { 1096 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1091 1097 } 1092 1098
Note:
See TracChangeset
for help on using the changeset viewer.