Changeset ba54f7d for src/Common


Ignore:
Timestamp:
Sep 13, 2017, 3:11:24 PM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
c57ded70, db70fe4
Parents:
d130fe8 (diff), 982832e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg2:software/cfa/cfa-cc

Location:
src/Common
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.h

    rd130fe8 rba54f7d  
    77#include "SynTree/Mutator.h"
    88#include "SynTree/Visitor.h"
     9
     10#include "SymTab/Indexer.h"
    911
    1012#include "SynTree/Initializer.h"
     
    265267
    266268        void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
     269
     270        void indexerScopeEnter  ()                             { indexer_impl_enterScope  ( pass, 0       ); }
     271        void indexerScopeLeave  ()                             { indexer_impl_leaveScope  ( pass, 0       ); }
     272        void indexerAddId       ( DeclarationWithType * node ) { indexer_impl_addId       ( pass, 0, node ); }
     273        void indexerAddType     ( NamedTypeDecl       * node ) { indexer_impl_addType     ( pass, 0, node ); }
     274        void indexerAddStruct   ( const std::string   & id   ) { indexer_impl_addStruct   ( pass, 0, id   ); }
     275        void indexerAddStruct   ( StructDecl          * node ) { indexer_impl_addStruct   ( pass, 0, node ); }
     276        void indexerAddStructFwd( StructDecl          * node ) { indexer_impl_addStructFwd( pass, 0, node ); }
     277        void indexerAddEnum     ( EnumDecl            * node ) { indexer_impl_addEnum     ( pass, 0, node ); }
     278        void indexerAddUnion    ( const std::string   & id   ) { indexer_impl_addUnion    ( pass, 0, id   ); }
     279        void indexerAddUnion    ( UnionDecl           * node ) { indexer_impl_addUnion    ( pass, 0, node ); }
     280        void indexerAddUnionFwd ( UnionDecl           * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
     281        void indexerAddTrait    ( TraitDecl           * node ) { indexer_impl_addTrait    ( pass, 0, node ); }
     282
     283        template< typename TreeType, typename VisitorType >
     284        friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor );
     285
     286        template< typename TreeType, typename VisitorType >
     287        friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor );
    267288};
    268289
     
    296317protected:
    297318        WithDeclsToAdd() = default;
    298         ~WithDeclsToAdd() = default;
     319        ~WithDeclsToAdd() {
     320                assert( declsToAddBefore.empty() );
     321        }
    299322
    300323public:
     
    351374};
    352375
     376class WithIndexer {
     377protected:
     378        WithIndexer() {}
     379        ~WithIndexer() {}
     380
     381public:
     382        SymTab::Indexer indexer;
     383};
     384
    353385#include "PassVisitor.impl.h"
  • src/Common/PassVisitor.impl.h

    rd130fe8 rba54f7d  
    101101}
    102102
     103template< typename Container, typename VisitorType >
     104inline void maybeAccept( Container &container, VisitorType &visitor ) {
     105        SemanticError errors;
     106        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
     107                try {
     108                        if ( *i ) {
     109                                (*i)->accept( visitor );
     110                        }
     111                } catch( SemanticError &e ) {
     112                        e.set_location( (*i)->location );
     113                        errors.append( e );
     114                }
     115        }
     116        if ( ! errors.isEmpty() ) {
     117                throw errors;
     118        }
     119}
     120
     121template< typename Container, typename MutatorType >
     122inline void maybeMutateRef( Container &container, MutatorType &mutator ) {
     123        SemanticError errors;
     124        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
     125                try {
     126                        if ( *i ) {
     127///                 *i = (*i)->acceptMutator( mutator );
     128                                *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
     129                                assert( *i );
     130                        } // if
     131                } catch( SemanticError &e ) {
     132                        e.set_location( (*i)->location );
     133                        errors.append( e );
     134                } // try
     135        } // for
     136        if ( ! errors.isEmpty() ) {
     137                throw errors;
     138        } // if
     139}
     140
    103141template< typename pass_type >
    104142template< typename func_t >
     
    230268
    231269//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    232 
     270//========================================================================================================================================================================
     271//========================================================================================================================================================================
     272//========================================================================================================================================================================
     273//========================================================================================================================================================================
     274//========================================================================================================================================================================
     275//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     276
     277
     278//--------------------------------------------------------------------------
     279// ObjectDecl
    233280template< typename pass_type >
    234281void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
    235         VISIT_BODY( node );
    236 }
    237 
     282        VISIT_START( node );
     283
     284        indexerScopedAccept( node->type         , *this );
     285        maybeAccept        ( node->init         , *this );
     286        maybeAccept        ( node->bitfieldWidth, *this );
     287
     288        if ( node->name != "" ) {
     289                indexerAddId( node );
     290        }
     291
     292        VISIT_END( node );
     293}
     294
     295template< typename pass_type >
     296DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
     297        MUTATE_START( node );
     298
     299        indexerScopedMutate( node->type         , *this );
     300        maybeMutateRef     ( node->init         , *this );
     301        maybeMutateRef     ( node->bitfieldWidth, *this );
     302
     303        if ( node->name != "" ) {
     304                indexerAddId( node );
     305        }
     306
     307        MUTATE_END( DeclarationWithType, node );
     308}
     309
     310//--------------------------------------------------------------------------
     311// FunctionDecl
    238312template< typename pass_type >
    239313void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
    240         VISIT_BODY( node );
    241 }
    242 
     314        VISIT_START( node );
     315
     316        if ( node->name != "" ) {
     317                indexerAddId( node );
     318        }
     319
     320        {
     321                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     322                maybeAccept( node->type, *this );
     323                maybeAccept( node->statements, *this );
     324        }
     325
     326        VISIT_END( node );
     327}
     328
     329template< typename pass_type >
     330DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
     331        MUTATE_START( node );
     332
     333        if ( node->name != "" ) {
     334                indexerAddId( node );
     335        }
     336
     337        {
     338                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     339                maybeMutateRef( node->type, *this );
     340                maybeMutateRef( node->statements, *this );
     341        }
     342
     343        MUTATE_END( DeclarationWithType, node );
     344}
     345
     346//--------------------------------------------------------------------------
     347// StructDecl
    243348template< typename pass_type >
    244349void PassVisitor< pass_type >::visit( StructDecl * node ) {
    245         VISIT_BODY( node );
    246 }
    247 
     350        VISIT_START( node );
     351
     352        // make up a forward declaration and add it before processing the members
     353        // needs to be on the heap because addStruct saves the pointer
     354        indexerAddStructFwd( node );
     355
     356        {
     357                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     358                maybeAccept( node->parameters, *this );
     359                maybeAccept( node->members   , *this );
     360        }
     361
     362        // this addition replaces the forward declaration
     363        indexerAddStruct( node );
     364
     365        VISIT_END( node );
     366}
     367
     368template< typename pass_type >
     369Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     370        MUTATE_START( node );
     371
     372        // make up a forward declaration and add it before processing the members
     373        // needs to be on the heap because addStruct saves the pointer
     374        indexerAddStructFwd( node );
     375
     376        {
     377                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     378                maybeMutateRef( node->parameters, *this );
     379                maybeMutateRef( node->members   , *this );
     380        }
     381
     382        // this addition replaces the forward declaration
     383        indexerAddStruct( node );
     384
     385        MUTATE_END( Declaration, node );
     386}
     387
     388//--------------------------------------------------------------------------
     389// UnionDecl
    248390template< typename pass_type >
    249391void PassVisitor< pass_type >::visit( UnionDecl * node ) {
    250         VISIT_BODY( node );
    251 }
    252 
     392        VISIT_START( node );
     393
     394        // make up a forward declaration and add it before processing the members
     395        indexerAddUnionFwd( node );
     396
     397        {
     398                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     399                maybeAccept( node->parameters, *this );
     400                maybeAccept( node->members   , *this );
     401        }
     402
     403        indexerAddUnion( node );
     404
     405        VISIT_END( node );
     406}
     407
     408template< typename pass_type >
     409Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
     410        MUTATE_START( node );
     411
     412        // make up a forward declaration and add it before processing the members
     413        indexerAddUnionFwd( node );
     414
     415        {
     416                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     417                maybeMutateRef( node->parameters, *this );
     418                maybeMutateRef( node->members   , *this );
     419        }
     420
     421        indexerAddUnion( node );
     422
     423        MUTATE_END( Declaration, node );
     424}
     425
     426//--------------------------------------------------------------------------
     427// EnumDecl
    253428template< typename pass_type >
    254429void PassVisitor< pass_type >::visit( EnumDecl * node ) {
    255         VISIT_BODY( node );
    256 }
    257 
     430        VISIT_START( node );
     431
     432        indexerAddEnum( node );
     433
     434        // unlike structs, contexts, and unions, enums inject their members into the global scope
     435        maybeAccept( node->parameters, *this );
     436        maybeAccept( node->members   , *this );
     437
     438        VISIT_END( node );
     439}
     440
     441template< typename pass_type >
     442Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
     443        MUTATE_START( node );
     444
     445        indexerAddEnum( node );
     446
     447        // unlike structs, contexts, and unions, enums inject their members into the global scope
     448        maybeMutateRef( node->parameters, *this );
     449        maybeMutateRef( node->members   , *this );
     450
     451        MUTATE_END( Declaration, node );
     452}
     453
     454//--------------------------------------------------------------------------
     455// TraitDecl
    258456template< typename pass_type >
    259457void PassVisitor< pass_type >::visit( TraitDecl * node ) {
    260         VISIT_BODY( node );
    261 }
    262 
     458        VISIT_START( node );
     459
     460        {
     461                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     462                maybeAccept( node->parameters, *this );
     463                maybeAccept( node->members   , *this );
     464        }
     465
     466        indexerAddTrait( node );
     467
     468        VISIT_END( node );
     469}
     470
     471template< typename pass_type >
     472Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
     473        MUTATE_START( node );
     474
     475        {
     476                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     477                maybeMutateRef( node->parameters, *this );
     478                maybeMutateRef( node->members   , *this );
     479        }
     480
     481        indexerAddTrait( node );
     482
     483        MUTATE_END( Declaration, node );
     484}
     485
     486//--------------------------------------------------------------------------
     487// TypeDecl
    263488template< typename pass_type >
    264489void PassVisitor< pass_type >::visit( TypeDecl * node ) {
    265         VISIT_BODY( node );
    266 }
    267 
     490        VISIT_START( node );
     491
     492        {
     493                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     494                maybeAccept( node->parameters, *this );
     495                maybeAccept( node->base      , *this );
     496        }
     497
     498        indexerAddType( node );
     499
     500        maybeAccept( node->assertions, *this );
     501
     502        indexerScopedAccept( node->init, *this );
     503
     504        VISIT_END( node );
     505}
     506
     507template< typename pass_type >
     508Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     509        MUTATE_START( node );
     510
     511        {
     512                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     513                maybeMutateRef( node->parameters, *this );
     514                maybeMutateRef( node->base      , *this );
     515        }
     516
     517        indexerAddType( node );
     518
     519        maybeMutateRef( node->assertions, *this );
     520
     521        indexerScopedMutate( node->init, *this );
     522
     523        MUTATE_END( Declaration, node );
     524}
     525
     526//--------------------------------------------------------------------------
     527// TypedefDecl
    268528template< typename pass_type >
    269529void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
    270         VISIT_BODY( node );
    271 }
    272 
     530        VISIT_START( node );
     531
     532        {
     533                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     534                maybeAccept( node->parameters, *this );
     535                maybeAccept( node->base      , *this );
     536        }
     537
     538        indexerAddType( node );
     539
     540        maybeAccept( node->assertions, *this );
     541
     542        VISIT_END( node );
     543}
     544
     545template< typename pass_type >
     546Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
     547        MUTATE_START( node );
     548
     549        {
     550                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     551                maybeMutateRef     ( node->parameters, *this );
     552                maybeMutateRef( node->base      , *this );
     553        }
     554
     555        indexerAddType( node );
     556
     557        maybeMutateRef( node->assertions, *this );
     558
     559        MUTATE_END( Declaration, node );
     560}
     561
     562//--------------------------------------------------------------------------
     563// AsmDecl
    273564template< typename pass_type >
    274565void PassVisitor< pass_type >::visit( AsmDecl * node ) {
    275         VISIT_BODY( node );
     566        VISIT_START( node );
     567
     568        maybeAccept( node->stmt, *this );
     569
     570        VISIT_END( node );
     571}
     572
     573template< typename pass_type >
     574AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
     575        MUTATE_START( node );
     576
     577        maybeMutateRef( node->stmt, *this );
     578
     579        MUTATE_END( AsmDecl, node );
    276580}
    277581
     
    281585void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
    282586        VISIT_START( node );
    283         call_beginScope();
    284 
    285         visitStatementList( node->get_kids() );
    286 
    287         call_endScope();
     587        {
     588                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     589                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     590                visitStatementList( node->kids );
     591        }
    288592        VISIT_END( node );
    289593}
     
    292596CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
    293597        MUTATE_START( node );
    294         call_beginScope();
    295 
    296         mutateStatementList( node->get_kids() );
    297 
    298         call_endScope();
     598        {
     599                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     600                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     601                mutateStatementList( node->kids );
     602        }
    299603        MUTATE_END( CompoundStmt, node );
    300604}
     
    306610        VISIT_START( node );
    307611
    308         visitExpression( node->get_expr() );
     612        visitExpression( node->expr );
    309613
    310614        VISIT_END( node );
     
    315619        MUTATE_START( node );
    316620
    317         node->set_expr( mutateExpression( node->get_expr() ) );
     621        node->expr = mutateExpression( node->expr );
    318622
    319623        MUTATE_END( Statement, node );
     
    338642        VISIT_START( node );
    339643
    340         visitExpression( node->get_condition() );
    341         node->set_thenPart ( visitStatement( node->get_thenPart() ) );
    342         node->set_elsePart ( visitStatement( node->get_elsePart() ) );
     644        visitExpression( node->condition );
     645        node->thenPart = visitStatement( node->thenPart );
     646        node->elsePart = visitStatement( node->elsePart );
    343647
    344648        VISIT_END( node );
     
    348652Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    349653        MUTATE_START( node );
    350 
    351         node->set_condition( mutateExpression( node->get_condition() ) );
    352         node->set_thenPart ( mutateStatement ( node->get_thenPart()  ) );
    353         node->set_elsePart ( mutateStatement ( node->get_elsePart()  ) );
    354 
     654        {
     655                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     656                node->condition = mutateExpression( node->condition );
     657                node->thenPart  = mutateStatement ( node->thenPart  );
     658                node->elsePart  = mutateStatement ( node->elsePart  );
     659        }
    355660        MUTATE_END( Statement, node );
    356661}
     
    362667        VISIT_START( node );
    363668
    364         visitExpression( node->get_condition() );
    365         node->set_body( visitStatement( node->get_body() ) );
     669        visitExpression( node->condition );
     670        node->body = visitStatement( node->body );
    366671
    367672        VISIT_END( node );
     
    372677        MUTATE_START( node );
    373678
    374         node->set_condition( mutateExpression( node->get_condition() ) );
    375         node->set_body( mutateStatement( node->get_body() ) );
     679        node->condition = mutateExpression( node->condition );
     680        node->body      = mutateStatement ( node->body      );
    376681
    377682        MUTATE_END( Statement, node );
     
    383688void PassVisitor< pass_type >::visit( ForStmt * node ) {
    384689        VISIT_START( node );
    385 
    386         acceptAll( node->get_initialization(), *this );
    387         visitExpression( node->get_condition() );
    388         visitExpression( node->get_increment() );
    389         node->set_body( visitStatement( node->get_body() ) );
    390 
     690        {
     691                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     692                maybeAccept( node->initialization, *this );
     693                visitExpression( node->condition );
     694                visitExpression( node->increment );
     695                node->body = visitStatement( node->body );
     696        }
    391697        VISIT_END( node );
    392698}
     
    395701Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    396702        MUTATE_START( node );
    397 
    398         mutateAll( node->get_initialization(), *this );
    399         node->set_condition( mutateExpression( node->get_condition() ) );
    400         node->set_increment( mutateExpression( node->get_increment() ) );
    401         node->set_body( mutateStatement( node->get_body() ) );
    402 
     703        {
     704                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     705                maybeMutateRef( node->initialization, *this );
     706                node->condition = mutateExpression( node->condition );
     707                node->increment = mutateExpression( node->increment );
     708                node->body      = mutateStatement ( node->body      );
     709        }
    403710        MUTATE_END( Statement, node );
    404711}
     
    410717        VISIT_START( node );
    411718
    412         visitExpression( node->get_condition() );
    413         visitStatementList( node->get_statements() );
     719        visitExpression   ( node->condition );
     720        visitStatementList( node->statements );
    414721
    415722        VISIT_END( node );
     
    420727        MUTATE_START( node );
    421728
    422         node->set_condition( mutateExpression( node->get_condition() ) );
    423         mutateStatementList( node->get_statements() );
     729        node->condition = mutateExpression( node->condition );
     730        mutateStatementList( node->statements );
    424731
    425732        MUTATE_END( Statement, node );
     
    432739        VISIT_START( node );
    433740
    434         visitExpression( node->get_condition() );
    435         visitStatementList( node->get_statements() );
     741        visitExpression   ( node->condition );
     742        visitStatementList( node->stmts    );
    436743
    437744        VISIT_END( node );
     
    442749        MUTATE_START( node );
    443750
    444         node->set_condition(  mutateExpression( node->get_condition() ) );
    445         mutateStatementList( node->get_statements() );
     751        node->condition = mutateExpression( node->condition );
     752        mutateStatementList( node->stmts );
    446753
    447754        MUTATE_END( Statement, node );
     
    466773        VISIT_START( node );
    467774
    468         visitExpression( node->get_expr() );
     775        visitExpression( node->expr );
    469776
    470777        VISIT_END( node );
     
    475782        MUTATE_START( node );
    476783
    477         node->set_expr( mutateExpression( node->get_expr() ) );
     784        node->expr = mutateExpression( node->expr );
    478785
    479786        MUTATE_END( Statement, node );
     
    499806        VISIT_START( node );
    500807
    501         maybeAccept( node->get_block(), *this );
    502         acceptAll( node->get_catchers(), *this );
    503         maybeAccept( node->get_finally(), *this );
     808        maybeAccept( node->block       , *this );
     809        maybeAccept( node->handlers    , *this );
     810        maybeAccept( node->finallyBlock, *this );
    504811
    505812        VISIT_END( node );
     
    510817        MUTATE_START( node );
    511818
    512         node->set_block(  maybeMutate( node->get_block(), *this ) );
    513         mutateAll( node->get_catchers(), *this );
    514         node->set_finally( maybeMutate( node->get_finally(), *this ) );
     819        maybeMutateRef( node->block       , *this );
     820        maybeMutateRef( node->handlers    , *this );
     821        maybeMutateRef( node->finallyBlock, *this );
    515822
    516823        MUTATE_END( Statement, node );
     
    522829void PassVisitor< pass_type >::visit( CatchStmt * node ) {
    523830        VISIT_START( node );
    524 
    525         maybeAccept( node->get_decl(), *this );
    526         node->set_cond( visitExpression( node->get_cond() ) );
    527         node->set_body( visitStatement( node->get_body() ) );
    528 
     831        {
     832                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     833                maybeAccept( node->decl, *this );
     834                node->cond = visitExpression( node->cond );
     835                node->body = visitStatement ( node->body );
     836        }
    529837        VISIT_END( node );
    530838}
     
    533841Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    534842        MUTATE_START( node );
    535 
    536         node->set_decl( maybeMutate( node->get_decl(), *this ) );
    537         node->set_cond( mutateExpression( node->get_cond() ) );
    538         node->set_body( mutateStatement( node->get_body() ) );
    539 
     843        {
     844                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     845                maybeMutateRef( node->decl, *this );
     846                node->cond = mutateExpression( node->cond );
     847                node->body = mutateStatement ( node->body );
     848        }
    540849        MUTATE_END( Statement, node );
    541850}
     
    605914template< typename pass_type >
    606915void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
    607         VISIT_BODY( node );
     916        VISIT_START( node );
     917
     918        indexerScopedAccept( node->result  , *this );
     919        maybeAccept        ( node->function, *this );
     920        maybeAccept        ( node->args    , *this );
     921
     922        VISIT_END( node );
    608923}
    609924
    610925template< typename pass_type >
    611926Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
    612         MUTATE_BODY( Expression, node );
     927        MUTATE_START( node );
     928
     929        indexerScopedMutate( node->env     , *this );
     930        indexerScopedMutate( node->result  , *this );
     931        maybeMutateRef     ( node->function, *this );
     932        maybeMutateRef     ( node->args    , *this );
     933
     934        MUTATE_END( Expression, node );
    613935}
    614936
     
    620942
    621943        // maybeAccept( node->get_env(), *this );
    622         maybeAccept( node->get_result(), *this );
    623 
    624         for ( auto expr : node->get_args() ) {
     944        indexerScopedAccept( node->result, *this );
     945
     946        for ( auto expr : node->args ) {
    625947                visitExpression( expr );
    626948        }
     
    633955        MUTATE_START( node );
    634956
    635         node->set_env( maybeMutate( node->get_env(), *this ) );
    636         node->set_result( maybeMutate( node->get_result(), *this ) );
    637 
    638         for ( auto& expr : node->get_args() ) {
     957        indexerScopedMutate( node->env   , *this );
     958        indexerScopedMutate( node->result, *this );
     959
     960        for ( auto& expr : node->args ) {
    639961                expr = mutateExpression( expr );
    640962        }
     
    643965}
    644966
     967//--------------------------------------------------------------------------
     968// NameExpr
    645969template< typename pass_type >
    646970void PassVisitor< pass_type >::visit( NameExpr * node ) {
    647         VISIT_BODY( node );
    648 }
    649 
     971        VISIT_START( node );
     972
     973        indexerScopedAccept( node->result, *this );
     974
     975        VISIT_END( node );
     976}
     977
     978template< typename pass_type >
     979Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
     980        MUTATE_START( node );
     981
     982        indexerScopedMutate( node->env   , *this );
     983        indexerScopedMutate( node->result, *this );
     984
     985        MUTATE_END( Expression, node );
     986}
     987
     988//--------------------------------------------------------------------------
     989// CastExpr
    650990template< typename pass_type >
    651991void PassVisitor< pass_type >::visit( CastExpr * node ) {
    652         VISIT_BODY( node );
    653 }
    654 
     992        VISIT_START( node );
     993
     994        indexerScopedAccept( node->result, *this );
     995        maybeAccept        ( node->arg   , *this );
     996
     997        VISIT_END( node );
     998}
     999
     1000template< typename pass_type >
     1001Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
     1002        MUTATE_START( node );
     1003
     1004        indexerScopedMutate( node->env   , *this );
     1005        indexerScopedMutate( node->result, *this );
     1006        maybeMutateRef     ( node->arg   , *this );
     1007
     1008        MUTATE_END( Expression, node );
     1009}
     1010
     1011//--------------------------------------------------------------------------
     1012// VirtualCastExpr
    6551013template< typename pass_type >
    6561014void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
    657         VISIT_BODY( node );
    658 }
    659 
     1015        VISIT_START( node );
     1016
     1017        indexerScopedAccept( node->result, *this );
     1018        maybeAccept( node->arg, *this );
     1019
     1020        VISIT_END( node );
     1021}
     1022
     1023template< typename pass_type >
     1024Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
     1025        MUTATE_START( node );
     1026
     1027        indexerScopedMutate( node->env   , *this );
     1028        indexerScopedMutate( node->result, *this );
     1029        maybeMutateRef     ( node->arg   , *this );
     1030
     1031        MUTATE_END( Expression, node );
     1032}
     1033
     1034//--------------------------------------------------------------------------
     1035// AddressExpr
    6601036template< typename pass_type >
    6611037void PassVisitor< pass_type >::visit( AddressExpr * node ) {
    662         VISIT_BODY( node );
    663 }
    664 
     1038        VISIT_START( node );
     1039
     1040        indexerScopedAccept( node->result, *this );
     1041        maybeAccept        ( node->arg   , *this );
     1042
     1043        VISIT_END( node );
     1044}
     1045
     1046template< typename pass_type >
     1047Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
     1048        MUTATE_START( node );
     1049
     1050        indexerScopedMutate( node->env   , *this );
     1051        indexerScopedMutate( node->result, *this );
     1052        maybeMutateRef     ( node->arg   , *this );
     1053
     1054        MUTATE_END( Expression, node );
     1055}
     1056
     1057//--------------------------------------------------------------------------
     1058// LabelAddressExpr
    6651059template< typename pass_type >
    6661060void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
    667         VISIT_BODY( node );
    668 }
    669 
     1061        VISIT_START( node );
     1062
     1063        indexerScopedAccept( node->result, *this );
     1064
     1065        VISIT_END( node );
     1066}
     1067
     1068template< typename pass_type >
     1069Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
     1070        MUTATE_START( node );
     1071
     1072        indexerScopedMutate( node->env   , *this );
     1073        indexerScopedMutate( node->result, *this );
     1074
     1075        MUTATE_END( Expression, node );
     1076}
     1077
     1078//--------------------------------------------------------------------------
     1079// UntypedMemberExpr
    6701080template< typename pass_type >
    6711081void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
    672         VISIT_BODY( node );
    673 }
    674 
     1082        VISIT_START( node );
     1083
     1084        indexerScopedAccept( node->result   , *this );
     1085        maybeAccept        ( node->aggregate, *this );
     1086        maybeAccept        ( node->member   , *this );
     1087
     1088        VISIT_END( node );
     1089}
     1090
     1091template< typename pass_type >
     1092Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
     1093        MUTATE_START( node );
     1094
     1095        indexerScopedMutate( node->env      , *this );
     1096        indexerScopedMutate( node->result   , *this );
     1097        maybeMutateRef     ( node->aggregate, *this );
     1098        maybeMutateRef     ( node->member   , *this );
     1099
     1100        MUTATE_END( Expression, node );
     1101}
     1102
     1103//--------------------------------------------------------------------------
     1104// MemberExpr
    6751105template< typename pass_type >
    6761106void PassVisitor< pass_type >::visit( MemberExpr * node ) {
    677         VISIT_BODY( node );
    678 }
    679 
     1107        VISIT_START( node );
     1108
     1109        indexerScopedAccept( node->result   , *this );
     1110        maybeAccept        ( node->aggregate, *this );
     1111
     1112        VISIT_END( node );
     1113}
     1114
     1115template< typename pass_type >
     1116Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
     1117        MUTATE_START( node );
     1118
     1119        indexerScopedMutate( node->env      , *this );
     1120        indexerScopedMutate( node->result   , *this );
     1121        maybeMutateRef     ( node->aggregate, *this );
     1122
     1123        MUTATE_END( Expression, node );
     1124}
     1125
     1126//--------------------------------------------------------------------------
     1127// VariableExpr
    6801128template< typename pass_type >
    6811129void PassVisitor< pass_type >::visit( VariableExpr * node ) {
    682         VISIT_BODY( node );
    683 }
    684 
     1130        VISIT_START( node );
     1131
     1132        indexerScopedAccept( node->result, *this );
     1133
     1134        VISIT_END( node );
     1135}
     1136
     1137template< typename pass_type >
     1138Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
     1139        MUTATE_START( node );
     1140
     1141        indexerScopedMutate( node->env   , *this );
     1142        indexerScopedMutate( node->result, *this );
     1143
     1144        MUTATE_END( Expression, node );
     1145}
     1146
     1147//--------------------------------------------------------------------------
     1148// ConstantExpr
    6851149template< typename pass_type >
    6861150void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
    687         VISIT_BODY( node );
    688 }
    689 
     1151        VISIT_START( node );
     1152
     1153        indexerScopedAccept( node->result   , *this );
     1154        maybeAccept        ( &node->constant, *this );
     1155
     1156        VISIT_END( node );
     1157}
     1158
     1159template< typename pass_type >
     1160Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
     1161        MUTATE_START( node );
     1162
     1163        indexerScopedMutate( node->env   , *this );
     1164        indexerScopedMutate( node->result, *this );
     1165        node->constant = *maybeMutate( &node->constant, *this );
     1166
     1167        MUTATE_END( Expression, node );
     1168}
     1169
     1170//--------------------------------------------------------------------------
     1171// SizeofExpr
    6901172template< typename pass_type >
    6911173void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
    692         VISIT_BODY( node );
    693 }
    694 
     1174        VISIT_START( node );
     1175
     1176        indexerScopedAccept( node->result, *this );
     1177        if ( node->get_isType() ) {
     1178                maybeAccept( node->type, *this );
     1179        } else {
     1180                maybeAccept( node->expr, *this );
     1181        }
     1182
     1183        VISIT_END( node );
     1184}
     1185
     1186template< typename pass_type >
     1187Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
     1188        MUTATE_START( node );
     1189
     1190        indexerScopedMutate( node->env   , *this );
     1191        indexerScopedMutate( node->result, *this );
     1192        if ( node->get_isType() ) {
     1193                maybeMutateRef( node->type, *this );
     1194        } else {
     1195                maybeMutateRef( node->expr, *this );
     1196        }
     1197
     1198        MUTATE_END( Expression, node );
     1199}
     1200
     1201//--------------------------------------------------------------------------
     1202// AlignofExpr
    6951203template< typename pass_type >
    6961204void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
    697         VISIT_BODY( node );
    698 }
    699 
     1205        VISIT_START( node );
     1206
     1207        indexerScopedAccept( node->result, *this );
     1208        if ( node->get_isType() ) {
     1209                maybeAccept( node->type, *this );
     1210        } else {
     1211                maybeAccept( node->expr, *this );
     1212        }
     1213
     1214        VISIT_END( node );
     1215}
     1216
     1217template< typename pass_type >
     1218Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
     1219        MUTATE_START( node );
     1220
     1221        indexerScopedMutate( node->env   , *this );
     1222        indexerScopedMutate( node->result, *this );
     1223        if ( node->get_isType() ) {
     1224                maybeMutateRef( node->type, *this );
     1225        } else {
     1226                maybeMutateRef( node->expr, *this );
     1227        }
     1228
     1229        MUTATE_END( Expression, node );
     1230}
     1231
     1232//--------------------------------------------------------------------------
     1233// UntypedOffsetofExpr
    7001234template< typename pass_type >
    7011235void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
    702         VISIT_BODY( node );
    703 }
    704 
     1236        VISIT_START( node );
     1237
     1238        indexerScopedAccept( node->result, *this );
     1239        maybeAccept        ( node->type  , *this );
     1240
     1241        VISIT_END( node );
     1242}
     1243
     1244template< typename pass_type >
     1245Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
     1246        MUTATE_START( node );
     1247
     1248        indexerScopedMutate( node->env   , *this );
     1249        indexerScopedMutate( node->result, *this );
     1250        maybeMutateRef     ( node->type  , *this );
     1251
     1252        MUTATE_END( Expression, node );
     1253}
     1254
     1255//--------------------------------------------------------------------------
     1256// OffsetofExpr
    7051257template< typename pass_type >
    7061258void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
    707         VISIT_BODY( node );
    708 }
    709 
     1259        VISIT_START( node );
     1260
     1261        indexerScopedAccept( node->result, *this );
     1262        maybeAccept        ( node->type  , *this );
     1263        maybeAccept        ( node->member, *this );
     1264
     1265        VISIT_END( node );
     1266}
     1267
     1268template< typename pass_type >
     1269Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
     1270        MUTATE_START( node );
     1271
     1272        indexerScopedMutate( node->env   , *this );
     1273        indexerScopedMutate( node->result, *this );
     1274        maybeMutateRef     ( node->type  , *this );
     1275        maybeMutateRef     ( node->member, *this );
     1276
     1277        MUTATE_END( Expression, node );
     1278}
     1279
     1280//--------------------------------------------------------------------------
     1281// OffsetPackExpr
    7101282template< typename pass_type >
    7111283void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
    712         VISIT_BODY( node );
    713 }
    714 
     1284        VISIT_START( node );
     1285
     1286        indexerScopedAccept( node->result, *this );
     1287        maybeAccept        ( node->type  , *this );
     1288
     1289        VISIT_END( node );
     1290}
     1291
     1292template< typename pass_type >
     1293Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
     1294        MUTATE_START( node );
     1295
     1296        indexerScopedMutate( node->env   , *this );
     1297        indexerScopedMutate( node->result, *this );
     1298        maybeMutateRef     ( node->type  , *this );
     1299
     1300        MUTATE_END( Expression, node );
     1301}
     1302
     1303//--------------------------------------------------------------------------
     1304// AttrExpr
    7151305template< typename pass_type >
    7161306void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    717         VISIT_BODY( node );
    718 }
    719 
     1307        VISIT_START( node );
     1308
     1309        indexerScopedAccept( node->result, *this );
     1310        if ( node->get_isType() ) {
     1311                maybeAccept( node->type, *this );
     1312        } else {
     1313                maybeAccept( node->expr, *this );
     1314        }
     1315
     1316        VISIT_END( node );
     1317}
     1318
     1319template< typename pass_type >
     1320Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
     1321        MUTATE_START( node );
     1322
     1323        indexerScopedMutate( node->env   , *this );
     1324        indexerScopedMutate( node->result, *this );
     1325        if ( node->get_isType() ) {
     1326                maybeMutateRef( node->type, *this );
     1327        } else {
     1328                maybeMutateRef( node->expr, *this );
     1329        }
     1330
     1331        MUTATE_END( Expression, node );
     1332}
     1333
     1334//--------------------------------------------------------------------------
     1335// LogicalExpr
    7201336template< typename pass_type >
    7211337void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
    722         VISIT_BODY( node );
    723 }
    724 
     1338        VISIT_START( node );
     1339
     1340        indexerScopedAccept( node->result, *this );
     1341        maybeAccept        ( node->arg1  , *this );
     1342        maybeAccept        ( node->arg2  , *this );
     1343
     1344        VISIT_END( node );
     1345}
     1346
     1347template< typename pass_type >
     1348Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
     1349        MUTATE_START( node );
     1350
     1351        indexerScopedMutate( node->env   , *this );
     1352        indexerScopedMutate( node->result, *this );
     1353        maybeMutateRef     ( node->arg1  , *this );
     1354        maybeMutateRef     ( node->arg2  , *this );
     1355
     1356        MUTATE_END( Expression, node );
     1357}
     1358
     1359//--------------------------------------------------------------------------
     1360// ConditionalExpr
    7251361template< typename pass_type >
    7261362void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
    727         VISIT_BODY( node );
    728 }
    729 
     1363        VISIT_START( node );
     1364
     1365        indexerScopedAccept( node->result, *this );
     1366        maybeAccept        ( node->arg1  , *this );
     1367        maybeAccept        ( node->arg2  , *this );
     1368        maybeAccept        ( node->arg3  , *this );
     1369
     1370        VISIT_END( node );
     1371}
     1372
     1373template< typename pass_type >
     1374Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
     1375        MUTATE_START( node );
     1376
     1377        indexerScopedMutate( node->env   , *this );
     1378        indexerScopedMutate( node->result, *this );
     1379        maybeMutateRef     ( node->arg1  , *this );
     1380        maybeMutateRef     ( node->arg2  , *this );
     1381        maybeMutateRef     ( node->arg3  , *this );
     1382
     1383        MUTATE_END( Expression, node );
     1384}
     1385
     1386//--------------------------------------------------------------------------
     1387// CommaExpr
    7301388template< typename pass_type >
    7311389void PassVisitor< pass_type >::visit( CommaExpr * node ) {
    732         VISIT_BODY( node );
    733 }
    734 
     1390        VISIT_START( node );
     1391
     1392        indexerScopedAccept( node->result, *this );
     1393        maybeAccept        ( node->arg1  , *this );
     1394        maybeAccept        ( node->arg2  , *this );
     1395
     1396        VISIT_END( node );
     1397}
     1398
     1399template< typename pass_type >
     1400Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
     1401        MUTATE_START( node );
     1402
     1403        indexerScopedMutate( node->env   , *this );
     1404        indexerScopedMutate( node->result, *this );
     1405        maybeMutateRef     ( node->arg1  , *this );
     1406        maybeMutateRef     ( node->arg2  , *this );
     1407
     1408        MUTATE_END( Expression, node );
     1409}
     1410
     1411//--------------------------------------------------------------------------
     1412// TypeExpr
    7351413template< typename pass_type >
    7361414void PassVisitor< pass_type >::visit( TypeExpr * node ) {
    737         VISIT_BODY( node );
    738 }
    739 
     1415        VISIT_START( node );
     1416
     1417        indexerScopedAccept( node->result, *this );
     1418        maybeAccept        ( node->type, *this );
     1419
     1420        VISIT_END( node );
     1421}
     1422
     1423template< typename pass_type >
     1424Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
     1425        MUTATE_START( node );
     1426
     1427        indexerScopedMutate( node->env   , *this );
     1428        indexerScopedMutate( node->result, *this );
     1429        maybeMutateRef     ( node->type  , *this );
     1430
     1431        MUTATE_END( Expression, node );
     1432}
     1433
     1434//--------------------------------------------------------------------------
     1435// AsmExpr
    7401436template< typename pass_type >
    7411437void PassVisitor< pass_type >::visit( AsmExpr * node ) {
    742         VISIT_BODY( node );
    743 }
    744 
     1438        VISIT_START( node );
     1439
     1440        indexerScopedAccept( node->result    , *this );
     1441        maybeAccept        ( node->inout     , *this );
     1442        maybeAccept        ( node->constraint, *this );
     1443        maybeAccept        ( node->operand   , *this );
     1444
     1445        VISIT_END( node );
     1446}
     1447
     1448template< typename pass_type >
     1449Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
     1450        MUTATE_START( node );
     1451
     1452        indexerScopedMutate( node->env       , *this );
     1453        indexerScopedMutate( node->result    , *this );
     1454        maybeMutateRef     ( node->inout     , *this );
     1455        maybeMutateRef     ( node->constraint, *this );
     1456        maybeMutateRef     ( node->operand   , *this );
     1457
     1458        MUTATE_END( Expression, node );
     1459}
     1460
     1461//--------------------------------------------------------------------------
     1462// ImplicitCopyCtorExpr
    7451463template< typename pass_type >
    7461464void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
    747         VISIT_BODY( node );
    748 }
    749 
     1465        VISIT_START( node );
     1466
     1467        indexerScopedAccept( node->result     , *this );
     1468        maybeAccept        ( node->callExpr   , *this );
     1469        maybeAccept        ( node->tempDecls  , *this );
     1470        maybeAccept        ( node->returnDecls, *this );
     1471        maybeAccept        ( node->dtors      , *this );
     1472
     1473        VISIT_END( node );
     1474}
     1475
     1476template< typename pass_type >
     1477Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
     1478        MUTATE_START( node );
     1479
     1480        indexerScopedMutate( node->env        , *this );
     1481        indexerScopedMutate( node->result     , *this );
     1482        maybeMutateRef     ( node->callExpr   , *this );
     1483        maybeMutateRef     ( node->tempDecls  , *this );
     1484        maybeMutateRef     ( node->returnDecls, *this );
     1485        maybeMutateRef     ( node->dtors      , *this );
     1486
     1487        MUTATE_END( Expression, node );
     1488}
     1489
     1490//--------------------------------------------------------------------------
     1491// ConstructorExpr
    7501492template< typename pass_type >
    7511493void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
    752         VISIT_BODY( node );
    753 }
    754 
     1494        VISIT_START( node );
     1495
     1496        indexerScopedAccept( node->result  , *this );
     1497        maybeAccept        ( node->callExpr, *this );
     1498
     1499        VISIT_END( node );
     1500}
     1501
     1502template< typename pass_type >
     1503Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
     1504        MUTATE_START( node );
     1505
     1506        indexerScopedMutate( node->env     , *this );
     1507        indexerScopedMutate( node->result  , *this );
     1508        maybeMutateRef     ( node->callExpr, *this );
     1509
     1510        MUTATE_END( Expression, node );
     1511}
     1512
     1513//--------------------------------------------------------------------------
     1514// CompoundLiteralExpr
    7551515template< typename pass_type >
    7561516void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
    757         VISIT_BODY( node );
    758 }
    759 
     1517        VISIT_START( node );
     1518
     1519        indexerScopedAccept( node->result     , *this );
     1520        maybeAccept        ( node->initializer, *this );
     1521
     1522        VISIT_END( node );
     1523}
     1524
     1525template< typename pass_type >
     1526Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
     1527        MUTATE_START( node );
     1528
     1529        indexerScopedMutate( node->env        , *this );
     1530        indexerScopedMutate( node->result     , *this );
     1531        maybeMutateRef     ( node->initializer, *this );
     1532
     1533        MUTATE_END( Expression, node );
     1534}
     1535
     1536//--------------------------------------------------------------------------
     1537// RangeExpr
    7601538template< typename pass_type >
    7611539void PassVisitor< pass_type >::visit( RangeExpr * node ) {
    762         VISIT_BODY( node );
    763 }
    764 
     1540        VISIT_START( node );
     1541
     1542        indexerScopedAccept( node->result, *this );
     1543        maybeAccept        ( node->low   , *this );
     1544        maybeAccept        ( node->high  , *this );
     1545
     1546        VISIT_END( node );
     1547}
     1548
     1549template< typename pass_type >
     1550Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
     1551        MUTATE_START( node );
     1552
     1553        indexerScopedMutate( node->env   , *this );
     1554        indexerScopedMutate( node->result, *this );
     1555        maybeMutateRef     ( node->low   , *this );
     1556        maybeMutateRef     ( node->high  , *this );
     1557
     1558        MUTATE_END( Expression, node );
     1559}
     1560
     1561//--------------------------------------------------------------------------
     1562// UntypedTupleExpr
    7651563template< typename pass_type >
    7661564void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
    767         VISIT_BODY( node );
    768 }
    769 
     1565        VISIT_START( node );
     1566
     1567        indexerScopedAccept( node->result, *this );
     1568        maybeAccept        ( node->exprs , *this );
     1569
     1570        VISIT_END( node );
     1571}
     1572
     1573template< typename pass_type >
     1574Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
     1575        MUTATE_START( node );
     1576
     1577        indexerScopedMutate( node->env   , *this );
     1578        indexerScopedMutate( node->result, *this );
     1579        maybeMutateRef     ( node->exprs , *this );
     1580
     1581        MUTATE_END( Expression, node );
     1582}
     1583
     1584//--------------------------------------------------------------------------
     1585// TupleExpr
    7701586template< typename pass_type >
    7711587void PassVisitor< pass_type >::visit( TupleExpr * node ) {
    772         VISIT_BODY( node );
    773 }
    774 
     1588        VISIT_START( node );
     1589
     1590        indexerScopedAccept( node->result, *this );
     1591        maybeAccept          ( node->exprs , *this );
     1592
     1593        VISIT_END( node );
     1594}
     1595
     1596template< typename pass_type >
     1597Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
     1598        MUTATE_START( node );
     1599
     1600        indexerScopedMutate( node->env   , *this );
     1601        indexerScopedMutate( node->result, *this );
     1602        maybeMutateRef     ( node->exprs , *this );
     1603
     1604        MUTATE_END( Expression, node );
     1605}
     1606
     1607//--------------------------------------------------------------------------
     1608// TupleIndexExpr
    7751609template< typename pass_type >
    7761610void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
    777         VISIT_BODY( node );
    778 }
    779 
     1611        VISIT_START( node );
     1612
     1613        indexerScopedAccept( node->result, *this );
     1614        maybeAccept        ( node->tuple , *this );
     1615
     1616        VISIT_END( node );
     1617}
     1618
     1619template< typename pass_type >
     1620Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
     1621        MUTATE_START( node );
     1622
     1623        indexerScopedMutate( node->env   , *this );
     1624        indexerScopedMutate( node->result, *this );
     1625        maybeMutateRef     ( node->tuple , *this );
     1626
     1627        MUTATE_END( Expression, node );
     1628}
     1629
     1630//--------------------------------------------------------------------------
     1631// TupleAssignExpr
    7801632template< typename pass_type >
    7811633void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
    782         VISIT_BODY( node );
    783 }
    784 
    785 //--------------------------------------------------------------------------
    786 // UntypedExpr
     1634        VISIT_START( node );
     1635
     1636        indexerScopedAccept( node->result  , *this );
     1637        maybeAccept        ( node->stmtExpr, *this );
     1638
     1639        VISIT_END( node );
     1640}
     1641
     1642template< typename pass_type >
     1643Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
     1644        MUTATE_START( node );
     1645
     1646        indexerScopedMutate( node->env     , *this );
     1647        indexerScopedMutate( node->result  , *this );
     1648        maybeMutateRef     ( node->stmtExpr, *this );
     1649
     1650        MUTATE_END( Expression, node );
     1651}
     1652
     1653//--------------------------------------------------------------------------
     1654// StmtExpr
    7871655template< typename pass_type >
    7881656void PassVisitor< pass_type >::visit( StmtExpr * node ) {
     
    7941662        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    7951663
    796         Visitor::visit( node );
     1664        indexerScopedAccept( node->result     , *this );
     1665        maybeAccept        ( node->statements , *this );
     1666        maybeAccept        ( node->returnDecls, *this );
     1667        maybeAccept        ( node->dtors      , *this );
    7971668
    7981669        VISIT_END( node );
     
    8081679        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    8091680
    810         Mutator::mutate( node );
    811 
    812         MUTATE_END( Expression, node );
    813 }
    814 
     1681        indexerScopedMutate( node->result     , *this );
     1682        maybeMutateRef     ( node->statements , *this );
     1683        maybeMutateRef     ( node->returnDecls, *this );
     1684        maybeMutateRef     ( node->dtors      , *this );
     1685
     1686        MUTATE_END( Expression, node );
     1687}
     1688
     1689//--------------------------------------------------------------------------
     1690// UniqueExpr
    8151691template< typename pass_type >
    8161692void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
    817         VISIT_BODY( node );
     1693        VISIT_START( node );
     1694
     1695        indexerScopedAccept( node->result, *this );
     1696        maybeAccept        ( node->expr  , *this );
     1697
     1698        VISIT_END( node );
     1699}
     1700
     1701template< typename pass_type >
     1702Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
     1703        MUTATE_START( node );
     1704
     1705        indexerScopedMutate( node->env   , *this );
     1706        indexerScopedMutate( node->result, *this );
     1707        maybeMutateRef     ( node->expr  , *this );
     1708
     1709        MUTATE_END( Expression, node );
    8181710}
    8191711
     
    8481740}
    8491741
     1742//--------------------------------------------------------------------------
     1743// StructInstType
    8501744template< typename pass_type >
    8511745void PassVisitor< pass_type >::visit( StructInstType * node ) {
    852         VISIT_BODY( node );
    853 }
    854 
     1746        VISIT_START( node );
     1747
     1748        indexerAddStruct( node->name );
     1749
     1750        {
     1751                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1752                maybeAccept( node->forall    , *this );
     1753                maybeAccept( node->parameters, *this );
     1754        }
     1755
     1756        VISIT_END( node );
     1757}
     1758
     1759template< typename pass_type >
     1760Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
     1761        MUTATE_START( node );
     1762
     1763        indexerAddStruct( node->name );
     1764
     1765        {
     1766                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1767                maybeMutateRef( node->forall    , *this );
     1768                maybeMutateRef( node->parameters, *this );
     1769        }
     1770
     1771        MUTATE_END( Type, node );
     1772}
     1773
     1774//--------------------------------------------------------------------------
     1775// UnionInstType
    8551776template< typename pass_type >
    8561777void PassVisitor< pass_type >::visit( UnionInstType * node ) {
    857         VISIT_BODY( node );
    858 }
    859 
     1778        VISIT_START( node );
     1779
     1780        indexerAddStruct( node->name );
     1781
     1782        {
     1783                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1784                maybeAccept( node->forall    , *this );
     1785                maybeAccept( node->parameters, *this );
     1786        }
     1787
     1788        VISIT_END( node );
     1789}
     1790
     1791template< typename pass_type >
     1792Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
     1793        MUTATE_START( node );
     1794
     1795        indexerAddStruct( node->name );
     1796
     1797        {
     1798                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1799                maybeMutateRef( node->forall    , *this );
     1800                maybeMutateRef( node->parameters, *this );
     1801        }
     1802
     1803        MUTATE_END( Type, node );
     1804}
     1805
     1806//--------------------------------------------------------------------------
     1807// EnumInstType
    8601808template< typename pass_type >
    8611809void PassVisitor< pass_type >::visit( EnumInstType * node ) {
     
    8641812
    8651813template< typename pass_type >
     1814Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
     1815        MUTATE_BODY( Type, node );
     1816}
     1817
     1818//--------------------------------------------------------------------------
     1819// TraitInstType
     1820template< typename pass_type >
    8661821void PassVisitor< pass_type >::visit( TraitInstType * node ) {
    867         VISIT_BODY( node );
    868 }
    869 
     1822        VISIT_START( node );
     1823
     1824        maybeAccept( node->forall    , *this );
     1825        maybeAccept( node->parameters, *this );
     1826
     1827        VISIT_END( node );
     1828}
     1829
     1830template< typename pass_type >
     1831Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
     1832        MUTATE_START( node );
     1833
     1834        maybeMutateRef( node->forall    , *this );
     1835        maybeMutateRef( node->parameters, *this );
     1836
     1837        MUTATE_END( Type, node );
     1838}
     1839
     1840//--------------------------------------------------------------------------
     1841// TypeInstType
    8701842template< typename pass_type >
    8711843void PassVisitor< pass_type >::visit( TypeInstType * node ) {
     
    9041876
    9051877//--------------------------------------------------------------------------
    906 // UntypedExpr
     1878// SingleInit
    9071879template< typename pass_type >
    9081880void PassVisitor< pass_type >::visit( SingleInit * node ) {
     
    9441916
    9451917//---------------------------------------------------------------------------------------------------------------
    946 
    947 template< typename pass_type >
    948 DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
    949         MUTATE_BODY( DeclarationWithType, node );
    950 }
    951 
    952 template< typename pass_type >
    953 DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
    954         MUTATE_BODY( DeclarationWithType, node );
    955 }
    956 
    957 template< typename pass_type >
    958 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
    959         MUTATE_BODY( Declaration, node );
    960 }
    961 
    962 template< typename pass_type >
    963 Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
    964         MUTATE_BODY( Declaration, node );
    965 }
    966 
    967 template< typename pass_type >
    968 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
    969         MUTATE_BODY( Declaration, node );
    970 }
    971 
    972 template< typename pass_type >
    973 Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
    974         MUTATE_BODY( Declaration, node );
    975 }
    976 
    977 template< typename pass_type >
    978 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
    979         MUTATE_BODY( Declaration, node );
    980 }
    981 
    982 template< typename pass_type >
    983 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
    984         MUTATE_BODY( Declaration, node );
    985 }
    986 
    987 template< typename pass_type >
    988 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
    989         MUTATE_BODY( AsmDecl, node );
    990 }
    991 
    992 template< typename pass_type >
    993 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
    994         MUTATE_BODY( Expression, node );
    995 }
    996 
    997 template< typename pass_type >
    998 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
    999         MUTATE_BODY( Expression, node );
    1000 }
    1001 
    1002 template< typename pass_type >
    1003 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
    1004         MUTATE_BODY( Expression, node );
    1005 }
    1006 
    1007 template< typename pass_type >
    1008 Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
    1009         MUTATE_BODY( Expression, node );
    1010 }
    1011 
    1012 template< typename pass_type >
    1013 Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
    1014         MUTATE_BODY( Expression, node );
    1015 }
    1016 
    1017 template< typename pass_type >
    1018 Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
    1019         MUTATE_BODY( Expression, node );
    1020 }
    1021 
    1022 template< typename pass_type >
    1023 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
    1024         MUTATE_BODY( Expression, node );
    1025 }
    1026 
    1027 template< typename pass_type >
    1028 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
    1029         MUTATE_BODY( Expression, node );
    1030 }
    1031 
    1032 template< typename pass_type >
    1033 Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
    1034         MUTATE_BODY( Expression, node );
    1035 }
    1036 
    1037 template< typename pass_type >
    1038 Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
    1039         MUTATE_BODY( Expression, node );
    1040 }
    1041 
    1042 template< typename pass_type >
    1043 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
    1044         MUTATE_BODY( Expression, node );
    1045 }
    1046 
    1047 template< typename pass_type >
    1048 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
    1049         MUTATE_BODY( Expression, node );
    1050 }
    1051 
    1052 template< typename pass_type >
    1053 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
    1054         MUTATE_BODY( Expression, node );
    1055 }
    1056 
    1057 template< typename pass_type >
    1058 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
    1059         MUTATE_BODY( Expression, node );
    1060 }
    1061 
    1062 template< typename pass_type >
    1063 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
    1064         MUTATE_BODY( Expression, node );
    1065 }
    1066 
    1067 template< typename pass_type >
    1068 Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
    1069         MUTATE_BODY( Expression, node );
    1070 }
    1071 
    1072 template< typename pass_type >
    1073 Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
    1074         MUTATE_BODY( Expression, node );
    1075 }
    1076 
    1077 template< typename pass_type >
    1078 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
    1079         MUTATE_BODY( Expression, node );
    1080 }
    1081 
    1082 template< typename pass_type >
    1083 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
    1084         MUTATE_BODY( Expression, node );
    1085 }
    1086 
    1087 template< typename pass_type >
    1088 Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
    1089         MUTATE_BODY( Expression, node );
    1090 }
    1091 
    1092 template< typename pass_type >
    1093 Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
    1094         MUTATE_BODY( Expression, node );
    1095 }
    1096 
    1097 template< typename pass_type >
    1098 Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
    1099         MUTATE_BODY( Expression, node );
    1100 }
    1101 
    1102 template< typename pass_type >
    1103 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
    1104         MUTATE_BODY( Expression, node );
    1105 }
    1106 
    1107 template< typename pass_type >
    1108 Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
    1109         MUTATE_BODY( Expression, node );
    1110 }
    1111 
    1112 template< typename pass_type >
    1113 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
    1114         MUTATE_BODY( Expression, node );
    1115 }
    1116 
    1117 template< typename pass_type >
    1118 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
    1119         MUTATE_BODY( Expression, node );
    1120 }
    1121 
    1122 template< typename pass_type >
    1123 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
    1124         MUTATE_BODY( Expression, node );
    1125 }
    1126 
    1127 template< typename pass_type >
    1128 Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
    1129         MUTATE_BODY( Expression, node );
    1130 }
    1131 
    1132 template< typename pass_type >
    1133 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
    1134         MUTATE_BODY( Expression, node );
    1135 }
    1136 
    11371918template< typename pass_type >
    11381919Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
     
    11661947
    11671948template< typename pass_type >
    1168 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
    1169         MUTATE_BODY( Type, node );
    1170 }
    1171 
    1172 template< typename pass_type >
    1173 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
    1174         MUTATE_BODY( Type, node );
    1175 }
    1176 
    1177 template< typename pass_type >
    1178 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
    1179         MUTATE_BODY( Type, node );
    1180 }
    1181 
    1182 template< typename pass_type >
    1183 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
    1184         MUTATE_BODY( Type, node );
    1185 }
    1186 
    1187 template< typename pass_type >
    11881949Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
    11891950        MUTATE_BODY( Type, node );
  • src/Common/PassVisitor.proto.h

    rd130fe8 rba54f7d  
    4141};
    4242
    43 
    4443class bool_ref {
    4544public:
     
    5958        bool * m_ref;
    6059};
     60
     61template< typename TreeType, typename VisitorType >
     62inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
     63        auto guard = makeFuncGuard(
     64                [&visitor]() { visitor.indexerScopeEnter(); },
     65                [&visitor]() { visitor.indexerScopeLeave(); }
     66        );
     67        maybeAccept( tree, visitor );
     68}
     69
     70template< typename TreeType, typename MutatorType >
     71inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {
     72        auto guard = makeFuncGuard(
     73                [&mutator]() { mutator.indexerScopeEnter(); },
     74                [&mutator]() { mutator.indexerScopeLeave(); }
     75        );
     76        tree = maybeMutate( tree, mutator );
     77}
     78
     79template< typename TreeType, typename MutatorType >
     80inline void maybeMutateRef( TreeType *& tree, MutatorType & mutator ) {
     81        tree = maybeMutate( tree, mutator );
     82}
    6183
    6284//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    93115static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
    94116
     117//---------------------------------------------------------
    95118// Mutate
    96119template<typename pass_type, typename node_type>
     
    111134static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
    112135
     136//---------------------------------------------------------
    113137// Begin/End scope
    114138template<typename pass_type>
     
    129153static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
    130154
     155//---------------------------------------------------------
    131156// Fields
    132157#define FIELD_PTR( type, name )                                                                                                        \
     
    145170FIELD_PTR( at_cleanup_t, at_cleanup )
    146171FIELD_PTR( PassVisitor<pass_type> * const, visitor )
     172
     173//---------------------------------------------------------
     174// Indexer
     175template<typename pass_type>
     176static inline auto indexer_impl_enterScope( pass_type & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) {
     177        pass.indexer.enterScope();
     178}
     179
     180template<typename pass_type>
     181static inline auto indexer_impl_enterScope( pass_type &, int ) {}
     182
     183template<typename pass_type>
     184static inline auto indexer_impl_leaveScope( pass_type & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) {
     185        pass.indexer.leaveScope();
     186}
     187
     188template<typename pass_type>
     189static inline auto indexer_impl_leaveScope( pass_type &, int ) {}
     190
     191
     192#define INDEXER_FUNC( func, type )                                                                                             \
     193template<typename pass_type>                                                                                                   \
     194static inline auto indexer_impl_##func ( pass_type & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {   \
     195        pass.indexer.func( arg );                                                                                                \
     196}                                                                                                                              \
     197                                                                                                                               \
     198template<typename pass_type>                                                                                                   \
     199static inline void indexer_impl_##func ( pass_type &, long, type ) {}                                                          \
     200
     201INDEXER_FUNC( addId     , DeclarationWithType * );
     202INDEXER_FUNC( addType   , NamedTypeDecl *       );
     203INDEXER_FUNC( addStruct , StructDecl *          );
     204INDEXER_FUNC( addEnum   , EnumDecl *            );
     205INDEXER_FUNC( addUnion  , UnionDecl *           );
     206INDEXER_FUNC( addTrait  , TraitDecl *           );
     207
     208
     209template<typename pass_type>
     210static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
     211        StructDecl * fwd = new StructDecl( decl->name );
     212        cloneAll( decl->parameters, fwd->parameters );
     213        pass.indexer.addStruct( fwd );
     214}
     215
     216template<typename pass_type>
     217static inline auto indexer_impl_addStructFwd( pass_type &, int, StructDecl * ) {}
     218
     219template<typename pass_type>
     220static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
     221        UnionDecl * fwd = new UnionDecl( decl->name );
     222        cloneAll( decl->parameters, fwd->parameters );
     223        pass.indexer.addUnion( fwd );
     224}
     225
     226template<typename pass_type>
     227static inline auto indexer_impl_addUnionFwd( pass_type &, int, UnionDecl * ) {}
     228
     229template<typename pass_type>
     230static inline auto indexer_impl_addStruct( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) {
     231        if ( ! pass.indexer.lookupStruct( str ) ) {
     232                pass.indexer.addStruct( str );
     233        }
     234}
     235
     236template<typename pass_type>
     237static inline auto indexer_impl_addStruct( pass_type &, int, const std::string & ) {}
     238
     239template<typename pass_type>
     240static inline auto indexer_impl_addUnion( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
     241        if ( ! pass.indexer.lookupUnion( str ) ) {
     242                pass.indexer.addUnion( str );
     243        }
     244}
     245
     246template<typename pass_type>
     247static inline auto indexer_impl_addUnion( pass_type &, int, const std::string & ) {}
  • src/Common/utility.h

    rd130fe8 rba54f7d  
    277277        ~ValueGuardPtr() { if( ref ) *ref = old; }
    278278};
     279
     280template< typename aT >
     281struct FuncGuard {
     282        aT m_after;
     283
     284        template< typename bT >
     285        FuncGuard( bT before, aT after ) : m_after( after ) {
     286                before();
     287        }
     288
     289        ~FuncGuard() {
     290                m_after();
     291        }
     292};
     293
     294template< typename bT, typename aT >
     295FuncGuard<aT> makeFuncGuard( bT && before, aT && after ) {
     296        return FuncGuard<aT>( std::forward<bT>(before), std::forward<aT>(after) );
     297}
    279298
    280299template< typename T >
Note: See TracChangeset for help on using the changeset viewer.