Changes in src/ResolvExpr/Resolver.cc [8f98b78:8b11840]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r8f98b78 r8b11840 40 40 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 41 41 #include "typeops.h" // for extractResultType 42 #include "Unify.h" // for unify43 42 44 43 using namespace std; … … 72 71 void previsit( ThrowStmt *throwStmt ); 73 72 void previsit( CatchStmt *catchStmt ); 74 void previsit( WaitForStmt * stmt );75 73 76 74 void previsit( SingleInit *singleInit ); … … 95 93 PassVisitor<Resolver> resolver; 96 94 acceptAll( translationUnit, resolver ); 95 } 96 97 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) { 98 PassVisitor<Resolver> resolver( indexer ); 99 maybeAccept( decl, resolver ); 97 100 } 98 101 … … 118 121 } 119 122 120 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {121 TypeEnvironment env;122 AlternativeFinder finder( indexer, env );123 finder.find( untyped );124 #if 0125 if ( finder.get_alternatives().size() != 1 ) {126 std::cout << "untyped expr is ";127 untyped->print( std::cout );128 std::cout << std::endl << "alternatives are:";129 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {130 i->print( std::cout );131 } // for132 } // if133 #endif134 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );135 Alternative &choice = finder.get_alternatives().front();136 Expression *newExpr = choice.expr->clone();137 finishExpr( newExpr, choice.env );138 return newExpr;139 }140 141 123 namespace { 124 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 125 TypeEnvironment env; 126 AlternativeFinder finder( indexer, env ); 127 finder.find( untyped ); 128 #if 0 129 if ( finder.get_alternatives().size() != 1 ) { 130 std::cout << "untyped expr is "; 131 untyped->print( std::cout ); 132 std::cout << std::endl << "alternatives are:"; 133 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 134 i->print( std::cout ); 135 } // for 136 } // if 137 #endif 138 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." ); 139 Alternative &choice = finder.get_alternatives().front(); 140 Expression *newExpr = choice.expr->clone(); 141 finishExpr( newExpr, choice.env ); 142 return newExpr; 143 } 144 142 145 bool isIntegralType( Type *type ) { 143 146 if ( dynamic_cast< EnumInstType * >( type ) ) { … … 393 396 } 394 397 395 inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {396 if( !expr ) return;397 Expression * newExpr = findSingleExpression( expr, indexer );398 delete expr;399 expr = newExpr;400 }401 402 inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {403 if( !expr ) return;404 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );405 delete expr;406 expr = newExpr;407 }408 409 template< typename iterator_t >410 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {411 while( it != end && !(*it)->get_type()->get_mutex() ) {412 it++;413 }414 415 return it != end;416 }417 418 void Resolver::previsit( WaitForStmt * stmt ) {419 visit_children = false;420 421 // Resolve all clauses first422 for( auto& clause : stmt->clauses ) {423 424 TypeEnvironment env;425 AlternativeFinder funcFinder( indexer, env );426 427 // Find all alternatives for a function in canonical form428 funcFinder.findWithAdjustment( clause.target.function );429 430 if ( funcFinder.get_alternatives().empty() ) {431 stringstream ss;432 ss << "Use of undeclared indentifier '";433 ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;434 ss << "' in call to waitfor";435 throw SemanticError( ss.str() );436 }437 438 // Find all alternatives for all arguments in canonical form439 std::list< AlternativeFinder > argAlternatives;440 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );441 442 // List all combinations of arguments443 std::list< AltList > possibilities;444 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );445 446 AltList func_candidates;447 std::vector< AltList > args_candidates;448 449 // For every possible function :450 // try matching the arguments to the parameters451 // not the other way around because we have more arguments than parameters452 SemanticError errors;453 for ( Alternative & func : funcFinder.get_alternatives() ) {454 try {455 PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );456 if( !pointer ) {457 throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );458 }459 460 FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );461 if( !function ) {462 throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );463 }464 465 466 {467 auto param = function->parameters.begin();468 auto param_end = function->parameters.end();469 470 if( !advance_to_mutex( param, param_end ) ) {471 throw SemanticError("candidate function not viable: no mutex parameters\n", function);472 }473 }474 475 Alternative newFunc( func );476 // Strip reference from function477 referenceToRvalueConversion( newFunc.expr );478 479 // For all the set of arguments we have try to match it with the parameter of the current function alternative480 for ( auto & argsList : possibilities ) {481 482 try {483 // Declare data structures need for resolution484 OpenVarSet openVars;485 AssertionSet resultNeed, resultHave;486 TypeEnvironment resultEnv;487 488 // Load type variables from arguemnts into one shared space489 simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );490 491 // Make sure we don't widen any existing bindings492 for ( auto & i : resultEnv ) {493 i.allowWidening = false;494 }495 496 // Find any unbound type variables497 resultEnv.extractOpenVars( openVars );498 499 auto param = function->parameters.begin();500 auto param_end = function->parameters.end();501 502 // For every arguments of its set, check if it matches one of the parameter503 // The order is important504 for( auto & arg : argsList ) {505 506 // Ignore non-mutex arguments507 if( !advance_to_mutex( param, param_end ) ) {508 // We ran out of parameters but still have arguments509 // this function doesn't match510 throw SemanticError("candidate function not viable: too many mutex arguments\n", function);511 }512 513 // Check if the argument matches the parameter type in the current scope514 if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {515 // Type doesn't match516 stringstream ss;517 ss << "candidate function not viable: no known convertion from '";518 arg.expr->get_result()->print( ss );519 ss << "' to '";520 (*param)->get_type()->print( ss );521 ss << "'\n";522 throw SemanticError(ss.str(), function);523 }524 525 param++;526 }527 528 // All arguments match !529 530 // Check if parameters are missing531 if( advance_to_mutex( param, param_end ) ) {532 // We ran out of arguments but still have parameters left533 // this function doesn't match534 throw SemanticError("candidate function not viable: too few mutex arguments\n", function);535 }536 537 // All parameters match !538 539 // Finish the expressions to tie in the proper environments540 finishExpr( newFunc.expr, resultEnv );541 for( Alternative & alt : argsList ) {542 finishExpr( alt.expr, resultEnv );543 }544 545 // This is a match store it and save it for later546 func_candidates.push_back( newFunc );547 args_candidates.push_back( argsList );548 549 }550 catch( SemanticError &e ) {551 errors.append( e );552 }553 }554 }555 catch( SemanticError &e ) {556 errors.append( e );557 }558 }559 560 // Make sure we got the right number of arguments561 if( func_candidates.empty() ) { SemanticError top( "No alternatives for function in call to waitfor" ); top.append( errors ); throw top; }562 if( args_candidates.empty() ) { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }563 if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor" ); top.append( errors ); throw top; }564 if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor" ); top.append( errors ); throw top; }565 566 567 // Swap the results from the alternative with the unresolved values.568 // Alternatives will handle deletion on destruction569 std::swap( clause.target.function, func_candidates.front().expr );570 for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {571 std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );572 }573 574 // Resolve the conditions as if it were an IfStmt575 // Resolve the statments normally576 resolveAsIf( clause.condition, this->indexer );577 clause.statement->accept( *visitor );578 }579 580 581 if( stmt->timeout.statement ) {582 // Resolve the timeout as an size_t for now583 // Resolve the conditions as if it were an IfStmt584 // Resolve the statments normally585 resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );586 resolveAsIf ( stmt->timeout.condition, this->indexer );587 stmt->timeout.statement->accept( *visitor );588 }589 590 if( stmt->orelse.statement ) {591 // Resolve the conditions as if it were an IfStmt592 // Resolve the statments normally593 resolveAsIf( stmt->orelse.condition, this->indexer );594 stmt->orelse.statement->accept( *visitor );595 }596 }597 598 398 template< typename T > 599 399 bool isCharType( T t ) {
Note:
See TracChangeset
for help on using the changeset viewer.