source: src/Common/PassVisitor.impl.h @ 675716e

aaron-thesisarm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 675716e was 675716e, checked in by tdelisle <tdelisle@…>, 4 years ago

Instrumented PassVisitor? to print average/max depth

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