Ignore:
Timestamp:
Jul 19, 2019, 2:16:01 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4eb43fa
Parents:
1f1c102 (diff), 8ac3b0e (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' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.impl.h

    r1f1c102 rf53acdf8  
    8080
    8181template< typename pass_type >
     82inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
     83        SemanticErrorException errors;
     84
     85        pass_visitor_stats.depth++;
     86        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     87        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     88        for ( const Declaration * decl : decls ) {
     89                try {
     90                        // run visitor on declaration
     91                        maybeAccept_impl( decl, visitor );
     92                }
     93                catch( SemanticErrorException &e ) {
     94                        errors.append( e );
     95                }
     96        }
     97        pass_visitor_stats.depth--;
     98        if ( ! errors.isEmpty() ) {
     99                throw errors;
     100        }
     101}
     102
     103template< typename pass_type >
    82104inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
    83105        DeclList_t* beforeDecls = mutator.get_beforeDecls();
     
    117139}
    118140
     141template< typename TreeType, typename pass_type >
     142inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
     143        if ( ! visitor.get_visit_children() ) return;
     144        if ( tree ) {
     145                tree->accept( visitor );
     146        }
     147}
     148
    119149template< typename Container, typename pass_type >
    120150inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
     
    129159                        if ( *i ) {
    130160                                (*i)->accept( visitor );
     161                        }
     162                } catch( SemanticErrorException &e ) {
     163                        errors.append( e );
     164                }
     165        }
     166        pass_visitor_stats.depth--;
     167        if ( ! errors.isEmpty() ) {
     168                throw errors;
     169        }
     170}
     171
     172template< typename Container, typename pass_type >
     173inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
     174        if ( ! visitor.get_visit_children() ) return;
     175        SemanticErrorException errors;
     176
     177        pass_visitor_stats.depth++;
     178        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     179        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     180        for ( const auto & i : container ) {
     181                try {
     182                        if ( i ) {
     183                                i->accept( visitor );
    131184                        }
    132185                } catch( SemanticErrorException &e ) {
     
    227280
    228281template< typename pass_type >
     282void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
     283        if ( ! get_visit_children() ) return;
     284        SemanticErrorException errors;
     285
     286        pass_visitor_stats.depth++;
     287        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     288        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     289        for ( const Statement * i : statements ) {
     290                try {
     291                        maybeAccept_impl( i, *this );
     292                } catch ( SemanticErrorException &e ) {
     293                        errors.append( e );
     294                }
     295        }
     296        pass_visitor_stats.depth--;
     297        if ( !errors.isEmpty() ) { throw errors; }
     298}
     299
     300template< typename pass_type >
    229301void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    230302        handleStatementList( statements, [this]( Statement *& stmt) {
     
    275347
    276348template< typename pass_type >
     349void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
     350        if ( ! get_visit_children() ) return;
     351
     352        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     353        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
     354
     355        maybeAccept_impl( stmt, *this );
     356}
     357
     358template< typename pass_type >
    277359Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    278360        return handleStatement( stmt, [this]( Statement * stmt ) {
     
    306388
    307389template< typename pass_type >
     390void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
     391        if ( ! get_visit_children() ) return;
     392        if( !expr ) return;
     393
     394        auto env_ptr = get_env_ptr();
     395        if ( env_ptr && expr->get_env() ) {
     396                *env_ptr = expr->get_env();
     397        }
     398
     399        maybeAccept_impl( expr, *this );
     400}
     401
     402template< typename pass_type >
    308403Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    309404        return handleExpression(expr, [this]( Expression * expr ) {
     
    315410template< typename TreeType, typename VisitorType >
    316411inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
     412        if ( ! visitor.get_visit_children() ) return;
     413        auto guard = makeFuncGuard(
     414                [&visitor]() { visitor.indexerScopeEnter(); },
     415                [&visitor]() { visitor.indexerScopeLeave(); }
     416        );
     417        maybeAccept_impl( tree, visitor );
     418}
     419
     420template< typename TreeType, typename VisitorType >
     421inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
    317422        if ( ! visitor.get_visit_children() ) return;
    318423        auto guard = makeFuncGuard(
     
    372477
    373478        indexerAddId( node );
     479
     480        VISIT_END( node );
     481}
     482
     483template< typename pass_type >
     484void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
     485        VISIT_START( node );
     486
     487        maybeAccept_impl( node->type         , *this );
     488        maybeAccept_impl( node->init         , *this );
     489        maybeAccept_impl( node->bitfieldWidth, *this );
     490        maybeAccept_impl( node->attributes   , *this );
    374491
    375492        VISIT_END( node );
     
    428545
    429546template< typename pass_type >
     547void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
     548        VISIT_START( node );
     549
     550        indexerAddId( node );
     551
     552        maybeAccept_impl( node->withExprs, *this );
     553        {
     554                // with clause introduces a level of scope (for the with expression members).
     555                // with clause exprs are added to the indexer before parameters so that parameters
     556                // shadow with exprs and not the other way around.
     557                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     558                indexerAddWith( node->withExprs, node );
     559                {
     560                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     561                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
     562                        static ObjectDecl func(
     563                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
     564                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
     565                                nullptr
     566                        );
     567                        indexerAddId( &func );
     568                        maybeAccept_impl( node->type, *this );
     569                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     570                        // a new scope if inFunction is true
     571                        ValueGuard< bool > oldInFunction( inFunction );
     572                        inFunction = true;
     573                        maybeAccept_impl( node->statements, *this );
     574                        maybeAccept_impl( node->attributes, *this );
     575                }
     576        }
     577
     578        VISIT_END( node );
     579}
     580
     581template< typename pass_type >
    430582DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
    431583        MUTATE_START( node );
     
    484636
    485637template< typename pass_type >
    486 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
    487         MUTATE_START( node );
     638void PassVisitor< pass_type >::visit( const StructDecl * node ) {
     639        VISIT_START( node );
    488640
    489641        // make up a forward declaration and add it before processing the members
     
    493645        {
    494646                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     647                maybeAccept_impl( node->parameters, *this );
     648                maybeAccept_impl( node->members   , *this );
     649        }
     650
     651        // this addition replaces the forward declaration
     652        indexerAddStruct( node );
     653
     654        VISIT_END( node );
     655}
     656
     657template< typename pass_type >
     658Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     659        MUTATE_START( node );
     660
     661        // make up a forward declaration and add it before processing the members
     662        // needs to be on the heap because addStruct saves the pointer
     663        indexerAddStructFwd( node );
     664
     665        {
     666                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    495667                maybeMutate_impl( node->parameters, *this );
    496668                maybeMutate_impl( node->members   , *this );
     
    522694        VISIT_END( node );
    523695}
     696template< typename pass_type >
     697void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
     698        VISIT_START( node );
     699
     700        // make up a forward declaration and add it before processing the members
     701        indexerAddUnionFwd( node );
     702
     703        {
     704                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     705                maybeAccept_impl( node->parameters, *this );
     706                maybeAccept_impl( node->members   , *this );
     707        }
     708
     709        indexerAddUnion( node );
     710
     711        VISIT_END( node );
     712}
    524713
    525714template< typename pass_type >
     
    557746
    558747template< typename pass_type >
     748void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
     749        VISIT_START( node );
     750
     751        indexerAddEnum( node );
     752
     753        // unlike structs, traits, and unions, enums inject their members into the global scope
     754        maybeAccept_impl( node->parameters, *this );
     755        maybeAccept_impl( node->members   , *this );
     756
     757        VISIT_END( node );
     758}
     759
     760template< typename pass_type >
    559761Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
    560762        MUTATE_START( node );
     
    573775template< typename pass_type >
    574776void PassVisitor< pass_type >::visit( TraitDecl * node ) {
     777        VISIT_START( node );
     778
     779        {
     780                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     781                maybeAccept_impl( node->parameters, *this );
     782                maybeAccept_impl( node->members   , *this );
     783        }
     784
     785        indexerAddTrait( node );
     786
     787        VISIT_END( node );
     788}
     789
     790template< typename pass_type >
     791void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
    575792        VISIT_START( node );
    576793
     
    625842}
    626843
    627 template< typename pass_type >
    628 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
    629         MUTATE_START( node );
     844
     845template< typename pass_type >
     846void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
     847        VISIT_START( node );
    630848
    631849        {
    632850                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    633                 maybeMutate_impl( node->parameters, *this );
    634                 maybeMutate_impl( node->base      , *this );
     851                maybeAccept_impl( node->parameters, *this );
     852                maybeAccept_impl( node->base      , *this );
    635853        }
    636854
     
    640858        indexerAddType( node );
    641859
     860        maybeAccept_impl( node->assertions, *this );
     861
     862        indexerScopedAccept( node->init, *this );
     863
     864        VISIT_END( node );
     865}
     866
     867template< typename pass_type >
     868Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     869        MUTATE_START( node );
     870
     871        {
     872                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     873                maybeMutate_impl( node->parameters, *this );
     874                maybeMutate_impl( node->base      , *this );
     875        }
     876
     877        // see A NOTE ON THE ORDER OF TRAVERSAL, above
     878        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
     879        // and may depend on the type itself
     880        indexerAddType( node );
     881
    642882        maybeMutate_impl( node->assertions, *this );
    643883
     
    667907
    668908template< typename pass_type >
     909void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
     910        VISIT_START( node );
     911
     912        {
     913                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     914                maybeAccept_impl( node->parameters, *this );
     915                maybeAccept_impl( node->base      , *this );
     916        }
     917
     918        indexerAddType( node );
     919
     920        maybeAccept_impl( node->assertions, *this );
     921
     922        VISIT_END( node );
     923}
     924
     925template< typename pass_type >
    669926Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
    670927        MUTATE_START( node );
     
    695952
    696953template< typename pass_type >
     954void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
     955        VISIT_START( node );
     956
     957        maybeAccept_impl( node->stmt, *this );
     958
     959        VISIT_END( node );
     960}
     961
     962template< typename pass_type >
    697963AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
    698964        MUTATE_START( node );
     
    710976
    711977        node->condition = visitExpression( node->condition );
     978        maybeAccept_impl( node->message, *this );
     979
     980        VISIT_END( node );
     981}
     982
     983template< typename pass_type >
     984void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
     985        VISIT_START( node );
     986
     987        visitExpression( node->condition );
    712988        maybeAccept_impl( node->message, *this );
    713989
     
    7421018
    7431019template< typename pass_type >
     1020void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
     1021        VISIT_START( node );
     1022        {
     1023                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     1024                ValueGuard< bool > oldInFunction( inFunction );
     1025                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
     1026                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     1027                inFunction = false;
     1028                visitStatementList( node->kids );
     1029        }
     1030        VISIT_END( node );
     1031}
     1032
     1033template< typename pass_type >
    7441034CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
    7451035        MUTATE_START( node );
     
    7671057
    7681058template< typename pass_type >
     1059void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
     1060        VISIT_START( node );
     1061
     1062        visitExpression( node->expr );
     1063
     1064        VISIT_END( node );
     1065}
     1066
     1067template< typename pass_type >
    7691068Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
    7701069        MUTATE_START( node );
     
    7901089
    7911090template< typename pass_type >
     1091void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
     1092        VISIT_START( node )
     1093
     1094        maybeAccept_impl( node->instruction, *this );
     1095        maybeAccept_impl( node->output, *this );
     1096        maybeAccept_impl( node->input, *this );
     1097        maybeAccept_impl( node->clobber, *this );
     1098
     1099        VISIT_END( node );
     1100}
     1101
     1102template< typename pass_type >
    7921103Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    7931104        MUTATE_START( node );
     
    8111122
    8121123template< typename pass_type >
     1124void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
     1125        VISIT_START( node )
     1126
     1127        VISIT_END( node );
     1128}
     1129
     1130template< typename pass_type >
    8131131Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
    8141132        MUTATE_START( node );
     
    8251143                // if statements introduce a level of scope (for the initialization)
    8261144                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    827                 maybeAccept_impl( node->get_initialization(), *this );
     1145                maybeAccept_impl( node->initialization, *this );
    8281146                visitExpression ( node->condition );
    8291147                node->thenPart = visitStatement( node->thenPart );
     
    8341152
    8351153template< typename pass_type >
    836 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    837         MUTATE_START( node );
     1154void PassVisitor< pass_type >::visit( const IfStmt * node ) {
     1155        VISIT_START( node );
    8381156        {
    8391157                // if statements introduce a level of scope (for the initialization)
    8401158                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    841                 maybeMutate_impl( node->get_initialization(), *this );
     1159                maybeAccept_impl( node->initialization, *this );
     1160                visitExpression ( node->condition );
     1161                visitStatement  ( node->thenPart );
     1162                visitStatement  ( node->elsePart );
     1163        }
     1164        VISIT_END( node );
     1165}
     1166
     1167template< typename pass_type >
     1168Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     1169        MUTATE_START( node );
     1170        {
     1171                // if statements introduce a level of scope (for the initialization)
     1172                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1173                maybeMutate_impl( node->initialization, *this );
    8421174                node->condition = mutateExpression( node->condition );
    8431175                node->thenPart  = mutateStatement ( node->thenPart  );
     
    8591191                visitExpression ( node->condition );
    8601192                node->body = visitStatement( node->body );
     1193        }
     1194
     1195        VISIT_END( node );
     1196}
     1197
     1198template< typename pass_type >
     1199void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
     1200        VISIT_START( node );
     1201
     1202        {
     1203                // while statements introduce a level of scope (for the initialization)
     1204                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1205                maybeAccept_impl( node->initialization, *this );
     1206                visitExpression ( node->condition );
     1207                visitStatement  ( node->body );
    8611208        }
    8621209
     
    8971244
    8981245template< typename pass_type >
     1246void PassVisitor< pass_type >::visit( const ForStmt * node ) {
     1247        VISIT_START( node );
     1248        {
     1249                // for statements introduce a level of scope (for the initialization)
     1250                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1251                maybeAccept_impl( node->initialization, *this );
     1252                visitExpression( node->condition );
     1253                visitExpression( node->increment );
     1254                visitStatement ( node->body );
     1255        }
     1256        VISIT_END( node );
     1257}
     1258
     1259template< typename pass_type >
    8991260Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    9001261        MUTATE_START( node );
     
    9231284
    9241285template< typename pass_type >
     1286void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
     1287        VISIT_START( node );
     1288
     1289        visitExpression   ( node->condition  );
     1290        visitStatementList( node->statements );
     1291
     1292        VISIT_END( node );
     1293}
     1294
     1295template< typename pass_type >
    9251296Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    9261297        MUTATE_START( node );
     
    9451316
    9461317template< typename pass_type >
     1318void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
     1319        VISIT_START( node );
     1320
     1321        visitExpression   ( node->condition );
     1322        visitStatementList( node->stmts     );
     1323
     1324        VISIT_END( node );
     1325}
     1326
     1327template< typename pass_type >
    9471328Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    9481329        MUTATE_START( node );
     
    9631344
    9641345template< typename pass_type >
     1346void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
     1347        VISIT_START( node );
     1348        VISIT_END( node );
     1349}
     1350
     1351template< typename pass_type >
    9651352Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    9661353        MUTATE_START( node );
     
    9801367
    9811368template< typename pass_type >
     1369void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
     1370        VISIT_START( node );
     1371
     1372        visitExpression( node->expr );
     1373
     1374        VISIT_END( node );
     1375}
     1376
     1377template< typename pass_type >
    9821378Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
    9831379        MUTATE_START( node );
     
    9901386//--------------------------------------------------------------------------
    9911387// ThrowStmt
    992 
    9931388template< typename pass_type >
    9941389void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
     
    10021397
    10031398template< typename pass_type >
     1399void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
     1400        VISIT_START( node );
     1401
     1402        maybeAccept_impl( node->expr, *this );
     1403        maybeAccept_impl( node->target, *this );
     1404
     1405        VISIT_END( node );
     1406}
     1407
     1408template< typename pass_type >
    10041409Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
    10051410        MUTATE_START( node );
     
    10151420template< typename pass_type >
    10161421void PassVisitor< pass_type >::visit( TryStmt * node ) {
     1422        VISIT_START( node );
     1423
     1424        maybeAccept_impl( node->block       , *this );
     1425        maybeAccept_impl( node->handlers    , *this );
     1426        maybeAccept_impl( node->finallyBlock, *this );
     1427
     1428        VISIT_END( node );
     1429}
     1430
     1431template< typename pass_type >
     1432void PassVisitor< pass_type >::visit( const TryStmt * node ) {
    10171433        VISIT_START( node );
    10181434
     
    10511467
    10521468template< typename pass_type >
     1469void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
     1470        VISIT_START( node );
     1471        {
     1472                // catch statements introduce a level of scope (for the caught exception)
     1473                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1474                maybeAccept_impl( node->decl, *this );
     1475                visitExpression ( node->cond );
     1476                visitStatement  ( node->body );
     1477        }
     1478        VISIT_END( node );
     1479}
     1480
     1481template< typename pass_type >
    10531482Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    10541483        MUTATE_START( node );
     
    10751504
    10761505template< typename pass_type >
     1506void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
     1507        VISIT_START( node );
     1508
     1509        maybeAccept_impl( node->block, *this );
     1510
     1511        VISIT_END( node );
     1512}
     1513
     1514template< typename pass_type >
    10771515Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    10781516        MUTATE_START( node );
     
    11071545
    11081546template< typename pass_type >
     1547void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
     1548        VISIT_START( node );
     1549
     1550        for( auto & clause : node->clauses ) {
     1551                maybeAccept_impl( clause.target.function, *this );
     1552                maybeAccept_impl( clause.target.arguments, *this );
     1553
     1554                maybeAccept_impl( clause.statement, *this );
     1555                maybeAccept_impl( clause.condition, *this );
     1556        }
     1557
     1558        maybeAccept_impl( node->timeout.time, *this );
     1559        maybeAccept_impl( node->timeout.statement, *this );
     1560        maybeAccept_impl( node->timeout.condition, *this );
     1561        maybeAccept_impl( node->orelse.statement, *this );
     1562        maybeAccept_impl( node->orelse.condition, *this );
     1563
     1564        VISIT_END( node );
     1565}
     1566
     1567template< typename pass_type >
    11091568Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
    11101569        MUTATE_START( node );
     
    11301589
    11311590//--------------------------------------------------------------------------
    1132 // NullStmt
     1591// WithStmt
    11331592template< typename pass_type >
    11341593void PassVisitor< pass_type >::visit( WithStmt * node ) {
     
    11451604
    11461605template< typename pass_type >
    1147 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
     1606void PassVisitor< pass_type >::visit( const WithStmt * node ) {
     1607        VISIT_START( node );
     1608        maybeAccept_impl( node->exprs, *this );
     1609        {
     1610                // catch statements introduce a level of scope (for the caught exception)
     1611                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1612                indexerAddWith( node->exprs, node );
     1613                maybeAccept_impl( node->stmt, *this );
     1614        }
     1615        VISIT_END( node );
     1616}
     1617
     1618template< typename pass_type >
     1619Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) {
    11481620        MUTATE_START( node );
    11491621        maybeMutate_impl( node->exprs, *this );
     
    11541626                maybeMutate_impl( node->stmt, *this );
    11551627        }
     1628        MUTATE_END( Declaration, node );
     1629}
     1630
     1631//--------------------------------------------------------------------------
     1632// NullStmt
     1633template< typename pass_type >
     1634void PassVisitor< pass_type >::visit( NullStmt * node ) {
     1635        VISIT_START( node );
     1636        VISIT_END( node );
     1637}
     1638
     1639template< typename pass_type >
     1640void PassVisitor< pass_type >::visit( const NullStmt * node ) {
     1641        VISIT_START( node );
     1642        VISIT_END( node );
     1643}
     1644
     1645template< typename pass_type >
     1646NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
     1647        MUTATE_START( node );
     1648        MUTATE_END( NullStmt, node );
     1649}
     1650
     1651//--------------------------------------------------------------------------
     1652// DeclStmt
     1653template< typename pass_type >
     1654void PassVisitor< pass_type >::visit( DeclStmt * node ) {
     1655        VISIT_START( node );
     1656
     1657        maybeAccept_impl( node->decl, *this );
     1658
     1659        VISIT_END( node );
     1660}
     1661
     1662template< typename pass_type >
     1663void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
     1664        VISIT_START( node );
     1665
     1666        maybeAccept_impl( node->decl, *this );
     1667
     1668        VISIT_END( node );
     1669}
     1670
     1671template< typename pass_type >
     1672Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
     1673        MUTATE_START( node );
     1674
     1675        maybeMutate_impl( node->decl, *this );
     1676
    11561677        MUTATE_END( Statement, node );
    11571678}
    11581679
    11591680//--------------------------------------------------------------------------
    1160 // NullStmt
    1161 template< typename pass_type >
    1162 void PassVisitor< pass_type >::visit( NullStmt * node ) {
    1163         VISIT_START( node );
    1164         VISIT_END( node );
    1165 }
    1166 
    1167 template< typename pass_type >
    1168 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
    1169         MUTATE_START( node );
    1170         MUTATE_END( NullStmt, node );
    1171 }
    1172 
    1173 //--------------------------------------------------------------------------
    1174 // DeclStmt
    1175 template< typename pass_type >
    1176 void PassVisitor< pass_type >::visit( DeclStmt * node ) {
    1177         VISIT_START( node );
    1178 
    1179         maybeAccept_impl( node->decl, *this );
    1180 
    1181         VISIT_END( node );
    1182 }
    1183 
    1184 template< typename pass_type >
    1185 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
    1186         MUTATE_START( node );
    1187 
    1188         maybeMutate_impl( node->decl, *this );
     1681// ImplicitCtorDtorStmt
     1682template< typename pass_type >
     1683void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
     1684        VISIT_START( node );
     1685
     1686        maybeAccept_impl( node->callStmt, *this );
     1687
     1688        VISIT_END( node );
     1689}
     1690
     1691template< typename pass_type >
     1692void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
     1693        VISIT_START( node );
     1694
     1695        maybeAccept_impl( node->callStmt, *this );
     1696
     1697        VISIT_END( node );
     1698}
     1699
     1700template< typename pass_type >
     1701Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
     1702        MUTATE_START( node );
     1703
     1704        maybeMutate_impl( node->callStmt, *this );
    11891705
    11901706        MUTATE_END( Statement, node );
     
    11921708
    11931709//--------------------------------------------------------------------------
    1194 // ImplicitCtorDtorStmt
    1195 template< typename pass_type >
    1196 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
    1197         VISIT_START( node );
    1198 
    1199         maybeAccept_impl( node->callStmt, *this );
    1200 
    1201         VISIT_END( node );
    1202 }
    1203 
    1204 template< typename pass_type >
    1205 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
    1206         MUTATE_START( node );
    1207 
    1208         maybeMutate_impl( node->callStmt, *this );
    1209 
    1210         MUTATE_END( Statement, node );
    1211 }
    1212 
    1213 //--------------------------------------------------------------------------
    12141710// ApplicationExpr
    12151711template< typename pass_type >
     
    12181714
    12191715        indexerScopedAccept( node->result  , *this );
    1220         maybeAccept_impl        ( node->function, *this );
    1221         maybeAccept_impl        ( node->args    , *this );
     1716        maybeAccept_impl   ( node->function, *this );
     1717        maybeAccept_impl   ( node->args    , *this );
     1718
     1719        VISIT_END( node );
     1720}
     1721
     1722template< typename pass_type >
     1723void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
     1724        VISIT_START( node );
     1725
     1726        indexerScopedAccept( node->result  , *this );
     1727        maybeAccept_impl   ( node->function, *this );
     1728        maybeAccept_impl   ( node->args    , *this );
    12221729
    12231730        VISIT_END( node );
     
    12531760
    12541761template< typename pass_type >
     1762void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
     1763        VISIT_START( node );
     1764
     1765        indexerScopedAccept( node->result, *this );
     1766
     1767        for ( auto expr : node->args ) {
     1768                visitExpression( expr );
     1769        }
     1770
     1771        VISIT_END( node );
     1772}
     1773
     1774template< typename pass_type >
    12551775Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    12561776        MUTATE_START( node );
     
    12781798
    12791799template< typename pass_type >
     1800void PassVisitor< pass_type >::visit( const NameExpr * node ) {
     1801        VISIT_START( node );
     1802
     1803        indexerScopedAccept( node->result, *this );
     1804
     1805        VISIT_END( node );
     1806}
     1807
     1808template< typename pass_type >
    12801809Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
    12811810        MUTATE_START( node );
     
    12941823
    12951824        indexerScopedAccept( node->result, *this );
    1296         maybeAccept_impl        ( node->arg   , *this );
     1825        maybeAccept_impl   ( node->arg   , *this );
     1826
     1827        VISIT_END( node );
     1828}
     1829
     1830template< typename pass_type >
     1831void PassVisitor< pass_type >::visit( const CastExpr * node ) {
     1832        VISIT_START( node );
     1833
     1834        indexerScopedAccept( node->result, *this );
     1835        maybeAccept_impl   ( node->arg   , *this );
    12971836
    12981837        VISIT_END( node );
     
    13231862
    13241863template< typename pass_type >
     1864void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
     1865        VISIT_START( node );
     1866
     1867        indexerScopedAccept( node->result, *this );
     1868        maybeAccept_impl   ( node->arg   , *this );
     1869
     1870        VISIT_END( node );
     1871}
     1872
     1873template< typename pass_type >
    13251874Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
    13261875        MUTATE_START( node );
     
    13401889
    13411890        indexerScopedAccept( node->result, *this );
    1342         maybeAccept_impl( node->arg, *this );
     1891        maybeAccept_impl   ( node->arg, *this );
     1892
     1893        VISIT_END( node );
     1894}
     1895
     1896template< typename pass_type >
     1897void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
     1898        VISIT_START( node );
     1899
     1900        indexerScopedAccept( node->result, *this );
     1901        maybeAccept_impl   ( node->arg, *this );
    13431902
    13441903        VISIT_END( node );
     
    13691928
    13701929template< typename pass_type >
     1930void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
     1931        VISIT_START( node );
     1932
     1933        indexerScopedAccept( node->result, *this );
     1934        maybeAccept_impl   ( node->arg   , *this );
     1935
     1936        VISIT_END( node );
     1937}
     1938
     1939template< typename pass_type >
    13711940Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
    13721941        MUTATE_START( node );
     
    13911960
    13921961template< typename pass_type >
     1962void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
     1963        VISIT_START( node );
     1964
     1965        indexerScopedAccept( node->result, *this );
     1966
     1967        VISIT_END( node );
     1968}
     1969
     1970template< typename pass_type >
    13931971Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
    13941972        MUTATE_START( node );
     
    14041982template< typename pass_type >
    14051983void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
     1984        VISIT_START( node );
     1985
     1986        indexerScopedAccept( node->result   , *this );
     1987        maybeAccept_impl   ( node->aggregate, *this );
     1988        maybeAccept_impl   ( node->member   , *this );
     1989
     1990        VISIT_END( node );
     1991}
     1992
     1993template< typename pass_type >
     1994void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
    14061995        VISIT_START( node );
    14071996
     
    14382027
    14392028template< typename pass_type >
     2029void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
     2030        VISIT_START( node );
     2031
     2032        indexerScopedAccept( node->result   , *this );
     2033        maybeAccept_impl   ( node->aggregate, *this );
     2034
     2035        VISIT_END( node );
     2036}
     2037
     2038template< typename pass_type >
    14402039Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
    14412040        MUTATE_START( node );
     
    14602059
    14612060template< typename pass_type >
     2061void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
     2062        VISIT_START( node );
     2063
     2064        indexerScopedAccept( node->result, *this );
     2065
     2066        VISIT_END( node );
     2067}
     2068
     2069template< typename pass_type >
    14622070Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
    14632071        MUTATE_START( node );
     
    14732081template< typename pass_type >
    14742082void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
     2083        VISIT_START( node );
     2084
     2085        indexerScopedAccept( node->result   , *this );
     2086        maybeAccept_impl   ( &node->constant, *this );
     2087
     2088        VISIT_END( node );
     2089}
     2090
     2091template< typename pass_type >
     2092void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
    14752093        VISIT_START( node );
    14762094
     
    14982116template< typename pass_type >
    14992117void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
     2118        VISIT_START( node );
     2119
     2120        indexerScopedAccept( node->result, *this );
     2121        if ( node->get_isType() ) {
     2122                maybeAccept_impl( node->type, *this );
     2123        } else {
     2124                maybeAccept_impl( node->expr, *this );
     2125        }
     2126
     2127        VISIT_END( node );
     2128}
     2129
     2130template< typename pass_type >
     2131void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
    15002132        VISIT_START( node );
    15012133
     
    15422174
    15432175template< typename pass_type >
     2176void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
     2177        VISIT_START( node );
     2178
     2179        indexerScopedAccept( node->result, *this );
     2180        if ( node->get_isType() ) {
     2181                maybeAccept_impl( node->type, *this );
     2182        } else {
     2183                maybeAccept_impl( node->expr, *this );
     2184        }
     2185
     2186        VISIT_END( node );
     2187}
     2188
     2189template< typename pass_type >
    15442190Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
    15452191        MUTATE_START( node );
     
    15692215
    15702216template< typename pass_type >
     2217void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
     2218        VISIT_START( node );
     2219
     2220        indexerScopedAccept( node->result, *this );
     2221        maybeAccept_impl   ( node->type  , *this );
     2222
     2223        VISIT_END( node );
     2224}
     2225
     2226template< typename pass_type >
    15712227Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
    15722228        MUTATE_START( node );
     
    15922248
    15932249template< typename pass_type >
     2250void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
     2251        VISIT_START( node );
     2252
     2253        indexerScopedAccept( node->result, *this );
     2254        maybeAccept_impl   ( node->type  , *this );
     2255
     2256        VISIT_END( node );
     2257}
     2258
     2259template< typename pass_type >
    15942260Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
    15952261        MUTATE_START( node );
     
    16152281
    16162282template< typename pass_type >
     2283void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
     2284        VISIT_START( node );
     2285
     2286        indexerScopedAccept( node->result, *this );
     2287        maybeAccept_impl   ( node->type  , *this );
     2288
     2289        VISIT_END( node );
     2290}
     2291
     2292template< typename pass_type >
    16172293Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
    16182294        MUTATE_START( node );
     
    16292305template< typename pass_type >
    16302306void PassVisitor< pass_type >::visit( AttrExpr * node ) {
     2307        VISIT_START( node );
     2308
     2309        indexerScopedAccept( node->result, *this );
     2310        if ( node->get_isType() ) {
     2311                maybeAccept_impl( node->type, *this );
     2312        } else {
     2313                maybeAccept_impl( node->expr, *this );
     2314        }
     2315
     2316        VISIT_END( node );
     2317}
     2318
     2319template< typename pass_type >
     2320void PassVisitor< pass_type >::visit( const AttrExpr * node ) {
    16312321        VISIT_START( node );
    16322322
     
    16702360
    16712361template< typename pass_type >
     2362void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
     2363        VISIT_START( node );
     2364
     2365        indexerScopedAccept( node->result, *this );
     2366        maybeAccept_impl   ( node->arg1  , *this );
     2367        maybeAccept_impl   ( node->arg2  , *this );
     2368
     2369        VISIT_END( node );
     2370}
     2371
     2372template< typename pass_type >
    16722373Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
    16732374        MUTATE_START( node );
     
    16912392        maybeAccept_impl        ( node->arg2  , *this );
    16922393        maybeAccept_impl        ( node->arg3  , *this );
     2394
     2395        VISIT_END( node );
     2396}
     2397
     2398template< typename pass_type >
     2399void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
     2400        VISIT_START( node );
     2401
     2402        indexerScopedAccept( node->result, *this );
     2403        maybeAccept_impl   ( node->arg1  , *this );
     2404        maybeAccept_impl   ( node->arg2  , *this );
     2405        maybeAccept_impl   ( node->arg3  , *this );
    16932406
    16942407        VISIT_END( node );
     
    17222435
    17232436template< typename pass_type >
     2437void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
     2438        VISIT_START( node );
     2439
     2440        indexerScopedAccept( node->result, *this );
     2441        maybeAccept_impl   ( node->arg1  , *this );
     2442        maybeAccept_impl   ( node->arg2  , *this );
     2443
     2444        VISIT_END( node );
     2445}
     2446
     2447template< typename pass_type >
    17242448Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
    17252449        MUTATE_START( node );
     
    17462470
    17472471template< typename pass_type >
     2472void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
     2473        VISIT_START( node );
     2474
     2475        indexerScopedAccept( node->result, *this );
     2476        maybeAccept_impl   ( node->type, *this );
     2477
     2478        VISIT_END( node );
     2479}
     2480
     2481template< typename pass_type >
    17482482Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
    17492483        MUTATE_START( node );
     
    17602494template< typename pass_type >
    17612495void PassVisitor< pass_type >::visit( AsmExpr * node ) {
     2496        VISIT_START( node );
     2497
     2498        indexerScopedAccept( node->result    , *this );
     2499        maybeAccept_impl   ( node->inout     , *this );
     2500        maybeAccept_impl   ( node->constraint, *this );
     2501        maybeAccept_impl   ( node->operand   , *this );
     2502
     2503        VISIT_END( node );
     2504}
     2505
     2506template< typename pass_type >
     2507void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
    17622508        VISIT_START( node );
    17632509
     
    17962542
    17972543template< typename pass_type >
     2544void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
     2545        VISIT_START( node );
     2546
     2547        indexerScopedAccept( node->result    , *this );
     2548        maybeAccept_impl   ( node->callExpr  , *this );
     2549
     2550        VISIT_END( node );
     2551}
     2552
     2553template< typename pass_type >
    17982554Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
    17992555        MUTATE_START( node );
     
    18192575
    18202576template< typename pass_type >
     2577void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
     2578        VISIT_START( node );
     2579
     2580        indexerScopedAccept( node->result  , *this );
     2581        maybeAccept_impl   ( node->callExpr, *this );
     2582
     2583        VISIT_END( node );
     2584}
     2585
     2586template< typename pass_type >
    18212587Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
    18222588        MUTATE_START( node );
     
    18422608
    18432609template< typename pass_type >
     2610void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
     2611        VISIT_START( node );
     2612
     2613        indexerScopedAccept( node->result     , *this );
     2614        maybeAccept_impl   ( node->initializer, *this );
     2615
     2616        VISIT_END( node );
     2617}
     2618
     2619template< typename pass_type >
    18442620Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
    18452621        MUTATE_START( node );
     
    18562632template< typename pass_type >
    18572633void PassVisitor< pass_type >::visit( RangeExpr * node ) {
     2634        VISIT_START( node );
     2635
     2636        indexerScopedAccept( node->result, *this );
     2637        maybeAccept_impl   ( node->low   , *this );
     2638        maybeAccept_impl   ( node->high  , *this );
     2639
     2640        VISIT_END( node );
     2641}
     2642
     2643template< typename pass_type >
     2644void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
    18582645        VISIT_START( node );
    18592646
     
    18902677
    18912678template< typename pass_type >
     2679void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
     2680        VISIT_START( node );
     2681
     2682        indexerScopedAccept( node->result, *this );
     2683        maybeAccept_impl   ( node->exprs , *this );
     2684
     2685        VISIT_END( node );
     2686}
     2687
     2688template< typename pass_type >
    18922689Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
    18932690        MUTATE_START( node );
     
    19132710
    19142711template< typename pass_type >
     2712void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
     2713        VISIT_START( node );
     2714
     2715        indexerScopedAccept( node->result, *this );
     2716        maybeAccept_impl   ( node->exprs , *this );
     2717
     2718        VISIT_END( node );
     2719}
     2720
     2721template< typename pass_type >
    19152722Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
    19162723        MUTATE_START( node );
     
    19362743
    19372744template< typename pass_type >
     2745void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
     2746        VISIT_START( node );
     2747
     2748        indexerScopedAccept( node->result, *this );
     2749        maybeAccept_impl   ( node->tuple , *this );
     2750
     2751        VISIT_END( node );
     2752}
     2753
     2754template< typename pass_type >
    19382755Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
    19392756        MUTATE_START( node );
     
    19542771        indexerScopedAccept( node->result  , *this );
    19552772        maybeAccept_impl   ( node->stmtExpr, *this );
     2773
     2774        VISIT_END( node );
     2775}
     2776
     2777template< typename pass_type >
     2778void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
     2779        VISIT_START( node );
     2780
     2781        indexerScopedAccept( node->result  , *this );
     2782        maybeAccept_impl( node->stmtExpr, *this );
    19562783
    19572784        VISIT_END( node );
     
    19892816
    19902817template< typename pass_type >
    1991 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    1992         MUTATE_START( node );
     2818void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
     2819        VISIT_START( node );
    19932820
    19942821        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     
    19972824        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    19982825
     2826        indexerScopedAccept( node->result     , *this );
     2827        maybeAccept_impl   ( node->statements , *this );
     2828        maybeAccept_impl   ( node->returnDecls, *this );
     2829        maybeAccept_impl   ( node->dtors      , *this );
     2830
     2831        VISIT_END( node );
     2832}
     2833
     2834template< typename pass_type >
     2835Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
     2836        MUTATE_START( node );
     2837
     2838        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     2839        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
     2840        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     2841        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     2842
    19992843        indexerScopedMutate( node->result     , *this );
    20002844        maybeMutate_impl   ( node->statements , *this );
     
    20182862
    20192863template< typename pass_type >
     2864void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
     2865        VISIT_START( node );
     2866
     2867        indexerScopedAccept( node->result, *this );
     2868        maybeAccept_impl   ( node->expr  , *this );
     2869
     2870        VISIT_END( node );
     2871}
     2872
     2873template< typename pass_type >
    20202874Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
    20212875        MUTATE_START( node );
     
    20322886template< typename pass_type >
    20332887void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
     2888        VISIT_START( node );
     2889
     2890        indexerScopedAccept( node->result, *this );
     2891        maybeAccept_impl   ( node->expr  , *this );
     2892        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     2893
     2894        VISIT_END( node );
     2895}
     2896
     2897template< typename pass_type >
     2898void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
    20342899        VISIT_START( node );
    20352900
     
    20672932
    20682933template< typename pass_type >
     2934void PassVisitor< pass_type >::visit( const InitExpr * node ) {
     2935        VISIT_START( node );
     2936
     2937        indexerScopedAccept( node->result, *this );
     2938        maybeAccept_impl   ( node->expr  , *this );
     2939        maybeAccept_impl   ( node->designation, *this );
     2940
     2941        VISIT_END( node );
     2942}
     2943
     2944template< typename pass_type >
    20692945Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
    20702946        MUTATE_START( node );
     
    20852961
    20862962        indexerScopedAccept( node->result, *this );
    2087         maybeAccept_impl( node->expr, *this );
     2963        maybeAccept_impl   ( node->expr, *this );
     2964        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
     2965
     2966        VISIT_END( node );
     2967}
     2968
     2969template< typename pass_type >
     2970void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
     2971        VISIT_START( node );
     2972
     2973        indexerScopedAccept( node->result, *this );
     2974        maybeAccept_impl   ( node->expr, *this );
    20882975        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
    20892976
     
    21092996
    21102997        indexerScopedAccept( node->result, *this );
    2111         maybeAccept_impl( node->expr, *this );
     2998        maybeAccept_impl   ( node->expr, *this );
     2999
     3000        VISIT_END( node );
     3001}
     3002
     3003template< typename pass_type >
     3004void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
     3005        VISIT_START( node );
     3006
     3007        indexerScopedAccept( node->result, *this );
     3008        maybeAccept_impl   ( node->expr, *this );
    21123009
    21133010        VISIT_END( node );
     
    21343031        maybeAccept_impl( node->control, *this );
    21353032        for ( GenericExpr::Association & assoc : node->associations ) {
     3033                indexerScopedAccept( assoc.type, *this );
     3034                maybeAccept_impl( assoc.expr, *this );
     3035        }
     3036
     3037        VISIT_END( node );
     3038}
     3039
     3040template< typename pass_type >
     3041void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
     3042        VISIT_START( node );
     3043
     3044        indexerScopedAccept( node->result, *this );
     3045        maybeAccept_impl( node->control, *this );
     3046        for ( const GenericExpr::Association & assoc : node->associations ) {
    21363047                indexerScopedAccept( assoc.type, *this );
    21373048                maybeAccept_impl( assoc.expr, *this );
     
    21683079
    21693080template< typename pass_type >
     3081void PassVisitor< pass_type >::visit( const VoidType * node ) {
     3082        VISIT_START( node );
     3083
     3084        maybeAccept_impl( node->forall, *this );
     3085
     3086        VISIT_END( node );
     3087}
     3088
     3089template< typename pass_type >
    21703090Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
    21713091        MUTATE_START( node );
     
    21803100template< typename pass_type >
    21813101void PassVisitor< pass_type >::visit( BasicType * node ) {
     3102        VISIT_START( node );
     3103
     3104        maybeAccept_impl( node->forall, *this );
     3105
     3106        VISIT_END( node );
     3107}
     3108
     3109template< typename pass_type >
     3110void PassVisitor< pass_type >::visit( const BasicType * node ) {
    21823111        VISIT_START( node );
    21833112
     
    22103139
    22113140template< typename pass_type >
     3141void PassVisitor< pass_type >::visit( const PointerType * node ) {
     3142        VISIT_START( node );
     3143
     3144        maybeAccept_impl( node->forall, *this );
     3145        // xxx - should PointerType visit/mutate dimension?
     3146        maybeAccept_impl( node->base, *this );
     3147
     3148        VISIT_END( node );
     3149}
     3150
     3151template< typename pass_type >
    22123152Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
    22133153        MUTATE_START( node );
     
    22343174
    22353175template< typename pass_type >
     3176void PassVisitor< pass_type >::visit( const ArrayType * node ) {
     3177        VISIT_START( node );
     3178
     3179        maybeAccept_impl( node->forall, *this );
     3180        maybeAccept_impl( node->dimension, *this );
     3181        maybeAccept_impl( node->base, *this );
     3182
     3183        VISIT_END( node );
     3184}
     3185
     3186template< typename pass_type >
    22363187Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
    22373188        MUTATE_START( node );
     
    22573208
    22583209template< typename pass_type >
     3210void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
     3211        VISIT_START( node );
     3212
     3213        maybeAccept_impl( node->forall, *this );
     3214        maybeAccept_impl( node->base, *this );
     3215
     3216        VISIT_END( node );
     3217}
     3218
     3219template< typename pass_type >
    22593220Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
    22603221        MUTATE_START( node );
     
    22803241
    22813242template< typename pass_type >
     3243void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
     3244        VISIT_START( node );
     3245
     3246        maybeAccept_impl( node->forall, *this );
     3247        maybeAccept_impl( node->parent, *this );
     3248        maybeAccept_impl( node->child, *this );
     3249
     3250        VISIT_END( node );
     3251}
     3252
     3253template< typename pass_type >
    22823254Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
    22833255        MUTATE_START( node );
     
    23043276
    23053277template< typename pass_type >
     3278void PassVisitor< pass_type >::visit( const FunctionType * node ) {
     3279        VISIT_START( node );
     3280
     3281        maybeAccept_impl( node->forall, *this );
     3282        maybeAccept_impl( node->returnVals, *this );
     3283        maybeAccept_impl( node->parameters, *this );
     3284
     3285        VISIT_END( node );
     3286}
     3287
     3288template< typename pass_type >
    23063289Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
    23073290        MUTATE_START( node );
     
    23323315
    23333316template< typename pass_type >
     3317void PassVisitor< pass_type >::visit( const StructInstType * node ) {
     3318        VISIT_START( node );
     3319
     3320        indexerAddStruct( node->name );
     3321
     3322        {
     3323                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     3324                maybeAccept_impl( node->forall    , *this );
     3325                maybeAccept_impl( node->parameters, *this );
     3326        }
     3327
     3328        VISIT_END( node );
     3329}
     3330
     3331template< typename pass_type >
    23343332Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
    23353333        MUTATE_START( node );
     
    23643362
    23653363template< typename pass_type >
     3364void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
     3365        VISIT_START( node );
     3366
     3367        indexerAddStruct( node->name );
     3368
     3369        {
     3370                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     3371                maybeAccept_impl( node->forall    , *this );
     3372                maybeAccept_impl( node->parameters, *this );
     3373        }
     3374
     3375        VISIT_END( node );
     3376}
     3377
     3378template< typename pass_type >
    23663379Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
    23673380        MUTATE_START( node );
     
    23913404
    23923405template< typename pass_type >
     3406void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
     3407        VISIT_START( node );
     3408
     3409        maybeAccept_impl( node->forall, *this );
     3410        maybeAccept_impl( node->parameters, *this );
     3411
     3412        VISIT_END( node );
     3413}
     3414
     3415template< typename pass_type >
    23933416Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
    23943417        MUTATE_START( node );
     
    24133436
    24143437template< typename pass_type >
     3438void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
     3439        VISIT_START( node );
     3440
     3441        maybeAccept_impl( node->forall    , *this );
     3442        maybeAccept_impl( node->parameters, *this );
     3443
     3444        VISIT_END( node );
     3445}
     3446
     3447template< typename pass_type >
    24153448Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
    24163449        MUTATE_START( node );
     
    24263459template< typename pass_type >
    24273460void PassVisitor< pass_type >::visit( TypeInstType * node ) {
     3461        VISIT_START( node );
     3462
     3463        maybeAccept_impl( node->forall    , *this );
     3464        maybeAccept_impl( node->parameters, *this );
     3465
     3466        VISIT_END( node );
     3467}
     3468
     3469template< typename pass_type >
     3470void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
    24283471        VISIT_START( node );
    24293472
     
    24583501
    24593502template< typename pass_type >
     3503void PassVisitor< pass_type >::visit( const TupleType * node ) {
     3504        VISIT_START( node );
     3505
     3506        maybeAccept_impl( node->forall, *this );
     3507        maybeAccept_impl( node->types, *this );
     3508        maybeAccept_impl( node->members, *this );
     3509
     3510        VISIT_END( node );
     3511}
     3512
     3513template< typename pass_type >
    24603514Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
    24613515        MUTATE_START( node );
     
    24723526template< typename pass_type >
    24733527void PassVisitor< pass_type >::visit( TypeofType * node ) {
     3528        VISIT_START( node );
     3529
     3530        assert( node->expr );
     3531        maybeAccept_impl( node->expr, *this );
     3532
     3533        VISIT_END( node );
     3534}
     3535
     3536template< typename pass_type >
     3537void PassVisitor< pass_type >::visit( const TypeofType * node ) {
    24743538        VISIT_START( node );
    24753539
     
    25083572
    25093573template< typename pass_type >
     3574void PassVisitor< pass_type >::visit( const AttrType * node ) {
     3575        VISIT_START( node );
     3576
     3577        if ( node->isType ) {
     3578                assert( node->type );
     3579                maybeAccept_impl( node->type, *this );
     3580        } else {
     3581                assert( node->expr );
     3582                maybeAccept_impl( node->expr, *this );
     3583        } // if
     3584
     3585        VISIT_END( node );
     3586}
     3587
     3588template< typename pass_type >
    25103589Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
    25113590        MUTATE_START( node );
     
    25343613
    25353614template< typename pass_type >
     3615void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
     3616        VISIT_START( node );
     3617
     3618        maybeAccept_impl( node->forall, *this );
     3619
     3620        VISIT_END( node );
     3621}
     3622
     3623template< typename pass_type >
    25363624Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
    25373625        MUTATE_START( node );
     
    25543642
    25553643template< typename pass_type >
     3644void PassVisitor< pass_type >::visit( const ZeroType * node ) {
     3645        VISIT_START( node );
     3646
     3647        maybeAccept_impl( node->forall, *this );
     3648
     3649        VISIT_END( node );
     3650}
     3651
     3652template< typename pass_type >
    25563653Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
    25573654        MUTATE_START( node );
     
    25743671
    25753672template< typename pass_type >
     3673void PassVisitor< pass_type >::visit( const OneType * node ) {
     3674        VISIT_START( node );
     3675
     3676        maybeAccept_impl( node->forall, *this );
     3677
     3678        VISIT_END( node );
     3679}
     3680
     3681template< typename pass_type >
    25763682Type * PassVisitor< pass_type >::mutate( OneType * node ) {
    25773683        MUTATE_START( node );
     
    25943700
    25953701template< typename pass_type >
     3702void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
     3703        VISIT_START( node );
     3704
     3705        maybeAccept_impl( node->forall, *this );
     3706
     3707        VISIT_END( node );
     3708}
     3709
     3710template< typename pass_type >
    25963711Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
    25973712        MUTATE_START( node );
     
    26143729
    26153730template< typename pass_type >
     3731void PassVisitor< pass_type >::visit( const Designation * node ) {
     3732        VISIT_START( node );
     3733
     3734        maybeAccept_impl( node->designators, *this );
     3735
     3736        VISIT_END( node );
     3737}
     3738
     3739template< typename pass_type >
    26163740Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
    26173741        MUTATE_START( node );
     
    26343758
    26353759template< typename pass_type >
     3760void PassVisitor< pass_type >::visit( const SingleInit * node ) {
     3761        VISIT_START( node );
     3762
     3763        visitExpression( node->value );
     3764
     3765        VISIT_END( node );
     3766}
     3767
     3768template< typename pass_type >
    26363769Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
    26373770        MUTATE_START( node );
     
    26463779template< typename pass_type >
    26473780void PassVisitor< pass_type >::visit( ListInit * node ) {
     3781        VISIT_START( node );
     3782
     3783        maybeAccept_impl( node->designations, *this );
     3784        maybeAccept_impl( node->initializers, *this );
     3785
     3786        VISIT_END( node );
     3787}
     3788
     3789template< typename pass_type >
     3790void PassVisitor< pass_type >::visit( const ListInit * node ) {
    26483791        VISIT_START( node );
    26493792
     
    26783821
    26793822template< typename pass_type >
     3823void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
     3824        VISIT_START( node );
     3825
     3826        maybeAccept_impl( node->ctor, *this );
     3827        maybeAccept_impl( node->dtor, *this );
     3828        maybeAccept_impl( node->init, *this );
     3829
     3830        VISIT_END( node );
     3831}
     3832
     3833template< typename pass_type >
    26803834Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
    26813835        MUTATE_START( node );
     
    26983852
    26993853template< typename pass_type >
     3854void PassVisitor< pass_type >::visit( const Constant * node ) {
     3855        VISIT_START( node );
     3856
     3857        VISIT_END( node );
     3858}
     3859
     3860template< typename pass_type >
    27003861Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
    27013862        MUTATE_START( node );
     
    27083869template< typename pass_type >
    27093870void PassVisitor< pass_type >::visit( Attribute * node ) {
     3871        VISIT_START( node );
     3872
     3873        maybeAccept_impl( node->parameters, *this );
     3874
     3875        VISIT_END( node );
     3876}
     3877
     3878template< typename pass_type >
     3879void PassVisitor< pass_type >::visit( const Attribute * node ) {
    27103880        VISIT_START( node );
    27113881
Note: See TracChangeset for help on using the changeset viewer.