source: src/Common/PassVisitor.impl.h @ aa685db

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since aa685db was aa685db, checked in by Rob Schluntz <rschlunt@…>, 5 years ago

Set location when aggregating errors in PassVisitor::handleStatementList

  • Property mode set to 100644
File size: 56.5 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
296//--------------------------------------------------------------------------
297// ObjectDecl
298template< typename pass_type >
299void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
300        VISIT_START( node );
301
302        indexerScopedAccept( node->type         , *this );
303        maybeAccept        ( node->init         , *this );
304        maybeAccept        ( node->bitfieldWidth, *this );
305
306        if ( node->name != "" ) {
307                indexerAddId( node );
308        }
309
310        VISIT_END( node );
311}
312
313template< typename pass_type >
314DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
315        MUTATE_START( node );
316
317        indexerScopedMutate( node->type         , *this );
318        maybeMutateRef     ( node->init         , *this );
319        maybeMutateRef     ( node->bitfieldWidth, *this );
320
321        if ( node->name != "" ) {
322                indexerAddId( node );
323        }
324
325        MUTATE_END( DeclarationWithType, node );
326}
327
328//--------------------------------------------------------------------------
329// FunctionDecl
330template< typename pass_type >
331void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
332        VISIT_START( node );
333
334        if ( node->name != "" ) {
335                indexerAddId( node );
336        }
337
338        {
339                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
340                maybeAccept( node->type, *this );
341                maybeAccept( node->statements, *this );
342        }
343
344        VISIT_END( node );
345}
346
347template< typename pass_type >
348DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
349        MUTATE_START( node );
350
351        if ( node->name != "" ) {
352                indexerAddId( node );
353        }
354
355        {
356                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
357                maybeMutateRef( node->type, *this );
358                maybeMutateRef( node->statements, *this );
359        }
360
361        MUTATE_END( DeclarationWithType, node );
362}
363
364//--------------------------------------------------------------------------
365// StructDecl
366template< typename pass_type >
367void PassVisitor< pass_type >::visit( StructDecl * node ) {
368        VISIT_START( node );
369
370        // make up a forward declaration and add it before processing the members
371        // needs to be on the heap because addStruct saves the pointer
372        indexerAddStructFwd( node );
373
374        {
375                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
376                maybeAccept( node->parameters, *this );
377                maybeAccept( node->members   , *this );
378        }
379
380        // this addition replaces the forward declaration
381        indexerAddStruct( node );
382
383        VISIT_END( node );
384}
385
386template< typename pass_type >
387Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
388        MUTATE_START( node );
389
390        // make up a forward declaration and add it before processing the members
391        // needs to be on the heap because addStruct saves the pointer
392        indexerAddStructFwd( node );
393
394        {
395                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
396                maybeMutateRef( node->parameters, *this );
397                maybeMutateRef( node->members   , *this );
398        }
399
400        // this addition replaces the forward declaration
401        indexerAddStruct( node );
402
403        MUTATE_END( Declaration, node );
404}
405
406//--------------------------------------------------------------------------
407// UnionDecl
408template< typename pass_type >
409void PassVisitor< pass_type >::visit( UnionDecl * node ) {
410        VISIT_START( node );
411
412        // make up a forward declaration and add it before processing the members
413        indexerAddUnionFwd( node );
414
415        {
416                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
417                maybeAccept( node->parameters, *this );
418                maybeAccept( node->members   , *this );
419        }
420
421        indexerAddUnion( node );
422
423        VISIT_END( node );
424}
425
426template< typename pass_type >
427Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
428        MUTATE_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                maybeMutateRef( node->parameters, *this );
436                maybeMutateRef( node->members   , *this );
437        }
438
439        indexerAddUnion( node );
440
441        MUTATE_END( Declaration, node );
442}
443
444//--------------------------------------------------------------------------
445// EnumDecl
446template< typename pass_type >
447void PassVisitor< pass_type >::visit( EnumDecl * node ) {
448        VISIT_START( node );
449
450        indexerAddEnum( node );
451
452        // unlike structs, contexts, and unions, enums inject their members into the global scope
453        maybeAccept( node->parameters, *this );
454        maybeAccept( node->members   , *this );
455
456        VISIT_END( node );
457}
458
459template< typename pass_type >
460Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
461        MUTATE_START( node );
462
463        indexerAddEnum( node );
464
465        // unlike structs, traits, and unions, enums inject their members into the global scope
466        maybeMutateRef( node->parameters, *this );
467        maybeMutateRef( node->members   , *this );
468
469        MUTATE_END( Declaration, node );
470}
471
472//--------------------------------------------------------------------------
473// TraitDecl
474template< typename pass_type >
475void PassVisitor< pass_type >::visit( TraitDecl * node ) {
476        VISIT_START( node );
477
478        {
479                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
480                maybeAccept( node->parameters, *this );
481                maybeAccept( node->members   , *this );
482        }
483
484        indexerAddTrait( node );
485
486        VISIT_END( node );
487}
488
489template< typename pass_type >
490Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
491        MUTATE_START( node );
492
493        {
494                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
495                maybeMutateRef( node->parameters, *this );
496                maybeMutateRef( node->members   , *this );
497        }
498
499        indexerAddTrait( node );
500
501        MUTATE_END( Declaration, node );
502}
503
504//--------------------------------------------------------------------------
505// TypeDecl
506template< typename pass_type >
507void PassVisitor< pass_type >::visit( TypeDecl * node ) {
508        VISIT_START( node );
509
510        {
511                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
512                maybeAccept( node->parameters, *this );
513                maybeAccept( node->base      , *this );
514        }
515
516        indexerAddType( node );
517
518        maybeAccept( node->assertions, *this );
519
520        indexerScopedAccept( node->init, *this );
521
522        VISIT_END( node );
523}
524
525template< typename pass_type >
526Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
527        MUTATE_START( node );
528
529        {
530                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
531                maybeMutateRef( node->parameters, *this );
532                maybeMutateRef( node->base      , *this );
533        }
534
535        indexerAddType( node );
536
537        maybeMutateRef( node->assertions, *this );
538
539        indexerScopedMutate( node->init, *this );
540
541        MUTATE_END( Declaration, node );
542}
543
544//--------------------------------------------------------------------------
545// TypedefDecl
546template< typename pass_type >
547void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
548        VISIT_START( node );
549
550        {
551                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
552                maybeAccept( node->parameters, *this );
553                maybeAccept( node->base      , *this );
554        }
555
556        indexerAddType( node );
557
558        maybeAccept( node->assertions, *this );
559
560        VISIT_END( node );
561}
562
563template< typename pass_type >
564Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
565        MUTATE_START( node );
566
567        {
568                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
569                maybeMutateRef     ( node->parameters, *this );
570                maybeMutateRef( node->base      , *this );
571        }
572
573        indexerAddType( node );
574
575        maybeMutateRef( node->assertions, *this );
576
577        MUTATE_END( Declaration, node );
578}
579
580//--------------------------------------------------------------------------
581// AsmDecl
582template< typename pass_type >
583void PassVisitor< pass_type >::visit( AsmDecl * node ) {
584        VISIT_START( node );
585
586        maybeAccept( node->stmt, *this );
587
588        VISIT_END( node );
589}
590
591template< typename pass_type >
592AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
593        MUTATE_START( node );
594
595        maybeMutateRef( node->stmt, *this );
596
597        MUTATE_END( AsmDecl, node );
598}
599
600//--------------------------------------------------------------------------
601// CompoundStmt
602template< typename pass_type >
603void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
604        VISIT_START( node );
605        {
606                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
607                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
608                visitStatementList( node->kids );
609        }
610        VISIT_END( node );
611}
612
613template< typename pass_type >
614CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
615        MUTATE_START( node );
616        {
617                auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
618                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
619                mutateStatementList( node->kids );
620        }
621        MUTATE_END( CompoundStmt, node );
622}
623
624//--------------------------------------------------------------------------
625// ExprStmt
626template< typename pass_type >
627void PassVisitor< pass_type >::visit( ExprStmt * node ) {
628        VISIT_START( node );
629
630        visitExpression( node->expr );
631
632        VISIT_END( node );
633}
634
635template< typename pass_type >
636Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
637        MUTATE_START( node );
638
639        node->expr = mutateExpression( node->expr );
640
641        MUTATE_END( Statement, node );
642}
643
644//--------------------------------------------------------------------------
645// AsmStmt
646template< typename pass_type >
647void PassVisitor< pass_type >::visit( AsmStmt * node ) {
648        VISIT_BODY( node );
649}
650
651template< typename pass_type >
652Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
653        MUTATE_BODY( Statement, node );
654}
655
656//--------------------------------------------------------------------------
657// IfStmt
658template< typename pass_type >
659void PassVisitor< pass_type >::visit( IfStmt * node ) {
660        VISIT_START( node );
661
662        visitExpression( node->condition );
663        node->thenPart = visitStatement( node->thenPart );
664        node->elsePart = visitStatement( node->elsePart );
665
666        VISIT_END( node );
667}
668
669template< typename pass_type >
670Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
671        MUTATE_START( node );
672        {
673                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
674                node->condition = mutateExpression( node->condition );
675                node->thenPart  = mutateStatement ( node->thenPart  );
676                node->elsePart  = mutateStatement ( node->elsePart  );
677        }
678        MUTATE_END( Statement, node );
679}
680
681//--------------------------------------------------------------------------
682// WhileStmt
683template< typename pass_type >
684void PassVisitor< pass_type >::visit( WhileStmt * node ) {
685        VISIT_START( node );
686
687        visitExpression( node->condition );
688        node->body = visitStatement( node->body );
689
690        VISIT_END( node );
691}
692
693template< typename pass_type >
694Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
695        MUTATE_START( node );
696
697        node->condition = mutateExpression( node->condition );
698        node->body      = mutateStatement ( node->body      );
699
700        MUTATE_END( Statement, node );
701}
702
703//--------------------------------------------------------------------------
704// ForStmt
705template< typename pass_type >
706void PassVisitor< pass_type >::visit( ForStmt * node ) {
707        VISIT_START( node );
708        {
709                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
710                maybeAccept( node->initialization, *this );
711                visitExpression( node->condition );
712                visitExpression( node->increment );
713                node->body = visitStatement( node->body );
714        }
715        VISIT_END( node );
716}
717
718template< typename pass_type >
719Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
720        MUTATE_START( node );
721        {
722                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
723                maybeMutateRef( node->initialization, *this );
724                node->condition = mutateExpression( node->condition );
725                node->increment = mutateExpression( node->increment );
726                node->body      = mutateStatement ( node->body      );
727        }
728        MUTATE_END( Statement, node );
729}
730
731//--------------------------------------------------------------------------
732// SwitchStmt
733template< typename pass_type >
734void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
735        VISIT_START( node );
736
737        visitExpression   ( node->condition  );
738        visitStatementList( node->statements );
739
740        VISIT_END( node );
741}
742
743template< typename pass_type >
744Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
745        MUTATE_START( node );
746
747        node->condition = mutateExpression( node->condition );
748        mutateStatementList( node->statements );
749
750        MUTATE_END( Statement, node );
751}
752
753//--------------------------------------------------------------------------
754// CaseStmt
755template< typename pass_type >
756void PassVisitor< pass_type >::visit( CaseStmt * node ) {
757        VISIT_START( node );
758
759        visitExpression   ( node->condition );
760        visitStatementList( node->stmts     );
761
762        VISIT_END( node );
763}
764
765template< typename pass_type >
766Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
767        MUTATE_START( node );
768
769        node->condition = mutateExpression( node->condition );
770        mutateStatementList( node->stmts );
771
772        MUTATE_END( Statement, node );
773}
774
775//--------------------------------------------------------------------------
776// BranchStmt
777template< typename pass_type >
778void PassVisitor< pass_type >::visit( BranchStmt * node ) {
779        VISIT_BODY( node );
780}
781
782template< typename pass_type >
783Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
784        MUTATE_BODY( Statement, node );
785}
786
787//--------------------------------------------------------------------------
788// ReturnStmt
789template< typename pass_type >
790void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
791        VISIT_START( node );
792
793        visitExpression( node->expr );
794
795        VISIT_END( node );
796}
797
798template< typename pass_type >
799Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
800        MUTATE_START( node );
801
802        node->expr = mutateExpression( node->expr );
803
804        MUTATE_END( Statement, node );
805}
806
807//--------------------------------------------------------------------------
808// ThrowStmt
809
810template< typename pass_type >
811void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
812        VISIT_BODY( node );
813}
814
815template< typename pass_type >
816Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
817        MUTATE_BODY( Statement, node );
818}
819
820//--------------------------------------------------------------------------
821// TryStmt
822template< typename pass_type >
823void PassVisitor< pass_type >::visit( TryStmt * node ) {
824        VISIT_START( node );
825
826        maybeAccept( node->block       , *this );
827        maybeAccept( node->handlers    , *this );
828        maybeAccept( node->finallyBlock, *this );
829
830        VISIT_END( node );
831}
832
833template< typename pass_type >
834Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
835        MUTATE_START( node );
836
837        maybeMutateRef( node->block       , *this );
838        maybeMutateRef( node->handlers    , *this );
839        maybeMutateRef( node->finallyBlock, *this );
840
841        MUTATE_END( Statement, node );
842}
843
844//--------------------------------------------------------------------------
845// CatchStmt
846template< typename pass_type >
847void PassVisitor< pass_type >::visit( CatchStmt * node ) {
848        VISIT_START( node );
849        {
850                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
851                maybeAccept( node->decl, *this );
852                node->cond = visitExpression( node->cond );
853                node->body = visitStatement ( node->body );
854        }
855        VISIT_END( node );
856}
857
858template< typename pass_type >
859Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
860        MUTATE_START( node );
861        {
862                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
863                maybeMutateRef( node->decl, *this );
864                node->cond = mutateExpression( node->cond );
865                node->body = mutateStatement ( node->body );
866        }
867        MUTATE_END( Statement, node );
868}
869
870//--------------------------------------------------------------------------
871// FinallyStmt
872template< typename pass_type >
873void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
874        VISIT_BODY( node );
875}
876
877template< typename pass_type >
878Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
879        MUTATE_BODY( Statement, node );
880}
881
882//--------------------------------------------------------------------------
883// WaitForStmt
884template< typename pass_type >
885void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
886        VISIT_BODY( node );
887}
888
889template< typename pass_type >
890Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
891        MUTATE_BODY( Statement, node );
892}
893
894//--------------------------------------------------------------------------
895// NullStmt
896template< typename pass_type >
897void PassVisitor< pass_type >::visit( NullStmt * node ) {
898        VISIT_BODY( node );
899}
900
901template< typename pass_type >
902NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
903        MUTATE_BODY( NullStmt, node );
904}
905
906//--------------------------------------------------------------------------
907// DeclStmt
908template< typename pass_type >
909void PassVisitor< pass_type >::visit( DeclStmt * node ) {
910        VISIT_BODY( node );
911}
912
913template< typename pass_type >
914Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
915        MUTATE_BODY( Statement, node );
916}
917
918//--------------------------------------------------------------------------
919// ImplicitCtorDtorStmt
920template< typename pass_type >
921void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
922        VISIT_BODY( node );
923}
924
925template< typename pass_type >
926Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
927        MUTATE_BODY( Statement, node );
928}
929
930//--------------------------------------------------------------------------
931// ApplicationExpr
932template< typename pass_type >
933void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
934        VISIT_START( node );
935
936        indexerScopedAccept( node->result  , *this );
937        maybeAccept        ( node->function, *this );
938        maybeAccept        ( node->args    , *this );
939
940        VISIT_END( node );
941}
942
943template< typename pass_type >
944Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
945        MUTATE_START( node );
946
947        indexerScopedMutate( node->env     , *this );
948        indexerScopedMutate( node->result  , *this );
949        maybeMutateRef     ( node->function, *this );
950        maybeMutateRef     ( node->args    , *this );
951
952        MUTATE_END( Expression, node );
953}
954
955//--------------------------------------------------------------------------
956// UntypedExpr
957template< typename pass_type >
958void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
959        VISIT_START( node );
960
961        // maybeAccept( node->get_env(), *this );
962        indexerScopedAccept( node->result, *this );
963
964        for ( auto expr : node->args ) {
965                visitExpression( expr );
966        }
967
968        VISIT_END( node );
969}
970
971template< typename pass_type >
972Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
973        MUTATE_START( node );
974
975        indexerScopedMutate( node->env   , *this );
976        indexerScopedMutate( node->result, *this );
977
978        for ( auto& expr : node->args ) {
979                expr = mutateExpression( expr );
980        }
981
982        MUTATE_END( Expression, node );
983}
984
985//--------------------------------------------------------------------------
986// NameExpr
987template< typename pass_type >
988void PassVisitor< pass_type >::visit( NameExpr * node ) {
989        VISIT_START( node );
990
991        indexerScopedAccept( node->result, *this );
992
993        VISIT_END( node );
994}
995
996template< typename pass_type >
997Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
998        MUTATE_START( node );
999
1000        indexerScopedMutate( node->env   , *this );
1001        indexerScopedMutate( node->result, *this );
1002
1003        MUTATE_END( Expression, node );
1004}
1005
1006//--------------------------------------------------------------------------
1007// CastExpr
1008template< typename pass_type >
1009void PassVisitor< pass_type >::visit( CastExpr * node ) {
1010        VISIT_START( node );
1011
1012        indexerScopedAccept( node->result, *this );
1013        maybeAccept        ( node->arg   , *this );
1014
1015        VISIT_END( node );
1016}
1017
1018template< typename pass_type >
1019Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
1020        MUTATE_START( node );
1021
1022        indexerScopedMutate( node->env   , *this );
1023        indexerScopedMutate( node->result, *this );
1024        maybeMutateRef     ( node->arg   , *this );
1025
1026        MUTATE_END( Expression, node );
1027}
1028
1029//--------------------------------------------------------------------------
1030// VirtualCastExpr
1031template< typename pass_type >
1032void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
1033        VISIT_START( node );
1034
1035        indexerScopedAccept( node->result, *this );
1036        maybeAccept( node->arg, *this );
1037
1038        VISIT_END( node );
1039}
1040
1041template< typename pass_type >
1042Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
1043        MUTATE_START( node );
1044
1045        indexerScopedMutate( node->env   , *this );
1046        indexerScopedMutate( node->result, *this );
1047        maybeMutateRef     ( node->arg   , *this );
1048
1049        MUTATE_END( Expression, node );
1050}
1051
1052//--------------------------------------------------------------------------
1053// AddressExpr
1054template< typename pass_type >
1055void PassVisitor< pass_type >::visit( AddressExpr * node ) {
1056        VISIT_START( node );
1057
1058        indexerScopedAccept( node->result, *this );
1059        maybeAccept        ( node->arg   , *this );
1060
1061        VISIT_END( node );
1062}
1063
1064template< typename pass_type >
1065Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
1066        MUTATE_START( node );
1067
1068        indexerScopedMutate( node->env   , *this );
1069        indexerScopedMutate( node->result, *this );
1070        maybeMutateRef     ( node->arg   , *this );
1071
1072        MUTATE_END( Expression, node );
1073}
1074
1075//--------------------------------------------------------------------------
1076// LabelAddressExpr
1077template< typename pass_type >
1078void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
1079        VISIT_START( node );
1080
1081        indexerScopedAccept( node->result, *this );
1082
1083        VISIT_END( node );
1084}
1085
1086template< typename pass_type >
1087Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
1088        MUTATE_START( node );
1089
1090        indexerScopedMutate( node->env   , *this );
1091        indexerScopedMutate( node->result, *this );
1092
1093        MUTATE_END( Expression, node );
1094}
1095
1096//--------------------------------------------------------------------------
1097// UntypedMemberExpr
1098template< typename pass_type >
1099void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
1100        VISIT_START( node );
1101
1102        indexerScopedAccept( node->result   , *this );
1103        maybeAccept        ( node->aggregate, *this );
1104        maybeAccept        ( node->member   , *this );
1105
1106        VISIT_END( node );
1107}
1108
1109template< typename pass_type >
1110Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
1111        MUTATE_START( node );
1112
1113        indexerScopedMutate( node->env      , *this );
1114        indexerScopedMutate( node->result   , *this );
1115        maybeMutateRef     ( node->aggregate, *this );
1116        maybeMutateRef     ( node->member   , *this );
1117
1118        MUTATE_END( Expression, node );
1119}
1120
1121//--------------------------------------------------------------------------
1122// MemberExpr
1123template< typename pass_type >
1124void PassVisitor< pass_type >::visit( MemberExpr * node ) {
1125        VISIT_START( node );
1126
1127        indexerScopedAccept( node->result   , *this );
1128        maybeAccept        ( node->aggregate, *this );
1129
1130        VISIT_END( node );
1131}
1132
1133template< typename pass_type >
1134Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
1135        MUTATE_START( node );
1136
1137        indexerScopedMutate( node->env      , *this );
1138        indexerScopedMutate( node->result   , *this );
1139        maybeMutateRef     ( node->aggregate, *this );
1140
1141        MUTATE_END( Expression, node );
1142}
1143
1144//--------------------------------------------------------------------------
1145// VariableExpr
1146template< typename pass_type >
1147void PassVisitor< pass_type >::visit( VariableExpr * node ) {
1148        VISIT_START( node );
1149
1150        indexerScopedAccept( node->result, *this );
1151
1152        VISIT_END( node );
1153}
1154
1155template< typename pass_type >
1156Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
1157        MUTATE_START( node );
1158
1159        indexerScopedMutate( node->env   , *this );
1160        indexerScopedMutate( node->result, *this );
1161
1162        MUTATE_END( Expression, node );
1163}
1164
1165//--------------------------------------------------------------------------
1166// ConstantExpr
1167template< typename pass_type >
1168void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
1169        VISIT_START( node );
1170
1171        indexerScopedAccept( node->result   , *this );
1172        maybeAccept        ( &node->constant, *this );
1173
1174        VISIT_END( node );
1175}
1176
1177template< typename pass_type >
1178Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
1179        MUTATE_START( node );
1180
1181        indexerScopedMutate( node->env   , *this );
1182        indexerScopedMutate( node->result, *this );
1183        node->constant = *maybeMutate( &node->constant, *this );
1184
1185        MUTATE_END( Expression, node );
1186}
1187
1188//--------------------------------------------------------------------------
1189// SizeofExpr
1190template< typename pass_type >
1191void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
1192        VISIT_START( node );
1193
1194        indexerScopedAccept( node->result, *this );
1195        if ( node->get_isType() ) {
1196                maybeAccept( node->type, *this );
1197        } else {
1198                maybeAccept( node->expr, *this );
1199        }
1200
1201        VISIT_END( node );
1202}
1203
1204template< typename pass_type >
1205Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
1206        MUTATE_START( node );
1207
1208        indexerScopedMutate( node->env   , *this );
1209        indexerScopedMutate( node->result, *this );
1210        if ( node->get_isType() ) {
1211                maybeMutateRef( node->type, *this );
1212        } else {
1213                maybeMutateRef( node->expr, *this );
1214        }
1215
1216        MUTATE_END( Expression, node );
1217}
1218
1219//--------------------------------------------------------------------------
1220// AlignofExpr
1221template< typename pass_type >
1222void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
1223        VISIT_START( node );
1224
1225        indexerScopedAccept( node->result, *this );
1226        if ( node->get_isType() ) {
1227                maybeAccept( node->type, *this );
1228        } else {
1229                maybeAccept( node->expr, *this );
1230        }
1231
1232        VISIT_END( node );
1233}
1234
1235template< typename pass_type >
1236Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
1237        MUTATE_START( node );
1238
1239        indexerScopedMutate( node->env   , *this );
1240        indexerScopedMutate( node->result, *this );
1241        if ( node->get_isType() ) {
1242                maybeMutateRef( node->type, *this );
1243        } else {
1244                maybeMutateRef( node->expr, *this );
1245        }
1246
1247        MUTATE_END( Expression, node );
1248}
1249
1250//--------------------------------------------------------------------------
1251// UntypedOffsetofExpr
1252template< typename pass_type >
1253void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
1254        VISIT_START( node );
1255
1256        indexerScopedAccept( node->result, *this );
1257        maybeAccept        ( node->type  , *this );
1258
1259        VISIT_END( node );
1260}
1261
1262template< typename pass_type >
1263Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
1264        MUTATE_START( node );
1265
1266        indexerScopedMutate( node->env   , *this );
1267        indexerScopedMutate( node->result, *this );
1268        maybeMutateRef     ( node->type  , *this );
1269
1270        MUTATE_END( Expression, node );
1271}
1272
1273//--------------------------------------------------------------------------
1274// OffsetofExpr
1275template< typename pass_type >
1276void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
1277        VISIT_START( node );
1278
1279        indexerScopedAccept( node->result, *this );
1280        maybeAccept        ( node->type  , *this );
1281        maybeAccept        ( node->member, *this );
1282
1283        VISIT_END( node );
1284}
1285
1286template< typename pass_type >
1287Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
1288        MUTATE_START( node );
1289
1290        indexerScopedMutate( node->env   , *this );
1291        indexerScopedMutate( node->result, *this );
1292        maybeMutateRef     ( node->type  , *this );
1293        maybeMutateRef     ( node->member, *this );
1294
1295        MUTATE_END( Expression, node );
1296}
1297
1298//--------------------------------------------------------------------------
1299// OffsetPackExpr
1300template< typename pass_type >
1301void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
1302        VISIT_START( node );
1303
1304        indexerScopedAccept( node->result, *this );
1305        maybeAccept        ( node->type  , *this );
1306
1307        VISIT_END( node );
1308}
1309
1310template< typename pass_type >
1311Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
1312        MUTATE_START( node );
1313
1314        indexerScopedMutate( node->env   , *this );
1315        indexerScopedMutate( node->result, *this );
1316        maybeMutateRef     ( node->type  , *this );
1317
1318        MUTATE_END( Expression, node );
1319}
1320
1321//--------------------------------------------------------------------------
1322// AttrExpr
1323template< typename pass_type >
1324void PassVisitor< pass_type >::visit( AttrExpr * node ) {
1325        VISIT_START( node );
1326
1327        indexerScopedAccept( node->result, *this );
1328        if ( node->get_isType() ) {
1329                maybeAccept( node->type, *this );
1330        } else {
1331                maybeAccept( node->expr, *this );
1332        }
1333
1334        VISIT_END( node );
1335}
1336
1337template< typename pass_type >
1338Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
1339        MUTATE_START( node );
1340
1341        indexerScopedMutate( node->env   , *this );
1342        indexerScopedMutate( node->result, *this );
1343        if ( node->get_isType() ) {
1344                maybeMutateRef( node->type, *this );
1345        } else {
1346                maybeMutateRef( node->expr, *this );
1347        }
1348
1349        MUTATE_END( Expression, node );
1350}
1351
1352//--------------------------------------------------------------------------
1353// LogicalExpr
1354template< typename pass_type >
1355void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
1356        VISIT_START( node );
1357
1358        indexerScopedAccept( node->result, *this );
1359        maybeAccept        ( node->arg1  , *this );
1360        maybeAccept        ( node->arg2  , *this );
1361
1362        VISIT_END( node );
1363}
1364
1365template< typename pass_type >
1366Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
1367        MUTATE_START( node );
1368
1369        indexerScopedMutate( node->env   , *this );
1370        indexerScopedMutate( node->result, *this );
1371        maybeMutateRef     ( node->arg1  , *this );
1372        maybeMutateRef     ( node->arg2  , *this );
1373
1374        MUTATE_END( Expression, node );
1375}
1376
1377//--------------------------------------------------------------------------
1378// ConditionalExpr
1379template< typename pass_type >
1380void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
1381        VISIT_START( node );
1382
1383        indexerScopedAccept( node->result, *this );
1384        maybeAccept        ( node->arg1  , *this );
1385        maybeAccept        ( node->arg2  , *this );
1386        maybeAccept        ( node->arg3  , *this );
1387
1388        VISIT_END( node );
1389}
1390
1391template< typename pass_type >
1392Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
1393        MUTATE_START( node );
1394
1395        indexerScopedMutate( node->env   , *this );
1396        indexerScopedMutate( node->result, *this );
1397        maybeMutateRef     ( node->arg1  , *this );
1398        maybeMutateRef     ( node->arg2  , *this );
1399        maybeMutateRef     ( node->arg3  , *this );
1400
1401        MUTATE_END( Expression, node );
1402}
1403
1404//--------------------------------------------------------------------------
1405// CommaExpr
1406template< typename pass_type >
1407void PassVisitor< pass_type >::visit( CommaExpr * node ) {
1408        VISIT_START( node );
1409
1410        indexerScopedAccept( node->result, *this );
1411        maybeAccept        ( node->arg1  , *this );
1412        maybeAccept        ( node->arg2  , *this );
1413
1414        VISIT_END( node );
1415}
1416
1417template< typename pass_type >
1418Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
1419        MUTATE_START( node );
1420
1421        indexerScopedMutate( node->env   , *this );
1422        indexerScopedMutate( node->result, *this );
1423        maybeMutateRef     ( node->arg1  , *this );
1424        maybeMutateRef     ( node->arg2  , *this );
1425
1426        MUTATE_END( Expression, node );
1427}
1428
1429//--------------------------------------------------------------------------
1430// TypeExpr
1431template< typename pass_type >
1432void PassVisitor< pass_type >::visit( TypeExpr * node ) {
1433        VISIT_START( node );
1434
1435        indexerScopedAccept( node->result, *this );
1436        maybeAccept        ( node->type, *this );
1437
1438        VISIT_END( node );
1439}
1440
1441template< typename pass_type >
1442Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
1443        MUTATE_START( node );
1444
1445        indexerScopedMutate( node->env   , *this );
1446        indexerScopedMutate( node->result, *this );
1447        maybeMutateRef     ( node->type  , *this );
1448
1449        MUTATE_END( Expression, node );
1450}
1451
1452//--------------------------------------------------------------------------
1453// AsmExpr
1454template< typename pass_type >
1455void PassVisitor< pass_type >::visit( AsmExpr * node ) {
1456        VISIT_START( node );
1457
1458        indexerScopedAccept( node->result    , *this );
1459        maybeAccept        ( node->inout     , *this );
1460        maybeAccept        ( node->constraint, *this );
1461        maybeAccept        ( node->operand   , *this );
1462
1463        VISIT_END( node );
1464}
1465
1466template< typename pass_type >
1467Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
1468        MUTATE_START( node );
1469
1470        indexerScopedMutate( node->env       , *this );
1471        indexerScopedMutate( node->result    , *this );
1472        maybeMutateRef     ( node->inout     , *this );
1473        maybeMutateRef     ( node->constraint, *this );
1474        maybeMutateRef     ( node->operand   , *this );
1475
1476        MUTATE_END( Expression, node );
1477}
1478
1479//--------------------------------------------------------------------------
1480// ImplicitCopyCtorExpr
1481template< typename pass_type >
1482void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
1483        VISIT_START( node );
1484
1485        indexerScopedAccept( node->result     , *this );
1486        maybeAccept        ( node->callExpr   , *this );
1487        maybeAccept        ( node->tempDecls  , *this );
1488        maybeAccept        ( node->returnDecls, *this );
1489        maybeAccept        ( node->dtors      , *this );
1490
1491        VISIT_END( node );
1492}
1493
1494template< typename pass_type >
1495Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
1496        MUTATE_START( node );
1497
1498        indexerScopedMutate( node->env        , *this );
1499        indexerScopedMutate( node->result     , *this );
1500        maybeMutateRef     ( node->callExpr   , *this );
1501        maybeMutateRef     ( node->tempDecls  , *this );
1502        maybeMutateRef     ( node->returnDecls, *this );
1503        maybeMutateRef     ( node->dtors      , *this );
1504
1505        MUTATE_END( Expression, node );
1506}
1507
1508//--------------------------------------------------------------------------
1509// ConstructorExpr
1510template< typename pass_type >
1511void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
1512        VISIT_START( node );
1513
1514        indexerScopedAccept( node->result  , *this );
1515        maybeAccept        ( node->callExpr, *this );
1516
1517        VISIT_END( node );
1518}
1519
1520template< typename pass_type >
1521Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
1522        MUTATE_START( node );
1523
1524        indexerScopedMutate( node->env     , *this );
1525        indexerScopedMutate( node->result  , *this );
1526        maybeMutateRef     ( node->callExpr, *this );
1527
1528        MUTATE_END( Expression, node );
1529}
1530
1531//--------------------------------------------------------------------------
1532// CompoundLiteralExpr
1533template< typename pass_type >
1534void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
1535        VISIT_START( node );
1536
1537        indexerScopedAccept( node->result     , *this );
1538        maybeAccept        ( node->initializer, *this );
1539
1540        VISIT_END( node );
1541}
1542
1543template< typename pass_type >
1544Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
1545        MUTATE_START( node );
1546
1547        indexerScopedMutate( node->env        , *this );
1548        indexerScopedMutate( node->result     , *this );
1549        maybeMutateRef     ( node->initializer, *this );
1550
1551        MUTATE_END( Expression, node );
1552}
1553
1554//--------------------------------------------------------------------------
1555// RangeExpr
1556template< typename pass_type >
1557void PassVisitor< pass_type >::visit( RangeExpr * node ) {
1558        VISIT_START( node );
1559
1560        indexerScopedAccept( node->result, *this );
1561        maybeAccept        ( node->low   , *this );
1562        maybeAccept        ( node->high  , *this );
1563
1564        VISIT_END( node );
1565}
1566
1567template< typename pass_type >
1568Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
1569        MUTATE_START( node );
1570
1571        indexerScopedMutate( node->env   , *this );
1572        indexerScopedMutate( node->result, *this );
1573        maybeMutateRef     ( node->low   , *this );
1574        maybeMutateRef     ( node->high  , *this );
1575
1576        MUTATE_END( Expression, node );
1577}
1578
1579//--------------------------------------------------------------------------
1580// UntypedTupleExpr
1581template< typename pass_type >
1582void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
1583        VISIT_START( node );
1584
1585        indexerScopedAccept( node->result, *this );
1586        maybeAccept        ( node->exprs , *this );
1587
1588        VISIT_END( node );
1589}
1590
1591template< typename pass_type >
1592Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
1593        MUTATE_START( node );
1594
1595        indexerScopedMutate( node->env   , *this );
1596        indexerScopedMutate( node->result, *this );
1597        maybeMutateRef     ( node->exprs , *this );
1598
1599        MUTATE_END( Expression, node );
1600}
1601
1602//--------------------------------------------------------------------------
1603// TupleExpr
1604template< typename pass_type >
1605void PassVisitor< pass_type >::visit( TupleExpr * node ) {
1606        VISIT_START( node );
1607
1608        indexerScopedAccept( node->result, *this );
1609        maybeAccept          ( node->exprs , *this );
1610
1611        VISIT_END( node );
1612}
1613
1614template< typename pass_type >
1615Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
1616        MUTATE_START( node );
1617
1618        indexerScopedMutate( node->env   , *this );
1619        indexerScopedMutate( node->result, *this );
1620        maybeMutateRef     ( node->exprs , *this );
1621
1622        MUTATE_END( Expression, node );
1623}
1624
1625//--------------------------------------------------------------------------
1626// TupleIndexExpr
1627template< typename pass_type >
1628void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
1629        VISIT_START( node );
1630
1631        indexerScopedAccept( node->result, *this );
1632        maybeAccept        ( node->tuple , *this );
1633
1634        VISIT_END( node );
1635}
1636
1637template< typename pass_type >
1638Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
1639        MUTATE_START( node );
1640
1641        indexerScopedMutate( node->env   , *this );
1642        indexerScopedMutate( node->result, *this );
1643        maybeMutateRef     ( node->tuple , *this );
1644
1645        MUTATE_END( Expression, node );
1646}
1647
1648//--------------------------------------------------------------------------
1649// TupleAssignExpr
1650template< typename pass_type >
1651void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
1652        VISIT_START( node );
1653
1654        indexerScopedAccept( node->result  , *this );
1655        maybeAccept        ( node->stmtExpr, *this );
1656
1657        VISIT_END( node );
1658}
1659
1660template< typename pass_type >
1661Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
1662        MUTATE_START( node );
1663
1664        indexerScopedMutate( node->env     , *this );
1665        indexerScopedMutate( node->result  , *this );
1666        maybeMutateRef     ( node->stmtExpr, *this );
1667
1668        MUTATE_END( Expression, node );
1669}
1670
1671//--------------------------------------------------------------------------
1672// StmtExpr
1673template< typename pass_type >
1674void PassVisitor< pass_type >::visit( StmtExpr * node ) {
1675        VISIT_START( node );
1676
1677        // don't want statements from outer CompoundStmts to be added to this StmtExpr
1678        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
1679        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
1680        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
1681
1682        indexerScopedAccept( node->result     , *this );
1683        maybeAccept        ( node->statements , *this );
1684        maybeAccept        ( node->returnDecls, *this );
1685        maybeAccept        ( node->dtors      , *this );
1686
1687        VISIT_END( node );
1688}
1689
1690template< typename pass_type >
1691Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
1692        MUTATE_START( node );
1693
1694        // don't want statements from outer CompoundStmts to be added to this StmtExpr
1695        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
1696        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
1697        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
1698
1699        indexerScopedMutate( node->result     , *this );
1700        maybeMutateRef     ( node->statements , *this );
1701        maybeMutateRef     ( node->returnDecls, *this );
1702        maybeMutateRef     ( node->dtors      , *this );
1703
1704        MUTATE_END( Expression, node );
1705}
1706
1707//--------------------------------------------------------------------------
1708// UniqueExpr
1709template< typename pass_type >
1710void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
1711        VISIT_START( node );
1712
1713        indexerScopedAccept( node->result, *this );
1714        maybeAccept        ( node->expr  , *this );
1715
1716        VISIT_END( node );
1717}
1718
1719template< typename pass_type >
1720Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
1721        MUTATE_START( node );
1722
1723        indexerScopedMutate( node->env   , *this );
1724        indexerScopedMutate( node->result, *this );
1725        maybeMutateRef     ( node->expr  , *this );
1726
1727        MUTATE_END( Expression, node );
1728}
1729
1730template< typename pass_type >
1731void PassVisitor< pass_type >::visit( VoidType * node ) {
1732        VISIT_BODY( node );
1733}
1734
1735template< typename pass_type >
1736void PassVisitor< pass_type >::visit( BasicType * node ) {
1737        VISIT_BODY( node );
1738}
1739
1740template< typename pass_type >
1741void PassVisitor< pass_type >::visit( PointerType * node ) {
1742        VISIT_BODY( node );
1743}
1744
1745template< typename pass_type >
1746void PassVisitor< pass_type >::visit( ArrayType * node ) {
1747        VISIT_BODY( node );
1748}
1749
1750template< typename pass_type >
1751void PassVisitor< pass_type >::visit( ReferenceType * node ) {
1752        VISIT_BODY( node );
1753}
1754
1755template< typename pass_type >
1756void PassVisitor< pass_type >::visit( FunctionType * node ) {
1757        VISIT_BODY( node );
1758}
1759
1760//--------------------------------------------------------------------------
1761// StructInstType
1762template< typename pass_type >
1763void PassVisitor< pass_type >::visit( StructInstType * node ) {
1764        VISIT_START( node );
1765
1766        indexerAddStruct( node->name );
1767
1768        {
1769                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1770                maybeAccept( node->forall    , *this );
1771                maybeAccept( node->parameters, *this );
1772        }
1773
1774        VISIT_END( node );
1775}
1776
1777template< typename pass_type >
1778Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
1779        MUTATE_START( node );
1780
1781        indexerAddStruct( node->name );
1782
1783        {
1784                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1785                maybeMutateRef( node->forall    , *this );
1786                maybeMutateRef( node->parameters, *this );
1787        }
1788
1789        MUTATE_END( Type, node );
1790}
1791
1792//--------------------------------------------------------------------------
1793// UnionInstType
1794template< typename pass_type >
1795void PassVisitor< pass_type >::visit( UnionInstType * node ) {
1796        VISIT_START( node );
1797
1798        indexerAddStruct( node->name );
1799
1800        {
1801                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1802                maybeAccept( node->forall    , *this );
1803                maybeAccept( node->parameters, *this );
1804        }
1805
1806        VISIT_END( node );
1807}
1808
1809template< typename pass_type >
1810Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
1811        MUTATE_START( node );
1812
1813        indexerAddStruct( node->name );
1814
1815        {
1816                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1817                maybeMutateRef( node->forall    , *this );
1818                maybeMutateRef( node->parameters, *this );
1819        }
1820
1821        MUTATE_END( Type, node );
1822}
1823
1824//--------------------------------------------------------------------------
1825// EnumInstType
1826template< typename pass_type >
1827void PassVisitor< pass_type >::visit( EnumInstType * node ) {
1828        VISIT_BODY( node );
1829}
1830
1831template< typename pass_type >
1832Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
1833        MUTATE_BODY( Type, node );
1834}
1835
1836//--------------------------------------------------------------------------
1837// TraitInstType
1838template< typename pass_type >
1839void PassVisitor< pass_type >::visit( TraitInstType * node ) {
1840        VISIT_START( node );
1841
1842        maybeAccept( node->forall    , *this );
1843        maybeAccept( node->parameters, *this );
1844
1845        VISIT_END( node );
1846}
1847
1848template< typename pass_type >
1849Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
1850        MUTATE_START( node );
1851
1852        maybeMutateRef( node->forall    , *this );
1853        maybeMutateRef( node->parameters, *this );
1854
1855        MUTATE_END( Type, node );
1856}
1857
1858//--------------------------------------------------------------------------
1859// TypeInstType
1860template< typename pass_type >
1861void PassVisitor< pass_type >::visit( TypeInstType * node ) {
1862        VISIT_BODY( node );
1863}
1864
1865template< typename pass_type >
1866void PassVisitor< pass_type >::visit( TupleType * node ) {
1867        VISIT_BODY( node );
1868}
1869
1870template< typename pass_type >
1871void PassVisitor< pass_type >::visit( TypeofType * node ) {
1872        VISIT_BODY( node );
1873}
1874
1875template< typename pass_type >
1876void PassVisitor< pass_type >::visit( AttrType * node ) {
1877        VISIT_BODY( node );
1878}
1879
1880template< typename pass_type >
1881void PassVisitor< pass_type >::visit( VarArgsType * node ) {
1882        VISIT_BODY( node );
1883}
1884
1885template< typename pass_type >
1886void PassVisitor< pass_type >::visit( ZeroType * node ) {
1887        VISIT_BODY( node );
1888}
1889
1890template< typename pass_type >
1891void PassVisitor< pass_type >::visit( OneType * node ) {
1892        VISIT_BODY( node );
1893}
1894
1895//--------------------------------------------------------------------------
1896// SingleInit
1897template< typename pass_type >
1898void PassVisitor< pass_type >::visit( SingleInit * node ) {
1899        VISIT_START( node );
1900
1901        visitExpression( node->get_value() );
1902
1903        VISIT_END( node );
1904}
1905
1906template< typename pass_type >
1907Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
1908        MUTATE_START( node );
1909
1910        node->set_value( mutateExpression( node->get_value() ) );
1911
1912        MUTATE_END( Initializer, node );
1913}
1914
1915template< typename pass_type >
1916void PassVisitor< pass_type >::visit( ListInit * node ) {
1917        VISIT_BODY( node );
1918}
1919
1920template< typename pass_type >
1921void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
1922        VISIT_BODY( node );
1923}
1924
1925template< typename pass_type >
1926void PassVisitor< pass_type >::visit( Subrange * node ) {
1927        VISIT_BODY( node );
1928}
1929
1930template< typename pass_type >
1931void PassVisitor< pass_type >::visit( Constant * node ) {
1932        VISIT_BODY( node );
1933}
1934
1935//---------------------------------------------------------------------------------------------------------------
1936template< typename pass_type >
1937Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
1938        MUTATE_BODY( Type, node );
1939}
1940
1941template< typename pass_type >
1942Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
1943        MUTATE_BODY( Type, node );
1944}
1945
1946template< typename pass_type >
1947Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
1948        MUTATE_BODY( Type, node );
1949}
1950
1951template< typename pass_type >
1952Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
1953        MUTATE_BODY( Type, node );
1954}
1955
1956template< typename pass_type >
1957Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
1958        MUTATE_BODY( Type, node );
1959}
1960
1961template< typename pass_type >
1962Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
1963        MUTATE_BODY( Type, node );
1964}
1965
1966template< typename pass_type >
1967Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
1968        MUTATE_BODY( Type, node );
1969}
1970
1971template< typename pass_type >
1972Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
1973        MUTATE_BODY( Type, node );
1974}
1975
1976template< typename pass_type >
1977Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
1978        MUTATE_BODY( Type, node );
1979}
1980
1981template< typename pass_type >
1982Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
1983        MUTATE_BODY( Type, node );
1984}
1985
1986template< typename pass_type >
1987Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
1988        MUTATE_BODY( Type, node );
1989}
1990
1991template< typename pass_type >
1992Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
1993        MUTATE_BODY( Type, node );
1994}
1995
1996template< typename pass_type >
1997Type * PassVisitor< pass_type >::mutate( OneType * node ) {
1998        MUTATE_BODY( Type, node );
1999}
2000
2001template< typename pass_type >
2002Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
2003        MUTATE_BODY( Initializer, node );
2004}
2005
2006template< typename pass_type >
2007Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
2008        MUTATE_BODY( Initializer, node );
2009}
2010
2011template< typename pass_type >
2012Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
2013        MUTATE_BODY( Subrange, node );
2014}
2015
2016template< typename pass_type >
2017Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
2018        MUTATE_BODY( Constant, node );
2019}
Note: See TracBrowser for help on using the repository browser.