source: src/Common/PassVisitor.impl.h @ 5ea7a22

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 5ea7a22 was 5ea7a22, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Make Attribute a child of BaseSyntaxNode?

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