Changeset d67cdb7 for src/ResolvExpr
- Timestamp:
- Sep 26, 2017, 11:27:38 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:
- 5dc26f5
- Parents:
- 201aeb9
- Location:
- src/ResolvExpr
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r201aeb9 rd67cdb7 144 144 expr->get_result()->accept( global_renamer ); 145 145 } 146 147 void referenceToRvalueConversion( Expression *& expr ) {148 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {149 // cast away reference from expr150 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );151 }152 }153 146 } // namespace 147 148 void referenceToRvalueConversion( Expression *& expr ) { 149 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) { 150 // cast away reference from expr 151 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() ); 152 } 153 } 154 154 155 155 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/AlternativeFinder.h
r201aeb9 rd67cdb7 50 50 const SymTab::Indexer &get_indexer() const { return indexer; } 51 51 const TypeEnvironment &get_environ() const { return env; } 52 53 /// Runs a new alternative finder on each element in [begin, end) 54 /// and writes each alternative finder to out. 55 template< typename InputIterator, typename OutputIterator > 56 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 52 57 private: 53 58 virtual void visit( ApplicationExpr *applicationExpr ); … … 81 86 virtual void visit( StmtExpr *stmtExpr ); 82 87 virtual void visit( UntypedInitExpr *initExpr ); 83 /// Runs a new alternative finder on each element in [begin, end)84 /// and writes each alternative finder to out.85 template< typename InputIterator, typename OutputIterator >86 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );87 88 88 89 /// Adds alternatives for anonymous members … … 108 109 109 110 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 111 void referenceToRvalueConversion( Expression *& expr ); 110 112 111 113 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/Resolver.cc
r201aeb9 rd67cdb7 40 40 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 41 41 #include "typeops.h" // for extractResultType 42 #include "Unify.h" // for unify 42 43 43 44 using namespace std; … … 71 72 void previsit( ThrowStmt *throwStmt ); 72 73 void previsit( CatchStmt *catchStmt ); 74 void previsit( WaitForStmt * stmt ); 73 75 74 76 void previsit( SingleInit *singleInit ); … … 93 95 PassVisitor<Resolver> resolver; 94 96 acceptAll( translationUnit, resolver ); 97 } 98 99 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) { 100 PassVisitor<Resolver> resolver( indexer ); 101 maybeAccept( decl, resolver ); 95 102 } 96 103 … … 116 123 } 117 124 125 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 126 TypeEnvironment env; 127 AlternativeFinder finder( indexer, env ); 128 finder.find( untyped ); 129 #if 0 130 if ( finder.get_alternatives().size() != 1 ) { 131 std::cout << "untyped expr is "; 132 untyped->print( std::cout ); 133 std::cout << std::endl << "alternatives are:"; 134 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 135 i->print( std::cout ); 136 } // for 137 } // if 138 #endif 139 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." ); 140 Alternative &choice = finder.get_alternatives().front(); 141 Expression *newExpr = choice.expr->clone(); 142 finishExpr( newExpr, choice.env ); 143 return newExpr; 144 } 145 118 146 namespace { 119 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {120 TypeEnvironment env;121 AlternativeFinder finder( indexer, env );122 finder.find( untyped );123 #if 0124 if ( finder.get_alternatives().size() != 1 ) {125 std::cout << "untyped expr is ";126 untyped->print( std::cout );127 std::cout << std::endl << "alternatives are:";128 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {129 i->print( std::cout );130 } // for131 } // if132 #endif133 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );134 Alternative &choice = finder.get_alternatives().front();135 Expression *newExpr = choice.expr->clone();136 finishExpr( newExpr, choice.env );137 return newExpr;138 }139 140 147 bool isIntegralType( Type *type ) { 141 148 if ( dynamic_cast< EnumInstType * >( type ) ) { … … 391 398 } 392 399 400 inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) { 401 if( !expr ) return; 402 Expression * newExpr = findSingleExpression( expr, indexer ); 403 delete expr; 404 expr = newExpr; 405 } 406 407 inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) { 408 if( !expr ) return; 409 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer ); 410 delete expr; 411 expr = newExpr; 412 } 413 414 template< typename iterator_t > 415 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) { 416 while( it != end && !(*it)->get_type()->get_mutex() ) { 417 it++; 418 } 419 420 return it != end; 421 } 422 423 void Resolver::previsit( WaitForStmt * stmt ) { 424 visit_children = false; 425 426 // Resolve all clauses first 427 for( auto& clause : stmt->clauses ) { 428 429 TypeEnvironment env; 430 AlternativeFinder funcFinder( indexer, env ); 431 432 // Find all alternatives for a function in canonical form 433 funcFinder.findWithAdjustment( clause.target.function ); 434 435 if ( funcFinder.get_alternatives().empty() ) { 436 stringstream ss; 437 ss << "Use of undeclared indentifier '"; 438 ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name; 439 ss << "' in call to waitfor"; 440 throw SemanticError( ss.str() ); 441 } 442 443 // Find all alternatives for all arguments in canonical form 444 std::list< AlternativeFinder > argAlternatives; 445 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) ); 446 447 // List all combinations of arguments 448 std::list< AltList > possibilities; 449 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 450 451 AltList func_candidates; 452 std::vector< AltList > args_candidates; 453 454 // For every possible function : 455 // try matching the arguments to the parameters 456 // not the other way around because we have more arguments than parameters 457 SemanticError errors; 458 for ( Alternative & func : funcFinder.get_alternatives() ) { 459 try { 460 PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() ); 461 if( !pointer ) { 462 throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() ); 463 } 464 465 FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() ); 466 if( !function ) { 467 throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() ); 468 } 469 470 471 { 472 auto param = function->parameters.begin(); 473 auto param_end = function->parameters.end(); 474 475 if( !advance_to_mutex( param, param_end ) ) { 476 throw SemanticError("candidate function not viable: no mutex parameters\n", function); 477 } 478 } 479 480 Alternative newFunc( func ); 481 // Strip reference from function 482 referenceToRvalueConversion( newFunc.expr ); 483 484 // For all the set of arguments we have try to match it with the parameter of the current function alternative 485 for ( auto & argsList : possibilities ) { 486 487 try { 488 // Declare data structures need for resolution 489 OpenVarSet openVars; 490 AssertionSet resultNeed, resultHave; 491 TypeEnvironment resultEnv; 492 493 // Load type variables from arguemnts into one shared space 494 simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv ); 495 496 // Make sure we don't widen any existing bindings 497 for ( auto & i : resultEnv ) { 498 i.allowWidening = false; 499 } 500 501 // Find any unbound type variables 502 resultEnv.extractOpenVars( openVars ); 503 504 auto param = function->parameters.begin(); 505 auto param_end = function->parameters.end(); 506 507 // For every arguments of its set, check if it matches one of the parameter 508 // The order is important 509 for( auto & arg : argsList ) { 510 511 // Ignore non-mutex arguments 512 if( !advance_to_mutex( param, param_end ) ) { 513 // We ran out of parameters but still have arguments 514 // this function doesn't match 515 throw SemanticError("candidate function not viable: too many mutex arguments\n", function); 516 } 517 518 // Check if the argument matches the parameter type in the current scope 519 if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) { 520 // Type doesn't match 521 stringstream ss; 522 ss << "candidate function not viable: no known convertion from '"; 523 arg.expr->get_result()->print( ss ); 524 ss << "' to '"; 525 (*param)->get_type()->print( ss ); 526 ss << "'\n"; 527 throw SemanticError(ss.str(), function); 528 } 529 530 param++; 531 } 532 533 // All arguments match ! 534 535 // Check if parameters are missing 536 if( advance_to_mutex( param, param_end ) ) { 537 // We ran out of arguments but still have parameters left 538 // this function doesn't match 539 throw SemanticError("candidate function not viable: too few mutex arguments\n", function); 540 } 541 542 // All parameters match ! 543 544 // Finish the expressions to tie in the proper environments 545 finishExpr( newFunc.expr, resultEnv ); 546 for( Alternative & alt : argsList ) { 547 finishExpr( alt.expr, resultEnv ); 548 } 549 550 // This is a match store it and save it for later 551 func_candidates.push_back( newFunc ); 552 args_candidates.push_back( argsList ); 553 554 } 555 catch( SemanticError &e ) { 556 errors.append( e ); 557 } 558 } 559 } 560 catch( SemanticError &e ) { 561 errors.append( e ); 562 } 563 } 564 565 // Make sure we got the right number of arguments 566 if( func_candidates.empty() ) { SemanticError top( "No alternatives for function in call to waitfor" ); top.append( errors ); throw top; } 567 if( args_candidates.empty() ) { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; } 568 if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor" ); top.append( errors ); throw top; } 569 if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor" ); top.append( errors ); throw top; } 570 571 572 // Swap the results from the alternative with the unresolved values. 573 // Alternatives will handle deletion on destruction 574 std::swap( clause.target.function, func_candidates.front().expr ); 575 for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) { 576 std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr ); 577 } 578 579 // Resolve the conditions as if it were an IfStmt 580 // Resolve the statments normally 581 resolveAsIf( clause.condition, this->indexer ); 582 clause.statement->accept( *visitor ); 583 } 584 585 586 if( stmt->timeout.statement ) { 587 // Resolve the timeout as an size_t for now 588 // Resolve the conditions as if it were an IfStmt 589 // Resolve the statments normally 590 resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer ); 591 resolveAsIf ( stmt->timeout.condition, this->indexer ); 592 stmt->timeout.statement->accept( *visitor ); 593 } 594 595 if( stmt->orelse.statement ) { 596 // Resolve the conditions as if it were an IfStmt 597 // Resolve the statments normally 598 resolveAsIf( stmt->orelse.condition, this->indexer ); 599 stmt->orelse.statement->accept( *visitor ); 600 } 601 } 602 393 603 template< typename T > 394 604 bool isCharType( T t ) { -
src/ResolvExpr/Resolver.h
r201aeb9 rd67cdb7 29 29 /// Checks types and binds syntactic constructs to typed representations 30 30 void resolve( std::list< Declaration * > translationUnit ); 31 void resolveDecl( Declaration *, const SymTab::Indexer &indexer ); 31 32 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 32 33 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 34 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ); 33 35 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 34 36 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
r201aeb9 rd67cdb7 123 123 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 124 124 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 125 /// std::c out<< "adding " << *theVar;125 /// std::cerr << "adding " << *theVar; 126 126 if ( theClass->type ) { 127 /// std::c out<< " bound to ";128 /// theClass->type->print( std::c out);129 /// std::c out<< std::endl;127 /// std::cerr << " bound to "; 128 /// theClass->type->print( std::cerr ); 129 /// std::cerr << std::endl; 130 130 sub.add( *theVar, theClass->type ); 131 131 } else if ( theVar != theClass->vars.begin() ) { 132 132 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 133 /// std::c out<< " bound to variable " << *theClass->vars.begin() << std::endl;133 /// std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl; 134 134 sub.add( *theVar, newTypeInst ); 135 135 delete newTypeInst;
Note: See TracChangeset
for help on using the changeset viewer.