Changeset aefcc3b for src/ResolvExpr
- Timestamp:
- Sep 20, 2016, 4:14:13 PM (8 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:
- 23b6643f
- Parents:
- 8c49c0e
- Location:
- src/ResolvExpr
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Alternative.cc
r8c49c0e raefcc3b 38 38 } 39 39 40 Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( other.env ) { 41 other.expr = nullptr; 42 } 43 44 Alternative & Alternative::operator=( Alternative && other ) { 45 if ( &other == this ) return *this; 46 delete expr; 47 cost = other.cost; 48 cvtCost = other.cvtCost; 49 expr = other.expr; 50 env = other.env; 51 other.expr = nullptr; 52 return *this; 53 } 54 40 55 void Alternative::initialize( const Alternative &src, Alternative &dest ) { 41 56 dest.cost = src.cost; -
src/ResolvExpr/Alternative.h
r8c49c0e raefcc3b 32 32 Alternative( const Alternative &other ); 33 33 Alternative &operator=( const Alternative &other ); 34 Alternative( Alternative && other ); 35 Alternative &operator=( Alternative && other ); 34 36 ~Alternative(); 35 37 … … 49 51 Type * res = expr->get_result(); 50 52 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) { 51 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( alt.expr ) ) { 53 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) { 54 // can open tuple expr and dump its exploded components 52 55 for ( Expression * expr : tupleExpr->get_exprs() ) { 53 56 explodeUnique( expr, alt, out ); 54 57 } 55 58 } else { 59 // tuple type, but not tuple expr - need to refer to single instance of the argument 60 // expression and index into its components 56 61 UniqueExpr * unq = new UniqueExpr( expr->clone() ); 57 62 for ( unsigned int i = 0; i < tupleType->size(); i++ ) { … … 63 68 } 64 69 } else { 70 // atomic (non-tuple) type - output a clone of the expression in a new alternative 65 71 *out++ = Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost ); 66 72 } … … 69 75 /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type 70 76 template< typename OutputIterator > 71 void explode( Alternative &alt, OutputIterator out ) {77 void explode( const Alternative &alt, OutputIterator out ) { 72 78 explodeUnique( alt.expr, alt, out ); 73 79 } … … 75 81 // explode list of alternatives 76 82 template< typename OutputIterator > 77 void explode( AltList & alts, OutputIterator out ) {78 for ( Alternative & alt : alts ) {83 void explode( const AltList & alts, OutputIterator out ) { 84 for ( const Alternative & alt : alts ) { 79 85 explode( alt, out ); 80 86 } -
src/ResolvExpr/AlternativeFinder.cc
r8c49c0e raefcc3b 371 371 } 372 372 373 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) { 373 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType, 374 /// producing expression(s) in out and their total cost in cost. 375 template< typename AltIterator, typename OutputIterator > 376 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 ) { 377 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) { 378 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType 379 TupleExpr * tupleExpr = new TupleExpr(); 380 for ( Type * type : *tupleType ) { 381 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) { 382 delete tupleExpr; 383 return false; 384 } 385 } 386 tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) ); 387 *out++ = tupleExpr; 388 } else if ( actualIt != actualEnd ) { 389 // both actualType and formalType are atomic (non-tuple) types - if they unify 390 // then accept actual as an argument, otherwise return false (fail to instantiate argument) 391 Expression * actual = actualIt->expr; 392 Type * actualType = actual->get_result(); 393 PRINT( 394 std::cerr << "formal type is "; 395 formalType->print( std::cerr ); 396 std::cerr << std::endl << "actual type is "; 397 actualType->print( std::cerr ); 398 std::cerr << std::endl; 399 ) 400 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 401 return false; 402 } 403 // move the expression from the alternative to the output iterator 404 *out++ = actual; 405 actualIt->expr = nullptr; 406 cost += actualIt->cost; 407 ++actualIt; 408 } else { 409 // End of actuals - Handle default values 410 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) { 411 // so far, only constant expressions are accepted as default values 412 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) { 413 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 414 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 415 // xxx - Don't know if this is right 416 *out++ = cnstexpr->clone(); 417 return true; 418 } // if 419 } // if 420 } // if 421 } // if 422 return false; 423 } // if 424 return true; 425 } 426 427 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) { 374 428 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv ); 375 429 // make sure we don't widen any existing bindings … … 379 433 resultEnv.extractOpenVars( openVars ); 380 434 381 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 382 383 AltList newActuals; 384 explode( actuals, back_inserter( newActuals ) ); 385 386 std::list< Type * > formalTypes; 387 std::list< Type * >::iterator formalType = formalTypes.end(); 388 389 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 390 std::list< Type * > flatActualTypes; 391 flatten( actualExpr->expr->get_result(), back_inserter( flatActualTypes ) ); 392 for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType, ++formalType ) { 393 if ( formalType == formalTypes.end() ) { 394 // the type of the formal parameter may be a tuple type. To make this easier to work with, 395 // flatten the tuple type and traverse the resulting list of types, incrementing the formal 396 // iterator once its types have been extracted. Once a particular formal parameter's type has 397 // been exhausted load the next formal parameter's type. 398 if ( formal == formals.end() ) { 399 return isVarArgs; 400 } 401 formalTypes.clear(); 402 flatten( (*formal)->get_type(), back_inserter( formalTypes ) ); 403 formalType = formalTypes.begin(); 404 ++formal; 405 } 406 PRINT( 407 std::cerr << "formal type is "; 408 (*formalType)->print( std::cerr ); 409 std::cerr << std::endl << "actual type is "; 410 (*actualType)->print( std::cerr ); 411 std::cerr << std::endl; 412 ) 413 if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 414 return false; 415 } 416 } 417 } 418 419 // xxx - a tuple type was not completely matched 420 // partially handle the tuple with default arguments?? 421 if ( formalType != formalTypes.end() ) return false; 422 423 // Handling of default values 424 while ( formal != formals.end() ) { 425 if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) ) 426 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() )) 427 // so far, only constant expressions are accepted as default values 428 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) 429 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) 430 if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 431 // XXX Don't know if this is right 432 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) ); 433 formal++; 434 if ( formal == formals.end()) break; 435 } 436 return false; 435 // flatten actuals so that each actual has an atomic (non-tuple) type 436 AltList exploded; 437 explode( actuals, back_inserter( exploded ) ); 438 439 AltList::iterator actualExpr = exploded.begin(); 440 AltList::iterator actualEnd = exploded.end(); 441 for ( DeclarationWithType * formal : formals ) { 442 // match flattened actuals with formal parameters - actuals will be grouped to match 443 // with formals as appropriate 444 Cost cost; 445 std::list< Expression * > newExprs; 446 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); 447 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) { 448 deleteAll( newExprs ); 449 return false; 450 } 451 // success - produce argument as a new alternative 452 assert( newExprs.size() == 1 ); 453 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) ); 454 } 455 if ( actualExpr != actualEnd ) { 456 // there are still actuals remaining, but we've run out of formal parameters to match against 457 // this is okay only if the function is variadic 458 if ( ! isVarArgs ) { 459 return false; 460 } 461 out.splice( out.end(), exploded, actualExpr, actualEnd ); 437 462 } 438 463 return true; … … 565 590 566 591 template< typename OutputIterator > 567 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {592 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) { 568 593 OpenVarSet openVars; 569 594 AssertionSet resultNeed, resultHave; 570 595 TypeEnvironment resultEnv; 571 596 makeUnifiableVars( funcType, openVars, resultNeed ); 572 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) { 597 AltList instantiatedActuals; // filled by instantiate function 598 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 573 599 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 574 Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt) );575 makeExprList( actualAlt, appExpr->get_args() );600 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) ); 601 makeExprList( instantiatedActuals, appExpr->get_args() ); 576 602 PRINT( 577 603 std::cerr << "need assertions:" << std::endl; -
src/ResolvExpr/AlternativeFinder.h
r8c49c0e raefcc3b 78 78 /// Adds alternatives for offsetof expressions, given the base type and name of the member 79 79 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 80 bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave);80 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ); 81 81 template< typename OutputIterator > 82 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );82 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ); 83 83 template< typename OutputIterator > 84 84 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); -
src/ResolvExpr/Unify.cc
r8c49c0e raefcc3b 416 416 417 417 void markAssertions( AssertionSet &assertion1, AssertionSet &assertion2, Type *type ) { 418 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {418 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { 419 419 for ( std::list< DeclarationWithType* >::const_iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) { 420 420 markAssertionSet( assertion1, *assert );
Note: See TracChangeset
for help on using the changeset viewer.