Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r8f98b78 r8b11840  
    4040#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4141#include "typeops.h"                     // for extractResultType
    42 #include "Unify.h"                       // for unify
    4342
    4443using namespace std;
     
    7271                void previsit( ThrowStmt *throwStmt );
    7372                void previsit( CatchStmt *catchStmt );
    74                 void previsit( WaitForStmt * stmt );
    7573
    7674                void previsit( SingleInit *singleInit );
     
    9593                PassVisitor<Resolver> resolver;
    9694                acceptAll( translationUnit, resolver );
     95        }
     96
     97        void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     98                PassVisitor<Resolver> resolver( indexer );
     99                maybeAccept( decl, resolver );
    97100        }
    98101
     
    118121        }
    119122
    120         Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    121                 TypeEnvironment env;
    122                 AlternativeFinder finder( indexer, env );
    123                 finder.find( untyped );
    124                 #if 0
    125                 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                         } // for
    132                 } // if
    133                 #endif
    134                 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 
    141123        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
    142145                bool isIntegralType( Type *type ) {
    143146                        if ( dynamic_cast< EnumInstType * >( type ) ) {
     
    393396        }
    394397
    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 first
    422                 for( auto& clause : stmt->clauses ) {
    423 
    424                         TypeEnvironment env;
    425                         AlternativeFinder funcFinder( indexer, env );
    426 
    427                         // Find all alternatives for a function in canonical form
    428                         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 form
    439                         std::list< AlternativeFinder > argAlternatives;
    440                         funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );
    441 
    442                         // List all combinations of arguments
    443                         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 parameters
    451                         //      not the other way around because we have more arguments than parameters
    452                         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 function
    477                                         referenceToRvalueConversion( newFunc.expr );
    478 
    479                                         // For all the set of arguments we have try to match it with the parameter of the current function alternative
    480                                         for ( auto & argsList : possibilities ) {
    481 
    482                                                 try {
    483                                                         // Declare data structures need for resolution
    484                                                         OpenVarSet openVars;
    485                                                         AssertionSet resultNeed, resultHave;
    486                                                         TypeEnvironment resultEnv;
    487 
    488                                                         // Load type variables from arguemnts into one shared space
    489                                                         simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );
    490 
    491                                                         // Make sure we don't widen any existing bindings
    492                                                         for ( auto & i : resultEnv ) {
    493                                                                 i.allowWidening = false;
    494                                                         }
    495 
    496                                                         // Find any unbound type variables
    497                                                         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 parameter
    503                                                         // The order is important
    504                                                         for( auto & arg : argsList ) {
    505 
    506                                                                 // Ignore non-mutex arguments
    507                                                                 if( !advance_to_mutex( param, param_end ) ) {
    508                                                                         // We ran out of parameters but still have arguments
    509                                                                         // this function doesn't match
    510                                                                         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 scope
    514                                                                 if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {
    515                                                                         // Type doesn't match
    516                                                                         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 missing
    531                                                         if( advance_to_mutex( param, param_end ) ) {
    532                                                                 // We ran out of arguments but still have parameters left
    533                                                                 // this function doesn't match
    534                                                                 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 environments
    540                                                         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 later
    546                                                         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 arguments
    561                         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 destruction
    569                         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 IfStmt
    575                         // Resolve the statments normally
    576                         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 now
    583                         // Resolve the conditions as if it were an IfStmt
    584                         // Resolve the statments normally
    585                         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 IfStmt
    592                         // Resolve the statments normally
    593                         resolveAsIf( stmt->orelse.condition, this->indexer );
    594                         stmt->orelse.statement->accept( *visitor );
    595                 }
    596         }
    597 
    598398        template< typename T >
    599399        bool isCharType( T t ) {
Note: See TracChangeset for help on using the changeset viewer.