Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    ra4ca48c r1dcd9554  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
    23 #include "Common/PassVisitor.h"          // for PassVisitor
    2423#include "Common/SemanticError.h"        // for SemanticError
    2524#include "Common/utility.h"              // for ValueGuard, group_iterate
     
    4039#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4140#include "typeops.h"                     // for extractResultType
     41#include "Unify.h"                       // for unify
    4242
    4343using namespace std;
    4444
    4545namespace ResolvExpr {
    46         struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {
    47                 Resolver() {}
    48                 Resolver( const SymTab::Indexer & other ) {
    49                         indexer = other;
    50                 }
    51 
    52                 void previsit( FunctionDecl *functionDecl );
    53                 void postvisit( FunctionDecl *functionDecl );
    54                 void previsit( ObjectDecl *functionDecl );
    55                 void previsit( TypeDecl *typeDecl );
    56                 void previsit( EnumDecl * enumDecl );
    57 
    58                 void previsit( ArrayType * at );
    59                 void previsit( PointerType * at );
    60 
    61                 void previsit( ExprStmt *exprStmt );
    62                 void previsit( AsmExpr *asmExpr );
    63                 void previsit( AsmStmt *asmStmt );
    64                 void previsit( IfStmt *ifStmt );
    65                 void previsit( WhileStmt *whileStmt );
    66                 void previsit( ForStmt *forStmt );
    67                 void previsit( SwitchStmt *switchStmt );
    68                 void previsit( CaseStmt *caseStmt );
    69                 void previsit( BranchStmt *branchStmt );
    70                 void previsit( ReturnStmt *returnStmt );
    71                 void previsit( ThrowStmt *throwStmt );
    72                 void previsit( CatchStmt *catchStmt );
    73 
    74                 void previsit( SingleInit *singleInit );
    75                 void previsit( ListInit *listInit );
    76                 void previsit( ConstructorInit *ctorInit );
     46        class Resolver final : public SymTab::Indexer {
     47          public:
     48                Resolver() : SymTab::Indexer( false ) {}
     49                Resolver( const SymTab:: Indexer & other ) : SymTab::Indexer( other ) {
     50                        if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
     51                                functionReturn = res->functionReturn;
     52                                currentObject = res->currentObject;
     53                                inEnumDecl = res->inEnumDecl;
     54                        }
     55                }
     56
     57                typedef SymTab::Indexer Parent;
     58                using Parent::visit;
     59                virtual void visit( FunctionDecl *functionDecl ) override;
     60                virtual void visit( ObjectDecl *functionDecl ) override;
     61                virtual void visit( TypeDecl *typeDecl ) override;
     62                virtual void visit( EnumDecl * enumDecl ) override;
     63
     64                virtual void visit( ArrayType * at ) override;
     65                virtual void visit( PointerType * at ) override;
     66
     67                virtual void visit( ExprStmt *exprStmt ) override;
     68                virtual void visit( AsmExpr *asmExpr ) override;
     69                virtual void visit( AsmStmt *asmStmt ) override;
     70                virtual void visit( IfStmt *ifStmt ) override;
     71                virtual void visit( WhileStmt *whileStmt ) override;
     72                virtual void visit( ForStmt *forStmt ) override;
     73                virtual void visit( SwitchStmt *switchStmt ) override;
     74                virtual void visit( CaseStmt *caseStmt ) override;
     75                virtual void visit( BranchStmt *branchStmt ) override;
     76                virtual void visit( ReturnStmt *returnStmt ) override;
     77                virtual void visit( ThrowStmt *throwStmt ) override;
     78                virtual void visit( CatchStmt *catchStmt ) override;
     79                virtual void visit( WaitForStmt *waitforStmt ) override;
     80
     81                virtual void visit( SingleInit *singleInit ) override;
     82                virtual void visit( ListInit *listInit ) override;
     83                virtual void visit( ConstructorInit *ctorInit ) override;
    7784          private:
    7885        typedef std::list< Initializer * >::iterator InitIterator;
     
    9198
    9299        void resolve( std::list< Declaration * > translationUnit ) {
    93                 PassVisitor<Resolver> resolver;
     100                Resolver resolver;
    94101                acceptAll( translationUnit, resolver );
    95102        }
    96103
    97         // used in resolveTypeof
    98104        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
    99105                TypeEnvironment env;
    100106                return resolveInVoidContext( expr, indexer, env );
    101107        }
     108
    102109
    103110        namespace {
     
    185192        }
    186193
    187         void Resolver::previsit( ObjectDecl *objectDecl ) {
    188                 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
     194        void Resolver::visit( ObjectDecl *objectDecl ) {
     195                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
    189196                objectDecl->set_type( new_type );
    190197                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     
    193200                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    194201                // the RHS.
    195                 GuardValue( currentObject );
     202                ValueGuard<CurrentObject> temp( currentObject );
    196203                currentObject = CurrentObject( objectDecl->get_type() );
    197204                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     
    200207                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    201208                }
     209                Parent::visit( objectDecl );
     210                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     211                        // delete newly created signed int type
     212                        // delete currentObject.getType();
     213                }
    202214        }
    203215
     
    206218                if ( type->get_dimension() ) {
    207219                        CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    208                         Expression *newExpr = findSingleExpression( castExpr, indexer );
     220                        Expression *newExpr = findSingleExpression( castExpr, *this );
    209221                        delete type->get_dimension();
    210222                        type->set_dimension( newExpr );
     
    212224        }
    213225
    214         void Resolver::previsit( ArrayType * at ) {
     226        void Resolver::visit( ArrayType * at ) {
    215227                handlePtrType( at );
    216         }
    217 
    218         void Resolver::previsit( PointerType * pt ) {
     228                Parent::visit( at );
     229        }
     230
     231        void Resolver::visit( PointerType * pt ) {
    219232                handlePtrType( pt );
    220         }
    221 
    222         void Resolver::previsit( TypeDecl *typeDecl ) {
     233                Parent::visit( pt );
     234        }
     235
     236        void Resolver::visit( TypeDecl *typeDecl ) {
    223237                if ( typeDecl->get_base() ) {
    224                         Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
     238                        Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
    225239                        typeDecl->set_base( new_type );
    226240                } // if
    227         }
    228 
    229         void Resolver::previsit( FunctionDecl *functionDecl ) {
     241                Parent::visit( typeDecl );
     242        }
     243
     244        void Resolver::visit( FunctionDecl *functionDecl ) {
    230245#if 0
    231                 std::cerr << "resolver visiting functiondecl ";
    232                 functionDecl->print( std::cerr );
    233                 std::cerr << std::endl;
     246                std::cout << "resolver visiting functiondecl ";
     247                functionDecl->print( std::cout );
     248                std::cout << std::endl;
    234249#endif
    235                 Type *new_type = resolveTypeof( functionDecl->get_type(), indexer );
     250                Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    236251                functionDecl->set_type( new_type );
    237                 GuardValue( functionReturn );
     252                ValueGuard< Type * > oldFunctionReturn( functionReturn );
    238253                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    239         }
    240 
    241 
    242         void Resolver::postvisit( FunctionDecl *functionDecl ) {
     254                Parent::visit( functionDecl );
     255
    243256                // default value expressions have an environment which shouldn't be there and trips up later passes.
    244257                // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
     
    254267        }
    255268
    256         void Resolver::previsit( EnumDecl * ) {
     269        void Resolver::visit( EnumDecl * enumDecl ) {
    257270                // in case we decide to allow nested enums
    258                 GuardValue( inEnumDecl );
     271                ValueGuard< bool > oldInEnumDecl( inEnumDecl );
    259272                inEnumDecl = true;
    260         }
    261 
    262         void Resolver::previsit( ExprStmt *exprStmt ) {
    263                 visit_children = false;
     273                Parent::visit( enumDecl );
     274        }
     275
     276        void Resolver::visit( ExprStmt *exprStmt ) {
    264277                assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    265                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
     278                Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
    266279                delete exprStmt->get_expr();
    267280                exprStmt->set_expr( newExpr );
    268281        }
    269282
    270         void Resolver::previsit( AsmExpr *asmExpr ) {
    271                 visit_children = false;
    272                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
     283        void Resolver::visit( AsmExpr *asmExpr ) {
     284                Expression *newExpr = findVoidExpression( asmExpr->get_operand(), *this );
    273285                delete asmExpr->get_operand();
    274286                asmExpr->set_operand( newExpr );
    275287                if ( asmExpr->get_inout() ) {
    276                         newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
     288                        newExpr = findVoidExpression( asmExpr->get_inout(), *this );
    277289                        delete asmExpr->get_inout();
    278290                        asmExpr->set_inout( newExpr );
     
    280292        }
    281293
    282         void Resolver::previsit( AsmStmt *asmStmt ) {
    283                 visit_children = false;
    284                 acceptAll( asmStmt->get_input(), *visitor );
    285                 acceptAll( asmStmt->get_output(), *visitor );
    286         }
    287 
    288         void Resolver::previsit( IfStmt *ifStmt ) {
    289                 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
     294        void Resolver::visit( AsmStmt *asmStmt ) {
     295                acceptAll( asmStmt->get_input(), *this);
     296                acceptAll( asmStmt->get_output(), *this);
     297        }
     298
     299        void Resolver::visit( IfStmt *ifStmt ) {
     300                Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
    290301                delete ifStmt->get_condition();
    291302                ifStmt->set_condition( newExpr );
    292         }
    293 
    294         void Resolver::previsit( WhileStmt *whileStmt ) {
    295                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
     303                Parent::visit( ifStmt );
     304        }
     305
     306        void Resolver::visit( WhileStmt *whileStmt ) {
     307                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
    296308                delete whileStmt->get_condition();
    297309                whileStmt->set_condition( newExpr );
    298         }
    299 
    300         void Resolver::previsit( ForStmt *forStmt ) {
     310                Parent::visit( whileStmt );
     311        }
     312
     313        void Resolver::visit( ForStmt *forStmt ) {
     314                Parent::visit( forStmt );
     315
    301316                if ( forStmt->get_condition() ) {
    302                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
     317                        Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this );
    303318                        delete forStmt->get_condition();
    304319                        forStmt->set_condition( newExpr );
     
    306321
    307322                if ( forStmt->get_increment() ) {
    308                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
     323                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
    309324                        delete forStmt->get_increment();
    310325                        forStmt->set_increment( newExpr );
     
    312327        }
    313328
    314         void Resolver::previsit( SwitchStmt *switchStmt ) {
    315                 GuardValue( currentObject );
     329        void Resolver::visit( SwitchStmt *switchStmt ) {
     330                ValueGuard< CurrentObject > oldCurrentObject( currentObject );
    316331                Expression *newExpr;
    317                 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
     332                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
    318333                delete switchStmt->get_condition();
    319334                switchStmt->set_condition( newExpr );
    320335
    321336                currentObject = CurrentObject( newExpr->get_result() );
    322         }
    323 
    324         void Resolver::previsit( CaseStmt *caseStmt ) {
     337                Parent::visit( switchStmt );
     338        }
     339
     340        void Resolver::visit( CaseStmt *caseStmt ) {
    325341                if ( caseStmt->get_condition() ) {
    326342                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    327343                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    328344                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    329                         Expression * newExpr = findSingleExpression( castExpr, indexer );
     345                        Expression * newExpr = findSingleExpression( castExpr, *this );
    330346                        castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    331347                        caseStmt->set_condition( castExpr->get_arg() );
     
    333349                        delete castExpr;
    334350                }
    335         }
    336 
    337         void Resolver::previsit( BranchStmt *branchStmt ) {
    338                 visit_children = false;
     351                Parent::visit( caseStmt );
     352        }
     353
     354        void Resolver::visit( BranchStmt *branchStmt ) {
    339355                // must resolve the argument for a computed goto
    340356                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
     
    343359                                PointerType pt( Type::Qualifiers(), v.clone() );
    344360                                CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    345                                 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
     361                                Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
    346362                                branchStmt->set_target( newExpr );
    347363                        } // if
     
    349365        }
    350366
    351         void Resolver::previsit( ReturnStmt *returnStmt ) {
    352                 visit_children = false;
     367        void Resolver::visit( ReturnStmt *returnStmt ) {
    353368                if ( returnStmt->get_expr() ) {
    354369                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    355                         Expression *newExpr = findSingleExpression( castExpr, indexer );
     370                        Expression *newExpr = findSingleExpression( castExpr, *this );
    356371                        delete castExpr;
    357372                        returnStmt->set_expr( newExpr );
     
    359374        }
    360375
    361         void Resolver::previsit( ThrowStmt *throwStmt ) {
    362                 visit_children = false;
     376        void Resolver::visit( ThrowStmt *throwStmt ) {
    363377                // TODO: Replace *exception type with &exception type.
    364378                if ( throwStmt->get_expr() ) {
    365379                        StructDecl * exception_decl =
    366                                 indexer.lookupStruct( "__cfaehm__base_exception_t" );
     380                                lookupStruct( "__cfaehm__base_exception_t" );
    367381                        assert( exception_decl );
    368382                        Expression * wrapped = new CastExpr(
     
    376390                                        )
    377391                                );
    378                         Expression * newExpr = findSingleExpression( wrapped, indexer );
     392                        Expression * newExpr = findSingleExpression( wrapped, *this );
    379393                        throwStmt->set_expr( newExpr );
    380394                }
    381395        }
    382396
    383         void Resolver::previsit( CatchStmt *catchStmt ) {
     397        void Resolver::visit( CatchStmt *catchStmt ) {
     398                // inline Indexer::visit so that the exception variable is still in-scope for
     399                // findSingleExpression() below
     400                Parent::enterScope();
     401                Visitor::visit( catchStmt );
     402
    384403                if ( catchStmt->get_cond() ) {
    385404                        Expression * wrapped = new CastExpr(
     
    387406                                new BasicType( noQualifiers, BasicType::Bool )
    388407                                );
    389                         catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
     408                        catchStmt->set_cond( findSingleExpression( wrapped, *this ) );
     409                }
     410
     411                Parent::leaveScope();
     412        }
     413
     414        inline void resolveAsIf( Expression *& expr, Resolver & resolver ) {
     415                if( !expr ) return;
     416                Expression * newExpr = findSingleExpression( expr, resolver );
     417                delete expr;
     418                expr = newExpr;
     419        }
     420
     421        inline void resolveAsType( Expression *& expr, Type * type, Resolver & resolver ) {
     422                if( !expr ) return;
     423                Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), resolver );
     424                delete expr;
     425                expr = newExpr;
     426        }
     427
     428        template< typename iterator_t >
     429        inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {
     430                while( it != end && !(*it)->get_type()->get_mutex() ) {
     431                        it++;
     432                }
     433
     434                return it != end;
     435        }
     436
     437        void Resolver::visit( WaitForStmt * stmt ) {
     438
     439                // Resolve all clauses first
     440                for( auto& clause : stmt->clauses ) {
     441
     442                        TypeEnvironment env;
     443                        AlternativeFinder funcFinder( *this, env );
     444
     445                        // Find all alternatives for a function in canonical form
     446                        funcFinder.findWithAdjustment( clause.target.function );
     447
     448                        if ( funcFinder.get_alternatives().empty() ) {
     449                                stringstream ss;
     450                                ss << "Use of undeclared indentifier '";
     451                                ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;
     452                                ss << "' in call to waitfor";
     453                                throw SemanticError( ss.str() );
     454                        }
     455
     456                        // Find all alternatives for all arguments in canonical form
     457                        std::list< AlternativeFinder > argAlternatives;
     458                        funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );
     459
     460                        // List all combinations of arguments
     461                        std::list< AltList > possibilities;
     462                        combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     463
     464                        AltList                func_candidates;
     465                        std::vector< AltList > args_candidates;
     466
     467                        // For every possible function :
     468                        //      try matching the arguments to the parameters
     469                        //      not the other way around because we have more arguments than parameters
     470                        SemanticError errors;
     471                        for ( Alternative & func : funcFinder.get_alternatives() ) {
     472                                try {
     473                                        PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );
     474                                        if( !pointer ) {
     475                                                throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );
     476                                        }
     477
     478                                        FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );
     479                                        if( !function ) {
     480                                                throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );
     481                                        }
     482
     483
     484                                        {
     485                                                auto param     = function->parameters.begin();
     486                                                auto param_end = function->parameters.end();
     487
     488                                                if( !advance_to_mutex( param, param_end ) ) {
     489                                                        throw SemanticError("candidate function not viable: no mutex parameters\n", function);
     490                                                }
     491                                        }
     492
     493                                        Alternative newFunc( func );
     494                                        // Strip reference from function
     495                                        referenceToRvalueConversion( newFunc.expr );
     496
     497                                        // For all the set of arguments we have try to match it with the parameter of the current function alternative
     498                                        for ( auto & argsList : possibilities ) {
     499
     500                                                try {
     501                                                        // Declare data structures need for resolution
     502                                                        OpenVarSet openVars;
     503                                                        AssertionSet resultNeed, resultHave;
     504                                                        TypeEnvironment resultEnv;
     505
     506                                                        // Load type variables from arguemnts into one shared space
     507                                                        simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );
     508
     509                                                        // Make sure we don't widen any existing bindings
     510                                                        for ( auto & i : resultEnv ) {
     511                                                                i.allowWidening = false;
     512                                                        }
     513
     514                                                        // Find any unbound type variables
     515                                                        resultEnv.extractOpenVars( openVars );
     516
     517                                                        auto param     = function->parameters.begin();
     518                                                        auto param_end = function->parameters.end();
     519
     520                                                        // For every arguments of its set, check if it matches one of the parameter
     521                                                        // The order is important
     522                                                        for( auto & arg : argsList ) {
     523
     524                                                                // Ignore non-mutex arguments
     525                                                                if( !advance_to_mutex( param, param_end ) ) {
     526                                                                        // We ran out of parameters but still have arguments
     527                                                                        // this function doesn't match
     528                                                                        throw SemanticError("candidate function not viable: too many mutex arguments\n", function);
     529                                                                }
     530
     531                                                                // Check if the argument matches the parameter type in the current scope
     532                                                                if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, *this ) ) {
     533                                                                        // Type doesn't match
     534                                                                        stringstream ss;
     535                                                                        ss << "candidate function not viable: no known convertion from '";
     536                                                                        arg.expr->get_result()->print( ss );
     537                                                                        ss << "' to '";
     538                                                                        (*param)->get_type()->print( ss );
     539                                                                        ss << "'\n";
     540                                                                        throw SemanticError(ss.str(), function);
     541                                                                }
     542
     543                                                                param++;
     544                                                        }
     545
     546                                                        // All arguments match !
     547
     548                                                        // Check if parameters are missing
     549                                                        if( advance_to_mutex( param, param_end ) ) {
     550                                                                // We ran out of arguments but still have parameters left
     551                                                                // this function doesn't match
     552                                                                throw SemanticError("candidate function not viable: too few mutex arguments\n", function);
     553                                                        }
     554
     555                                                        // All parameters match !
     556
     557                                                        // Finish the expressions to tie in the proper environments
     558                                                        finishExpr( newFunc.expr, resultEnv );
     559                                                        for( Alternative & alt : argsList ) {
     560                                                                finishExpr( alt.expr, resultEnv );
     561                                                        }
     562
     563                                                        // This is a match store it and save it for later
     564                                                        func_candidates.push_back( newFunc );
     565                                                        args_candidates.push_back( argsList );
     566
     567                                                }
     568                                                catch( SemanticError &e ) {
     569                                                        errors.append( e );
     570                                                }
     571                                        }
     572                                }
     573                                catch( SemanticError &e ) {
     574                                        errors.append( e );
     575                                }
     576                        }
     577
     578                        // Make sure we got the right number of arguments
     579                        if( func_candidates.empty() )    { SemanticError top( "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
     580                        if( args_candidates.empty() )    { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
     581                        if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
     582                        if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
     583
     584
     585                        // Swap the results from the alternative with the unresolved values.
     586                        // Alternatives will handle deletion on destruction
     587                        std::swap( clause.target.function, func_candidates.front().expr );
     588                        for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {
     589                                std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );
     590                        }
     591
     592                        // Resolve the conditions as if it were an IfStmt
     593                        // Resolve the statments normally
     594                        resolveAsIf( clause.condition, *this );
     595                        clause.statement->accept( *this );
     596                }
     597
     598
     599                if( stmt->timeout.statement ) {
     600                        // Resolve the timeout as an size_t for now
     601                        // Resolve the conditions as if it were an IfStmt
     602                        // Resolve the statments normally
     603                        resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), *this );
     604                        resolveAsIf  ( stmt->timeout.condition, *this );
     605                        stmt->timeout.statement->accept( *this );
     606                }
     607
     608                if( stmt->orelse.statement ) {
     609                        // Resolve the conditions as if it were an IfStmt
     610                        // Resolve the statments normally
     611                        resolveAsIf( stmt->orelse.condition, *this );
     612                        stmt->orelse.statement->accept( *this );
    390613                }
    391614        }
     
    400623        }
    401624
    402         void Resolver::previsit( SingleInit *singleInit ) {
    403                 visit_children = false;
     625        void Resolver::visit( SingleInit *singleInit ) {
    404626                // resolve initialization using the possibilities as determined by the currentObject cursor
    405627                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    406                 Expression * newExpr = findSingleExpression( untyped, indexer );
     628                Expression * newExpr = findSingleExpression( untyped, *this );
    407629                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    408630
     
    443665        }
    444666
    445         void Resolver::previsit( ListInit * listInit ) {
    446                 visit_children = false;
     667        void Resolver::visit( ListInit * listInit ) {
    447668                // move cursor into brace-enclosed initializer-list
    448669                currentObject.enterListInit();
     
    455676                        Initializer * init = std::get<1>(p);
    456677                        newDesignations.push_back( currentObject.findNext( des ) );
    457                         init->accept( *visitor );
     678                        init->accept( *this );
    458679                }
    459680                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     
    484705                delete ctorInit->get_dtor();
    485706                ctorInit->set_dtor( NULL );
    486                 maybeAccept( ctorInit->get_init(), *visitor );
     707                maybeAccept( ctorInit->get_init(), *this );
    487708        }
    488709
     
    490711        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
    491712                assert( ctorInit );
    492                 PassVisitor<Resolver> resolver( indexer );
     713                Resolver resolver( indexer );
    493714                ctorInit->accept( resolver );
    494715        }
     
    496717        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
    497718                assert( stmtExpr );
    498                 PassVisitor<Resolver> resolver( indexer );
     719                Resolver resolver( indexer );
    499720                stmtExpr->accept( resolver );
    500721        }
    501722
    502         void Resolver::previsit( ConstructorInit *ctorInit ) {
    503                 visit_children = false;
     723        void Resolver::visit( ConstructorInit *ctorInit ) {
    504724                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
    505                 maybeAccept( ctorInit->get_ctor(), *visitor );
    506                 maybeAccept( ctorInit->get_dtor(), *visitor );
     725                maybeAccept( ctorInit->get_ctor(), *this );
     726                maybeAccept( ctorInit->get_dtor(), *this );
    507727
    508728                // found a constructor - can get rid of C-style initializer
Note: See TracChangeset for help on using the changeset viewer.