- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rac9ca967 rb6fe7e6 38 38 #include "SynTree/TypeSubstitution.h" 39 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuples.h" 40 #include "Tuples/TupleAssignment.h" 41 #include "Tuples/NameMatcher.h" 41 42 #include "Common/utility.h" 42 43 #include "InitTweak/InitTweak.h" … … 63 64 } 64 65 65 Cost sumCost( const AltList &in ) {66 Cost total;67 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {68 total += i->cost;69 }70 return total;71 }72 73 66 namespace { 74 67 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) { … … 83 76 out.push_back( i->expr->clone() ); 84 77 } 78 } 79 80 Cost sumCost( const AltList &in ) { 81 Cost total; 82 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { 83 total += i->cost; 84 } 85 return total; 85 86 } 86 87 … … 100 101 PruneStruct current( candidate ); 101 102 std::string mangleName; 102 {103 Type * newType = candidate->expr->get_result()->clone();103 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) { 104 Type *newType = (*retType)->clone(); 104 105 candidate->env.apply( newType ); 105 mangleName = SymTab::Mangler::mangle( newType );106 mangleName += SymTab::Mangler::mangle( newType ); 106 107 delete newType; 107 108 } … … 132 133 if ( ! target->second.isAmbiguous ) { 133 134 Alternative &alt = *target->second.candidate; 134 alt.env.applyFree( alt.expr->get_result() ); 135 for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) { 136 alt.env.applyFree( *result ); 137 } 135 138 *out++ = alt; 136 139 } 137 140 } 141 142 } 143 144 template< typename InputIterator, typename OutputIterator > 145 void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) { 146 AltList alternatives; 147 148 // select the alternatives that have the minimum parameter cost 149 Cost minCost = Cost::infinity; 150 for ( AltList::iterator i = begin; i != end; ++i ) { 151 if ( i->cost < minCost ) { 152 minCost = i->cost; 153 i->cost = i->cvtCost; 154 alternatives.clear(); 155 alternatives.push_back( *i ); 156 } else if ( i->cost == minCost ) { 157 i->cost = i->cvtCost; 158 alternatives.push_back( *i ); 159 } 160 } 161 std::copy( alternatives.begin(), alternatives.end(), out ); 162 } 163 164 template< typename InputIterator > 165 void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) { 166 while ( begin != end ) { 167 result.simpleCombine( (*begin++).env ); 168 } 138 169 } 139 170 140 171 void renameTypes( Expression *expr ) { 141 expr->get_result()->accept( global_renamer ); 172 for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 173 (*i)->accept( global_renamer ); 174 } 142 175 } 143 176 } … … 171 204 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) { 172 205 if ( adjust ) { 173 adjustExprType ( i->expr->get_result(), i->env, indexer );206 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer ); 174 207 } 175 208 } … … 208 241 209 242 template< typename StructOrUnionType > 210 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 211 // member must be either a tuple expression or a name expr 212 if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) { 213 const std::string & name = nameExpr->get_name(); 214 std::list< Declaration* > members; 215 aggInst->lookup( name, members ); 216 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 217 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 218 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) ); 219 renameTypes( alternatives.back().expr ); 220 } else { 221 assert( false ); 222 } 223 } 224 } else if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( member ) ) { 225 assert( false ); 226 } else { 227 // xxx - temporary 228 std::cerr << member << std::endl; 229 assertf( false, "reached unexpected case of addAggMembers" ); 243 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) { 244 std::list< Declaration* > members; 245 aggInst->lookup( name, members ); 246 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 247 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 248 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) ); 249 renameTypes( alternatives.back().expr ); 250 } else { 251 assert( false ); 252 } 230 253 } 231 254 } … … 236 259 237 260 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 238 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 239 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 240 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 261 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr ); 262 assert( appExpr ); 263 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 264 assert( pointer ); 265 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 266 assert( function ); 241 267 242 268 Cost convCost( 0, 0, 0 ); … … 244 270 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 245 271 std::list< Expression* >& actuals = appExpr->get_args(); 246 247 std::list< Type * > formalTypes;248 std::list< Type * >::iterator formalType = formalTypes.end();249 250 272 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 251 252 273 PRINT( 253 274 std::cerr << "actual expression:" << std::endl; 254 275 (*actualExpr)->print( std::cerr, 8 ); 255 276 std::cerr << "--- results are" << std::endl; 256 (*actualExpr)->get_result()->print(std::cerr, 8 );277 printAll( (*actualExpr)->get_results(), std::cerr, 8 ); 257 278 ) 258 279 std::list< DeclarationWithType* >::iterator startFormal = formal; 259 280 Cost actualCost; 260 std::list< Type * > flatActualTypes; 261 flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) ); 262 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) { 263 264 265 // tuple handling code 266 if ( formalType == formalTypes.end() ) { 267 // the type of the formal parameter may be a tuple type. To make this easier to work with, 268 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 269 // iterator once its types have been extracted. Once a particular formal parameter's type has 270 // been exhausted load the next formal parameter's type. 271 if ( formal == formals.end() ) { 272 if ( function->get_isVarArgs() ) { 273 convCost += Cost( 1, 0, 0 ); 274 break; 275 } else { 276 return Cost::infinity; 277 } 281 for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) { 282 if ( formal == formals.end() ) { 283 if ( function->get_isVarArgs() ) { 284 convCost += Cost( 1, 0, 0 ); 285 break; 286 } else { 287 return Cost::infinity; 278 288 } 279 formalTypes.clear();280 flatten( (*formal)->get_type(), back_inserter( formalTypes ) );281 formalType = formalTypes.begin();282 ++formal;283 289 } 284 285 290 PRINT( 286 291 std::cerr << std::endl << "converting "; 287 (*actual Type)->print( std::cerr, 8 );292 (*actual)->print( std::cerr, 8 ); 288 293 std::cerr << std::endl << " to "; 289 294 (*formal)->get_type()->print( std::cerr, 8 ); 290 295 ) 291 Cost newCost = conversionCost( *actual Type, *formalType, indexer, alt.env );296 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env ); 292 297 PRINT( 293 298 std::cerr << std::endl << "cost is" << newCost << std::endl; … … 300 305 actualCost += newCost; 301 306 302 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );303 304 formal Type++;307 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 ); 308 309 formal++; 305 310 } 306 311 if ( actualCost != Cost( 0, 0, 0 ) ) { … … 351 356 /// Adds type variables to the open variable set and marks their assertions 352 357 void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) { 353 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {358 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 354 359 unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind(); 355 360 for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { … … 360 365 } 361 366 362 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType, 363 /// producing expression(s) in out and their total cost in cost. 364 template< typename AltIterator, typename OutputIterator > 365 bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) { 366 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 367 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 368 TupleExpr * tupleExpr = new TupleExpr(); 369 for ( Type * type : *tupleType ) { 370 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) { 371 delete tupleExpr; 372 return false; 373 } 374 } 375 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 376 *out++ = tupleExpr; 377 } else if ( actualIt != actualEnd ) { 378 // both actualType and formalType are atomic (non-tuple) types - if they unify 379 // then accept actual as an argument, otherwise return false (fail to instantiate argument) 380 Expression * actual = actualIt->expr; 381 Type * actualType = actual->get_result(); 382 PRINT( 383 std::cerr << "formal type is "; 384 formalType->print( std::cerr ); 385 std::cerr << std::endl << "actual type is "; 386 actualType->print( std::cerr ); 387 std::cerr << std::endl; 388 ) 389 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 390 return false; 391 } 392 // move the expression from the alternative to the output iterator 393 *out++ = actual; 394 actualIt->expr = nullptr; 395 cost += actualIt->cost; 396 ++actualIt; 397 } else { 398 // End of actuals - Handle default values 399 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) { 400 // so far, only constant expressions are accepted as default values 401 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) { 402 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 403 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 404 // xxx - Don't know if this is right 405 *out++ = cnstexpr->clone(); 406 return true; 407 } // if 408 } // if 409 } // if 410 } // if 411 return false; 412 } // if 413 return true; 414 } 415 416 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) { 367 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) { 417 368 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv ); 418 369 // make sure we don't widen any existing bindings … … 422 373 resultEnv.extractOpenVars( openVars ); 423 374 424 // flatten actuals so that each actual has an atomic (non-tuple) type 425 AltList exploded; 426 Tuples::explode( actuals, back_inserter( exploded ) ); 427 428 AltList::iterator actualExpr = exploded.begin(); 429 AltList::iterator actualEnd = exploded.end(); 430 for ( DeclarationWithType * formal : formals ) { 431 // match flattened actuals with formal parameters - actuals will be grouped to match 432 // with formals as appropriate 433 Cost cost; 434 std::list< Expression * > newExprs; 435 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); 436 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) { 437 deleteAll( newExprs ); 438 return false; 439 } 440 // success - produce argument as a new alternative 441 assert( newExprs.size() == 1 ); 442 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) ); 443 } 444 if ( actualExpr != actualEnd ) { 445 // there are still actuals remaining, but we've run out of formal parameters to match against 446 // this is okay only if the function is variadic 447 if ( ! isVarArgs ) { 448 return false; 449 } 450 out.splice( out.end(), exploded, actualExpr, actualEnd ); 375 /* 376 Tuples::NameMatcher matcher( formals ); 377 try { 378 matcher.match( actuals ); 379 } catch ( Tuples::NoMatch &e ) { 380 std::cerr << "Alternative doesn't match: " << e.message << std::endl; 381 } 382 */ 383 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 384 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 385 for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) { 386 if ( formal == formals.end() ) { 387 return isVarArgs; 388 } 389 PRINT( 390 std::cerr << "formal type is "; 391 (*formal)->get_type()->print( std::cerr ); 392 std::cerr << std::endl << "actual type is "; 393 (*actual)->print( std::cerr ); 394 std::cerr << std::endl; 395 ) 396 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 397 return false; 398 } 399 formal++; 400 } 401 } 402 // Handling of default values 403 while ( formal != formals.end() ) { 404 if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) ) 405 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() )) 406 // so far, only constant expressions are accepted as default values 407 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) 408 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) 409 if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 410 // XXX Don't know if this is right 411 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) ); 412 formal++; 413 if ( formal == formals.end()) break; 414 } 415 return false; 451 416 } 452 417 return true; … … 535 500 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 536 501 Expression *varExpr = new VariableExpr( candDecl ); 537 delete varExpr->get_result(); 538 varExpr->set_result( adjType->clone() ); 502 deleteAll( varExpr->get_results() ); 503 varExpr->get_results().clear(); 504 varExpr->get_results().push_front( adjType->clone() ); 539 505 PRINT( 540 506 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; … … 579 545 580 546 template< typename OutputIterator > 581 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, constAltList &actualAlt, OutputIterator out ) {547 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) { 582 548 OpenVarSet openVars; 583 549 AssertionSet resultNeed, resultHave; 584 550 TypeEnvironment resultEnv; 585 551 makeUnifiableVars( funcType, openVars, resultNeed ); 586 AltList instantiatedActuals; // filled by instantiate function 587 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 552 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) { 588 553 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 589 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals) );590 makeExprList( instantiatedActuals, appExpr->get_args() );554 Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) ); 555 makeExprList( actualAlt, appExpr->get_args() ); 591 556 PRINT( 592 557 std::cerr << "need assertions:" << std::endl; … … 609 574 PointerType pt( Type::Qualifiers(), v.clone() ); 610 575 UntypedExpr *vexpr = untypedExpr->clone(); 611 vexpr-> set_result( pt.clone() );576 vexpr->get_results().push_front( pt.clone() ); 612 577 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 613 578 return; … … 622 587 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 623 588 624 // take care of possible tuple assignments 625 // if not tuple assignment, assignment is taken care of as a normal function call 626 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities ); 589 Tuples::TupleAssignSpotter tassign( this ); 590 if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) { 591 // take care of possible tuple assignments, or discard expression 592 return; 593 } // else ... 627 594 628 595 AltList candidates; … … 637 604 // check if the type is pointer to function 638 605 PointerType *pointer; 639 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {606 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) { 640 607 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 641 608 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 673 640 // check if the type is pointer to function 674 641 PointerType *pointer; 675 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 642 if ( funcOp->expr->get_results().size() == 1 643 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 676 644 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 677 645 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { … … 697 665 698 666 PRINT( 699 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr ); 700 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 701 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 667 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr ); 668 assert( appExpr ); 669 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 670 assert( pointer ); 671 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 672 assert( function ); 702 673 std::cerr << "Case +++++++++++++" << std::endl; 703 674 std::cerr << "formals are:" << std::endl; … … 721 692 722 693 bool isLvalue( Expression *expr ) { 723 // xxx - recurse into tuples? 724 return expr->has_result() && expr->get_result()->get_isLvalue(); 694 for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) { 695 if ( !(*i)->get_isLvalue() ) return false; 696 } // for 697 return true; 725 698 } 726 699 … … 736 709 737 710 void AlternativeFinder::visit( CastExpr *castExpr ) { 738 Type *& toType = castExpr->get_result(); 739 toType = resolveTypeof( toType, indexer ); 740 SymTab::validateType( toType, &indexer ); 741 adjustExprType( toType, env, indexer ); 711 for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) { 712 *i = resolveTypeof( *i, indexer ); 713 SymTab::validateType( *i, &indexer ); 714 adjustExprType( *i, env, indexer ); 715 } // for 742 716 743 717 AlternativeFinder finder( indexer, env ); … … 753 727 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 754 728 // to. 755 int discardedValues = (*i).expr->get_result ()->size() - castExpr->get_result()->size();729 int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size(); 756 730 if ( discardedValues < 0 ) continue; 757 // xxx - may need to go into tuple types and extract relavent types and use unifyList 731 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 732 std::advance( candidate_end, castExpr->get_results().size() ); 758 733 // unification run for side-effects 759 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 760 Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env ); 734 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(), 735 (*i).expr->get_results().begin(), candidate_end, 736 i->env, needAssertions, haveAssertions, openVars, indexer ); 737 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 738 castExpr->get_results().begin(), castExpr->get_results().end(), 739 indexer, i->env ); 761 740 if ( thisCost != Cost::infinity ) { 762 741 // count one safe conversion for each value that is thrown away … … 781 760 782 761 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 783 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) { 784 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 785 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) { 786 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 762 if ( agg->expr->get_results().size() == 1 ) { 763 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) { 764 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 765 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) { 766 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 767 } // if 787 768 } // if 788 769 } // for … … 810 791 renameTypes( alternatives.back().expr ); 811 792 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) { 812 NameExpr nameExpr( "" ); 813 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 793 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 814 794 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) { 815 NameExpr nameExpr( "" ); 816 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr ); 795 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" ); 817 796 } // if 818 797 } // for … … 915 894 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 916 895 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 917 alternatives.back().expr-> set_result( (*i)->get_type()->clone() );896 alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() ); 918 897 } // for 919 898 } // if … … 938 917 finder.find( attrExpr->get_expr() ); 939 918 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 940 if ( choice->expr->get_result ()->size() == 1 ) {941 resolveAttr(*i, function, choice->expr->get_result (), choice->env );919 if ( choice->expr->get_results().size() == 1 ) { 920 resolveAttr(*i, function, choice->expr->get_results().front(), choice->env ); 942 921 } // fi 943 922 } // for … … 981 960 AssertionSet needAssertions, haveAssertions; 982 961 Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost ); 983 Type* commonType;984 if ( unify ( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType) ) {962 std::list< Type* > commonTypes; 963 if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 985 964 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 986 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 965 std::list< Type* >::const_iterator original = second->expr->get_results().begin(); 966 std::list< Type* >::const_iterator commonType = commonTypes.begin(); 967 for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) { 968 if ( *commonType ) { 969 newExpr->get_results().push_back( *commonType ); 970 } else { 971 newExpr->get_results().push_back( (*original)->clone() ); 972 } // if 973 } // for 987 974 newAlt.expr = newExpr; 988 975 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); … … 1012 999 TupleExpr *newExpr = new TupleExpr; 1013 1000 makeExprList( *i, newExpr->get_exprs() ); 1014 newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) ); 1001 for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) { 1002 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) { 1003 newExpr->get_results().push_back( (*resultType)->clone() ); 1004 } // for 1005 } // for 1015 1006 1016 1007 TypeEnvironment compositeEnv; … … 1033 1024 } 1034 1025 } 1035 1036 void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {1037 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );1038 }1039 1040 void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {1041 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );1042 }1043 1026 } // namespace ResolvExpr 1044 1027
Note:
See TracChangeset
for help on using the changeset viewer.