source: src/Common/PassVisitor.impl.h @ 77a3f41

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 77a3f41 was 6a625de, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Some clean-up, some more assertions to check assumptions and changes to node.hpp

  • Property mode set to 100644
File size: 79.6 KB
Line 
1#pragma once
2// IWYU pragma: private, include "PassVisitor.h"
3
4#define VISIT_START( node )                                     \
5        __attribute__((unused))                                   \
6        ChildrenGuard children_guard( get_visit_children_ptr() ); \
7        __attribute__((unused))                                   \
8        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
9        call_previsit( node );                                    \
10
11#define VISIT_END( node )                       \
12        call_postvisit( node );                   \
13
14#define MUTATE_START( node )                                    \
15        __attribute__((unused))                                   \
16        ChildrenGuard children_guard( get_visit_children_ptr() ); \
17        __attribute__((unused))                                   \
18        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
19        call_premutate( node );                                   \
20
21#define MUTATE_END( type, node )                \
22        auto __return = call_postmutate< type * >( node ); \
23        assert( __return ); \
24        return __return;
25
26
27#define VISIT_BODY( node )          \
28        VISIT_START( node );          \
29        if( children_guard ) {        \
30                Visitor::visit( node ); \
31        }                             \
32        VISIT_END( node );            \
33
34
35#define MUTATE_BODY( type, node )    \
36        MUTATE_START( node );          \
37        if( children_guard ) {         \
38                Mutator::mutate( node ); \
39        }                              \
40        MUTATE_END( type, node );      \
41
42
43
44template<typename T>
45static inline bool empty( T * ptr ) {
46        return !ptr || ptr->empty();
47}
48
49typedef std::list< Statement   * > StmtList_t;
50typedef std::list< Declaration * > DeclList_t;
51
52template<typename iterator_t>
53static inline void splice( iterator_t it, DeclList_t * decls ) {
54        std::transform(
55                decls->begin(),
56                decls->end(),
57                it,
58                [](Declaration * decl) -> auto {
59                        return new DeclStmt( decl );
60                }
61        );
62        decls->clear();
63}
64
65template< typename pass_type >
66inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
67        DeclList_t* beforeDecls = visitor.get_beforeDecls();
68        DeclList_t* afterDecls  = visitor.get_afterDecls();
69        SemanticErrorException errors;
70
71        pass_visitor_stats.depth++;
72        pass_visitor_stats.max->push(pass_visitor_stats.depth);
73        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
74        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
75
76
77                // splice in new declarations after previous decl
78                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
79
80                if ( i == decls.end() ) break;
81
82                try {
83                        // run visitor on declaration
84                        maybeAccept_impl( *i, visitor );
85                } catch( SemanticErrorException &e ) {
86                        errors.append( e );
87                }
88
89                // splice in new declarations before current decl
90                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
91        }
92        pass_visitor_stats.depth--;
93        if ( ! errors.isEmpty() ) {
94                throw errors;
95        }
96}
97
98template< typename pass_type >
99inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
100        DeclList_t* beforeDecls = mutator.get_beforeDecls();
101        DeclList_t* afterDecls  = mutator.get_afterDecls();
102        SemanticErrorException errors;
103
104        pass_visitor_stats.depth++;
105        pass_visitor_stats.max->push(pass_visitor_stats.depth);
106        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
107        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
108                // splice in new declarations after previous decl
109                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
110
111                if ( i == decls.end() ) break;
112                try {
113                        // run mutator on declaration
114                        maybeMutate_impl( *i, mutator );
115                } catch( SemanticErrorException &e ) {
116                        errors.append( e );
117                }
118
119                // splice in new declarations before current decl
120                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
121        }
122        pass_visitor_stats.depth--;
123        if ( ! errors.isEmpty() ) {
124                throw errors;
125        }
126}
127
128template< typename TreeType, typename pass_type >
129inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) {
130        if ( ! visitor.get_visit_children() ) return;
131        if ( tree ) {
132                tree->accept( visitor );
133        }
134}
135
136template< typename Container, typename pass_type >
137inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
138        if ( ! visitor.get_visit_children() ) return;
139        SemanticErrorException errors;
140
141        pass_visitor_stats.depth++;
142        pass_visitor_stats.max->push(pass_visitor_stats.depth);
143        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
144        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
145                try {
146                        if ( *i ) {
147                                (*i)->accept( visitor );
148                        }
149                } catch( SemanticErrorException &e ) {
150                        errors.append( e );
151                }
152        }
153        pass_visitor_stats.depth--;
154        if ( ! errors.isEmpty() ) {
155                throw errors;
156        }
157}
158
159template< typename TreeType, typename pass_type >
160inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) {
161        if ( ! mutator.get_visit_children() ) return;
162
163        if ( tree ) {
164                tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) );
165        }
166}
167
168template< typename Container, typename pass_type >
169inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
170        if ( ! mutator.get_visit_children() ) return;
171        SemanticErrorException errors;
172
173        pass_visitor_stats.depth++;
174        pass_visitor_stats.max->push(pass_visitor_stats.depth);
175        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
176        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
177                try {
178                        if ( *i ) {
179                                *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
180                                assert( *i );
181                        } // if
182                } catch( SemanticErrorException &e ) {
183                        errors.append( e );
184                } // try
185        } // for
186        pass_visitor_stats.depth--;
187        if ( ! errors.isEmpty() ) {
188                throw errors;
189        } // if
190}
191
192template< typename pass_type >
193template< typename func_t >
194void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
195        if ( ! get_visit_children() ) return;
196        SemanticErrorException errors;
197
198        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
199        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
200        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
201        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
202        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
203
204        StmtList_t* beforeStmts = get_beforeStmts();
205        StmtList_t* afterStmts  = get_afterStmts();
206        DeclList_t* beforeDecls = get_beforeDecls();
207        DeclList_t* afterDecls  = get_afterDecls();
208
209        pass_visitor_stats.depth++;
210        pass_visitor_stats.max->push(pass_visitor_stats.depth);
211        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
212        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
213
214                if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
215                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
216
217                try {
218                        func( *i );
219                        assert(( empty( beforeStmts ) && empty( afterStmts ))
220                            || ( empty( beforeDecls ) && empty( afterDecls )) );
221
222                } catch ( SemanticErrorException &e ) {
223                        errors.append( e );
224                }
225
226                if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
227                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
228        }
229        pass_visitor_stats.depth--;
230
231        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
232        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
233        if ( !errors.isEmpty() ) { throw errors; }
234}
235
236template< typename pass_type >
237void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
238        handleStatementList( statements, [this]( Statement * stmt) {
239                maybeAccept_impl( stmt, *this );
240        });
241}
242
243template< typename pass_type >
244void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
245        handleStatementList( statements, [this]( Statement *& stmt) {
246                maybeMutate_impl( stmt, *this );
247        });
248}
249
250
251template< typename pass_type >
252template< typename func_t >
253Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
254        if ( ! get_visit_children() ) return stmt;
255
256        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
257        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
258        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
259        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
260        ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
261        ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
262
263        Statement *newStmt = func( stmt );
264
265        StmtList_t* beforeStmts = get_beforeStmts();
266        StmtList_t* afterStmts  = get_afterStmts();
267        DeclList_t* beforeDecls = get_beforeDecls();
268        DeclList_t* afterDecls  = get_afterDecls();
269
270        if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
271        assert(( empty( beforeStmts ) && empty( afterStmts ))
272            || ( empty( beforeDecls ) && empty( afterDecls )) );
273
274        CompoundStmt *compound = new CompoundStmt();
275        if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
276        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
277        compound->get_kids().push_back( newStmt );
278        if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
279        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
280        return compound;
281}
282
283template< typename pass_type >
284Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
285        return handleStatement( stmt, [this]( Statement * stmt ) {
286                maybeAccept_impl( stmt, *this );
287                return stmt;
288        });
289}
290
291template< typename pass_type >
292Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
293        return handleStatement( stmt, [this]( Statement * stmt ) {
294                maybeMutate_impl( stmt, *this );
295                return stmt;
296        });
297}
298
299template< typename pass_type >
300template< typename func_t >
301Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
302        if ( ! get_visit_children() ) return expr;
303        if( !expr ) return nullptr;
304
305        auto env_ptr = get_env_ptr();
306        if ( env_ptr && expr->get_env() ) {
307                *env_ptr = expr->get_env();
308        }
309
310        // should env be moved onto the result of the mutate?
311        return func( expr );
312}
313
314template< typename pass_type >
315Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
316        return handleExpression(expr, [this]( Expression * expr ) {
317                maybeAccept_impl( expr, *this );
318                return expr;
319        });
320}
321
322template< typename pass_type >
323Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
324        return handleExpression(expr, [this]( Expression * expr ) {
325                maybeMutate_impl( expr, *this );
326                return expr;
327        });
328}
329
330template< typename TreeType, typename VisitorType >
331inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
332        if ( ! visitor.get_visit_children() ) return;
333        auto guard = makeFuncGuard(
334                [&visitor]() { visitor.indexerScopeEnter(); },
335                [&visitor]() { visitor.indexerScopeLeave(); }
336        );
337        maybeAccept_impl( tree, visitor );
338}
339
340template< typename TreeType, typename MutatorType >
341inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {
342        if ( ! mutator.get_visit_children() ) return;
343        auto guard = makeFuncGuard(
344                [&mutator]() { mutator.indexerScopeEnter(); },
345                [&mutator]() { mutator.indexerScopeLeave(); }
346        );
347        maybeMutate_impl( tree, mutator );
348}
349
350//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
351//========================================================================================================================================================================
352//========================================================================================================================================================================
353//========================================================================================================================================================================
354//========================================================================================================================================================================
355//========================================================================================================================================================================
356//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
357
358// A NOTE ON THE ORDER OF TRAVERSAL
359//
360// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
361// no such thing as a recursive type or typedef.
362//
363//             typedef struct { T *x; } T; // never allowed
364//
365// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
366// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
367// declaration).
368//
369//             struct T { struct T *x; }; // allowed
370//
371// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
372// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
373// queried later in this pass.
374//
375// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
376
377//--------------------------------------------------------------------------
378// ObjectDecl
379template< typename pass_type >
380void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
381        VISIT_START( node );
382
383        indexerScopedAccept( node->type         , *this );
384        maybeAccept_impl   ( node->init         , *this );
385        maybeAccept_impl   ( node->bitfieldWidth, *this );
386        maybeAccept_impl   ( node->attributes   , *this );
387
388        indexerAddId( node );
389
390        VISIT_END( node );
391}
392
393template< typename pass_type >
394DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
395        MUTATE_START( node );
396
397        indexerScopedMutate( node->type         , *this );
398        maybeMutate_impl   ( node->init         , *this );
399        maybeMutate_impl   ( node->bitfieldWidth, *this );
400        maybeMutate_impl   ( node->attributes   , *this );
401
402        indexerAddId( node );
403
404        MUTATE_END( DeclarationWithType, node );
405}
406
407//--------------------------------------------------------------------------
408// FunctionDecl
409template< typename pass_type >
410void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
411        VISIT_START( node );
412
413        indexerAddId( node );
414
415        maybeAccept_impl( node->withExprs, *this );
416        {
417                // with clause introduces a level of scope (for the with expression members).
418                // with clause exprs are added to the indexer before parameters so that parameters
419                // shadow with exprs and not the other way around.
420                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
421                indexerAddWith( node->withExprs, node );
422                {
423                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
424                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
425                        static ObjectDecl func(
426                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
427                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
428                                nullptr
429                        );
430                        indexerAddId( &func );
431                        maybeAccept_impl( node->type, *this );
432                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
433                        // a new scope if inFunction is true
434                        ValueGuard< bool > oldInFunction( inFunction );
435                        inFunction = true;
436                        maybeAccept_impl( node->statements, *this );
437                        maybeAccept_impl( node->attributes, *this );
438                }
439        }
440
441        VISIT_END( node );
442}
443
444template< typename pass_type >
445DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
446        MUTATE_START( node );
447
448        indexerAddId( node );
449
450        {
451                // with clause introduces a level of scope (for the with expression members).
452                // with clause exprs are added to the indexer before parameters so that parameters
453                // shadow with exprs and not the other way around.
454                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
455                indexerAddWith( node->withExprs, node );
456                {
457                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
458                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
459                        static ObjectDecl func(
460                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
461                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
462                                nullptr
463                        );
464                        indexerAddId( &func );
465                        maybeMutate_impl( node->type, *this );
466                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
467                        // a new scope if inFunction is true
468                        ValueGuard< bool > oldInFunction( inFunction );
469                        inFunction = true;
470                        maybeMutate_impl( node->statements, *this );
471                        maybeMutate_impl( node->attributes, *this );
472                }
473        }
474
475        MUTATE_END( DeclarationWithType, node );
476}
477
478//--------------------------------------------------------------------------
479// StructDecl
480template< typename pass_type >
481void PassVisitor< pass_type >::visit( StructDecl * node ) {
482        VISIT_START( node );
483
484        // make up a forward declaration and add it before processing the members
485        // needs to be on the heap because addStruct saves the pointer
486        indexerAddStructFwd( node );
487
488        {
489                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
490                maybeAccept_impl( node->parameters, *this );
491                maybeAccept_impl( node->members   , *this );
492        }
493
494        // this addition replaces the forward declaration
495        indexerAddStruct( node );
496
497        VISIT_END( node );
498}
499
500template< typename pass_type >
501Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
502        MUTATE_START( node );
503
504        // make up a forward declaration and add it before processing the members
505        // needs to be on the heap because addStruct saves the pointer
506        indexerAddStructFwd( node );
507
508        {
509                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
510                maybeMutate_impl( node->parameters, *this );
511                maybeMutate_impl( node->members   , *this );
512        }
513
514        // this addition replaces the forward declaration
515        indexerAddStruct( node );
516
517        MUTATE_END( Declaration, node );
518}
519
520//--------------------------------------------------------------------------
521// UnionDecl
522template< typename pass_type >
523void PassVisitor< pass_type >::visit( UnionDecl * node ) {
524        VISIT_START( node );
525
526        // make up a forward declaration and add it before processing the members
527        indexerAddUnionFwd( node );
528
529        {
530                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
531                maybeAccept_impl( node->parameters, *this );
532                maybeAccept_impl( node->members   , *this );
533        }
534
535        indexerAddUnion( node );
536
537        VISIT_END( node );
538}
539
540template< typename pass_type >
541Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
542        MUTATE_START( node );
543
544        // make up a forward declaration and add it before processing the members
545        indexerAddUnionFwd( node );
546
547        {
548                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
549                maybeMutate_impl( node->parameters, *this );
550                maybeMutate_impl( node->members   , *this );
551        }
552
553        indexerAddUnion( node );
554
555        MUTATE_END( Declaration, node );
556}
557
558//--------------------------------------------------------------------------
559// EnumDecl
560template< typename pass_type >
561void PassVisitor< pass_type >::visit( EnumDecl * node ) {
562        VISIT_START( node );
563
564        indexerAddEnum( node );
565
566        // unlike structs, traits, and unions, enums inject their members into the global scope
567        maybeAccept_impl( node->parameters, *this );
568        maybeAccept_impl( node->members   , *this );
569
570        VISIT_END( node );
571}
572
573template< typename pass_type >
574Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
575        MUTATE_START( node );
576
577        indexerAddEnum( node );
578
579        // unlike structs, traits, and unions, enums inject their members into the global scope
580        maybeMutate_impl( node->parameters, *this );
581        maybeMutate_impl( node->members   , *this );
582
583        MUTATE_END( Declaration, node );
584}
585
586//--------------------------------------------------------------------------
587// TraitDecl
588template< typename pass_type >
589void PassVisitor< pass_type >::visit( TraitDecl * node ) {
590        VISIT_START( node );
591
592        {
593                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
594                maybeAccept_impl( node->parameters, *this );
595                maybeAccept_impl( node->members   , *this );
596        }
597
598        indexerAddTrait( node );
599
600        VISIT_END( node );
601}
602
603template< typename pass_type >
604Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
605        MUTATE_START( node );
606
607        {
608                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
609                maybeMutate_impl( node->parameters, *this );
610                maybeMutate_impl( node->members   , *this );
611        }
612
613        indexerAddTrait( node );
614
615        MUTATE_END( Declaration, node );
616}
617
618//--------------------------------------------------------------------------
619// TypeDecl
620template< typename pass_type >
621void PassVisitor< pass_type >::visit( TypeDecl * node ) {
622        VISIT_START( node );
623
624        {
625                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
626                maybeAccept_impl( node->parameters, *this );
627                maybeAccept_impl( node->base      , *this );
628        }
629
630        // see A NOTE ON THE ORDER OF TRAVERSAL, above
631        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
632        // and may depend on the type itself
633        indexerAddType( node );
634
635        maybeAccept_impl( node->assertions, *this );
636
637        indexerScopedAccept( node->init, *this );
638
639        VISIT_END( node );
640}
641
642template< typename pass_type >
643Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
644        MUTATE_START( node );
645
646        {
647                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
648                maybeMutate_impl( node->parameters, *this );
649                maybeMutate_impl( node->base      , *this );
650        }
651
652        // see A NOTE ON THE ORDER OF TRAVERSAL, above
653        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
654        // and may depend on the type itself
655        indexerAddType( node );
656
657        maybeMutate_impl( node->assertions, *this );
658
659        indexerScopedMutate( node->init, *this );
660
661        MUTATE_END( Declaration, node );
662}
663
664//--------------------------------------------------------------------------
665// TypedefDecl
666template< typename pass_type >
667void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
668        VISIT_START( node );
669
670        {
671                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
672                maybeAccept_impl( node->parameters, *this );
673                maybeAccept_impl( node->base      , *this );
674        }
675
676        indexerAddType( node );
677
678        maybeAccept_impl( node->assertions, *this );
679
680        VISIT_END( node );
681}
682
683template< typename pass_type >
684Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
685        MUTATE_START( node );
686
687        {
688                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
689                maybeMutate_impl( node->parameters, *this );
690                maybeMutate_impl( node->base      , *this );
691        }
692
693        indexerAddType( node );
694
695        maybeMutate_impl( node->assertions, *this );
696
697        MUTATE_END( Declaration, node );
698}
699
700//--------------------------------------------------------------------------
701// AsmDecl
702template< typename pass_type >
703void PassVisitor< pass_type >::visit( AsmDecl * node ) {
704        VISIT_START( node );
705
706        maybeAccept_impl( node->stmt, *this );
707
708        VISIT_END( node );
709}
710
711template< typename pass_type >
712AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
713        MUTATE_START( node );
714
715        maybeMutate_impl( node->stmt, *this );
716
717        MUTATE_END( AsmDecl, node );
718}
719
720//--------------------------------------------------------------------------
721// StaticAssertDecl
722template< typename pass_type >
723void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) {
724        VISIT_START( node );
725
726        node->condition = visitExpression( node->condition );
727        maybeAccept_impl( node->message, *this );
728
729        VISIT_END( node );
730}
731
732template< typename pass_type >
733StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
734        MUTATE_START( node );
735
736        node->condition = mutateExpression( node->condition );
737        maybeMutate_impl( node->message, *this );
738
739        MUTATE_END( StaticAssertDecl, node );
740}
741
742//--------------------------------------------------------------------------
743// CompoundStmt
744template< typename pass_type >
745void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
746        VISIT_START( node );
747        {
748                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
749                ValueGuard< bool > oldInFunction( inFunction );
750                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
751                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
752                inFunction = false;
753                visitStatementList( node->kids );
754        }
755        VISIT_END( node );
756}
757
758template< typename pass_type >
759CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
760        MUTATE_START( node );
761        {
762                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
763                ValueGuard< bool > oldInFunction( inFunction );
764                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
765                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
766                inFunction = false;
767                mutateStatementList( node->kids );
768        }
769        MUTATE_END( CompoundStmt, node );
770}
771
772//--------------------------------------------------------------------------
773// ExprStmt
774template< typename pass_type >
775void PassVisitor< pass_type >::visit( ExprStmt * node ) {
776        VISIT_START( node );
777
778        visitExpression( node->expr );
779
780        VISIT_END( node );
781}
782
783template< typename pass_type >
784Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
785        MUTATE_START( node );
786
787        node->expr = mutateExpression( node->expr );
788
789        MUTATE_END( Statement, node );
790}
791
792//--------------------------------------------------------------------------
793// AsmStmt
794template< typename pass_type >
795void PassVisitor< pass_type >::visit( AsmStmt * node ) {
796        VISIT_START( node )
797
798        maybeAccept_impl( node->instruction, *this );
799        maybeAccept_impl( node->output, *this );
800        maybeAccept_impl( node->input, *this );
801        maybeAccept_impl( node->clobber, *this );
802
803        VISIT_END( node );
804}
805
806template< typename pass_type >
807Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
808        MUTATE_START( node );
809
810        maybeMutate_impl( node->instruction, *this );
811        maybeMutate_impl( node->output, *this );
812        maybeMutate_impl( node->input, *this );
813        maybeMutate_impl( node->clobber, *this );
814
815        MUTATE_END( Statement, node );
816}
817
818//--------------------------------------------------------------------------
819// AsmStmt
820template< typename pass_type >
821void PassVisitor< pass_type >::visit( DirectiveStmt * node ) {
822        VISIT_START( node )
823
824        VISIT_END( node );
825}
826
827template< typename pass_type >
828Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
829        MUTATE_START( node );
830
831        MUTATE_END( Statement, node );
832}
833
834//--------------------------------------------------------------------------
835// IfStmt
836template< typename pass_type >
837void PassVisitor< pass_type >::visit( IfStmt * node ) {
838        VISIT_START( node );
839        {
840                // if statements introduce a level of scope (for the initialization)
841                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
842                maybeAccept_impl( node->get_initialization(), *this );
843                visitExpression ( node->condition );
844                node->thenPart = visitStatement( node->thenPart );
845                node->elsePart = visitStatement( node->elsePart );
846        }
847        VISIT_END( node );
848}
849
850template< typename pass_type >
851Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
852        MUTATE_START( node );
853        {
854                // if statements introduce a level of scope (for the initialization)
855                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
856                maybeMutate_impl( node->get_initialization(), *this );
857                node->condition = mutateExpression( node->condition );
858                node->thenPart  = mutateStatement ( node->thenPart  );
859                node->elsePart  = mutateStatement ( node->elsePart  );
860        }
861        MUTATE_END( Statement, node );
862}
863
864//--------------------------------------------------------------------------
865// WhileStmt
866template< typename pass_type >
867void PassVisitor< pass_type >::visit( WhileStmt * node ) {
868        VISIT_START( node );
869
870        {
871                // while statements introduce a level of scope (for the initialization)
872                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
873                maybeAccept_impl( node->initialization, *this );
874                visitExpression ( node->condition );
875                node->body = visitStatement( node->body );
876        }
877
878        VISIT_END( node );
879}
880
881template< typename pass_type >
882Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
883        MUTATE_START( node );
884
885        {
886                // while statements introduce a level of scope (for the initialization)
887                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
888                maybeMutate_impl( node->initialization, *this );
889                node->condition = mutateExpression( node->condition );
890                node->body      = mutateStatement ( node->body      );
891        }
892
893
894        MUTATE_END( Statement, node );
895}
896
897//--------------------------------------------------------------------------
898// ForStmt
899template< typename pass_type >
900void PassVisitor< pass_type >::visit( ForStmt * node ) {
901        VISIT_START( node );
902        {
903                // for statements introduce a level of scope (for the initialization)
904                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
905                maybeAccept_impl( node->initialization, *this );
906                visitExpression( node->condition );
907                visitExpression( node->increment );
908                node->body = visitStatement( node->body );
909        }
910        VISIT_END( node );
911}
912
913template< typename pass_type >
914Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
915        MUTATE_START( node );
916        {
917                // for statements introduce a level of scope (for the initialization)
918                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
919                maybeMutate_impl( node->initialization, *this );
920                node->condition = mutateExpression( node->condition );
921                node->increment = mutateExpression( node->increment );
922                node->body      = mutateStatement ( node->body      );
923        }
924        MUTATE_END( Statement, node );
925}
926
927//--------------------------------------------------------------------------
928// SwitchStmt
929template< typename pass_type >
930void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
931        VISIT_START( node );
932
933        visitExpression   ( node->condition  );
934        visitStatementList( node->statements );
935
936        VISIT_END( node );
937}
938
939template< typename pass_type >
940Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
941        MUTATE_START( node );
942
943        node->condition = mutateExpression( node->condition );
944        mutateStatementList( node->statements );
945
946        MUTATE_END( Statement, node );
947}
948
949//--------------------------------------------------------------------------
950// CaseStmt
951template< typename pass_type >
952void PassVisitor< pass_type >::visit( CaseStmt * node ) {
953        VISIT_START( node );
954
955        visitExpression   ( node->condition );
956        visitStatementList( node->stmts     );
957
958        VISIT_END( node );
959}
960
961template< typename pass_type >
962Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
963        MUTATE_START( node );
964
965        node->condition = mutateExpression( node->condition );
966        mutateStatementList( node->stmts );
967
968        MUTATE_END( Statement, node );
969}
970
971//--------------------------------------------------------------------------
972// BranchStmt
973template< typename pass_type >
974void PassVisitor< pass_type >::visit( BranchStmt * node ) {
975        VISIT_START( node );
976        VISIT_END( node );
977}
978
979template< typename pass_type >
980Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
981        MUTATE_START( node );
982        MUTATE_END( Statement, node );
983}
984
985//--------------------------------------------------------------------------
986// ReturnStmt
987template< typename pass_type >
988void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
989        VISIT_START( node );
990
991        visitExpression( node->expr );
992
993        VISIT_END( node );
994}
995
996template< typename pass_type >
997Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
998        MUTATE_START( node );
999
1000        node->expr = mutateExpression( node->expr );
1001
1002        MUTATE_END( Statement, node );
1003}
1004
1005//--------------------------------------------------------------------------
1006// ThrowStmt
1007
1008template< typename pass_type >
1009void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
1010        VISIT_START( node );
1011
1012        maybeAccept_impl( node->expr, *this );
1013        maybeAccept_impl( node->target, *this );
1014
1015        VISIT_END( node );
1016}
1017
1018template< typename pass_type >
1019Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
1020        MUTATE_START( node );
1021
1022        maybeMutate_impl( node->expr, *this );
1023        maybeMutate_impl( node->target, *this );
1024
1025        MUTATE_END( Statement, node );
1026}
1027
1028//--------------------------------------------------------------------------
1029// TryStmt
1030template< typename pass_type >
1031void PassVisitor< pass_type >::visit( TryStmt * node ) {
1032        VISIT_START( node );
1033
1034        maybeAccept_impl( node->block       , *this );
1035        maybeAccept_impl( node->handlers    , *this );
1036        maybeAccept_impl( node->finallyBlock, *this );
1037
1038        VISIT_END( node );
1039}
1040
1041template< typename pass_type >
1042Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
1043        MUTATE_START( node );
1044
1045        maybeMutate_impl( node->block       , *this );
1046        maybeMutate_impl( node->handlers    , *this );
1047        maybeMutate_impl( node->finallyBlock, *this );
1048
1049        MUTATE_END( Statement, node );
1050}
1051
1052//--------------------------------------------------------------------------
1053// CatchStmt
1054template< typename pass_type >
1055void PassVisitor< pass_type >::visit( CatchStmt * node ) {
1056        VISIT_START( node );
1057        {
1058                // catch statements introduce a level of scope (for the caught exception)
1059                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1060                maybeAccept_impl( node->decl, *this );
1061                node->cond = visitExpression( node->cond );
1062                node->body = visitStatement ( node->body );
1063        }
1064        VISIT_END( node );
1065}
1066
1067template< typename pass_type >
1068Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
1069        MUTATE_START( node );
1070        {
1071                // catch statements introduce a level of scope (for the caught exception)
1072                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1073                maybeMutate_impl( node->decl, *this );
1074                node->cond = mutateExpression( node->cond );
1075                node->body = mutateStatement ( node->body );
1076        }
1077        MUTATE_END( Statement, node );
1078}
1079
1080//--------------------------------------------------------------------------
1081// FinallyStmt
1082template< typename pass_type >
1083void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
1084        VISIT_START( node );
1085
1086        maybeAccept_impl( node->block, *this );
1087
1088        VISIT_END( node );
1089}
1090
1091template< typename pass_type >
1092Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
1093        MUTATE_START( node );
1094
1095        maybeMutate_impl( node->block, *this );
1096
1097        MUTATE_END( Statement, node );
1098}
1099
1100//--------------------------------------------------------------------------
1101// WaitForStmt
1102template< typename pass_type >
1103void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
1104        VISIT_START( node );
1105
1106        for( auto & clause : node->clauses ) {
1107                maybeAccept_impl( clause.target.function, *this );
1108                maybeAccept_impl( clause.target.arguments, *this );
1109
1110                maybeAccept_impl( clause.statement, *this );
1111                maybeAccept_impl( clause.condition, *this );
1112        }
1113
1114        maybeAccept_impl( node->timeout.time, *this );
1115        maybeAccept_impl( node->timeout.statement, *this );
1116        maybeAccept_impl( node->timeout.condition, *this );
1117        maybeAccept_impl( node->orelse.statement, *this );
1118        maybeAccept_impl( node->orelse.condition, *this );
1119
1120        VISIT_END( node );
1121}
1122
1123template< typename pass_type >
1124Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
1125        MUTATE_START( node );
1126
1127        for( auto & clause : node->clauses ) {
1128                maybeMutate_impl( clause.target.function, *this );
1129                maybeMutate_impl( clause.target.arguments, *this );
1130
1131                maybeMutate_impl( clause.statement, *this );
1132                maybeMutate_impl( clause.condition, *this );
1133        }
1134
1135        maybeMutate_impl( node->timeout.time, *this );
1136        maybeMutate_impl( node->timeout.statement, *this );
1137        maybeMutate_impl( node->timeout.condition, *this );
1138        maybeMutate_impl( node->orelse.statement, *this );
1139        maybeMutate_impl( node->orelse.condition, *this );
1140
1141        MUTATE_END( Statement, node );
1142}
1143
1144
1145
1146//--------------------------------------------------------------------------
1147// NullStmt
1148template< typename pass_type >
1149void PassVisitor< pass_type >::visit( WithStmt * node ) {
1150        VISIT_START( node );
1151        maybeAccept_impl( node->exprs, *this );
1152        {
1153                // catch statements introduce a level of scope (for the caught exception)
1154                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1155                indexerAddWith( node->exprs, node );
1156                maybeAccept_impl( node->stmt, *this );
1157        }
1158        VISIT_END( node );
1159}
1160
1161template< typename pass_type >
1162Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
1163        MUTATE_START( node );
1164        maybeMutate_impl( node->exprs, *this );
1165        {
1166                // catch statements introduce a level of scope (for the caught exception)
1167                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1168                indexerAddWith( node->exprs, node );
1169                maybeMutate_impl( node->stmt, *this );
1170        }
1171        MUTATE_END( Statement, node );
1172}
1173
1174//--------------------------------------------------------------------------
1175// NullStmt
1176template< typename pass_type >
1177void PassVisitor< pass_type >::visit( NullStmt * node ) {
1178        VISIT_START( node );
1179        VISIT_END( node );
1180}
1181
1182template< typename pass_type >
1183NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
1184        MUTATE_START( node );
1185        MUTATE_END( NullStmt, node );
1186}
1187
1188//--------------------------------------------------------------------------
1189// DeclStmt
1190template< typename pass_type >
1191void PassVisitor< pass_type >::visit( DeclStmt * node ) {
1192        VISIT_START( node );
1193
1194        maybeAccept_impl( node->decl, *this );
1195
1196        VISIT_END( node );
1197}
1198
1199template< typename pass_type >
1200Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
1201        MUTATE_START( node );
1202
1203        maybeMutate_impl( node->decl, *this );
1204
1205        MUTATE_END( Statement, node );
1206}
1207
1208//--------------------------------------------------------------------------
1209// ImplicitCtorDtorStmt
1210template< typename pass_type >
1211void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
1212        VISIT_START( node );
1213
1214        maybeAccept_impl( node->callStmt, *this );
1215
1216        VISIT_END( node );
1217}
1218
1219template< typename pass_type >
1220Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
1221        MUTATE_START( node );
1222
1223        maybeMutate_impl( node->callStmt, *this );
1224
1225        MUTATE_END( Statement, node );
1226}
1227
1228//--------------------------------------------------------------------------
1229// ApplicationExpr
1230template< typename pass_type >
1231void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
1232        VISIT_START( node );
1233
1234        indexerScopedAccept( node->result  , *this );
1235        maybeAccept_impl        ( node->function, *this );
1236        maybeAccept_impl        ( node->args    , *this );
1237
1238        VISIT_END( node );
1239}
1240
1241template< typename pass_type >
1242Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
1243        MUTATE_START( node );
1244
1245        indexerScopedMutate( node->env     , *this );
1246        indexerScopedMutate( node->result  , *this );
1247        maybeMutate_impl   ( node->function, *this );
1248        maybeMutate_impl   ( node->args    , *this );
1249
1250        MUTATE_END( Expression, node );
1251}
1252
1253//--------------------------------------------------------------------------
1254// UntypedExpr
1255template< typename pass_type >
1256void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
1257        VISIT_START( node );
1258
1259        // maybeAccept_impl( node->get_env(), *this );
1260        indexerScopedAccept( node->result, *this );
1261
1262        for ( auto expr : node->args ) {
1263                visitExpression( expr );
1264        }
1265
1266        VISIT_END( node );
1267}
1268
1269template< typename pass_type >
1270Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
1271        MUTATE_START( node );
1272
1273        indexerScopedMutate( node->env   , *this );
1274        indexerScopedMutate( node->result, *this );
1275
1276        for ( auto& expr : node->args ) {
1277                expr = mutateExpression( expr );
1278        }
1279
1280        MUTATE_END( Expression, node );
1281}
1282
1283//--------------------------------------------------------------------------
1284// NameExpr
1285template< typename pass_type >
1286void PassVisitor< pass_type >::visit( NameExpr * node ) {
1287        VISIT_START( node );
1288
1289        indexerScopedAccept( node->result, *this );
1290
1291        VISIT_END( node );
1292}
1293
1294template< typename pass_type >
1295Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
1296        MUTATE_START( node );
1297
1298        indexerScopedMutate( node->env   , *this );
1299        indexerScopedMutate( node->result, *this );
1300
1301        MUTATE_END( Expression, node );
1302}
1303
1304//--------------------------------------------------------------------------
1305// CastExpr
1306template< typename pass_type >
1307void PassVisitor< pass_type >::visit( CastExpr * node ) {
1308        VISIT_START( node );
1309
1310        indexerScopedAccept( node->result, *this );
1311        maybeAccept_impl        ( node->arg   , *this );
1312
1313        VISIT_END( node );
1314}
1315
1316template< typename pass_type >
1317Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
1318        MUTATE_START( node );
1319
1320        indexerScopedMutate( node->env   , *this );
1321        indexerScopedMutate( node->result, *this );
1322        maybeMutate_impl   ( node->arg   , *this );
1323
1324        MUTATE_END( Expression, node );
1325}
1326
1327//--------------------------------------------------------------------------
1328// KeywordCastExpr
1329template< typename pass_type >
1330void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
1331        VISIT_START( node );
1332
1333        indexerScopedAccept( node->result, *this );
1334        maybeAccept_impl        ( node->arg   , *this );
1335
1336        VISIT_END( node );
1337}
1338
1339template< typename pass_type >
1340Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
1341        MUTATE_START( node );
1342
1343        indexerScopedMutate( node->env   , *this );
1344        indexerScopedMutate( node->result, *this );
1345        maybeMutate_impl   ( node->arg   , *this );
1346
1347        MUTATE_END( Expression, node );
1348}
1349
1350//--------------------------------------------------------------------------
1351// VirtualCastExpr
1352template< typename pass_type >
1353void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
1354        VISIT_START( node );
1355
1356        indexerScopedAccept( node->result, *this );
1357        maybeAccept_impl( node->arg, *this );
1358
1359        VISIT_END( node );
1360}
1361
1362template< typename pass_type >
1363Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
1364        MUTATE_START( node );
1365
1366        indexerScopedMutate( node->env   , *this );
1367        indexerScopedMutate( node->result, *this );
1368        maybeMutate_impl   ( node->arg   , *this );
1369
1370        MUTATE_END( Expression, node );
1371}
1372
1373//--------------------------------------------------------------------------
1374// AddressExpr
1375template< typename pass_type >
1376void PassVisitor< pass_type >::visit( AddressExpr * node ) {
1377        VISIT_START( node );
1378
1379        indexerScopedAccept( node->result, *this );
1380        maybeAccept_impl   ( node->arg   , *this );
1381
1382        VISIT_END( node );
1383}
1384
1385template< typename pass_type >
1386Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
1387        MUTATE_START( node );
1388
1389        indexerScopedMutate( node->env   , *this );
1390        indexerScopedMutate( node->result, *this );
1391        maybeMutate_impl   ( node->arg   , *this );
1392
1393        MUTATE_END( Expression, node );
1394}
1395
1396//--------------------------------------------------------------------------
1397// LabelAddressExpr
1398template< typename pass_type >
1399void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
1400        VISIT_START( node );
1401
1402        indexerScopedAccept( node->result, *this );
1403
1404        VISIT_END( node );
1405}
1406
1407template< typename pass_type >
1408Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
1409        MUTATE_START( node );
1410
1411        indexerScopedMutate( node->env   , *this );
1412        indexerScopedMutate( node->result, *this );
1413
1414        MUTATE_END( Expression, node );
1415}
1416
1417//--------------------------------------------------------------------------
1418// UntypedMemberExpr
1419template< typename pass_type >
1420void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
1421        VISIT_START( node );
1422
1423        indexerScopedAccept( node->result   , *this );
1424        maybeAccept_impl   ( node->aggregate, *this );
1425        maybeAccept_impl   ( node->member   , *this );
1426
1427        VISIT_END( node );
1428}
1429
1430template< typename pass_type >
1431Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
1432        MUTATE_START( node );
1433
1434        indexerScopedMutate( node->env      , *this );
1435        indexerScopedMutate( node->result   , *this );
1436        maybeMutate_impl   ( node->aggregate, *this );
1437        maybeMutate_impl   ( node->member   , *this );
1438
1439        MUTATE_END( Expression, node );
1440}
1441
1442//--------------------------------------------------------------------------
1443// MemberExpr
1444template< typename pass_type >
1445void PassVisitor< pass_type >::visit( MemberExpr * node ) {
1446        VISIT_START( node );
1447
1448        indexerScopedAccept( node->result   , *this );
1449        maybeAccept_impl   ( node->aggregate, *this );
1450
1451        VISIT_END( node );
1452}
1453
1454template< typename pass_type >
1455Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
1456        MUTATE_START( node );
1457
1458        indexerScopedMutate( node->env      , *this );
1459        indexerScopedMutate( node->result   , *this );
1460        maybeMutate_impl   ( node->aggregate, *this );
1461
1462        MUTATE_END( Expression, node );
1463}
1464
1465//--------------------------------------------------------------------------
1466// VariableExpr
1467template< typename pass_type >
1468void PassVisitor< pass_type >::visit( VariableExpr * node ) {
1469        VISIT_START( node );
1470
1471        indexerScopedAccept( node->result, *this );
1472
1473        VISIT_END( node );
1474}
1475
1476template< typename pass_type >
1477Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
1478        MUTATE_START( node );
1479
1480        indexerScopedMutate( node->env   , *this );
1481        indexerScopedMutate( node->result, *this );
1482
1483        MUTATE_END( Expression, node );
1484}
1485
1486//--------------------------------------------------------------------------
1487// ConstantExpr
1488template< typename pass_type >
1489void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
1490        VISIT_START( node );
1491
1492        indexerScopedAccept( node->result   , *this );
1493        maybeAccept_impl   ( &node->constant, *this );
1494
1495        VISIT_END( node );
1496}
1497
1498template< typename pass_type >
1499Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
1500        MUTATE_START( node );
1501
1502        indexerScopedMutate( node->env   , *this );
1503        indexerScopedMutate( node->result, *this );
1504        Constant * ptr = &node->constant;
1505        maybeMutate_impl( ptr, *this );
1506        node->constant = *ptr;
1507
1508        MUTATE_END( Expression, node );
1509}
1510
1511//--------------------------------------------------------------------------
1512// SizeofExpr
1513template< typename pass_type >
1514void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
1515        VISIT_START( node );
1516
1517        indexerScopedAccept( node->result, *this );
1518        if ( node->get_isType() ) {
1519                maybeAccept_impl( node->type, *this );
1520        } else {
1521                maybeAccept_impl( node->expr, *this );
1522        }
1523
1524        VISIT_END( node );
1525}
1526
1527template< typename pass_type >
1528Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
1529        MUTATE_START( node );
1530
1531        indexerScopedMutate( node->env   , *this );
1532        indexerScopedMutate( node->result, *this );
1533        if ( node->get_isType() ) {
1534                maybeMutate_impl( node->type, *this );
1535        } else {
1536                maybeMutate_impl( node->expr, *this );
1537        }
1538
1539        MUTATE_END( Expression, node );
1540}
1541
1542//--------------------------------------------------------------------------
1543// AlignofExpr
1544template< typename pass_type >
1545void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
1546        VISIT_START( node );
1547
1548        indexerScopedAccept( node->result, *this );
1549        if ( node->get_isType() ) {
1550                maybeAccept_impl( node->type, *this );
1551        } else {
1552                maybeAccept_impl( node->expr, *this );
1553        }
1554
1555        VISIT_END( node );
1556}
1557
1558template< typename pass_type >
1559Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
1560        MUTATE_START( node );
1561
1562        indexerScopedMutate( node->env   , *this );
1563        indexerScopedMutate( node->result, *this );
1564        if ( node->get_isType() ) {
1565                maybeMutate_impl( node->type, *this );
1566        } else {
1567                maybeMutate_impl( node->expr, *this );
1568        }
1569
1570        MUTATE_END( Expression, node );
1571}
1572
1573//--------------------------------------------------------------------------
1574// UntypedOffsetofExpr
1575template< typename pass_type >
1576void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
1577        VISIT_START( node );
1578
1579        indexerScopedAccept( node->result, *this );
1580        maybeAccept_impl   ( node->type  , *this );
1581
1582        VISIT_END( node );
1583}
1584
1585template< typename pass_type >
1586Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
1587        MUTATE_START( node );
1588
1589        indexerScopedMutate( node->env   , *this );
1590        indexerScopedMutate( node->result, *this );
1591        maybeMutate_impl   ( node->type  , *this );
1592
1593        MUTATE_END( Expression, node );
1594}
1595
1596//--------------------------------------------------------------------------
1597// OffsetofExpr
1598template< typename pass_type >
1599void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
1600        VISIT_START( node );
1601
1602        indexerScopedAccept( node->result, *this );
1603        maybeAccept_impl   ( node->type  , *this );
1604
1605        VISIT_END( node );
1606}
1607
1608template< typename pass_type >
1609Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
1610        MUTATE_START( node );
1611
1612        indexerScopedMutate( node->env   , *this );
1613        indexerScopedMutate( node->result, *this );
1614        maybeMutate_impl   ( node->type  , *this );
1615
1616        MUTATE_END( Expression, node );
1617}
1618
1619//--------------------------------------------------------------------------
1620// OffsetPackExpr
1621template< typename pass_type >
1622void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
1623        VISIT_START( node );
1624
1625        indexerScopedAccept( node->result, *this );
1626        maybeAccept_impl   ( node->type  , *this );
1627
1628        VISIT_END( node );
1629}
1630
1631template< typename pass_type >
1632Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
1633        MUTATE_START( node );
1634
1635        indexerScopedMutate( node->env   , *this );
1636        indexerScopedMutate( node->result, *this );
1637        maybeMutate_impl   ( node->type  , *this );
1638
1639        MUTATE_END( Expression, node );
1640}
1641
1642//--------------------------------------------------------------------------
1643// AttrExpr
1644template< typename pass_type >
1645void PassVisitor< pass_type >::visit( AttrExpr * node ) {
1646        VISIT_START( node );
1647
1648        indexerScopedAccept( node->result, *this );
1649        if ( node->get_isType() ) {
1650                maybeAccept_impl( node->type, *this );
1651        } else {
1652                maybeAccept_impl( node->expr, *this );
1653        }
1654
1655        VISIT_END( node );
1656}
1657
1658template< typename pass_type >
1659Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
1660        MUTATE_START( node );
1661
1662        indexerScopedMutate( node->env   , *this );
1663        indexerScopedMutate( node->result, *this );
1664        if ( node->get_isType() ) {
1665                maybeMutate_impl( node->type, *this );
1666        } else {
1667                maybeMutate_impl( node->expr, *this );
1668        }
1669
1670        MUTATE_END( Expression, node );
1671}
1672
1673//--------------------------------------------------------------------------
1674// LogicalExpr
1675template< typename pass_type >
1676void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
1677        VISIT_START( node );
1678
1679        indexerScopedAccept( node->result, *this );
1680        maybeAccept_impl   ( node->arg1  , *this );
1681        maybeAccept_impl   ( node->arg2  , *this );
1682
1683        VISIT_END( node );
1684}
1685
1686template< typename pass_type >
1687Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
1688        MUTATE_START( node );
1689
1690        indexerScopedMutate( node->env   , *this );
1691        indexerScopedMutate( node->result, *this );
1692        maybeMutate_impl   ( node->arg1  , *this );
1693        maybeMutate_impl   ( node->arg2  , *this );
1694
1695        MUTATE_END( Expression, node );
1696}
1697
1698//--------------------------------------------------------------------------
1699// ConditionalExpr
1700template< typename pass_type >
1701void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
1702        VISIT_START( node );
1703
1704        indexerScopedAccept( node->result, *this );
1705        maybeAccept_impl        ( node->arg1  , *this );
1706        maybeAccept_impl        ( node->arg2  , *this );
1707        maybeAccept_impl        ( node->arg3  , *this );
1708
1709        VISIT_END( node );
1710}
1711
1712template< typename pass_type >
1713Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
1714        MUTATE_START( node );
1715
1716        indexerScopedMutate( node->env   , *this );
1717        indexerScopedMutate( node->result, *this );
1718        maybeMutate_impl   ( node->arg1  , *this );
1719        maybeMutate_impl   ( node->arg2  , *this );
1720        maybeMutate_impl   ( node->arg3  , *this );
1721
1722        MUTATE_END( Expression, node );
1723}
1724
1725//--------------------------------------------------------------------------
1726// CommaExpr
1727template< typename pass_type >
1728void PassVisitor< pass_type >::visit( CommaExpr * node ) {
1729        VISIT_START( node );
1730
1731        indexerScopedAccept( node->result, *this );
1732        maybeAccept_impl   ( node->arg1  , *this );
1733        maybeAccept_impl   ( node->arg2  , *this );
1734
1735        VISIT_END( node );
1736}
1737
1738template< typename pass_type >
1739Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
1740        MUTATE_START( node );
1741
1742        indexerScopedMutate( node->env   , *this );
1743        indexerScopedMutate( node->result, *this );
1744        maybeMutate_impl   ( node->arg1  , *this );
1745        maybeMutate_impl   ( node->arg2  , *this );
1746
1747        MUTATE_END( Expression, node );
1748}
1749
1750//--------------------------------------------------------------------------
1751// TypeExpr
1752template< typename pass_type >
1753void PassVisitor< pass_type >::visit( TypeExpr * node ) {
1754        VISIT_START( node );
1755
1756        indexerScopedAccept( node->result, *this );
1757        maybeAccept_impl   ( node->type, *this );
1758
1759        VISIT_END( node );
1760}
1761
1762template< typename pass_type >
1763Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
1764        MUTATE_START( node );
1765
1766        indexerScopedMutate( node->env   , *this );
1767        indexerScopedMutate( node->result, *this );
1768        maybeMutate_impl   ( node->type  , *this );
1769
1770        MUTATE_END( Expression, node );
1771}
1772
1773//--------------------------------------------------------------------------
1774// AsmExpr
1775template< typename pass_type >
1776void PassVisitor< pass_type >::visit( AsmExpr * node ) {
1777        VISIT_START( node );
1778
1779        indexerScopedAccept( node->result    , *this );
1780        maybeAccept_impl   ( node->inout     , *this );
1781        maybeAccept_impl   ( node->constraint, *this );
1782        maybeAccept_impl   ( node->operand   , *this );
1783
1784        VISIT_END( node );
1785}
1786
1787template< typename pass_type >
1788Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
1789        MUTATE_START( node );
1790
1791        indexerScopedMutate( node->env       , *this );
1792        indexerScopedMutate( node->result    , *this );
1793        maybeMutate_impl   ( node->inout     , *this );
1794        maybeMutate_impl   ( node->constraint, *this );
1795        maybeMutate_impl   ( node->operand   , *this );
1796
1797        MUTATE_END( Expression, node );
1798}
1799
1800//--------------------------------------------------------------------------
1801// ImplicitCopyCtorExpr
1802template< typename pass_type >
1803void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
1804        VISIT_START( node );
1805
1806        indexerScopedAccept( node->result     , *this );
1807        maybeAccept_impl   ( node->callExpr   , *this );
1808        maybeAccept_impl   ( node->tempDecls  , *this );
1809        maybeAccept_impl   ( node->returnDecls, *this );
1810        maybeAccept_impl   ( node->dtors      , *this );
1811
1812        VISIT_END( node );
1813}
1814
1815template< typename pass_type >
1816Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
1817        MUTATE_START( node );
1818
1819        indexerScopedMutate( node->env        , *this );
1820        indexerScopedMutate( node->result     , *this );
1821        maybeMutate_impl   ( node->callExpr   , *this );
1822        maybeMutate_impl   ( node->tempDecls  , *this );
1823        maybeMutate_impl   ( node->returnDecls, *this );
1824        maybeMutate_impl   ( node->dtors      , *this );
1825
1826        MUTATE_END( Expression, node );
1827}
1828
1829//--------------------------------------------------------------------------
1830// ConstructorExpr
1831template< typename pass_type >
1832void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
1833        VISIT_START( node );
1834
1835        indexerScopedAccept( node->result  , *this );
1836        maybeAccept_impl   ( node->callExpr, *this );
1837
1838        VISIT_END( node );
1839}
1840
1841template< typename pass_type >
1842Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
1843        MUTATE_START( node );
1844
1845        indexerScopedMutate( node->env     , *this );
1846        indexerScopedMutate( node->result  , *this );
1847        maybeMutate_impl   ( node->callExpr, *this );
1848
1849        MUTATE_END( Expression, node );
1850}
1851
1852//--------------------------------------------------------------------------
1853// CompoundLiteralExpr
1854template< typename pass_type >
1855void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
1856        VISIT_START( node );
1857
1858        indexerScopedAccept( node->result     , *this );
1859        maybeAccept_impl   ( node->initializer, *this );
1860
1861        VISIT_END( node );
1862}
1863
1864template< typename pass_type >
1865Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
1866        MUTATE_START( node );
1867
1868        indexerScopedMutate( node->env        , *this );
1869        indexerScopedMutate( node->result     , *this );
1870        maybeMutate_impl     ( node->initializer, *this );
1871
1872        MUTATE_END( Expression, node );
1873}
1874
1875//--------------------------------------------------------------------------
1876// RangeExpr
1877template< typename pass_type >
1878void PassVisitor< pass_type >::visit( RangeExpr * node ) {
1879        VISIT_START( node );
1880
1881        indexerScopedAccept( node->result, *this );
1882        maybeAccept_impl   ( node->low   , *this );
1883        maybeAccept_impl   ( node->high  , *this );
1884
1885        VISIT_END( node );
1886}
1887
1888template< typename pass_type >
1889Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
1890        MUTATE_START( node );
1891
1892        indexerScopedMutate( node->env   , *this );
1893        indexerScopedMutate( node->result, *this );
1894        maybeMutate_impl   ( node->low   , *this );
1895        maybeMutate_impl   ( node->high  , *this );
1896
1897        MUTATE_END( Expression, node );
1898}
1899
1900//--------------------------------------------------------------------------
1901// UntypedTupleExpr
1902template< typename pass_type >
1903void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
1904        VISIT_START( node );
1905
1906        indexerScopedAccept( node->result, *this );
1907        maybeAccept_impl   ( node->exprs , *this );
1908
1909        VISIT_END( node );
1910}
1911
1912template< typename pass_type >
1913Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
1914        MUTATE_START( node );
1915
1916        indexerScopedMutate( node->env   , *this );
1917        indexerScopedMutate( node->result, *this );
1918        maybeMutate_impl   ( node->exprs , *this );
1919
1920        MUTATE_END( Expression, node );
1921}
1922
1923//--------------------------------------------------------------------------
1924// TupleExpr
1925template< typename pass_type >
1926void PassVisitor< pass_type >::visit( TupleExpr * node ) {
1927        VISIT_START( node );
1928
1929        indexerScopedAccept( node->result, *this );
1930        maybeAccept_impl   ( node->exprs , *this );
1931
1932        VISIT_END( node );
1933}
1934
1935template< typename pass_type >
1936Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
1937        MUTATE_START( node );
1938
1939        indexerScopedMutate( node->env   , *this );
1940        indexerScopedMutate( node->result, *this );
1941        maybeMutate_impl   ( node->exprs , *this );
1942
1943        MUTATE_END( Expression, node );
1944}
1945
1946//--------------------------------------------------------------------------
1947// TupleIndexExpr
1948template< typename pass_type >
1949void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
1950        VISIT_START( node );
1951
1952        indexerScopedAccept( node->result, *this );
1953        maybeAccept_impl   ( node->tuple , *this );
1954
1955        VISIT_END( node );
1956}
1957
1958template< typename pass_type >
1959Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
1960        MUTATE_START( node );
1961
1962        indexerScopedMutate( node->env   , *this );
1963        indexerScopedMutate( node->result, *this );
1964        maybeMutate_impl   ( node->tuple , *this );
1965
1966        MUTATE_END( Expression, node );
1967}
1968
1969//--------------------------------------------------------------------------
1970// TupleAssignExpr
1971template< typename pass_type >
1972void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
1973        VISIT_START( node );
1974
1975        indexerScopedAccept( node->result  , *this );
1976        maybeAccept_impl   ( node->stmtExpr, *this );
1977
1978        VISIT_END( node );
1979}
1980
1981template< typename pass_type >
1982Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
1983        MUTATE_START( node );
1984
1985        indexerScopedMutate( node->env     , *this );
1986        indexerScopedMutate( node->result  , *this );
1987        maybeMutate_impl   ( node->stmtExpr, *this );
1988
1989        MUTATE_END( Expression, node );
1990}
1991
1992//--------------------------------------------------------------------------
1993// StmtExpr
1994template< typename pass_type >
1995void PassVisitor< pass_type >::visit( StmtExpr * node ) {
1996        VISIT_START( node );
1997
1998        // don't want statements from outer CompoundStmts to be added to this StmtExpr
1999        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
2000        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
2001        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
2002
2003        indexerScopedAccept( node->result     , *this );
2004        maybeAccept_impl   ( node->statements , *this );
2005        maybeAccept_impl   ( node->returnDecls, *this );
2006        maybeAccept_impl   ( node->dtors      , *this );
2007
2008        VISIT_END( node );
2009}
2010
2011template< typename pass_type >
2012Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
2013        MUTATE_START( node );
2014
2015        // don't want statements from outer CompoundStmts to be added to this StmtExpr
2016        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
2017        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
2018        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
2019
2020        indexerScopedMutate( node->result     , *this );
2021        maybeMutate_impl   ( node->statements , *this );
2022        maybeMutate_impl   ( node->returnDecls, *this );
2023        maybeMutate_impl   ( node->dtors      , *this );
2024
2025        MUTATE_END( Expression, node );
2026}
2027
2028//--------------------------------------------------------------------------
2029// UniqueExpr
2030template< typename pass_type >
2031void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
2032        VISIT_START( node );
2033
2034        indexerScopedAccept( node->result, *this );
2035        maybeAccept_impl   ( node->expr  , *this );
2036
2037        VISIT_END( node );
2038}
2039
2040template< typename pass_type >
2041Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
2042        MUTATE_START( node );
2043
2044        indexerScopedMutate( node->env   , *this );
2045        indexerScopedMutate( node->result, *this );
2046        maybeMutate_impl   ( node->expr  , *this );
2047
2048        MUTATE_END( Expression, node );
2049}
2050
2051//--------------------------------------------------------------------------
2052// UntypedInitExpr
2053template< typename pass_type >
2054void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
2055        VISIT_START( node );
2056
2057        indexerScopedAccept( node->result, *this );
2058        maybeAccept_impl   ( node->expr  , *this );
2059        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
2060
2061        VISIT_END( node );
2062}
2063
2064template< typename pass_type >
2065Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) {
2066        MUTATE_START( node );
2067
2068        indexerScopedMutate( node->env   , *this );
2069        indexerScopedMutate( node->result, *this );
2070        maybeMutate_impl   ( node->expr  , *this );
2071        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
2072
2073        MUTATE_END( Expression, node );
2074}
2075
2076//--------------------------------------------------------------------------
2077// InitExpr
2078template< typename pass_type >
2079void PassVisitor< pass_type >::visit( InitExpr * node ) {
2080        VISIT_START( node );
2081
2082        indexerScopedAccept( node->result, *this );
2083        maybeAccept_impl   ( node->expr  , *this );
2084        maybeAccept_impl   ( node->designation, *this );
2085
2086        VISIT_END( node );
2087}
2088
2089template< typename pass_type >
2090Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
2091        MUTATE_START( node );
2092
2093        indexerScopedMutate( node->env   , *this );
2094        indexerScopedMutate( node->result, *this );
2095        maybeMutate_impl   ( node->expr  , *this );
2096        maybeMutate_impl   ( node->designation, *this );
2097
2098        MUTATE_END( Expression, node );
2099}
2100
2101//--------------------------------------------------------------------------
2102// DeletedExpr
2103template< typename pass_type >
2104void PassVisitor< pass_type >::visit( DeletedExpr * node ) {
2105        VISIT_START( node );
2106
2107        indexerScopedAccept( node->result, *this );
2108        maybeAccept_impl( node->expr, *this );
2109        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
2110
2111        VISIT_END( node );
2112}
2113
2114template< typename pass_type >
2115Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
2116        MUTATE_START( node );
2117
2118        indexerScopedMutate( node->env, *this );
2119        indexerScopedMutate( node->result, *this );
2120        maybeMutate_impl( node->expr, *this );
2121
2122        MUTATE_END( Expression, node );
2123}
2124
2125//--------------------------------------------------------------------------
2126// DefaultArgExpr
2127template< typename pass_type >
2128void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
2129        VISIT_START( node );
2130
2131        indexerScopedAccept( node->result, *this );
2132        maybeAccept_impl( node->expr, *this );
2133
2134        VISIT_END( node );
2135}
2136
2137template< typename pass_type >
2138Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
2139        MUTATE_START( node );
2140
2141        indexerScopedMutate( node->env, *this );
2142        indexerScopedMutate( node->result, *this );
2143        maybeMutate_impl( node->expr, *this );
2144
2145        MUTATE_END( Expression, node );
2146}
2147
2148//--------------------------------------------------------------------------
2149// GenericExpr
2150template< typename pass_type >
2151void PassVisitor< pass_type >::visit( GenericExpr * node ) {
2152        VISIT_START( node );
2153
2154        indexerScopedAccept( node->result, *this );
2155        maybeAccept_impl( node->control, *this );
2156        for ( GenericExpr::Association & assoc : node->associations ) {
2157                indexerScopedAccept( assoc.type, *this );
2158                maybeAccept_impl( assoc.expr, *this );
2159        }
2160
2161        VISIT_END( node );
2162}
2163
2164template< typename pass_type >
2165Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
2166        MUTATE_START( node );
2167
2168        indexerScopedMutate( node->env, *this );
2169        indexerScopedMutate( node->result, *this );
2170        maybeMutate_impl( node->control, *this );
2171        for ( GenericExpr::Association & assoc : node->associations ) {
2172                indexerScopedMutate( assoc.type, *this );
2173                maybeMutate_impl( assoc.expr, *this );
2174        }
2175
2176        MUTATE_END( Expression, node );
2177}
2178
2179//--------------------------------------------------------------------------
2180// VoidType
2181template< typename pass_type >
2182void PassVisitor< pass_type >::visit( VoidType * node ) {
2183        VISIT_START( node );
2184
2185        maybeAccept_impl( node->forall, *this );
2186
2187        VISIT_END( node );
2188}
2189
2190template< typename pass_type >
2191Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
2192        MUTATE_START( node );
2193
2194        maybeMutate_impl( node->forall, *this );
2195
2196        MUTATE_END( Type, node );
2197}
2198
2199//--------------------------------------------------------------------------
2200// BasicType
2201template< typename pass_type >
2202void PassVisitor< pass_type >::visit( BasicType * node ) {
2203        VISIT_START( node );
2204
2205        maybeAccept_impl( node->forall, *this );
2206
2207        VISIT_END( node );
2208}
2209
2210template< typename pass_type >
2211Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
2212        MUTATE_START( node );
2213
2214        maybeMutate_impl( node->forall, *this );
2215
2216        MUTATE_END( Type, node );
2217}
2218
2219//--------------------------------------------------------------------------
2220// PointerType
2221template< typename pass_type >
2222void PassVisitor< pass_type >::visit( PointerType * node ) {
2223        VISIT_START( node );
2224
2225        maybeAccept_impl( node->forall, *this );
2226        // xxx - should PointerType visit/mutate dimension?
2227        maybeAccept_impl( node->base, *this );
2228
2229        VISIT_END( node );
2230}
2231
2232template< typename pass_type >
2233Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
2234        MUTATE_START( node );
2235
2236        maybeMutate_impl( node->forall, *this );
2237        // xxx - should PointerType visit/mutate dimension?
2238        maybeMutate_impl( node->base, *this );
2239
2240        MUTATE_END( Type, node );
2241}
2242
2243//--------------------------------------------------------------------------
2244// ArrayType
2245template< typename pass_type >
2246void PassVisitor< pass_type >::visit( ArrayType * node ) {
2247        VISIT_START( node );
2248
2249        maybeAccept_impl( node->forall, *this );
2250        maybeAccept_impl( node->dimension, *this );
2251        maybeAccept_impl( node->base, *this );
2252
2253        VISIT_END( node );
2254}
2255
2256template< typename pass_type >
2257Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
2258        MUTATE_START( node );
2259
2260        maybeMutate_impl( node->forall, *this );
2261        maybeMutate_impl( node->dimension, *this );
2262        maybeMutate_impl( node->base, *this );
2263
2264        MUTATE_END( Type, node );
2265}
2266
2267//--------------------------------------------------------------------------
2268// ReferenceType
2269template< typename pass_type >
2270void PassVisitor< pass_type >::visit( ReferenceType * node ) {
2271        VISIT_START( node );
2272
2273        maybeAccept_impl( node->forall, *this );
2274        maybeAccept_impl( node->base, *this );
2275
2276        VISIT_END( node );
2277}
2278
2279template< typename pass_type >
2280Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
2281        MUTATE_START( node );
2282
2283        maybeMutate_impl( node->forall, *this );
2284        maybeMutate_impl( node->base, *this );
2285
2286        MUTATE_END( Type, node );
2287}
2288
2289//--------------------------------------------------------------------------
2290// QualifiedType
2291template< typename pass_type >
2292void PassVisitor< pass_type >::visit( QualifiedType * node ) {
2293        VISIT_START( node );
2294
2295        maybeAccept_impl( node->forall, *this );
2296        maybeAccept_impl( node->parent, *this );
2297        maybeAccept_impl( node->child, *this );
2298
2299        VISIT_END( node );
2300}
2301
2302template< typename pass_type >
2303Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
2304        MUTATE_START( node );
2305
2306        maybeMutate_impl( node->forall, *this );
2307        maybeMutate_impl( node->parent, *this );
2308        maybeMutate_impl( node->child, *this );
2309
2310        MUTATE_END( Type, node );
2311}
2312
2313//--------------------------------------------------------------------------
2314// FunctionType
2315template< typename pass_type >
2316void PassVisitor< pass_type >::visit( FunctionType * node ) {
2317        VISIT_START( node );
2318
2319        maybeAccept_impl( node->forall, *this );
2320        maybeAccept_impl( node->returnVals, *this );
2321        maybeAccept_impl( node->parameters, *this );
2322
2323        VISIT_END( node );
2324}
2325
2326template< typename pass_type >
2327Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
2328        MUTATE_START( node );
2329
2330        maybeMutate_impl( node->forall, *this );
2331        maybeMutate_impl( node->returnVals, *this );
2332        maybeMutate_impl( node->parameters, *this );
2333
2334        MUTATE_END( Type, node );
2335}
2336
2337//--------------------------------------------------------------------------
2338// StructInstType
2339template< typename pass_type >
2340void PassVisitor< pass_type >::visit( StructInstType * node ) {
2341        VISIT_START( node );
2342
2343        indexerAddStruct( node->name );
2344
2345        {
2346                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
2347                maybeAccept_impl( node->forall    , *this );
2348                maybeAccept_impl( node->parameters, *this );
2349        }
2350
2351        VISIT_END( node );
2352}
2353
2354template< typename pass_type >
2355Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
2356        MUTATE_START( node );
2357
2358        indexerAddStruct( node->name );
2359
2360        {
2361                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
2362                maybeMutate_impl( node->forall    , *this );
2363                maybeMutate_impl( node->parameters, *this );
2364        }
2365
2366        MUTATE_END( Type, node );
2367}
2368
2369//--------------------------------------------------------------------------
2370// UnionInstType
2371template< typename pass_type >
2372void PassVisitor< pass_type >::visit( UnionInstType * node ) {
2373        VISIT_START( node );
2374
2375        indexerAddStruct( node->name );
2376
2377        {
2378                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
2379                maybeAccept_impl( node->forall    , *this );
2380                maybeAccept_impl( node->parameters, *this );
2381        }
2382
2383        VISIT_END( node );
2384}
2385
2386template< typename pass_type >
2387Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
2388        MUTATE_START( node );
2389
2390        indexerAddStruct( node->name );
2391
2392        {
2393                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
2394                maybeMutate_impl( node->forall    , *this );
2395                maybeMutate_impl( node->parameters, *this );
2396        }
2397
2398        MUTATE_END( Type, node );
2399}
2400
2401//--------------------------------------------------------------------------
2402// EnumInstType
2403template< typename pass_type >
2404void PassVisitor< pass_type >::visit( EnumInstType * node ) {
2405        VISIT_START( node );
2406
2407        maybeAccept_impl( node->forall, *this );
2408        maybeAccept_impl( node->parameters, *this );
2409
2410        VISIT_END( node );
2411}
2412
2413template< typename pass_type >
2414Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
2415        MUTATE_START( node );
2416
2417        maybeMutate_impl( node->forall, *this );
2418        maybeMutate_impl( node->parameters, *this );
2419
2420        MUTATE_END( Type, node );
2421}
2422
2423//--------------------------------------------------------------------------
2424// TraitInstType
2425template< typename pass_type >
2426void PassVisitor< pass_type >::visit( TraitInstType * node ) {
2427        VISIT_START( node );
2428
2429        maybeAccept_impl( node->forall    , *this );
2430        maybeAccept_impl( node->parameters, *this );
2431
2432        VISIT_END( node );
2433}
2434
2435template< typename pass_type >
2436Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
2437        MUTATE_START( node );
2438
2439        maybeMutate_impl( node->forall    , *this );
2440        maybeMutate_impl( node->parameters, *this );
2441
2442        MUTATE_END( Type, node );
2443}
2444
2445//--------------------------------------------------------------------------
2446// TypeInstType
2447template< typename pass_type >
2448void PassVisitor< pass_type >::visit( TypeInstType * node ) {
2449        VISIT_START( node );
2450
2451        maybeAccept_impl( node->forall    , *this );
2452        maybeAccept_impl( node->parameters, *this );
2453
2454        VISIT_END( node );
2455}
2456
2457template< typename pass_type >
2458Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
2459        MUTATE_START( node );
2460
2461        maybeMutate_impl( node->forall    , *this );
2462        maybeMutate_impl( node->parameters, *this );
2463
2464        MUTATE_END( Type, node );
2465}
2466
2467//--------------------------------------------------------------------------
2468// TupleType
2469template< typename pass_type >
2470void PassVisitor< pass_type >::visit( TupleType * node ) {
2471        VISIT_START( node );
2472
2473        maybeAccept_impl( node->forall, *this );
2474        maybeAccept_impl( node->types, *this );
2475        maybeAccept_impl( node->members, *this );
2476
2477        VISIT_END( node );
2478}
2479
2480template< typename pass_type >
2481Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
2482        MUTATE_START( node );
2483
2484        maybeMutate_impl( node->forall, *this );
2485        maybeMutate_impl( node->types, *this );
2486        maybeMutate_impl( node->members, *this );
2487
2488        MUTATE_END( Type, node );
2489}
2490
2491//--------------------------------------------------------------------------
2492// TypeofType
2493template< typename pass_type >
2494void PassVisitor< pass_type >::visit( TypeofType * node ) {
2495        VISIT_START( node );
2496
2497        assert( node->expr );
2498        maybeAccept_impl( node->expr, *this );
2499
2500        VISIT_END( node );
2501}
2502
2503template< typename pass_type >
2504Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
2505        MUTATE_START( node );
2506
2507        assert( node->expr );
2508        maybeMutate_impl( node->expr, *this );
2509
2510        MUTATE_END( Type, node );
2511}
2512
2513//--------------------------------------------------------------------------
2514// AttrType
2515template< typename pass_type >
2516void PassVisitor< pass_type >::visit( AttrType * node ) {
2517        VISIT_START( node );
2518
2519        if ( node->isType ) {
2520                assert( node->type );
2521                maybeAccept_impl( node->type, *this );
2522        } else {
2523                assert( node->expr );
2524                maybeAccept_impl( node->expr, *this );
2525        } // if
2526
2527        VISIT_END( node );
2528}
2529
2530template< typename pass_type >
2531Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
2532        MUTATE_START( node );
2533
2534        if ( node->isType ) {
2535                assert( node->type );
2536                maybeMutate_impl( node->type, *this );
2537        } else {
2538                assert( node->expr );
2539                maybeMutate_impl( node->expr, *this );
2540        } // if
2541
2542        MUTATE_END( Type, node );
2543}
2544
2545//--------------------------------------------------------------------------
2546// VarArgsType
2547template< typename pass_type >
2548void PassVisitor< pass_type >::visit( VarArgsType * node ) {
2549        VISIT_START( node );
2550
2551        maybeAccept_impl( node->forall, *this );
2552
2553        VISIT_END( node );
2554}
2555
2556template< typename pass_type >
2557Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
2558        MUTATE_START( node );
2559
2560        maybeMutate_impl( node->forall, *this );
2561
2562        MUTATE_END( Type, node );
2563}
2564
2565//--------------------------------------------------------------------------
2566// ZeroType
2567template< typename pass_type >
2568void PassVisitor< pass_type >::visit( ZeroType * node ) {
2569        VISIT_START( node );
2570
2571        maybeAccept_impl( node->forall, *this );
2572
2573        VISIT_END( node );
2574}
2575
2576template< typename pass_type >
2577Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
2578        MUTATE_START( node );
2579
2580        maybeMutate_impl( node->forall, *this );
2581
2582        MUTATE_END( Type, node );
2583}
2584
2585//--------------------------------------------------------------------------
2586// OneType
2587template< typename pass_type >
2588void PassVisitor< pass_type >::visit( OneType * node ) {
2589        VISIT_START( node );
2590
2591        maybeAccept_impl( node->forall, *this );
2592
2593        VISIT_END( node );
2594}
2595
2596template< typename pass_type >
2597Type * PassVisitor< pass_type >::mutate( OneType * node ) {
2598        MUTATE_START( node );
2599
2600        maybeMutate_impl( node->forall, *this );
2601
2602        MUTATE_END( Type, node );
2603}
2604
2605//--------------------------------------------------------------------------
2606// GlobalScopeType
2607template< typename pass_type >
2608void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
2609        VISIT_START( node );
2610
2611        maybeAccept_impl( node->forall, *this );
2612
2613        VISIT_END( node );
2614}
2615
2616template< typename pass_type >
2617Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
2618        MUTATE_START( node );
2619
2620        maybeMutate_impl( node->forall, *this );
2621
2622        MUTATE_END( Type, node );
2623}
2624
2625//--------------------------------------------------------------------------
2626// Designation
2627template< typename pass_type >
2628void PassVisitor< pass_type >::visit( Designation * node ) {
2629        VISIT_START( node );
2630
2631        maybeAccept_impl( node->designators, *this );
2632
2633        VISIT_END( node );
2634}
2635
2636template< typename pass_type >
2637Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
2638        MUTATE_START( node );
2639
2640        maybeMutate_impl( node->designators, *this );
2641
2642        MUTATE_END( Designation, node );
2643}
2644
2645//--------------------------------------------------------------------------
2646// SingleInit
2647template< typename pass_type >
2648void PassVisitor< pass_type >::visit( SingleInit * node ) {
2649        VISIT_START( node );
2650
2651        visitExpression( node->value );
2652
2653        VISIT_END( node );
2654}
2655
2656template< typename pass_type >
2657Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
2658        MUTATE_START( node );
2659
2660        node->value = mutateExpression( node->value );
2661
2662        MUTATE_END( Initializer, node );
2663}
2664
2665//--------------------------------------------------------------------------
2666// ListInit
2667template< typename pass_type >
2668void PassVisitor< pass_type >::visit( ListInit * node ) {
2669        VISIT_START( node );
2670
2671        maybeAccept_impl( node->designations, *this );
2672        maybeAccept_impl( node->initializers, *this );
2673
2674        VISIT_END( node );
2675}
2676
2677template< typename pass_type >
2678Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
2679        MUTATE_START( node );
2680
2681        maybeMutate_impl( node->designations, *this );
2682        maybeMutate_impl( node->initializers, *this );
2683
2684        MUTATE_END( Initializer, node );
2685}
2686
2687//--------------------------------------------------------------------------
2688// ConstructorInit
2689template< typename pass_type >
2690void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
2691        VISIT_START( node );
2692
2693        maybeAccept_impl( node->ctor, *this );
2694        maybeAccept_impl( node->dtor, *this );
2695        maybeAccept_impl( node->init, *this );
2696
2697        VISIT_END( node );
2698}
2699
2700template< typename pass_type >
2701Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
2702        MUTATE_START( node );
2703
2704        maybeMutate_impl( node->ctor, *this );
2705        maybeMutate_impl( node->dtor, *this );
2706        maybeMutate_impl( node->init, *this );
2707
2708        MUTATE_END( Initializer, node );
2709}
2710
2711//--------------------------------------------------------------------------
2712// Subrange
2713template< typename pass_type >
2714void PassVisitor< pass_type >::visit( Subrange * node ) {
2715        VISIT_START( node );
2716
2717        VISIT_END( node );
2718}
2719
2720template< typename pass_type >
2721Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
2722        MUTATE_START( node );
2723
2724        MUTATE_END( Subrange, node );
2725}
2726
2727//--------------------------------------------------------------------------
2728// Attribute
2729template< typename pass_type >
2730void PassVisitor< pass_type >::visit( Constant * node ) {
2731        VISIT_START( node );
2732
2733        VISIT_END( node );
2734}
2735
2736template< typename pass_type >
2737Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
2738        MUTATE_START( node );
2739
2740        MUTATE_END( Constant, node );
2741}
2742
2743//--------------------------------------------------------------------------
2744// Attribute
2745template< typename pass_type >
2746void PassVisitor< pass_type >::visit( Attribute * node ) {
2747        VISIT_START( node );
2748
2749        maybeAccept_impl( node->parameters, *this );
2750
2751        VISIT_END( node );
2752}
2753
2754template< typename pass_type >
2755Attribute * PassVisitor< pass_type >::mutate( Attribute * node  )  {
2756        MUTATE_START( node );
2757
2758        maybeMutate_impl( node->parameters, *this );
2759
2760        MUTATE_END( Attribute, node );
2761}
2762
2763//--------------------------------------------------------------------------
2764// TypeSubstitution
2765template< typename pass_type >
2766TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
2767        MUTATE_START( node );
2768
2769        for ( auto & p : node->typeEnv ) {
2770                indexerScopedMutate( p.second, *this );
2771        }
2772        for ( auto & p : node->varEnv ) {
2773                indexerScopedMutate( p.second, *this );
2774        }
2775
2776        MUTATE_END( TypeSubstitution, node );
2777}
Note: See TracBrowser for help on using the repository browser.