source: src/Common/PassVisitor.impl.h @ 447c356

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 447c356 was 447c356, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add support for TypeSubstitution? in PassVisitor?

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