source: src/Common/PassVisitor.impl.h @ 33a25f9

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 33a25f9 was 33a25f9, checked in by Rob Schluntz <rschlunt@…>, 4 years ago

Remove visitor feature from Indexer

  • Property mode set to 100644
File size: 58.4 KB
Line 
1#pragma once
2// IWYU pragma: private, include "PassVisitor.h"
3
4#define VISIT_START( node )                     \
5        __attribute__((unused))                   \
6        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
7        bool visit_children = true;               \
8        set_visit_children( visit_children );   \
9        call_previsit( node );                    \
10        if( visit_children ) {                    \
11
12#define VISIT_END( node )                       \
13        }                                         \
14        call_postvisit( node );                   \
15
16#define MUTATE_START( node )                    \
17        __attribute__((unused))                   \
18        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
19        bool visit_children = true;               \
20        set_visit_children( visit_children );   \
21        call_premutate( node );                   \
22        if( visit_children ) {                    \
23
24#define MUTATE_END( type, node )                \
25        }                                         \
26        return call_postmutate< type * >( node ); \
27
28
29#define VISIT_BODY( node )        \
30        VISIT_START( node );        \
31        Visitor::visit( node );     \
32        VISIT_END( node );          \
33
34
35#define MUTATE_BODY( type, node ) \
36        MUTATE_START( node );       \
37        Mutator::mutate( node );    \
38        MUTATE_END( type, node );   \
39
40
41
42template<typename T>
43static inline bool empty( T * ptr ) {
44        return !ptr || ptr->empty();
45}
46
47typedef std::list< Statement   * > StmtList_t;
48typedef std::list< Declaration * > DeclList_t;
49
50template<typename iterator_t>
51static inline void splice( iterator_t it, DeclList_t * decls ) {
52        std::transform(
53                decls->begin(),
54                decls->end(),
55                it,
56                [](Declaration * decl) -> auto {
57                        return new DeclStmt( noLabels, decl );
58                }
59        );
60        decls->clear();
61}
62
63template< typename pass_type >
64static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
65
66        DeclList_t* beforeDecls = visitor.get_beforeDecls();
67        DeclList_t* afterDecls  = visitor.get_afterDecls();
68        SemanticError errors;
69
70        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
71                // splice in new declarations after previous decl
72                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
73
74                if ( i == decls.end() ) break;
75
76                try {
77                        // run visitor on declaration
78                        maybeAccept( *i, visitor );
79                } catch( SemanticError &e ) {
80                        e.set_location( (*i)->location );
81                        errors.append( e );
82                }
83
84                // splice in new declarations before current decl
85                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
86        }
87        if ( ! errors.isEmpty() ) {
88                throw errors;
89        }
90}
91
92template< typename pass_type >
93static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
94
95        DeclList_t* beforeDecls = mutator.get_beforeDecls();
96        DeclList_t* afterDecls  = mutator.get_afterDecls();
97        SemanticError errors;
98
99        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
100                // splice in new declarations after previous decl
101                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
102
103                if ( i == decls.end() ) break;
104                try {
105                        // run mutator on declaration
106                        *i = maybeMutate( *i, mutator );
107                } catch( SemanticError &e ) {
108                        e.set_location( (*i)->location );
109                        errors.append( e );
110                }
111
112                // splice in new declarations before current decl
113                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
114        }
115        if ( ! errors.isEmpty() ) {
116                throw errors;
117        }
118}
119
120template< typename Container, typename VisitorType >
121inline void maybeAccept( Container &container, VisitorType &visitor ) {
122        SemanticError errors;
123        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
124                try {
125                        if ( *i ) {
126                                (*i)->accept( visitor );
127                        }
128                } catch( SemanticError &e ) {
129                        e.set_location( (*i)->location );
130                        errors.append( e );
131                }
132        }
133        if ( ! errors.isEmpty() ) {
134                throw errors;
135        }
136}
137
138template< typename Container, typename MutatorType >
139inline void maybeMutateRef( Container &container, MutatorType &mutator ) {
140        SemanticError errors;
141        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
142                try {
143                        if ( *i ) {
144///                 *i = (*i)->acceptMutator( mutator );
145                                *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
146                                assert( *i );
147                        } // if
148                } catch( SemanticError &e ) {
149                        e.set_location( (*i)->location );
150                        errors.append( e );
151                } // try
152        } // for
153        if ( ! errors.isEmpty() ) {
154                throw errors;
155        } // if
156}
157
158template< typename pass_type >
159template< typename func_t >
160void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
161        SemanticError errors;
162
163        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
164        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
165        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
166        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
167        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
168
169        StmtList_t* beforeStmts = get_beforeStmts();
170        StmtList_t* afterStmts  = get_afterStmts();
171        DeclList_t* beforeDecls = get_beforeDecls();
172        DeclList_t* afterDecls  = get_afterDecls();
173
174        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
175
176                if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
177                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
178
179                try {
180                        func( *i );
181                        assert(( empty( beforeStmts ) && empty( afterStmts ))
182                            || ( empty( beforeDecls ) && empty( afterDecls )) );
183
184                } catch ( SemanticError &e ) {
185                        e.set_location( (*i)->location );
186                        errors.append( e );
187                }
188
189                if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
190                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
191        }
192
193        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
194        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
195        if ( !errors.isEmpty() ) { throw errors; }
196}
197
198template< typename pass_type >
199void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
200        handleStatementList( statements, [this]( Statement * stmt) {
201                stmt->accept( *this );
202        });
203}
204
205template< typename pass_type >
206void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
207        handleStatementList( statements, [this]( Statement *& stmt) {
208                stmt = stmt->acceptMutator( *this );
209        });
210}
211
212
213template< typename pass_type >
214template< typename func_t >
215Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
216        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
217        ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
218        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
219        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
220        ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
221        ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
222
223        Statement *newStmt = func( stmt );
224
225        StmtList_t* beforeStmts = get_beforeStmts();
226        StmtList_t* afterStmts  = get_afterStmts();
227        DeclList_t* beforeDecls = get_beforeDecls();
228        DeclList_t* afterDecls  = get_afterDecls();
229
230        if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
231        assert(( empty( beforeStmts ) && empty( afterStmts ))
232            || ( empty( beforeDecls ) && empty( afterDecls )) );
233
234        CompoundStmt *compound = new CompoundStmt( noLabels );
235        if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
236        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
237        compound->get_kids().push_back( newStmt );
238        if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
239        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
240        return compound;
241}
242
243template< typename pass_type >
244Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
245        return handleStatement( stmt, [this]( Statement * stmt ) {
246                maybeAccept( stmt, *this );
247                return stmt;
248        });
249}
250
251template< typename pass_type >
252Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
253        return handleStatement( stmt, [this]( Statement * stmt ) {
254                return maybeMutate( stmt, *this );
255        });
256}
257
258template< typename pass_type >
259template< typename func_t >
260Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
261        if( !expr ) return nullptr;
262
263        auto env_ptr = get_env_ptr();
264        if ( env_ptr && expr->get_env() ) {
265                *env_ptr = expr->get_env();
266        }
267
268        // should env be cloned (or moved) onto the result of the mutate?
269        return func( expr );
270}
271
272template< typename pass_type >
273Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
274        return handleExpression(expr, [this]( Expression * expr ) {
275                expr->accept( *this );
276                return expr;
277        });
278}
279
280template< typename pass_type >
281Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
282        return handleExpression(expr, [this]( Expression * expr ) {
283                return expr->acceptMutator( *this );
284        });
285}
286
287//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
288//========================================================================================================================================================================
289//========================================================================================================================================================================
290//========================================================================================================================================================================
291//========================================================================================================================================================================
292//========================================================================================================================================================================
293//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
294
295// A NOTE ON THE ORDER OF TRAVERSAL
296//
297// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
298// no such thing as a recursive type or typedef.
299//
300//             typedef struct { T *x; } T; // never allowed
301//
302// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
303// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
304// declaration).
305//
306//             struct T { struct T *x; }; // allowed
307//
308// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
309// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
310// queried later in this pass.
311//
312// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
313
314//--------------------------------------------------------------------------
315// ObjectDecl
316template< typename pass_type >
317void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
318        VISIT_START( node );
319
320        indexerScopedAccept( node->type         , *this );
321        maybeAccept        ( node->init         , *this );
322        maybeAccept        ( node->bitfieldWidth, *this );
323
324        if ( node->name != "" ) {
325                indexerAddId( node );
326        }
327
328        VISIT_END( node );
329}
330
331template< typename pass_type >
332DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
333        MUTATE_START( node );
334
335        indexerScopedMutate( node->type         , *this );
336        maybeMutateRef     ( node->init         , *this );
337        maybeMutateRef     ( node->bitfieldWidth, *this );
338
339        if ( node->name != "" ) {
340                indexerAddId( node );
341        }
342
343        MUTATE_END( DeclarationWithType, node );
344}
345
346//--------------------------------------------------------------------------
347// FunctionDecl
348template< typename pass_type >
349void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
350        VISIT_START( node );
351
352        if ( node->name != "" ) {
353                indexerAddId( node );
354        }
355
356        {
357                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
358                maybeAccept( node->type, *this );
359                maybeAccept( node->statements, *this );
360        }
361
362        VISIT_END( node );
363}
364
365template< typename pass_type >
366DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
367        MUTATE_START( node );
368
369        if ( node->name != "" ) {
370                indexerAddId( node );
371        }
372
373        {
374                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
375                maybeMutateRef( node->type, *this );
376                maybeMutateRef( node->statements, *this );
377        }
378
379        MUTATE_END( DeclarationWithType, node );
380}
381
382//--------------------------------------------------------------------------
383// StructDecl
384template< typename pass_type >
385void PassVisitor< pass_type >::visit( StructDecl * node ) {
386        VISIT_START( node );
387
388        // make up a forward declaration and add it before processing the members
389        // needs to be on the heap because addStruct saves the pointer
390        indexerAddStructFwd( node );
391
392        {
393                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
394                maybeAccept( node->parameters, *this );
395                maybeAccept( node->members   , *this );
396        }
397
398        // this addition replaces the forward declaration
399        indexerAddStruct( node );
400
401        VISIT_END( node );
402}
403
404template< typename pass_type >
405Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
406        MUTATE_START( node );
407
408        // make up a forward declaration and add it before processing the members
409        // needs to be on the heap because addStruct saves the pointer
410        indexerAddStructFwd( node );
411
412        {
413                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
414                maybeMutateRef( node->parameters, *this );
415                maybeMutateRef( node->members   , *this );
416        }
417
418        // this addition replaces the forward declaration
419        indexerAddStruct( node );
420
421        MUTATE_END( Declaration, node );
422}
423
424//--------------------------------------------------------------------------
425// UnionDecl
426template< typename pass_type >
427void PassVisitor< pass_type >::visit( UnionDecl * node ) {
428        VISIT_START( node );
429
430        // make up a forward declaration and add it before processing the members
431        indexerAddUnionFwd( node );
432
433        {
434                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
435                maybeAccept( node->parameters, *this );
436                maybeAccept( node->members   , *this );
437        }
438
439        indexerAddUnion( node );
440
441        VISIT_END( node );
442}
443
444template< typename pass_type >
445Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
446        MUTATE_START( node );
447
448        // make up a forward declaration and add it before processing the members
449        indexerAddUnionFwd( node );
450
451        {
452                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
453                maybeMutateRef( node->parameters, *this );
454                maybeMutateRef( node->members   , *this );
455        }
456
457        indexerAddUnion( node );
458
459        MUTATE_END( Declaration, node );
460}
461
462//--------------------------------------------------------------------------
463// EnumDecl
464template< typename pass_type >
465void PassVisitor< pass_type >::visit( EnumDecl * node ) {
466        VISIT_START( node );
467
468        indexerAddEnum( node );
469
470        // unlike structs, traits, and unions, enums inject their members into the global scope
471        maybeAccept( node->parameters, *this );
472        maybeAccept( node->members   , *this );
473
474        VISIT_END( node );
475}
476
477template< typename pass_type >
478Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
479        MUTATE_START( node );
480
481        indexerAddEnum( node );
482
483        // unlike structs, traits, and unions, enums inject their members into the global scope
484        maybeMutateRef( node->parameters, *this );
485        maybeMutateRef( node->members   , *this );
486
487        MUTATE_END( Declaration, node );
488}
489
490//--------------------------------------------------------------------------
491// TraitDecl
492template< typename pass_type >
493void PassVisitor< pass_type >::visit( TraitDecl * node ) {
494        VISIT_START( node );
495
496        {
497                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
498                maybeAccept( node->parameters, *this );
499                maybeAccept( node->members   , *this );
500        }
501
502        indexerAddTrait( node );
503
504        VISIT_END( node );
505}
506
507template< typename pass_type >
508Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
509        MUTATE_START( node );
510
511        {
512                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
513                maybeMutateRef( node->parameters, *this );
514                maybeMutateRef( node->members   , *this );
515        }
516
517        indexerAddTrait( node );
518
519        MUTATE_END( Declaration, node );
520}
521
522//--------------------------------------------------------------------------
523// TypeDecl
524template< typename pass_type >
525void PassVisitor< pass_type >::visit( TypeDecl * node ) {
526        VISIT_START( node );
527
528        {
529                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
530                maybeAccept( node->parameters, *this );
531                maybeAccept( node->base      , *this );
532        }
533
534        // see A NOTE ON THE ORDER OF TRAVERSAL, above
535        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
536        // and may depend on the type itself
537        indexerAddType( node );
538
539        maybeAccept( node->assertions, *this );
540
541        indexerScopedAccept( node->init, *this );
542
543        VISIT_END( node );
544}
545
546template< typename pass_type >
547Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
548        MUTATE_START( node );
549
550        {
551                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
552                maybeMutateRef( node->parameters, *this );
553                maybeMutateRef( node->base      , *this );
554        }
555
556        // see A NOTE ON THE ORDER OF TRAVERSAL, above
557        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
558        // and may depend on the type itself
559        indexerAddType( node );
560
561        maybeMutateRef( node->assertions, *this );
562
563        indexerScopedMutate( node->init, *this );
564
565        MUTATE_END( Declaration, node );
566}
567
568//--------------------------------------------------------------------------
569// TypedefDecl
570template< typename pass_type >
571void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
572        VISIT_START( node );
573
574        {
575                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
576                maybeAccept( node->parameters, *this );
577                maybeAccept( node->base      , *this );
578        }
579
580        indexerAddType( node );
581
582        maybeAccept( node->assertions, *this );
583
584        VISIT_END( node );
585}
586
587template< typename pass_type >
588Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
589        MUTATE_START( node );
590
591        {
592                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
593                maybeMutateRef     ( node->parameters, *this );
594                maybeMutateRef( node->base      , *this );
595        }
596
597        indexerAddType( node );
598
599        maybeMutateRef( node->assertions, *this );
600
601        MUTATE_END( Declaration, node );
602}
603
604//--------------------------------------------------------------------------
605// AsmDecl
606template< typename pass_type >
607void PassVisitor< pass_type >::visit( AsmDecl * node ) {
608        VISIT_START( node );
609
610        maybeAccept( node->stmt, *this );
611
612        VISIT_END( node );
613}
614
615template< typename pass_type >
616AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
617        MUTATE_START( node );
618
619        maybeMutateRef( node->stmt, *this );
620
621        MUTATE_END( AsmDecl, node );
622}
623
624//--------------------------------------------------------------------------
625// CompoundStmt
626template< typename pass_type >
627void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
628        VISIT_START( node );
629        {
630                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
631                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
632                visitStatementList( node->kids );
633        }
634        VISIT_END( node );
635}
636
637template< typename pass_type >
638CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
639        MUTATE_START( node );
640        {
641                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
642                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
643                mutateStatementList( node->kids );
644        }
645        MUTATE_END( CompoundStmt, node );
646}
647
648//--------------------------------------------------------------------------
649// ExprStmt
650template< typename pass_type >
651void PassVisitor< pass_type >::visit( ExprStmt * node ) {
652        VISIT_START( node );
653
654        visitExpression( node->expr );
655
656        VISIT_END( node );
657}
658
659template< typename pass_type >
660Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
661        MUTATE_START( node );
662
663        node->expr = mutateExpression( node->expr );
664
665        MUTATE_END( Statement, node );
666}
667
668//--------------------------------------------------------------------------
669// AsmStmt
670template< typename pass_type >
671void PassVisitor< pass_type >::visit( AsmStmt * node ) {
672        VISIT_BODY( node );
673}
674
675template< typename pass_type >
676Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
677        MUTATE_BODY( Statement, node );
678}
679
680//--------------------------------------------------------------------------
681// IfStmt
682template< typename pass_type >
683void PassVisitor< pass_type >::visit( IfStmt * node ) {
684        VISIT_START( node );
685        {
686                // if statements introduce a level of scope (for the initialization)
687                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
688                acceptAll( node->get_initialization(), *this );
689                visitExpression( node->condition );
690                node->thenPart = visitStatement( node->thenPart );
691                node->elsePart = visitStatement( node->elsePart );
692        }
693        VISIT_END( node );
694}
695
696template< typename pass_type >
697Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
698        MUTATE_START( node );
699        {
700                // if statements introduce a level of scope (for the initialization)
701                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
702                maybeMutateRef( node->get_initialization(), *this );
703                node->condition = mutateExpression( node->condition );
704                node->thenPart  = mutateStatement ( node->thenPart  );
705                node->elsePart  = mutateStatement ( node->elsePart  );
706        }
707        MUTATE_END( Statement, node );
708}
709
710//--------------------------------------------------------------------------
711// WhileStmt
712template< typename pass_type >
713void PassVisitor< pass_type >::visit( WhileStmt * node ) {
714        VISIT_START( node );
715
716        visitExpression( node->condition );
717        node->body = visitStatement( node->body );
718
719        VISIT_END( node );
720}
721
722template< typename pass_type >
723Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
724        MUTATE_START( node );
725
726        node->condition = mutateExpression( node->condition );
727        node->body      = mutateStatement ( node->body      );
728
729        MUTATE_END( Statement, node );
730}
731
732//--------------------------------------------------------------------------
733// ForStmt
734template< typename pass_type >
735void PassVisitor< pass_type >::visit( ForStmt * node ) {
736        VISIT_START( node );
737        {
738                // for statements introduce a level of scope (for the initialization)
739                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
740                maybeAccept( node->initialization, *this );
741                visitExpression( node->condition );
742                visitExpression( node->increment );
743                node->body = visitStatement( node->body );
744        }
745        VISIT_END( node );
746}
747
748template< typename pass_type >
749Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
750        MUTATE_START( node );
751        {
752                // for statements introduce a level of scope (for the initialization)
753                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
754                maybeMutateRef( node->initialization, *this );
755                node->condition = mutateExpression( node->condition );
756                node->increment = mutateExpression( node->increment );
757                node->body      = mutateStatement ( node->body      );
758        }
759        MUTATE_END( Statement, node );
760}
761
762//--------------------------------------------------------------------------
763// SwitchStmt
764template< typename pass_type >
765void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
766        VISIT_START( node );
767
768        visitExpression   ( node->condition  );
769        visitStatementList( node->statements );
770
771        VISIT_END( node );
772}
773
774template< typename pass_type >
775Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
776        MUTATE_START( node );
777
778        node->condition = mutateExpression( node->condition );
779        mutateStatementList( node->statements );
780
781        MUTATE_END( Statement, node );
782}
783
784//--------------------------------------------------------------------------
785// CaseStmt
786template< typename pass_type >
787void PassVisitor< pass_type >::visit( CaseStmt * node ) {
788        VISIT_START( node );
789
790        visitExpression   ( node->condition );
791        visitStatementList( node->stmts     );
792
793        VISIT_END( node );
794}
795
796template< typename pass_type >
797Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
798        MUTATE_START( node );
799
800        node->condition = mutateExpression( node->condition );
801        mutateStatementList( node->stmts );
802
803        MUTATE_END( Statement, node );
804}
805
806//--------------------------------------------------------------------------
807// BranchStmt
808template< typename pass_type >
809void PassVisitor< pass_type >::visit( BranchStmt * node ) {
810        VISIT_BODY( node );
811}
812
813template< typename pass_type >
814Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
815        MUTATE_BODY( Statement, node );
816}
817
818//--------------------------------------------------------------------------
819// ReturnStmt
820template< typename pass_type >
821void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
822        VISIT_START( node );
823
824        visitExpression( node->expr );
825
826        VISIT_END( node );
827}
828
829template< typename pass_type >
830Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
831        MUTATE_START( node );
832
833        node->expr = mutateExpression( node->expr );
834
835        MUTATE_END( Statement, node );
836}
837
838//--------------------------------------------------------------------------
839// ThrowStmt
840
841template< typename pass_type >
842void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
843        VISIT_BODY( node );
844}
845
846template< typename pass_type >
847Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
848        MUTATE_BODY( Statement, node );
849}
850
851//--------------------------------------------------------------------------
852// TryStmt
853template< typename pass_type >
854void PassVisitor< pass_type >::visit( TryStmt * node ) {
855        VISIT_START( node );
856
857        maybeAccept( node->block       , *this );
858        maybeAccept( node->handlers    , *this );
859        maybeAccept( node->finallyBlock, *this );
860
861        VISIT_END( node );
862}
863
864template< typename pass_type >
865Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
866        MUTATE_START( node );
867
868        maybeMutateRef( node->block       , *this );
869        maybeMutateRef( node->handlers    , *this );
870        maybeMutateRef( node->finallyBlock, *this );
871
872        MUTATE_END( Statement, node );
873}
874
875//--------------------------------------------------------------------------
876// CatchStmt
877template< typename pass_type >
878void PassVisitor< pass_type >::visit( CatchStmt * node ) {
879        VISIT_START( node );
880        {
881                // catch statements introduce a level of scope (for the caught exception)
882                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
883                maybeAccept( node->decl, *this );
884                node->cond = visitExpression( node->cond );
885                node->body = visitStatement ( node->body );
886        }
887        VISIT_END( node );
888}
889
890template< typename pass_type >
891Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
892        MUTATE_START( node );
893        {
894                // catch statements introduce a level of scope (for the caught exception)
895                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
896                maybeMutateRef( node->decl, *this );
897                node->cond = mutateExpression( node->cond );
898                node->body = mutateStatement ( node->body );
899        }
900        MUTATE_END( Statement, node );
901}
902
903//--------------------------------------------------------------------------
904// FinallyStmt
905template< typename pass_type >
906void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
907        VISIT_BODY( node );
908}
909
910template< typename pass_type >
911Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
912        MUTATE_BODY( Statement, node );
913}
914
915//--------------------------------------------------------------------------
916// WaitForStmt
917template< typename pass_type >
918void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
919        VISIT_BODY( node );
920}
921
922template< typename pass_type >
923Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
924        MUTATE_BODY( Statement, node );
925}
926
927//--------------------------------------------------------------------------
928// NullStmt
929template< typename pass_type >
930void PassVisitor< pass_type >::visit( NullStmt * node ) {
931        VISIT_BODY( node );
932}
933
934template< typename pass_type >
935NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
936        MUTATE_BODY( NullStmt, node );
937}
938
939//--------------------------------------------------------------------------
940// DeclStmt
941template< typename pass_type >
942void PassVisitor< pass_type >::visit( DeclStmt * node ) {
943        VISIT_BODY( node );
944}
945
946template< typename pass_type >
947Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
948        MUTATE_BODY( Statement, node );
949}
950
951//--------------------------------------------------------------------------
952// ImplicitCtorDtorStmt
953template< typename pass_type >
954void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
955        VISIT_BODY( node );
956}
957
958template< typename pass_type >
959Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
960        MUTATE_BODY( Statement, node );
961}
962
963//--------------------------------------------------------------------------
964// ApplicationExpr
965template< typename pass_type >
966void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
967        VISIT_START( node );
968
969        indexerScopedAccept( node->result  , *this );
970        maybeAccept        ( node->function, *this );
971        maybeAccept        ( node->args    , *this );
972
973        VISIT_END( node );
974}
975
976template< typename pass_type >
977Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
978        MUTATE_START( node );
979
980        indexerScopedMutate( node->env     , *this );
981        indexerScopedMutate( node->result  , *this );
982        maybeMutateRef     ( node->function, *this );
983        maybeMutateRef     ( node->args    , *this );
984
985        MUTATE_END( Expression, node );
986}
987
988//--------------------------------------------------------------------------
989// UntypedExpr
990template< typename pass_type >
991void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
992        VISIT_START( node );
993
994        // maybeAccept( node->get_env(), *this );
995        indexerScopedAccept( node->result, *this );
996
997        for ( auto expr : node->args ) {
998                visitExpression( expr );
999        }
1000
1001        VISIT_END( node );
1002}
1003
1004template< typename pass_type >
1005Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
1006        MUTATE_START( node );
1007
1008        indexerScopedMutate( node->env   , *this );
1009        indexerScopedMutate( node->result, *this );
1010
1011        for ( auto& expr : node->args ) {
1012                expr = mutateExpression( expr );
1013        }
1014
1015        MUTATE_END( Expression, node );
1016}
1017
1018//--------------------------------------------------------------------------
1019// NameExpr
1020template< typename pass_type >
1021void PassVisitor< pass_type >::visit( NameExpr * node ) {
1022        VISIT_START( node );
1023
1024        indexerScopedAccept( node->result, *this );
1025
1026        VISIT_END( node );
1027}
1028
1029template< typename pass_type >
1030Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
1031        MUTATE_START( node );
1032
1033        indexerScopedMutate( node->env   , *this );
1034        indexerScopedMutate( node->result, *this );
1035
1036        MUTATE_END( Expression, node );
1037}
1038
1039//--------------------------------------------------------------------------
1040// CastExpr
1041template< typename pass_type >
1042void PassVisitor< pass_type >::visit( CastExpr * node ) {
1043        VISIT_START( node );
1044
1045        indexerScopedAccept( node->result, *this );
1046        maybeAccept        ( node->arg   , *this );
1047
1048        VISIT_END( node );
1049}
1050
1051template< typename pass_type >
1052Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
1053        MUTATE_START( node );
1054
1055        indexerScopedMutate( node->env   , *this );
1056        indexerScopedMutate( node->result, *this );
1057        maybeMutateRef     ( node->arg   , *this );
1058
1059        MUTATE_END( Expression, node );
1060}
1061
1062//--------------------------------------------------------------------------
1063// VirtualCastExpr
1064template< typename pass_type >
1065void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
1066        VISIT_START( node );
1067
1068        indexerScopedAccept( node->result, *this );
1069        maybeAccept( node->arg, *this );
1070
1071        VISIT_END( node );
1072}
1073
1074template< typename pass_type >
1075Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
1076        MUTATE_START( node );
1077
1078        indexerScopedMutate( node->env   , *this );
1079        indexerScopedMutate( node->result, *this );
1080        maybeMutateRef     ( node->arg   , *this );
1081
1082        MUTATE_END( Expression, node );
1083}
1084
1085//--------------------------------------------------------------------------
1086// AddressExpr
1087template< typename pass_type >
1088void PassVisitor< pass_type >::visit( AddressExpr * node ) {
1089        VISIT_START( node );
1090
1091        indexerScopedAccept( node->result, *this );
1092        maybeAccept        ( node->arg   , *this );
1093
1094        VISIT_END( node );
1095}
1096
1097template< typename pass_type >
1098Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
1099        MUTATE_START( node );
1100
1101        indexerScopedMutate( node->env   , *this );
1102        indexerScopedMutate( node->result, *this );
1103        maybeMutateRef     ( node->arg   , *this );
1104
1105        MUTATE_END( Expression, node );
1106}
1107
1108//--------------------------------------------------------------------------
1109// LabelAddressExpr
1110template< typename pass_type >
1111void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
1112        VISIT_START( node );
1113
1114        indexerScopedAccept( node->result, *this );
1115
1116        VISIT_END( node );
1117}
1118
1119template< typename pass_type >
1120Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
1121        MUTATE_START( node );
1122
1123        indexerScopedMutate( node->env   , *this );
1124        indexerScopedMutate( node->result, *this );
1125
1126        MUTATE_END( Expression, node );
1127}
1128
1129//--------------------------------------------------------------------------
1130// UntypedMemberExpr
1131template< typename pass_type >
1132void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
1133        VISIT_START( node );
1134
1135        indexerScopedAccept( node->result   , *this );
1136        maybeAccept        ( node->aggregate, *this );
1137        maybeAccept        ( node->member   , *this );
1138
1139        VISIT_END( node );
1140}
1141
1142template< typename pass_type >
1143Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
1144        MUTATE_START( node );
1145
1146        indexerScopedMutate( node->env      , *this );
1147        indexerScopedMutate( node->result   , *this );
1148        maybeMutateRef     ( node->aggregate, *this );
1149        maybeMutateRef     ( node->member   , *this );
1150
1151        MUTATE_END( Expression, node );
1152}
1153
1154//--------------------------------------------------------------------------
1155// MemberExpr
1156template< typename pass_type >
1157void PassVisitor< pass_type >::visit( MemberExpr * node ) {
1158        VISIT_START( node );
1159
1160        indexerScopedAccept( node->result   , *this );
1161        maybeAccept        ( node->aggregate, *this );
1162
1163        VISIT_END( node );
1164}
1165
1166template< typename pass_type >
1167Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
1168        MUTATE_START( node );
1169
1170        indexerScopedMutate( node->env      , *this );
1171        indexerScopedMutate( node->result   , *this );
1172        maybeMutateRef     ( node->aggregate, *this );
1173
1174        MUTATE_END( Expression, node );
1175}
1176
1177//--------------------------------------------------------------------------
1178// VariableExpr
1179template< typename pass_type >
1180void PassVisitor< pass_type >::visit( VariableExpr * node ) {
1181        VISIT_START( node );
1182
1183        indexerScopedAccept( node->result, *this );
1184
1185        VISIT_END( node );
1186}
1187
1188template< typename pass_type >
1189Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
1190        MUTATE_START( node );
1191
1192        indexerScopedMutate( node->env   , *this );
1193        indexerScopedMutate( node->result, *this );
1194
1195        MUTATE_END( Expression, node );
1196}
1197
1198//--------------------------------------------------------------------------
1199// ConstantExpr
1200template< typename pass_type >
1201void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
1202        VISIT_START( node );
1203
1204        indexerScopedAccept( node->result   , *this );
1205        maybeAccept        ( &node->constant, *this );
1206
1207        VISIT_END( node );
1208}
1209
1210template< typename pass_type >
1211Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
1212        MUTATE_START( node );
1213
1214        indexerScopedMutate( node->env   , *this );
1215        indexerScopedMutate( node->result, *this );
1216        node->constant = *maybeMutate( &node->constant, *this );
1217
1218        MUTATE_END( Expression, node );
1219}
1220
1221//--------------------------------------------------------------------------
1222// SizeofExpr
1223template< typename pass_type >
1224void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
1225        VISIT_START( node );
1226
1227        indexerScopedAccept( node->result, *this );
1228        if ( node->get_isType() ) {
1229                maybeAccept( node->type, *this );
1230        } else {
1231                maybeAccept( node->expr, *this );
1232        }
1233
1234        VISIT_END( node );
1235}
1236
1237template< typename pass_type >
1238Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
1239        MUTATE_START( node );
1240
1241        indexerScopedMutate( node->env   , *this );
1242        indexerScopedMutate( node->result, *this );
1243        if ( node->get_isType() ) {
1244                maybeMutateRef( node->type, *this );
1245        } else {
1246                maybeMutateRef( node->expr, *this );
1247        }
1248
1249        MUTATE_END( Expression, node );
1250}
1251
1252//--------------------------------------------------------------------------
1253// AlignofExpr
1254template< typename pass_type >
1255void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
1256        VISIT_START( node );
1257
1258        indexerScopedAccept( node->result, *this );
1259        if ( node->get_isType() ) {
1260                maybeAccept( node->type, *this );
1261        } else {
1262                maybeAccept( node->expr, *this );
1263        }
1264
1265        VISIT_END( node );
1266}
1267
1268template< typename pass_type >
1269Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
1270        MUTATE_START( node );
1271
1272        indexerScopedMutate( node->env   , *this );
1273        indexerScopedMutate( node->result, *this );
1274        if ( node->get_isType() ) {
1275                maybeMutateRef( node->type, *this );
1276        } else {
1277                maybeMutateRef( node->expr, *this );
1278        }
1279
1280        MUTATE_END( Expression, node );
1281}
1282
1283//--------------------------------------------------------------------------
1284// UntypedOffsetofExpr
1285template< typename pass_type >
1286void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
1287        VISIT_START( node );
1288
1289        indexerScopedAccept( node->result, *this );
1290        maybeAccept        ( node->type  , *this );
1291
1292        VISIT_END( node );
1293}
1294
1295template< typename pass_type >
1296Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
1297        MUTATE_START( node );
1298
1299        indexerScopedMutate( node->env   , *this );
1300        indexerScopedMutate( node->result, *this );
1301        maybeMutateRef     ( node->type  , *this );
1302
1303        MUTATE_END( Expression, node );
1304}
1305
1306//--------------------------------------------------------------------------
1307// OffsetofExpr
1308template< typename pass_type >
1309void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
1310        VISIT_START( node );
1311
1312        indexerScopedAccept( node->result, *this );
1313        maybeAccept        ( node->type  , *this );
1314        maybeAccept        ( node->member, *this );
1315
1316        VISIT_END( node );
1317}
1318
1319template< typename pass_type >
1320Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
1321        MUTATE_START( node );
1322
1323        indexerScopedMutate( node->env   , *this );
1324        indexerScopedMutate( node->result, *this );
1325        maybeMutateRef     ( node->type  , *this );
1326        maybeMutateRef     ( node->member, *this );
1327
1328        MUTATE_END( Expression, node );
1329}
1330
1331//--------------------------------------------------------------------------
1332// OffsetPackExpr
1333template< typename pass_type >
1334void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
1335        VISIT_START( node );
1336
1337        indexerScopedAccept( node->result, *this );
1338        maybeAccept        ( node->type  , *this );
1339
1340        VISIT_END( node );
1341}
1342
1343template< typename pass_type >
1344Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
1345        MUTATE_START( node );
1346
1347        indexerScopedMutate( node->env   , *this );
1348        indexerScopedMutate( node->result, *this );
1349        maybeMutateRef     ( node->type  , *this );
1350
1351        MUTATE_END( Expression, node );
1352}
1353
1354//--------------------------------------------------------------------------
1355// AttrExpr
1356template< typename pass_type >
1357void PassVisitor< pass_type >::visit( AttrExpr * node ) {
1358        VISIT_START( node );
1359
1360        indexerScopedAccept( node->result, *this );
1361        if ( node->get_isType() ) {
1362                maybeAccept( node->type, *this );
1363        } else {
1364                maybeAccept( node->expr, *this );
1365        }
1366
1367        VISIT_END( node );
1368}
1369
1370template< typename pass_type >
1371Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
1372        MUTATE_START( node );
1373
1374        indexerScopedMutate( node->env   , *this );
1375        indexerScopedMutate( node->result, *this );
1376        if ( node->get_isType() ) {
1377                maybeMutateRef( node->type, *this );
1378        } else {
1379                maybeMutateRef( node->expr, *this );
1380        }
1381
1382        MUTATE_END( Expression, node );
1383}
1384
1385//--------------------------------------------------------------------------
1386// LogicalExpr
1387template< typename pass_type >
1388void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
1389        VISIT_START( node );
1390
1391        indexerScopedAccept( node->result, *this );
1392        maybeAccept        ( node->arg1  , *this );
1393        maybeAccept        ( node->arg2  , *this );
1394
1395        VISIT_END( node );
1396}
1397
1398template< typename pass_type >
1399Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
1400        MUTATE_START( node );
1401
1402        indexerScopedMutate( node->env   , *this );
1403        indexerScopedMutate( node->result, *this );
1404        maybeMutateRef     ( node->arg1  , *this );
1405        maybeMutateRef     ( node->arg2  , *this );
1406
1407        MUTATE_END( Expression, node );
1408}
1409
1410//--------------------------------------------------------------------------
1411// ConditionalExpr
1412template< typename pass_type >
1413void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
1414        VISIT_START( node );
1415
1416        indexerScopedAccept( node->result, *this );
1417        maybeAccept        ( node->arg1  , *this );
1418        maybeAccept        ( node->arg2  , *this );
1419        maybeAccept        ( node->arg3  , *this );
1420
1421        VISIT_END( node );
1422}
1423
1424template< typename pass_type >
1425Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
1426        MUTATE_START( node );
1427
1428        indexerScopedMutate( node->env   , *this );
1429        indexerScopedMutate( node->result, *this );
1430        maybeMutateRef     ( node->arg1  , *this );
1431        maybeMutateRef     ( node->arg2  , *this );
1432        maybeMutateRef     ( node->arg3  , *this );
1433
1434        MUTATE_END( Expression, node );
1435}
1436
1437//--------------------------------------------------------------------------
1438// CommaExpr
1439template< typename pass_type >
1440void PassVisitor< pass_type >::visit( CommaExpr * node ) {
1441        VISIT_START( node );
1442
1443        indexerScopedAccept( node->result, *this );
1444        maybeAccept        ( node->arg1  , *this );
1445        maybeAccept        ( node->arg2  , *this );
1446
1447        VISIT_END( node );
1448}
1449
1450template< typename pass_type >
1451Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
1452        MUTATE_START( node );
1453
1454        indexerScopedMutate( node->env   , *this );
1455        indexerScopedMutate( node->result, *this );
1456        maybeMutateRef     ( node->arg1  , *this );
1457        maybeMutateRef     ( node->arg2  , *this );
1458
1459        MUTATE_END( Expression, node );
1460}
1461
1462//--------------------------------------------------------------------------
1463// TypeExpr
1464template< typename pass_type >
1465void PassVisitor< pass_type >::visit( TypeExpr * node ) {
1466        VISIT_START( node );
1467
1468        indexerScopedAccept( node->result, *this );
1469        maybeAccept        ( node->type, *this );
1470
1471        VISIT_END( node );
1472}
1473
1474template< typename pass_type >
1475Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
1476        MUTATE_START( node );
1477
1478        indexerScopedMutate( node->env   , *this );
1479        indexerScopedMutate( node->result, *this );
1480        maybeMutateRef     ( node->type  , *this );
1481
1482        MUTATE_END( Expression, node );
1483}
1484
1485//--------------------------------------------------------------------------
1486// AsmExpr
1487template< typename pass_type >
1488void PassVisitor< pass_type >::visit( AsmExpr * node ) {
1489        VISIT_START( node );
1490
1491        indexerScopedAccept( node->result    , *this );
1492        maybeAccept        ( node->inout     , *this );
1493        maybeAccept        ( node->constraint, *this );
1494        maybeAccept        ( node->operand   , *this );
1495
1496        VISIT_END( node );
1497}
1498
1499template< typename pass_type >
1500Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
1501        MUTATE_START( node );
1502
1503        indexerScopedMutate( node->env       , *this );
1504        indexerScopedMutate( node->result    , *this );
1505        maybeMutateRef     ( node->inout     , *this );
1506        maybeMutateRef     ( node->constraint, *this );
1507        maybeMutateRef     ( node->operand   , *this );
1508
1509        MUTATE_END( Expression, node );
1510}
1511
1512//--------------------------------------------------------------------------
1513// ImplicitCopyCtorExpr
1514template< typename pass_type >
1515void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
1516        VISIT_START( node );
1517
1518        indexerScopedAccept( node->result     , *this );
1519        maybeAccept        ( node->callExpr   , *this );
1520        maybeAccept        ( node->tempDecls  , *this );
1521        maybeAccept        ( node->returnDecls, *this );
1522        maybeAccept        ( node->dtors      , *this );
1523
1524        VISIT_END( node );
1525}
1526
1527template< typename pass_type >
1528Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
1529        MUTATE_START( node );
1530
1531        indexerScopedMutate( node->env        , *this );
1532        indexerScopedMutate( node->result     , *this );
1533        maybeMutateRef     ( node->callExpr   , *this );
1534        maybeMutateRef     ( node->tempDecls  , *this );
1535        maybeMutateRef     ( node->returnDecls, *this );
1536        maybeMutateRef     ( node->dtors      , *this );
1537
1538        MUTATE_END( Expression, node );
1539}
1540
1541//--------------------------------------------------------------------------
1542// ConstructorExpr
1543template< typename pass_type >
1544void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
1545        VISIT_START( node );
1546
1547        indexerScopedAccept( node->result  , *this );
1548        maybeAccept        ( node->callExpr, *this );
1549
1550        VISIT_END( node );
1551}
1552
1553template< typename pass_type >
1554Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
1555        MUTATE_START( node );
1556
1557        indexerScopedMutate( node->env     , *this );
1558        indexerScopedMutate( node->result  , *this );
1559        maybeMutateRef     ( node->callExpr, *this );
1560
1561        MUTATE_END( Expression, node );
1562}
1563
1564//--------------------------------------------------------------------------
1565// CompoundLiteralExpr
1566template< typename pass_type >
1567void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
1568        VISIT_START( node );
1569
1570        indexerScopedAccept( node->result     , *this );
1571        maybeAccept        ( node->initializer, *this );
1572
1573        VISIT_END( node );
1574}
1575
1576template< typename pass_type >
1577Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
1578        MUTATE_START( node );
1579
1580        indexerScopedMutate( node->env        , *this );
1581        indexerScopedMutate( node->result     , *this );
1582        maybeMutateRef     ( node->initializer, *this );
1583
1584        MUTATE_END( Expression, node );
1585}
1586
1587//--------------------------------------------------------------------------
1588// RangeExpr
1589template< typename pass_type >
1590void PassVisitor< pass_type >::visit( RangeExpr * node ) {
1591        VISIT_START( node );
1592
1593        indexerScopedAccept( node->result, *this );
1594        maybeAccept        ( node->low   , *this );
1595        maybeAccept        ( node->high  , *this );
1596
1597        VISIT_END( node );
1598}
1599
1600template< typename pass_type >
1601Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
1602        MUTATE_START( node );
1603
1604        indexerScopedMutate( node->env   , *this );
1605        indexerScopedMutate( node->result, *this );
1606        maybeMutateRef     ( node->low   , *this );
1607        maybeMutateRef     ( node->high  , *this );
1608
1609        MUTATE_END( Expression, node );
1610}
1611
1612//--------------------------------------------------------------------------
1613// UntypedTupleExpr
1614template< typename pass_type >
1615void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
1616        VISIT_START( node );
1617
1618        indexerScopedAccept( node->result, *this );
1619        maybeAccept        ( node->exprs , *this );
1620
1621        VISIT_END( node );
1622}
1623
1624template< typename pass_type >
1625Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
1626        MUTATE_START( node );
1627
1628        indexerScopedMutate( node->env   , *this );
1629        indexerScopedMutate( node->result, *this );
1630        maybeMutateRef     ( node->exprs , *this );
1631
1632        MUTATE_END( Expression, node );
1633}
1634
1635//--------------------------------------------------------------------------
1636// TupleExpr
1637template< typename pass_type >
1638void PassVisitor< pass_type >::visit( TupleExpr * node ) {
1639        VISIT_START( node );
1640
1641        indexerScopedAccept( node->result, *this );
1642        maybeAccept          ( node->exprs , *this );
1643
1644        VISIT_END( node );
1645}
1646
1647template< typename pass_type >
1648Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
1649        MUTATE_START( node );
1650
1651        indexerScopedMutate( node->env   , *this );
1652        indexerScopedMutate( node->result, *this );
1653        maybeMutateRef     ( node->exprs , *this );
1654
1655        MUTATE_END( Expression, node );
1656}
1657
1658//--------------------------------------------------------------------------
1659// TupleIndexExpr
1660template< typename pass_type >
1661void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
1662        VISIT_START( node );
1663
1664        indexerScopedAccept( node->result, *this );
1665        maybeAccept        ( node->tuple , *this );
1666
1667        VISIT_END( node );
1668}
1669
1670template< typename pass_type >
1671Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
1672        MUTATE_START( node );
1673
1674        indexerScopedMutate( node->env   , *this );
1675        indexerScopedMutate( node->result, *this );
1676        maybeMutateRef     ( node->tuple , *this );
1677
1678        MUTATE_END( Expression, node );
1679}
1680
1681//--------------------------------------------------------------------------
1682// TupleAssignExpr
1683template< typename pass_type >
1684void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
1685        VISIT_START( node );
1686
1687        indexerScopedAccept( node->result  , *this );
1688        maybeAccept        ( node->stmtExpr, *this );
1689
1690        VISIT_END( node );
1691}
1692
1693template< typename pass_type >
1694Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
1695        MUTATE_START( node );
1696
1697        indexerScopedMutate( node->env     , *this );
1698        indexerScopedMutate( node->result  , *this );
1699        maybeMutateRef     ( node->stmtExpr, *this );
1700
1701        MUTATE_END( Expression, node );
1702}
1703
1704//--------------------------------------------------------------------------
1705// StmtExpr
1706template< typename pass_type >
1707void PassVisitor< pass_type >::visit( StmtExpr * node ) {
1708        VISIT_START( node );
1709
1710        // don't want statements from outer CompoundStmts to be added to this StmtExpr
1711        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
1712        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
1713        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
1714
1715        indexerScopedAccept( node->result     , *this );
1716        maybeAccept        ( node->statements , *this );
1717        maybeAccept        ( node->returnDecls, *this );
1718        maybeAccept        ( node->dtors      , *this );
1719
1720        VISIT_END( node );
1721}
1722
1723template< typename pass_type >
1724Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
1725        MUTATE_START( node );
1726
1727        // don't want statements from outer CompoundStmts to be added to this StmtExpr
1728        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
1729        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
1730        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
1731
1732        indexerScopedMutate( node->result     , *this );
1733        maybeMutateRef     ( node->statements , *this );
1734        maybeMutateRef     ( node->returnDecls, *this );
1735        maybeMutateRef     ( node->dtors      , *this );
1736
1737        MUTATE_END( Expression, node );
1738}
1739
1740//--------------------------------------------------------------------------
1741// UniqueExpr
1742template< typename pass_type >
1743void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
1744        VISIT_START( node );
1745
1746        indexerScopedAccept( node->result, *this );
1747        maybeAccept        ( node->expr  , *this );
1748
1749        VISIT_END( node );
1750}
1751
1752template< typename pass_type >
1753Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
1754        MUTATE_START( node );
1755
1756        indexerScopedMutate( node->env   , *this );
1757        indexerScopedMutate( node->result, *this );
1758        maybeMutateRef     ( node->expr  , *this );
1759
1760        MUTATE_END( Expression, node );
1761}
1762
1763template< typename pass_type >
1764void PassVisitor< pass_type >::visit( VoidType * node ) {
1765        VISIT_BODY( node );
1766}
1767
1768template< typename pass_type >
1769void PassVisitor< pass_type >::visit( BasicType * node ) {
1770        VISIT_BODY( node );
1771}
1772
1773template< typename pass_type >
1774void PassVisitor< pass_type >::visit( PointerType * node ) {
1775        VISIT_BODY( node );
1776}
1777
1778template< typename pass_type >
1779void PassVisitor< pass_type >::visit( ArrayType * node ) {
1780        VISIT_BODY( node );
1781}
1782
1783template< typename pass_type >
1784void PassVisitor< pass_type >::visit( ReferenceType * node ) {
1785        VISIT_BODY( node );
1786}
1787
1788template< typename pass_type >
1789void PassVisitor< pass_type >::visit( FunctionType * node ) {
1790        VISIT_BODY( node );
1791}
1792
1793//--------------------------------------------------------------------------
1794// StructInstType
1795template< typename pass_type >
1796void PassVisitor< pass_type >::visit( StructInstType * node ) {
1797        VISIT_START( node );
1798
1799        indexerAddStruct( node->name );
1800
1801        {
1802                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1803                maybeAccept( node->forall    , *this );
1804                maybeAccept( node->parameters, *this );
1805        }
1806
1807        VISIT_END( node );
1808}
1809
1810template< typename pass_type >
1811Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
1812        MUTATE_START( node );
1813
1814        indexerAddStruct( node->name );
1815
1816        {
1817                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1818                maybeMutateRef( node->forall    , *this );
1819                maybeMutateRef( node->parameters, *this );
1820        }
1821
1822        MUTATE_END( Type, node );
1823}
1824
1825//--------------------------------------------------------------------------
1826// UnionInstType
1827template< typename pass_type >
1828void PassVisitor< pass_type >::visit( UnionInstType * node ) {
1829        VISIT_START( node );
1830
1831        indexerAddStruct( node->name );
1832
1833        {
1834                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1835                maybeAccept( node->forall    , *this );
1836                maybeAccept( node->parameters, *this );
1837        }
1838
1839        VISIT_END( node );
1840}
1841
1842template< typename pass_type >
1843Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
1844        MUTATE_START( node );
1845
1846        indexerAddStruct( node->name );
1847
1848        {
1849                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1850                maybeMutateRef( node->forall    , *this );
1851                maybeMutateRef( node->parameters, *this );
1852        }
1853
1854        MUTATE_END( Type, node );
1855}
1856
1857//--------------------------------------------------------------------------
1858// EnumInstType
1859template< typename pass_type >
1860void PassVisitor< pass_type >::visit( EnumInstType * node ) {
1861        VISIT_BODY( node );
1862}
1863
1864template< typename pass_type >
1865Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
1866        MUTATE_BODY( Type, node );
1867}
1868
1869//--------------------------------------------------------------------------
1870// TraitInstType
1871template< typename pass_type >
1872void PassVisitor< pass_type >::visit( TraitInstType * node ) {
1873        VISIT_START( node );
1874
1875        maybeAccept( node->forall    , *this );
1876        maybeAccept( node->parameters, *this );
1877
1878        VISIT_END( node );
1879}
1880
1881template< typename pass_type >
1882Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
1883        MUTATE_START( node );
1884
1885        maybeMutateRef( node->forall    , *this );
1886        maybeMutateRef( node->parameters, *this );
1887
1888        MUTATE_END( Type, node );
1889}
1890
1891//--------------------------------------------------------------------------
1892// TypeInstType
1893template< typename pass_type >
1894void PassVisitor< pass_type >::visit( TypeInstType * node ) {
1895        VISIT_BODY( node );
1896}
1897
1898template< typename pass_type >
1899void PassVisitor< pass_type >::visit( TupleType * node ) {
1900        VISIT_BODY( node );
1901}
1902
1903template< typename pass_type >
1904void PassVisitor< pass_type >::visit( TypeofType * node ) {
1905        VISIT_BODY( node );
1906}
1907
1908template< typename pass_type >
1909void PassVisitor< pass_type >::visit( AttrType * node ) {
1910        VISIT_BODY( node );
1911}
1912
1913template< typename pass_type >
1914void PassVisitor< pass_type >::visit( VarArgsType * node ) {
1915        VISIT_BODY( node );
1916}
1917
1918template< typename pass_type >
1919void PassVisitor< pass_type >::visit( ZeroType * node ) {
1920        VISIT_BODY( node );
1921}
1922
1923template< typename pass_type >
1924void PassVisitor< pass_type >::visit( OneType * node ) {
1925        VISIT_BODY( node );
1926}
1927
1928//--------------------------------------------------------------------------
1929// SingleInit
1930template< typename pass_type >
1931void PassVisitor< pass_type >::visit( SingleInit * node ) {
1932        VISIT_START( node );
1933
1934        visitExpression( node->get_value() );
1935
1936        VISIT_END( node );
1937}
1938
1939template< typename pass_type >
1940Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
1941        MUTATE_START( node );
1942
1943        node->set_value( mutateExpression( node->get_value() ) );
1944
1945        MUTATE_END( Initializer, node );
1946}
1947
1948template< typename pass_type >
1949void PassVisitor< pass_type >::visit( ListInit * node ) {
1950        VISIT_BODY( node );
1951}
1952
1953template< typename pass_type >
1954void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
1955        VISIT_BODY( node );
1956}
1957
1958template< typename pass_type >
1959void PassVisitor< pass_type >::visit( Subrange * node ) {
1960        VISIT_BODY( node );
1961}
1962
1963template< typename pass_type >
1964void PassVisitor< pass_type >::visit( Constant * node ) {
1965        VISIT_BODY( node );
1966}
1967
1968//---------------------------------------------------------------------------------------------------------------
1969template< typename pass_type >
1970Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
1971        MUTATE_BODY( Type, node );
1972}
1973
1974template< typename pass_type >
1975Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
1976        MUTATE_BODY( Type, node );
1977}
1978
1979template< typename pass_type >
1980Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
1981        MUTATE_BODY( Type, node );
1982}
1983
1984template< typename pass_type >
1985Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
1986        MUTATE_BODY( Type, node );
1987}
1988
1989template< typename pass_type >
1990Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
1991        MUTATE_BODY( Type, node );
1992}
1993
1994template< typename pass_type >
1995Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
1996        MUTATE_BODY( Type, node );
1997}
1998
1999template< typename pass_type >
2000Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
2001        MUTATE_BODY( Type, node );
2002}
2003
2004template< typename pass_type >
2005Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
2006        MUTATE_BODY( Type, node );
2007}
2008
2009template< typename pass_type >
2010Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
2011        MUTATE_BODY( Type, node );
2012}
2013
2014template< typename pass_type >
2015Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
2016        MUTATE_BODY( Type, node );
2017}
2018
2019template< typename pass_type >
2020Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
2021        MUTATE_BODY( Type, node );
2022}
2023
2024template< typename pass_type >
2025Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
2026        MUTATE_BODY( Type, node );
2027}
2028
2029template< typename pass_type >
2030Type * PassVisitor< pass_type >::mutate( OneType * node ) {
2031        MUTATE_BODY( Type, node );
2032}
2033
2034template< typename pass_type >
2035Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
2036        MUTATE_BODY( Initializer, node );
2037}
2038
2039template< typename pass_type >
2040Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
2041        MUTATE_BODY( Initializer, node );
2042}
2043
2044template< typename pass_type >
2045Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
2046        MUTATE_BODY( Subrange, node );
2047}
2048
2049template< typename pass_type >
2050Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
2051        MUTATE_BODY( Constant, node );
2052}
Note: See TracBrowser for help on using the repository browser.