Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r1dcd9554 ra4ca48c  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Common/PassVisitor.h"          // for PassVisitor
    2324#include "Common/SemanticError.h"        // for SemanticError
    2425#include "Common/utility.h"              // for ValueGuard, group_iterate
     
    3940#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4041#include "typeops.h"                     // for extractResultType
    41 #include "Unify.h"                       // for unify
    4242
    4343using namespace std;
    4444
    4545namespace ResolvExpr {
    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;
     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 );
    8477          private:
    8578        typedef std::list< Initializer * >::iterator InitIterator;
     
    9891
    9992        void resolve( std::list< Declaration * > translationUnit ) {
    100                 Resolver resolver;
     93                PassVisitor<Resolver> resolver;
    10194                acceptAll( translationUnit, resolver );
    10295        }
    10396
     97        // used in resolveTypeof
    10498        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
    10599                TypeEnvironment env;
    106100                return resolveInVoidContext( expr, indexer, env );
    107101        }
    108 
    109102
    110103        namespace {
     
    192185        }
    193186
    194         void Resolver::visit( ObjectDecl *objectDecl ) {
    195                 Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     187        void Resolver::previsit( ObjectDecl *objectDecl ) {
     188                Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
    196189                objectDecl->set_type( new_type );
    197190                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     
    200193                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    201194                // the RHS.
    202                 ValueGuard<CurrentObject> temp( currentObject );
     195                GuardValue( currentObject );
    203196                currentObject = CurrentObject( objectDecl->get_type() );
    204197                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     
    207200                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    208201                }
    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                 }
    214202        }
    215203
     
    218206                if ( type->get_dimension() ) {
    219207                        CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    220                         Expression *newExpr = findSingleExpression( castExpr, *this );
     208                        Expression *newExpr = findSingleExpression( castExpr, indexer );
    221209                        delete type->get_dimension();
    222210                        type->set_dimension( newExpr );
     
    224212        }
    225213
    226         void Resolver::visit( ArrayType * at ) {
     214        void Resolver::previsit( ArrayType * at ) {
    227215                handlePtrType( at );
    228                 Parent::visit( at );
    229         }
    230 
    231         void Resolver::visit( PointerType * pt ) {
     216        }
     217
     218        void Resolver::previsit( PointerType * pt ) {
    232219                handlePtrType( pt );
    233                 Parent::visit( pt );
    234         }
    235 
    236         void Resolver::visit( TypeDecl *typeDecl ) {
     220        }
     221
     222        void Resolver::previsit( TypeDecl *typeDecl ) {
    237223                if ( typeDecl->get_base() ) {
    238                         Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
     224                        Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
    239225                        typeDecl->set_base( new_type );
    240226                } // if
    241                 Parent::visit( typeDecl );
    242         }
    243 
    244         void Resolver::visit( FunctionDecl *functionDecl ) {
     227        }
     228
     229        void Resolver::previsit( FunctionDecl *functionDecl ) {
    245230#if 0
    246                 std::cout << "resolver visiting functiondecl ";
    247                 functionDecl->print( std::cout );
    248                 std::cout << std::endl;
     231                std::cerr << "resolver visiting functiondecl ";
     232                functionDecl->print( std::cerr );
     233                std::cerr << std::endl;
    249234#endif
    250                 Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
     235                Type *new_type = resolveTypeof( functionDecl->get_type(), indexer );
    251236                functionDecl->set_type( new_type );
    252                 ValueGuard< Type * > oldFunctionReturn( functionReturn );
     237                GuardValue( functionReturn );
    253238                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    254                 Parent::visit( functionDecl );
    255 
     239        }
     240
     241
     242        void Resolver::postvisit( FunctionDecl *functionDecl ) {
    256243                // default value expressions have an environment which shouldn't be there and trips up later passes.
    257244                // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
     
    267254        }
    268255
    269         void Resolver::visit( EnumDecl * enumDecl ) {
     256        void Resolver::previsit( EnumDecl * ) {
    270257                // in case we decide to allow nested enums
    271                 ValueGuard< bool > oldInEnumDecl( inEnumDecl );
     258                GuardValue( inEnumDecl );
    272259                inEnumDecl = true;
    273                 Parent::visit( enumDecl );
    274         }
    275 
    276         void Resolver::visit( ExprStmt *exprStmt ) {
     260        }
     261
     262        void Resolver::previsit( ExprStmt *exprStmt ) {
     263                visit_children = false;
    277264                assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    278                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
     265                Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
    279266                delete exprStmt->get_expr();
    280267                exprStmt->set_expr( newExpr );
    281268        }
    282269
    283         void Resolver::visit( AsmExpr *asmExpr ) {
    284                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), *this );
     270        void Resolver::previsit( AsmExpr *asmExpr ) {
     271                visit_children = false;
     272                Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
    285273                delete asmExpr->get_operand();
    286274                asmExpr->set_operand( newExpr );
    287275                if ( asmExpr->get_inout() ) {
    288                         newExpr = findVoidExpression( asmExpr->get_inout(), *this );
     276                        newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
    289277                        delete asmExpr->get_inout();
    290278                        asmExpr->set_inout( newExpr );
     
    292280        }
    293281
    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 );
     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 );
    301290                delete ifStmt->get_condition();
    302291                ifStmt->set_condition( newExpr );
    303                 Parent::visit( ifStmt );
    304         }
    305 
    306         void Resolver::visit( WhileStmt *whileStmt ) {
    307                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
     292        }
     293
     294        void Resolver::previsit( WhileStmt *whileStmt ) {
     295                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
    308296                delete whileStmt->get_condition();
    309297                whileStmt->set_condition( newExpr );
    310                 Parent::visit( whileStmt );
    311         }
    312 
    313         void Resolver::visit( ForStmt *forStmt ) {
    314                 Parent::visit( forStmt );
    315 
     298        }
     299
     300        void Resolver::previsit( ForStmt *forStmt ) {
    316301                if ( forStmt->get_condition() ) {
    317                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this );
     302                        Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
    318303                        delete forStmt->get_condition();
    319304                        forStmt->set_condition( newExpr );
     
    321306
    322307                if ( forStmt->get_increment() ) {
    323                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     308                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
    324309                        delete forStmt->get_increment();
    325310                        forStmt->set_increment( newExpr );
     
    327312        }
    328313
    329         void Resolver::visit( SwitchStmt *switchStmt ) {
    330                 ValueGuard< CurrentObject > oldCurrentObject( currentObject );
     314        void Resolver::previsit( SwitchStmt *switchStmt ) {
     315                GuardValue( currentObject );
    331316                Expression *newExpr;
    332                 newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     317                newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
    333318                delete switchStmt->get_condition();
    334319                switchStmt->set_condition( newExpr );
    335320
    336321                currentObject = CurrentObject( newExpr->get_result() );
    337                 Parent::visit( switchStmt );
    338         }
    339 
    340         void Resolver::visit( CaseStmt *caseStmt ) {
     322        }
     323
     324        void Resolver::previsit( CaseStmt *caseStmt ) {
    341325                if ( caseStmt->get_condition() ) {
    342326                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    343327                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    344328                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    345                         Expression * newExpr = findSingleExpression( castExpr, *this );
     329                        Expression * newExpr = findSingleExpression( castExpr, indexer );
    346330                        castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    347331                        caseStmt->set_condition( castExpr->get_arg() );
     
    349333                        delete castExpr;
    350334                }
    351                 Parent::visit( caseStmt );
    352         }
    353 
    354         void Resolver::visit( BranchStmt *branchStmt ) {
     335        }
     336
     337        void Resolver::previsit( BranchStmt *branchStmt ) {
     338                visit_children = false;
    355339                // must resolve the argument for a computed goto
    356340                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
     
    359343                                PointerType pt( Type::Qualifiers(), v.clone() );
    360344                                CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    361                                 Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
     345                                Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
    362346                                branchStmt->set_target( newExpr );
    363347                        } // if
     
    365349        }
    366350
    367         void Resolver::visit( ReturnStmt *returnStmt ) {
     351        void Resolver::previsit( ReturnStmt *returnStmt ) {
     352                visit_children = false;
    368353                if ( returnStmt->get_expr() ) {
    369354                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    370                         Expression *newExpr = findSingleExpression( castExpr, *this );
     355                        Expression *newExpr = findSingleExpression( castExpr, indexer );
    371356                        delete castExpr;
    372357                        returnStmt->set_expr( newExpr );
     
    374359        }
    375360
    376         void Resolver::visit( ThrowStmt *throwStmt ) {
     361        void Resolver::previsit( ThrowStmt *throwStmt ) {
     362                visit_children = false;
    377363                // TODO: Replace *exception type with &exception type.
    378364                if ( throwStmt->get_expr() ) {
    379365                        StructDecl * exception_decl =
    380                                 lookupStruct( "__cfaehm__base_exception_t" );
     366                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    381367                        assert( exception_decl );
    382368                        Expression * wrapped = new CastExpr(
     
    390376                                        )
    391377                                );
    392                         Expression * newExpr = findSingleExpression( wrapped, *this );
     378                        Expression * newExpr = findSingleExpression( wrapped, indexer );
    393379                        throwStmt->set_expr( newExpr );
    394380                }
    395381        }
    396382
    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 
     383        void Resolver::previsit( CatchStmt *catchStmt ) {
    403384                if ( catchStmt->get_cond() ) {
    404385                        Expression * wrapped = new CastExpr(
     
    406387                                new BasicType( noQualifiers, BasicType::Bool )
    407388                                );
    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 );
     389                        catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
    613390                }
    614391        }
     
    623400        }
    624401
    625         void Resolver::visit( SingleInit *singleInit ) {
     402        void Resolver::previsit( SingleInit *singleInit ) {
     403                visit_children = false;
    626404                // resolve initialization using the possibilities as determined by the currentObject cursor
    627405                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    628                 Expression * newExpr = findSingleExpression( untyped, *this );
     406                Expression * newExpr = findSingleExpression( untyped, indexer );
    629407                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    630408
     
    665443        }
    666444
    667         void Resolver::visit( ListInit * listInit ) {
     445        void Resolver::previsit( ListInit * listInit ) {
     446                visit_children = false;
    668447                // move cursor into brace-enclosed initializer-list
    669448                currentObject.enterListInit();
     
    676455                        Initializer * init = std::get<1>(p);
    677456                        newDesignations.push_back( currentObject.findNext( des ) );
    678                         init->accept( *this );
     457                        init->accept( *visitor );
    679458                }
    680459                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     
    705484                delete ctorInit->get_dtor();
    706485                ctorInit->set_dtor( NULL );
    707                 maybeAccept( ctorInit->get_init(), *this );
     486                maybeAccept( ctorInit->get_init(), *visitor );
    708487        }
    709488
     
    711490        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
    712491                assert( ctorInit );
    713                 Resolver resolver( indexer );
     492                PassVisitor<Resolver> resolver( indexer );
    714493                ctorInit->accept( resolver );
    715494        }
     
    717496        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
    718497                assert( stmtExpr );
    719                 Resolver resolver( indexer );
     498                PassVisitor<Resolver> resolver( indexer );
    720499                stmtExpr->accept( resolver );
    721500        }
    722501
    723         void Resolver::visit( ConstructorInit *ctorInit ) {
     502        void Resolver::previsit( ConstructorInit *ctorInit ) {
     503                visit_children = false;
    724504                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
    725                 maybeAccept( ctorInit->get_ctor(), *this );
    726                 maybeAccept( ctorInit->get_dtor(), *this );
     505                maybeAccept( ctorInit->get_ctor(), *visitor );
     506                maybeAccept( ctorInit->get_dtor(), *visitor );
    727507
    728508                // found a constructor - can get rid of C-style initializer
Note: See TracChangeset for help on using the changeset viewer.