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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 7870799 was 7870799, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Cast cost and conversion cost now take constant parameters.
This required supporting visiting const node.
The PassVisitor? can now visit const nodes but not when using the Indexer

  • Property mode set to 100644
File size: 104.9 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        auto __return = call_postmutate< type * >( node ); \
23        assert( __return ); \
24        return __return;
25
26
27template<typename T>
28static inline bool empty( T * ptr ) {
29        return !ptr || ptr->empty();
30}
31
32typedef std::list< Statement   * > StmtList_t;
33typedef std::list< Declaration * > DeclList_t;
34
35template<typename iterator_t>
36static inline void splice( iterator_t it, DeclList_t * decls ) {
37        std::transform(
38                decls->begin(),
39                decls->end(),
40                it,
41                [](Declaration * decl) -> auto {
42                        return new DeclStmt( decl );
43                }
44        );
45        decls->clear();
46}
47
48template< typename pass_type >
49inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
50        DeclList_t* beforeDecls = visitor.get_beforeDecls();
51        DeclList_t* afterDecls  = visitor.get_afterDecls();
52        SemanticErrorException errors;
53
54        pass_visitor_stats.depth++;
55        pass_visitor_stats.max->push(pass_visitor_stats.depth);
56        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
57        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
58
59
60                // splice in new declarations after previous decl
61                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
62
63                if ( i == decls.end() ) break;
64
65                try {
66                        // run visitor on declaration
67                        maybeAccept_impl( *i, visitor );
68                } catch( SemanticErrorException &e ) {
69                        errors.append( e );
70                }
71
72                // splice in new declarations before current decl
73                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
74        }
75        pass_visitor_stats.depth--;
76        if ( ! errors.isEmpty() ) {
77                throw errors;
78        }
79}
80
81template< typename pass_type >
82inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
83        SemanticErrorException errors;
84
85        pass_visitor_stats.depth++;
86        pass_visitor_stats.max->push(pass_visitor_stats.depth);
87        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
88        for ( const Declaration * decl : decls ) {
89                try {
90                        // run visitor on declaration
91                        maybeAccept_impl( decl, visitor );
92                }
93                catch( SemanticErrorException &e ) {
94                        errors.append( e );
95                }
96        }
97        pass_visitor_stats.depth--;
98        if ( ! errors.isEmpty() ) {
99                throw errors;
100        }
101}
102
103template< typename pass_type >
104inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
105        DeclList_t* beforeDecls = mutator.get_beforeDecls();
106        DeclList_t* afterDecls  = mutator.get_afterDecls();
107        SemanticErrorException errors;
108
109        pass_visitor_stats.depth++;
110        pass_visitor_stats.max->push(pass_visitor_stats.depth);
111        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
112        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
113                // splice in new declarations after previous decl
114                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
115
116                if ( i == decls.end() ) break;
117                try {
118                        // run mutator on declaration
119                        maybeMutate_impl( *i, mutator );
120                } catch( SemanticErrorException &e ) {
121                        errors.append( e );
122                }
123
124                // splice in new declarations before current decl
125                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
126        }
127        pass_visitor_stats.depth--;
128        if ( ! errors.isEmpty() ) {
129                throw errors;
130        }
131}
132
133template< typename TreeType, typename pass_type >
134inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) {
135        if ( ! visitor.get_visit_children() ) return;
136        if ( tree ) {
137                tree->accept( visitor );
138        }
139}
140
141template< typename TreeType, typename pass_type >
142inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
143        if ( ! visitor.get_visit_children() ) return;
144        if ( tree ) {
145                tree->accept( visitor );
146        }
147}
148
149template< typename Container, typename pass_type >
150inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
151        if ( ! visitor.get_visit_children() ) return;
152        SemanticErrorException errors;
153
154        pass_visitor_stats.depth++;
155        pass_visitor_stats.max->push(pass_visitor_stats.depth);
156        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
157        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
158                try {
159                        if ( *i ) {
160                                (*i)->accept( visitor );
161                        }
162                } catch( SemanticErrorException &e ) {
163                        errors.append( e );
164                }
165        }
166        pass_visitor_stats.depth--;
167        if ( ! errors.isEmpty() ) {
168                throw errors;
169        }
170}
171
172template< typename Container, typename pass_type >
173inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
174        if ( ! visitor.get_visit_children() ) return;
175        SemanticErrorException errors;
176
177        pass_visitor_stats.depth++;
178        pass_visitor_stats.max->push(pass_visitor_stats.depth);
179        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
180        for ( const auto & i : container ) {
181                try {
182                        if ( i ) {
183                                i->accept( visitor );
184                        }
185                } catch( SemanticErrorException &e ) {
186                        errors.append( e );
187                }
188        }
189        pass_visitor_stats.depth--;
190        if ( ! errors.isEmpty() ) {
191                throw errors;
192        }
193}
194
195template< typename TreeType, typename pass_type >
196inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) {
197        if ( ! mutator.get_visit_children() ) return;
198
199        if ( tree ) {
200                tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) );
201        }
202}
203
204template< typename Container, typename pass_type >
205inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
206
207        if ( ! mutator.get_visit_children() ) return;
208        SemanticErrorException errors;
209
210        pass_visitor_stats.depth++;
211        pass_visitor_stats.max->push(pass_visitor_stats.depth);
212        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
213        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
214                try {
215                        if ( *i ) {
216                                *i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
217                                assert( *i );
218                        } // if
219                } catch( SemanticErrorException &e ) {
220                        errors.append( e );
221                } // try
222        } // for
223        pass_visitor_stats.depth--;
224        if ( ! errors.isEmpty() ) {
225                throw errors;
226        } // if
227}
228
229template< typename pass_type >
230template< typename func_t >
231void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
232        if ( ! get_visit_children() ) return;
233        SemanticErrorException errors;
234
235        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
236        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
237        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
238        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
239        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
240
241        StmtList_t* beforeStmts = get_beforeStmts();
242        StmtList_t* afterStmts  = get_afterStmts();
243        DeclList_t* beforeDecls = get_beforeDecls();
244        DeclList_t* afterDecls  = get_afterDecls();
245
246        pass_visitor_stats.depth++;
247        pass_visitor_stats.max->push(pass_visitor_stats.depth);
248        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
249        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
250
251                if ( !empty( afterDecls ) ) { splice( std::inserter( statements, i ), afterDecls ); }
252                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
253
254                try {
255                        func( *i );
256                        assert( *i );
257                        assert(( empty( beforeStmts ) && empty( afterStmts ))
258                            || ( empty( beforeDecls ) && empty( afterDecls )) );
259
260                } catch ( SemanticErrorException &e ) {
261                        errors.append( e );
262                }
263
264                if ( !empty( beforeDecls ) ) { splice( std::inserter( statements, i ), beforeDecls ); }
265                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
266        }
267        pass_visitor_stats.depth--;
268
269        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
270        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
271        if ( !errors.isEmpty() ) { throw errors; }
272}
273
274template< typename pass_type >
275void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
276        handleStatementList( statements, [this]( Statement * stmt) {
277                maybeAccept_impl( stmt, *this );
278        });
279}
280
281template< typename pass_type >
282void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
283        if ( ! get_visit_children() ) return;
284        SemanticErrorException errors;
285
286        pass_visitor_stats.depth++;
287        pass_visitor_stats.max->push(pass_visitor_stats.depth);
288        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
289        for ( const Statement * i : statements ) {
290                try {
291                        maybeAccept_impl( i, *this );
292                } catch ( SemanticErrorException &e ) {
293                        errors.append( e );
294                }
295        }
296        pass_visitor_stats.depth--;
297        if ( !errors.isEmpty() ) { throw errors; }
298}
299
300template< typename pass_type >
301void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
302        handleStatementList( statements, [this]( Statement *& stmt) {
303                maybeMutate_impl( stmt, *this );
304        });
305}
306
307
308template< typename pass_type >
309template< typename func_t >
310Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
311        if ( ! get_visit_children() ) return stmt;
312
313        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
314        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
315        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
316        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
317        ValueGuardPtr< StmtList_t >          oldBeforeStmts( get_beforeStmts() );
318        ValueGuardPtr< StmtList_t >          oldAfterStmts ( get_afterStmts () );
319
320        Statement *newStmt = func( stmt );
321
322        StmtList_t* beforeStmts = get_beforeStmts();
323        StmtList_t* afterStmts  = get_afterStmts();
324        DeclList_t* beforeDecls = get_beforeDecls();
325        DeclList_t* afterDecls  = get_afterDecls();
326
327        if( empty(beforeStmts) && empty(afterStmts) && empty(beforeDecls) && empty(afterDecls) ) { return newStmt; }
328        assert(( empty( beforeStmts ) && empty( afterStmts ))
329            || ( empty( beforeDecls ) && empty( afterDecls )) );
330
331        CompoundStmt *compound = new CompoundStmt();
332        if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); }
333        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
334        compound->get_kids().push_back( newStmt );
335        if( !empty(afterDecls) ) { splice( std::back_inserter( compound->get_kids() ), afterDecls ); }
336        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
337        return compound;
338}
339
340template< typename pass_type >
341Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
342        return handleStatement( stmt, [this]( Statement * stmt ) {
343                maybeAccept_impl( stmt, *this );
344                return stmt;
345        });
346}
347
348template< typename pass_type >
349void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
350        if ( ! get_visit_children() ) return;
351
352        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
353        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
354
355        maybeAccept_impl( stmt, *this );
356}
357
358template< typename pass_type >
359Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
360        return handleStatement( stmt, [this]( Statement * stmt ) {
361                maybeMutate_impl( stmt, *this );
362                return stmt;
363        });
364}
365
366template< typename pass_type >
367template< typename func_t >
368Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
369        if ( ! get_visit_children() ) return expr;
370        if( !expr ) return nullptr;
371
372        auto env_ptr = get_env_ptr();
373        if ( env_ptr && expr->get_env() ) {
374                *env_ptr = expr->get_env();
375        }
376
377        // should env be moved onto the result of the mutate?
378        return func( expr );
379}
380
381template< typename pass_type >
382Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
383        return handleExpression(expr, [this]( Expression * expr ) {
384                maybeAccept_impl( expr, *this );
385                return expr;
386        });
387}
388
389template< typename pass_type >
390void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
391        if ( ! get_visit_children() ) return;
392        if( !expr ) return;
393
394        auto env_ptr = get_env_ptr();
395        if ( env_ptr && expr->get_env() ) {
396                *env_ptr = expr->get_env();
397        }
398
399        maybeAccept_impl( expr, *this );
400}
401
402template< typename pass_type >
403Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
404        return handleExpression(expr, [this]( Expression * expr ) {
405                maybeMutate_impl( expr, *this );
406                return expr;
407        });
408}
409
410template< typename TreeType, typename VisitorType >
411inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
412        if ( ! visitor.get_visit_children() ) return;
413        auto guard = makeFuncGuard(
414                [&visitor]() { visitor.indexerScopeEnter(); },
415                [&visitor]() { visitor.indexerScopeLeave(); }
416        );
417        maybeAccept_impl( tree, visitor );
418}
419
420template< typename TreeType, typename VisitorType >
421inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
422        if ( ! visitor.get_visit_children() ) return;
423        auto guard = makeFuncGuard(
424                [&visitor]() { visitor.indexerScopeEnter(); },
425                [&visitor]() { visitor.indexerScopeLeave(); }
426        );
427        maybeAccept_impl( tree, visitor );
428}
429
430template< typename TreeType, typename MutatorType >
431inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {
432        if ( ! mutator.get_visit_children() ) return;
433        auto guard = makeFuncGuard(
434                [&mutator]() { mutator.indexerScopeEnter(); },
435                [&mutator]() { mutator.indexerScopeLeave(); }
436        );
437        maybeMutate_impl( tree, mutator );
438}
439
440//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
441//========================================================================================================================================================================
442//========================================================================================================================================================================
443//========================================================================================================================================================================
444//========================================================================================================================================================================
445//========================================================================================================================================================================
446//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
447
448// A NOTE ON THE ORDER OF TRAVERSAL
449//
450// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
451// no such thing as a recursive type or typedef.
452//
453//             typedef struct { T *x; } T; // never allowed
454//
455// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
456// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
457// declaration).
458//
459//             struct T { struct T *x; }; // allowed
460//
461// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
462// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
463// queried later in this pass.
464//
465// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
466
467//--------------------------------------------------------------------------
468// ObjectDecl
469template< typename pass_type >
470void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
471        VISIT_START( node );
472
473        indexerScopedAccept( node->type         , *this );
474        maybeAccept_impl   ( node->init         , *this );
475        maybeAccept_impl   ( node->bitfieldWidth, *this );
476        maybeAccept_impl   ( node->attributes   , *this );
477
478        indexerAddId( node );
479
480        VISIT_END( node );
481}
482
483template< typename pass_type >
484void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
485        VISIT_START( node );
486
487        maybeAccept_impl( node->type         , *this );
488        maybeAccept_impl( node->init         , *this );
489        maybeAccept_impl( node->bitfieldWidth, *this );
490        maybeAccept_impl( node->attributes   , *this );
491
492        VISIT_END( node );
493}
494
495template< typename pass_type >
496DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
497        MUTATE_START( node );
498
499        indexerScopedMutate( node->type         , *this );
500        maybeMutate_impl   ( node->init         , *this );
501        maybeMutate_impl   ( node->bitfieldWidth, *this );
502        maybeMutate_impl   ( node->attributes   , *this );
503
504        indexerAddId( node );
505
506        MUTATE_END( DeclarationWithType, node );
507}
508
509//--------------------------------------------------------------------------
510// FunctionDecl
511template< typename pass_type >
512void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
513        VISIT_START( node );
514
515        indexerAddId( node );
516
517        maybeAccept_impl( node->withExprs, *this );
518        {
519                // with clause introduces a level of scope (for the with expression members).
520                // with clause exprs are added to the indexer before parameters so that parameters
521                // shadow with exprs and not the other way around.
522                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
523                indexerAddWith( node->withExprs, node );
524                {
525                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
526                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
527                        static ObjectDecl func(
528                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
529                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
530                                nullptr
531                        );
532                        indexerAddId( &func );
533                        maybeAccept_impl( node->type, *this );
534                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
535                        // a new scope if inFunction is true
536                        ValueGuard< bool > oldInFunction( inFunction );
537                        inFunction = true;
538                        maybeAccept_impl( node->statements, *this );
539                        maybeAccept_impl( node->attributes, *this );
540                }
541        }
542
543        VISIT_END( node );
544}
545
546template< typename pass_type >
547void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
548        VISIT_START( node );
549
550        maybeAccept_impl( node->withExprs, *this );
551        {
552                // implicit add __func__ identifier as specified in the C manual 6.4.2.2
553                static ObjectDecl func(
554                        "__func__", noStorageClasses, LinkageSpec::C, nullptr,
555                        new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
556                        nullptr
557                );
558                maybeAccept_impl( node->type, *this );
559                // function body needs to have the same scope as parameters - CompoundStmt will not enter
560                // a new scope if inFunction is true
561                ValueGuard< bool > oldInFunction( inFunction );
562                inFunction = true;
563                maybeAccept_impl( node->statements, *this );
564                maybeAccept_impl( node->attributes, *this );
565        }
566
567        VISIT_END( node );
568}
569
570template< typename pass_type >
571DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
572        MUTATE_START( node );
573
574        indexerAddId( node );
575
576        {
577                // with clause introduces a level of scope (for the with expression members).
578                // with clause exprs are added to the indexer before parameters so that parameters
579                // shadow with exprs and not the other way around.
580                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
581                indexerAddWith( node->withExprs, node );
582                {
583                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
584                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
585                        static ObjectDecl func(
586                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
587                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
588                                nullptr
589                        );
590                        indexerAddId( &func );
591                        maybeMutate_impl( node->type, *this );
592                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
593                        // a new scope if inFunction is true
594                        ValueGuard< bool > oldInFunction( inFunction );
595                        inFunction = true;
596                        maybeMutate_impl( node->statements, *this );
597                        maybeMutate_impl( node->attributes, *this );
598                }
599        }
600
601        MUTATE_END( DeclarationWithType, node );
602}
603
604//--------------------------------------------------------------------------
605// StructDecl
606template< typename pass_type >
607void PassVisitor< pass_type >::visit( StructDecl * node ) {
608        VISIT_START( node );
609
610        // make up a forward declaration and add it before processing the members
611        // needs to be on the heap because addStruct saves the pointer
612        indexerAddStructFwd( node );
613
614        {
615                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
616                maybeAccept_impl( node->parameters, *this );
617                maybeAccept_impl( node->members   , *this );
618        }
619
620        // this addition replaces the forward declaration
621        indexerAddStruct( node );
622
623        VISIT_END( node );
624}
625
626template< typename pass_type >
627void PassVisitor< pass_type >::visit( const StructDecl * node ) {
628        VISIT_START( node );
629
630        maybeAccept_impl( node->parameters, *this );
631        maybeAccept_impl( node->members   , *this );
632
633        VISIT_END( node );
634}
635
636template< typename pass_type >
637Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
638        MUTATE_START( node );
639
640        // make up a forward declaration and add it before processing the members
641        // needs to be on the heap because addStruct saves the pointer
642        indexerAddStructFwd( node );
643
644        {
645                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
646                maybeMutate_impl( node->parameters, *this );
647                maybeMutate_impl( node->members   , *this );
648        }
649
650        // this addition replaces the forward declaration
651        indexerAddStruct( node );
652
653        MUTATE_END( Declaration, node );
654}
655
656//--------------------------------------------------------------------------
657// UnionDecl
658template< typename pass_type >
659void PassVisitor< pass_type >::visit( UnionDecl * node ) {
660        VISIT_START( node );
661
662        // make up a forward declaration and add it before processing the members
663        indexerAddUnionFwd( node );
664
665        {
666                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
667                maybeAccept_impl( node->parameters, *this );
668                maybeAccept_impl( node->members   , *this );
669        }
670
671        indexerAddUnion( node );
672
673        VISIT_END( node );
674}
675template< typename pass_type >
676void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
677        VISIT_START( node );
678
679        maybeAccept_impl( node->parameters, *this );
680        maybeAccept_impl( node->members   , *this );
681
682        VISIT_END( node );
683}
684
685template< typename pass_type >
686Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
687        MUTATE_START( node );
688
689        // make up a forward declaration and add it before processing the members
690        indexerAddUnionFwd( node );
691
692        {
693                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
694                maybeMutate_impl( node->parameters, *this );
695                maybeMutate_impl( node->members   , *this );
696        }
697
698        indexerAddUnion( node );
699
700        MUTATE_END( Declaration, node );
701}
702
703//--------------------------------------------------------------------------
704// EnumDecl
705template< typename pass_type >
706void PassVisitor< pass_type >::visit( EnumDecl * node ) {
707        VISIT_START( node );
708
709        indexerAddEnum( node );
710
711        // unlike structs, traits, and unions, enums inject their members into the global scope
712        maybeAccept_impl( node->parameters, *this );
713        maybeAccept_impl( node->members   , *this );
714
715        VISIT_END( node );
716}
717
718template< typename pass_type >
719void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
720        VISIT_START( node );
721
722        // unlike structs, traits, and unions, enums inject their members into the global scope
723        maybeAccept_impl( node->parameters, *this );
724        maybeAccept_impl( node->members   , *this );
725
726        VISIT_END( node );
727}
728
729template< typename pass_type >
730Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
731        MUTATE_START( node );
732
733        indexerAddEnum( node );
734
735        // unlike structs, traits, and unions, enums inject their members into the global scope
736        maybeMutate_impl( node->parameters, *this );
737        maybeMutate_impl( node->members   , *this );
738
739        MUTATE_END( Declaration, node );
740}
741
742//--------------------------------------------------------------------------
743// TraitDecl
744template< typename pass_type >
745void PassVisitor< pass_type >::visit( TraitDecl * node ) {
746        VISIT_START( node );
747
748        {
749                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
750                maybeAccept_impl( node->parameters, *this );
751                maybeAccept_impl( node->members   , *this );
752        }
753
754        indexerAddTrait( node );
755
756        VISIT_END( node );
757}
758
759template< typename pass_type >
760void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
761        VISIT_START( node );
762
763        maybeAccept_impl( node->parameters, *this );
764        maybeAccept_impl( node->members   , *this );
765
766        VISIT_END( node );
767}
768
769template< typename pass_type >
770Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
771        MUTATE_START( node );
772
773        {
774                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
775                maybeMutate_impl( node->parameters, *this );
776                maybeMutate_impl( node->members   , *this );
777        }
778
779        indexerAddTrait( node );
780
781        MUTATE_END( Declaration, node );
782}
783
784//--------------------------------------------------------------------------
785// TypeDecl
786template< typename pass_type >
787void PassVisitor< pass_type >::visit( TypeDecl * node ) {
788        VISIT_START( node );
789
790        {
791                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
792                maybeAccept_impl( node->parameters, *this );
793                maybeAccept_impl( node->base      , *this );
794        }
795
796        // see A NOTE ON THE ORDER OF TRAVERSAL, above
797        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
798        // and may depend on the type itself
799        indexerAddType( node );
800
801        maybeAccept_impl( node->assertions, *this );
802
803        indexerScopedAccept( node->init, *this );
804
805        VISIT_END( node );
806}
807
808
809template< typename pass_type >
810void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
811        VISIT_START( node );
812
813        maybeAccept_impl( node->parameters, *this );
814        maybeAccept_impl( node->base      , *this );
815        maybeAccept_impl( node->assertions, *this );
816
817        VISIT_END( node );
818}
819
820template< typename pass_type >
821Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
822        MUTATE_START( node );
823
824        {
825                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
826                maybeMutate_impl( node->parameters, *this );
827                maybeMutate_impl( node->base      , *this );
828        }
829
830        // see A NOTE ON THE ORDER OF TRAVERSAL, above
831        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
832        // and may depend on the type itself
833        indexerAddType( node );
834
835        maybeMutate_impl( node->assertions, *this );
836
837        indexerScopedMutate( node->init, *this );
838
839        MUTATE_END( Declaration, node );
840}
841
842//--------------------------------------------------------------------------
843// TypedefDecl
844template< typename pass_type >
845void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
846        VISIT_START( node );
847
848        {
849                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
850                maybeAccept_impl( node->parameters, *this );
851                maybeAccept_impl( node->base      , *this );
852        }
853
854        indexerAddType( node );
855
856        maybeAccept_impl( node->assertions, *this );
857
858        VISIT_END( node );
859}
860
861template< typename pass_type >
862void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
863        VISIT_START( node );
864
865        maybeAccept_impl( node->parameters, *this );
866        maybeAccept_impl( node->base      , *this );
867        maybeAccept_impl( node->assertions, *this );
868
869        VISIT_END( node );
870}
871
872template< typename pass_type >
873Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
874        MUTATE_START( node );
875
876        {
877                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
878                maybeMutate_impl( node->parameters, *this );
879                maybeMutate_impl( node->base      , *this );
880        }
881
882        indexerAddType( node );
883
884        maybeMutate_impl( node->assertions, *this );
885
886        MUTATE_END( Declaration, node );
887}
888
889//--------------------------------------------------------------------------
890// AsmDecl
891template< typename pass_type >
892void PassVisitor< pass_type >::visit( AsmDecl * node ) {
893        VISIT_START( node );
894
895        maybeAccept_impl( node->stmt, *this );
896
897        VISIT_END( node );
898}
899
900template< typename pass_type >
901void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
902        VISIT_START( node );
903
904        maybeAccept_impl( node->stmt, *this );
905
906        VISIT_END( node );
907}
908
909template< typename pass_type >
910AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
911        MUTATE_START( node );
912
913        maybeMutate_impl( node->stmt, *this );
914
915        MUTATE_END( AsmDecl, node );
916}
917
918//--------------------------------------------------------------------------
919// StaticAssertDecl
920template< typename pass_type >
921void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) {
922        VISIT_START( node );
923
924        node->condition = visitExpression( node->condition );
925        maybeAccept_impl( node->message, *this );
926
927        VISIT_END( node );
928}
929
930template< typename pass_type >
931void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
932        VISIT_START( node );
933
934        visitExpression( node->condition );
935        maybeAccept_impl( node->message, *this );
936
937        VISIT_END( node );
938}
939
940template< typename pass_type >
941StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
942        MUTATE_START( node );
943
944        node->condition = mutateExpression( node->condition );
945        maybeMutate_impl( node->message, *this );
946
947        MUTATE_END( StaticAssertDecl, node );
948}
949
950//--------------------------------------------------------------------------
951// CompoundStmt
952template< typename pass_type >
953void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
954        VISIT_START( node );
955        {
956                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
957                ValueGuard< bool > oldInFunction( inFunction );
958                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
959                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
960                inFunction = false;
961                visitStatementList( node->kids );
962        }
963        VISIT_END( node );
964}
965
966template< typename pass_type >
967void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
968        VISIT_START( node );
969        {
970                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
971                ValueGuard< bool > oldInFunction( inFunction );
972                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
973                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
974                inFunction = false;
975                visitStatementList( node->kids );
976        }
977        VISIT_END( node );
978}
979
980template< typename pass_type >
981CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
982        MUTATE_START( node );
983        {
984                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
985                ValueGuard< bool > oldInFunction( inFunction );
986                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
987                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
988                inFunction = false;
989                mutateStatementList( node->kids );
990        }
991        MUTATE_END( CompoundStmt, node );
992}
993
994//--------------------------------------------------------------------------
995// ExprStmt
996template< typename pass_type >
997void PassVisitor< pass_type >::visit( ExprStmt * node ) {
998        VISIT_START( node );
999
1000        visitExpression( node->expr );
1001
1002        VISIT_END( node );
1003}
1004
1005template< typename pass_type >
1006void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
1007        VISIT_START( node );
1008
1009        visitExpression( node->expr );
1010
1011        VISIT_END( node );
1012}
1013
1014template< typename pass_type >
1015Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
1016        MUTATE_START( node );
1017
1018        node->expr = mutateExpression( node->expr );
1019
1020        MUTATE_END( Statement, node );
1021}
1022
1023//--------------------------------------------------------------------------
1024// AsmStmt
1025template< typename pass_type >
1026void PassVisitor< pass_type >::visit( AsmStmt * node ) {
1027        VISIT_START( node )
1028
1029        maybeAccept_impl( node->instruction, *this );
1030        maybeAccept_impl( node->output, *this );
1031        maybeAccept_impl( node->input, *this );
1032        maybeAccept_impl( node->clobber, *this );
1033
1034        VISIT_END( node );
1035}
1036
1037template< typename pass_type >
1038void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
1039        VISIT_START( node )
1040
1041        maybeAccept_impl( node->instruction, *this );
1042        maybeAccept_impl( node->output, *this );
1043        maybeAccept_impl( node->input, *this );
1044        maybeAccept_impl( node->clobber, *this );
1045
1046        VISIT_END( node );
1047}
1048
1049template< typename pass_type >
1050Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
1051        MUTATE_START( node );
1052
1053        maybeMutate_impl( node->instruction, *this );
1054        maybeMutate_impl( node->output, *this );
1055        maybeMutate_impl( node->input, *this );
1056        maybeMutate_impl( node->clobber, *this );
1057
1058        MUTATE_END( Statement, node );
1059}
1060
1061//--------------------------------------------------------------------------
1062// AsmStmt
1063template< typename pass_type >
1064void PassVisitor< pass_type >::visit( DirectiveStmt * node ) {
1065        VISIT_START( node )
1066
1067        VISIT_END( node );
1068}
1069
1070template< typename pass_type >
1071void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
1072        VISIT_START( node )
1073
1074        VISIT_END( node );
1075}
1076
1077template< typename pass_type >
1078Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
1079        MUTATE_START( node );
1080
1081        MUTATE_END( Statement, node );
1082}
1083
1084//--------------------------------------------------------------------------
1085// IfStmt
1086template< typename pass_type >
1087void PassVisitor< pass_type >::visit( IfStmt * node ) {
1088        VISIT_START( node );
1089        {
1090                // if statements introduce a level of scope (for the initialization)
1091                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1092                maybeAccept_impl( node->initialization, *this );
1093                visitExpression ( node->condition );
1094                node->thenPart = visitStatement( node->thenPart );
1095                node->elsePart = visitStatement( node->elsePart );
1096        }
1097        VISIT_END( node );
1098}
1099
1100template< typename pass_type >
1101void PassVisitor< pass_type >::visit( const IfStmt * node ) {
1102        VISIT_START( node );
1103
1104        maybeAccept_impl( node->initialization, *this );
1105        visitExpression ( node->condition );
1106        visitStatement( node->thenPart );
1107        visitStatement( node->elsePart );
1108
1109        VISIT_END( node );
1110}
1111
1112template< typename pass_type >
1113Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
1114        MUTATE_START( node );
1115        {
1116                // if statements introduce a level of scope (for the initialization)
1117                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1118                maybeMutate_impl( node->initialization, *this );
1119                node->condition = mutateExpression( node->condition );
1120                node->thenPart  = mutateStatement ( node->thenPart  );
1121                node->elsePart  = mutateStatement ( node->elsePart  );
1122        }
1123        MUTATE_END( Statement, node );
1124}
1125
1126//--------------------------------------------------------------------------
1127// WhileStmt
1128template< typename pass_type >
1129void PassVisitor< pass_type >::visit( WhileStmt * node ) {
1130        VISIT_START( node );
1131
1132        {
1133                // while statements introduce a level of scope (for the initialization)
1134                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1135                maybeAccept_impl( node->initialization, *this );
1136                visitExpression ( node->condition );
1137                node->body = visitStatement( node->body );
1138        }
1139
1140        VISIT_END( node );
1141}
1142
1143template< typename pass_type >
1144void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
1145        VISIT_START( node );
1146
1147        maybeAccept_impl( node->initialization, *this );
1148        visitExpression ( node->condition );
1149        visitStatement( node->body );
1150
1151        VISIT_END( node );
1152}
1153
1154template< typename pass_type >
1155Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
1156        MUTATE_START( node );
1157
1158        {
1159                // while statements introduce a level of scope (for the initialization)
1160                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1161                maybeMutate_impl( node->initialization, *this );
1162                node->condition = mutateExpression( node->condition );
1163                node->body      = mutateStatement ( node->body      );
1164        }
1165
1166
1167        MUTATE_END( Statement, node );
1168}
1169
1170//--------------------------------------------------------------------------
1171// ForStmt
1172template< typename pass_type >
1173void PassVisitor< pass_type >::visit( ForStmt * node ) {
1174        VISIT_START( node );
1175        {
1176                // for statements introduce a level of scope (for the initialization)
1177                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1178                maybeAccept_impl( node->initialization, *this );
1179                visitExpression( node->condition );
1180                visitExpression( node->increment );
1181                node->body = visitStatement( node->body );
1182        }
1183        VISIT_END( node );
1184}
1185
1186template< typename pass_type >
1187void PassVisitor< pass_type >::visit( const ForStmt * node ) {
1188        VISIT_START( node );
1189
1190        maybeAccept_impl( node->initialization, *this );
1191        visitExpression( node->condition );
1192        visitExpression( node->increment );
1193        visitStatement( node->body );
1194
1195        VISIT_END( node );
1196}
1197
1198template< typename pass_type >
1199Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
1200        MUTATE_START( node );
1201        {
1202                // for statements introduce a level of scope (for the initialization)
1203                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1204                maybeMutate_impl( node->initialization, *this );
1205                node->condition = mutateExpression( node->condition );
1206                node->increment = mutateExpression( node->increment );
1207                node->body      = mutateStatement ( node->body      );
1208        }
1209        MUTATE_END( Statement, node );
1210}
1211
1212//--------------------------------------------------------------------------
1213// SwitchStmt
1214template< typename pass_type >
1215void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
1216        VISIT_START( node );
1217
1218        visitExpression   ( node->condition  );
1219        visitStatementList( node->statements );
1220
1221        VISIT_END( node );
1222}
1223
1224template< typename pass_type >
1225void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
1226        VISIT_START( node );
1227
1228        visitExpression   ( node->condition  );
1229        visitStatementList( node->statements );
1230
1231        VISIT_END( node );
1232}
1233
1234template< typename pass_type >
1235Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
1236        MUTATE_START( node );
1237
1238        node->condition = mutateExpression( node->condition );
1239        mutateStatementList( node->statements );
1240
1241        MUTATE_END( Statement, node );
1242}
1243
1244//--------------------------------------------------------------------------
1245// CaseStmt
1246template< typename pass_type >
1247void PassVisitor< pass_type >::visit( CaseStmt * node ) {
1248        VISIT_START( node );
1249
1250        visitExpression   ( node->condition );
1251        visitStatementList( node->stmts     );
1252
1253        VISIT_END( node );
1254}
1255
1256template< typename pass_type >
1257void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
1258        VISIT_START( node );
1259
1260        visitExpression   ( node->condition );
1261        visitStatementList( node->stmts     );
1262
1263        VISIT_END( node );
1264}
1265
1266template< typename pass_type >
1267Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
1268        MUTATE_START( node );
1269
1270        node->condition = mutateExpression( node->condition );
1271        mutateStatementList( node->stmts );
1272
1273        MUTATE_END( Statement, node );
1274}
1275
1276//--------------------------------------------------------------------------
1277// BranchStmt
1278template< typename pass_type >
1279void PassVisitor< pass_type >::visit( BranchStmt * node ) {
1280        VISIT_START( node );
1281        VISIT_END( node );
1282}
1283
1284template< typename pass_type >
1285void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
1286        VISIT_START( node );
1287        VISIT_END( node );
1288}
1289
1290template< typename pass_type >
1291Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
1292        MUTATE_START( node );
1293        MUTATE_END( Statement, node );
1294}
1295
1296//--------------------------------------------------------------------------
1297// ReturnStmt
1298template< typename pass_type >
1299void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
1300        VISIT_START( node );
1301
1302        visitExpression( node->expr );
1303
1304        VISIT_END( node );
1305}
1306
1307template< typename pass_type >
1308void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
1309        VISIT_START( node );
1310
1311        visitExpression( node->expr );
1312
1313        VISIT_END( node );
1314}
1315
1316template< typename pass_type >
1317Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
1318        MUTATE_START( node );
1319
1320        node->expr = mutateExpression( node->expr );
1321
1322        MUTATE_END( Statement, node );
1323}
1324
1325//--------------------------------------------------------------------------
1326// ThrowStmt
1327template< typename pass_type >
1328void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
1329        VISIT_START( node );
1330
1331        maybeAccept_impl( node->expr, *this );
1332        maybeAccept_impl( node->target, *this );
1333
1334        VISIT_END( node );
1335}
1336
1337template< typename pass_type >
1338void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
1339        VISIT_START( node );
1340
1341        maybeAccept_impl( node->expr, *this );
1342        maybeAccept_impl( node->target, *this );
1343
1344        VISIT_END( node );
1345}
1346
1347template< typename pass_type >
1348Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
1349        MUTATE_START( node );
1350
1351        maybeMutate_impl( node->expr, *this );
1352        maybeMutate_impl( node->target, *this );
1353
1354        MUTATE_END( Statement, node );
1355}
1356
1357//--------------------------------------------------------------------------
1358// TryStmt
1359template< typename pass_type >
1360void PassVisitor< pass_type >::visit( TryStmt * node ) {
1361        VISIT_START( node );
1362
1363        maybeAccept_impl( node->block       , *this );
1364        maybeAccept_impl( node->handlers    , *this );
1365        maybeAccept_impl( node->finallyBlock, *this );
1366
1367        VISIT_END( node );
1368}
1369
1370template< typename pass_type >
1371void PassVisitor< pass_type >::visit( const TryStmt * node ) {
1372        VISIT_START( node );
1373
1374        maybeAccept_impl( node->block       , *this );
1375        maybeAccept_impl( node->handlers    , *this );
1376        maybeAccept_impl( node->finallyBlock, *this );
1377
1378        VISIT_END( node );
1379}
1380
1381template< typename pass_type >
1382Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
1383        MUTATE_START( node );
1384
1385        maybeMutate_impl( node->block       , *this );
1386        maybeMutate_impl( node->handlers    , *this );
1387        maybeMutate_impl( node->finallyBlock, *this );
1388
1389        MUTATE_END( Statement, node );
1390}
1391
1392//--------------------------------------------------------------------------
1393// CatchStmt
1394template< typename pass_type >
1395void PassVisitor< pass_type >::visit( CatchStmt * node ) {
1396        VISIT_START( node );
1397        {
1398                // catch statements introduce a level of scope (for the caught exception)
1399                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1400                maybeAccept_impl( node->decl, *this );
1401                node->cond = visitExpression( node->cond );
1402                node->body = visitStatement ( node->body );
1403        }
1404        VISIT_END( node );
1405}
1406
1407template< typename pass_type >
1408void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
1409        VISIT_START( node );
1410
1411        maybeAccept_impl( node->decl, *this );
1412        visitExpression( node->cond );
1413        visitStatement ( node->body );
1414
1415        VISIT_END( node );
1416}
1417
1418template< typename pass_type >
1419Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
1420        MUTATE_START( node );
1421        {
1422                // catch statements introduce a level of scope (for the caught exception)
1423                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1424                maybeMutate_impl( node->decl, *this );
1425                node->cond = mutateExpression( node->cond );
1426                node->body = mutateStatement ( node->body );
1427        }
1428        MUTATE_END( Statement, node );
1429}
1430
1431//--------------------------------------------------------------------------
1432// FinallyStmt
1433template< typename pass_type >
1434void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
1435        VISIT_START( node );
1436
1437        maybeAccept_impl( node->block, *this );
1438
1439        VISIT_END( node );
1440}
1441
1442template< typename pass_type >
1443void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
1444        VISIT_START( node );
1445
1446        maybeAccept_impl( node->block, *this );
1447
1448        VISIT_END( node );
1449}
1450
1451template< typename pass_type >
1452Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
1453        MUTATE_START( node );
1454
1455        maybeMutate_impl( node->block, *this );
1456
1457        MUTATE_END( Statement, node );
1458}
1459
1460//--------------------------------------------------------------------------
1461// WaitForStmt
1462template< typename pass_type >
1463void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
1464        VISIT_START( node );
1465
1466        for( auto & clause : node->clauses ) {
1467                maybeAccept_impl( clause.target.function, *this );
1468                maybeAccept_impl( clause.target.arguments, *this );
1469
1470                maybeAccept_impl( clause.statement, *this );
1471                maybeAccept_impl( clause.condition, *this );
1472        }
1473
1474        maybeAccept_impl( node->timeout.time, *this );
1475        maybeAccept_impl( node->timeout.statement, *this );
1476        maybeAccept_impl( node->timeout.condition, *this );
1477        maybeAccept_impl( node->orelse.statement, *this );
1478        maybeAccept_impl( node->orelse.condition, *this );
1479
1480        VISIT_END( node );
1481}
1482
1483template< typename pass_type >
1484void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
1485        VISIT_START( node );
1486
1487        for( auto & clause : node->clauses ) {
1488                maybeAccept_impl( clause.target.function, *this );
1489                maybeAccept_impl( clause.target.arguments, *this );
1490
1491                maybeAccept_impl( clause.statement, *this );
1492                maybeAccept_impl( clause.condition, *this );
1493        }
1494
1495        maybeAccept_impl( node->timeout.time, *this );
1496        maybeAccept_impl( node->timeout.statement, *this );
1497        maybeAccept_impl( node->timeout.condition, *this );
1498        maybeAccept_impl( node->orelse.statement, *this );
1499        maybeAccept_impl( node->orelse.condition, *this );
1500
1501        VISIT_END( node );
1502}
1503
1504template< typename pass_type >
1505Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
1506        MUTATE_START( node );
1507
1508        for( auto & clause : node->clauses ) {
1509                maybeMutate_impl( clause.target.function, *this );
1510                maybeMutate_impl( clause.target.arguments, *this );
1511
1512                maybeMutate_impl( clause.statement, *this );
1513                maybeMutate_impl( clause.condition, *this );
1514        }
1515
1516        maybeMutate_impl( node->timeout.time, *this );
1517        maybeMutate_impl( node->timeout.statement, *this );
1518        maybeMutate_impl( node->timeout.condition, *this );
1519        maybeMutate_impl( node->orelse.statement, *this );
1520        maybeMutate_impl( node->orelse.condition, *this );
1521
1522        MUTATE_END( Statement, node );
1523}
1524
1525
1526
1527//--------------------------------------------------------------------------
1528// WithStmt
1529template< typename pass_type >
1530void PassVisitor< pass_type >::visit( WithStmt * node ) {
1531        VISIT_START( node );
1532        maybeAccept_impl( node->exprs, *this );
1533        {
1534                // catch statements introduce a level of scope (for the caught exception)
1535                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1536                indexerAddWith( node->exprs, node );
1537                maybeAccept_impl( node->stmt, *this );
1538        }
1539        VISIT_END( node );
1540}
1541
1542template< typename pass_type >
1543void PassVisitor< pass_type >::visit( const WithStmt * node ) {
1544        VISIT_START( node );
1545
1546        maybeAccept_impl( node->exprs, *this );
1547        maybeAccept_impl( node->stmt, *this );
1548
1549        VISIT_END( node );
1550}
1551
1552template< typename pass_type >
1553Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
1554        MUTATE_START( node );
1555        maybeMutate_impl( node->exprs, *this );
1556        {
1557                // catch statements introduce a level of scope (for the caught exception)
1558                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
1559                indexerAddWith( node->exprs, node );
1560                maybeMutate_impl( node->stmt, *this );
1561        }
1562        MUTATE_END( Statement, node );
1563}
1564
1565//--------------------------------------------------------------------------
1566// NullStmt
1567template< typename pass_type >
1568void PassVisitor< pass_type >::visit( NullStmt * node ) {
1569        VISIT_START( node );
1570        VISIT_END( node );
1571}
1572
1573template< typename pass_type >
1574void PassVisitor< pass_type >::visit( const NullStmt * node ) {
1575        VISIT_START( node );
1576        VISIT_END( node );
1577}
1578
1579template< typename pass_type >
1580NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
1581        MUTATE_START( node );
1582        MUTATE_END( NullStmt, node );
1583}
1584
1585//--------------------------------------------------------------------------
1586// DeclStmt
1587template< typename pass_type >
1588void PassVisitor< pass_type >::visit( DeclStmt * node ) {
1589        VISIT_START( node );
1590
1591        maybeAccept_impl( node->decl, *this );
1592
1593        VISIT_END( node );
1594}
1595
1596template< typename pass_type >
1597void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
1598        VISIT_START( node );
1599
1600        maybeAccept_impl( node->decl, *this );
1601
1602        VISIT_END( node );
1603}
1604
1605template< typename pass_type >
1606Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
1607        MUTATE_START( node );
1608
1609        maybeMutate_impl( node->decl, *this );
1610
1611        MUTATE_END( Statement, node );
1612}
1613
1614//--------------------------------------------------------------------------
1615// ImplicitCtorDtorStmt
1616template< typename pass_type >
1617void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
1618        VISIT_START( node );
1619
1620        maybeAccept_impl( node->callStmt, *this );
1621
1622        VISIT_END( node );
1623}
1624
1625template< typename pass_type >
1626void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
1627        VISIT_START( node );
1628
1629        maybeAccept_impl( node->callStmt, *this );
1630
1631        VISIT_END( node );
1632}
1633
1634template< typename pass_type >
1635Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
1636        MUTATE_START( node );
1637
1638        maybeMutate_impl( node->callStmt, *this );
1639
1640        MUTATE_END( Statement, node );
1641}
1642
1643//--------------------------------------------------------------------------
1644// ApplicationExpr
1645template< typename pass_type >
1646void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
1647        VISIT_START( node );
1648
1649        indexerScopedAccept( node->result  , *this );
1650        maybeAccept_impl        ( node->function, *this );
1651        maybeAccept_impl        ( node->args    , *this );
1652
1653        VISIT_END( node );
1654}
1655
1656template< typename pass_type >
1657void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
1658        VISIT_START( node );
1659
1660        maybeAccept_impl( node->result  , *this );
1661        maybeAccept_impl( node->function, *this );
1662        maybeAccept_impl( node->args    , *this );
1663
1664        VISIT_END( node );
1665}
1666
1667template< typename pass_type >
1668Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
1669        MUTATE_START( node );
1670
1671        indexerScopedMutate( node->env     , *this );
1672        indexerScopedMutate( node->result  , *this );
1673        maybeMutate_impl   ( node->function, *this );
1674        maybeMutate_impl   ( node->args    , *this );
1675
1676        MUTATE_END( Expression, node );
1677}
1678
1679//--------------------------------------------------------------------------
1680// UntypedExpr
1681template< typename pass_type >
1682void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
1683        VISIT_START( node );
1684
1685        // maybeAccept_impl( node->get_env(), *this );
1686        indexerScopedAccept( node->result, *this );
1687
1688        for ( auto expr : node->args ) {
1689                visitExpression( expr );
1690        }
1691
1692        VISIT_END( node );
1693}
1694
1695template< typename pass_type >
1696void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
1697        VISIT_START( node );
1698
1699        maybeAccept_impl( node->result, *this );
1700
1701        for ( auto expr : node->args ) {
1702                visitExpression( expr );
1703        }
1704
1705        VISIT_END( node );
1706}
1707
1708template< typename pass_type >
1709Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
1710        MUTATE_START( node );
1711
1712        indexerScopedMutate( node->env   , *this );
1713        indexerScopedMutate( node->result, *this );
1714
1715        for ( auto& expr : node->args ) {
1716                expr = mutateExpression( expr );
1717        }
1718
1719        MUTATE_END( Expression, node );
1720}
1721
1722//--------------------------------------------------------------------------
1723// NameExpr
1724template< typename pass_type >
1725void PassVisitor< pass_type >::visit( NameExpr * node ) {
1726        VISIT_START( node );
1727
1728        indexerScopedAccept( node->result, *this );
1729
1730        VISIT_END( node );
1731}
1732
1733template< typename pass_type >
1734void PassVisitor< pass_type >::visit( const NameExpr * node ) {
1735        VISIT_START( node );
1736
1737        maybeAccept_impl( node->result, *this );
1738
1739        VISIT_END( node );
1740}
1741
1742template< typename pass_type >
1743Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
1744        MUTATE_START( node );
1745
1746        indexerScopedMutate( node->env   , *this );
1747        indexerScopedMutate( node->result, *this );
1748
1749        MUTATE_END( Expression, node );
1750}
1751
1752//--------------------------------------------------------------------------
1753// CastExpr
1754template< typename pass_type >
1755void PassVisitor< pass_type >::visit( CastExpr * node ) {
1756        VISIT_START( node );
1757
1758        indexerScopedAccept( node->result, *this );
1759        maybeAccept_impl        ( node->arg   , *this );
1760
1761        VISIT_END( node );
1762}
1763
1764template< typename pass_type >
1765void PassVisitor< pass_type >::visit( const CastExpr * node ) {
1766        VISIT_START( node );
1767
1768        maybeAccept_impl( node->result, *this );
1769        maybeAccept_impl( node->arg   , *this );
1770
1771        VISIT_END( node );
1772}
1773
1774template< typename pass_type >
1775Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
1776        MUTATE_START( node );
1777
1778        indexerScopedMutate( node->env   , *this );
1779        indexerScopedMutate( node->result, *this );
1780        maybeMutate_impl   ( node->arg   , *this );
1781
1782        MUTATE_END( Expression, node );
1783}
1784
1785//--------------------------------------------------------------------------
1786// KeywordCastExpr
1787template< typename pass_type >
1788void PassVisitor< pass_type >::visit( KeywordCastExpr * node ) {
1789        VISIT_START( node );
1790
1791        indexerScopedAccept( node->result, *this );
1792        maybeAccept_impl        ( node->arg   , *this );
1793
1794        VISIT_END( node );
1795}
1796
1797template< typename pass_type >
1798void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
1799        VISIT_START( node );
1800
1801        maybeAccept_impl( node->result, *this );
1802        maybeAccept_impl( node->arg   , *this );
1803
1804        VISIT_END( node );
1805}
1806
1807template< typename pass_type >
1808Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
1809        MUTATE_START( node );
1810
1811        indexerScopedMutate( node->env   , *this );
1812        indexerScopedMutate( node->result, *this );
1813        maybeMutate_impl   ( node->arg   , *this );
1814
1815        MUTATE_END( Expression, node );
1816}
1817
1818//--------------------------------------------------------------------------
1819// VirtualCastExpr
1820template< typename pass_type >
1821void PassVisitor< pass_type >::visit( VirtualCastExpr * node ) {
1822        VISIT_START( node );
1823
1824        indexerScopedAccept( node->result, *this );
1825        maybeAccept_impl( node->arg, *this );
1826
1827        VISIT_END( node );
1828}
1829
1830template< typename pass_type >
1831void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
1832        VISIT_START( node );
1833
1834        maybeAccept_impl( node->result, *this );
1835        maybeAccept_impl( node->arg, *this );
1836
1837        VISIT_END( node );
1838}
1839
1840template< typename pass_type >
1841Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) {
1842        MUTATE_START( node );
1843
1844        indexerScopedMutate( node->env   , *this );
1845        indexerScopedMutate( node->result, *this );
1846        maybeMutate_impl   ( node->arg   , *this );
1847
1848        MUTATE_END( Expression, node );
1849}
1850
1851//--------------------------------------------------------------------------
1852// AddressExpr
1853template< typename pass_type >
1854void PassVisitor< pass_type >::visit( AddressExpr * node ) {
1855        VISIT_START( node );
1856
1857        indexerScopedAccept( node->result, *this );
1858        maybeAccept_impl   ( node->arg   , *this );
1859
1860        VISIT_END( node );
1861}
1862
1863template< typename pass_type >
1864void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
1865        VISIT_START( node );
1866
1867        maybeAccept_impl( node->result, *this );
1868        maybeAccept_impl( node->arg   , *this );
1869
1870        VISIT_END( node );
1871}
1872
1873template< typename pass_type >
1874Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
1875        MUTATE_START( node );
1876
1877        indexerScopedMutate( node->env   , *this );
1878        indexerScopedMutate( node->result, *this );
1879        maybeMutate_impl   ( node->arg   , *this );
1880
1881        MUTATE_END( Expression, node );
1882}
1883
1884//--------------------------------------------------------------------------
1885// LabelAddressExpr
1886template< typename pass_type >
1887void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
1888        VISIT_START( node );
1889
1890        indexerScopedAccept( node->result, *this );
1891
1892        VISIT_END( node );
1893}
1894
1895template< typename pass_type >
1896void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
1897        VISIT_START( node );
1898
1899        maybeAccept_impl( node->result, *this );
1900
1901        VISIT_END( node );
1902}
1903
1904template< typename pass_type >
1905Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
1906        MUTATE_START( node );
1907
1908        indexerScopedMutate( node->env   , *this );
1909        indexerScopedMutate( node->result, *this );
1910
1911        MUTATE_END( Expression, node );
1912}
1913
1914//--------------------------------------------------------------------------
1915// UntypedMemberExpr
1916template< typename pass_type >
1917void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
1918        VISIT_START( node );
1919
1920        indexerScopedAccept( node->result   , *this );
1921        maybeAccept_impl   ( node->aggregate, *this );
1922        maybeAccept_impl   ( node->member   , *this );
1923
1924        VISIT_END( node );
1925}
1926
1927template< typename pass_type >
1928void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
1929        VISIT_START( node );
1930
1931        maybeAccept_impl( node->result   , *this );
1932        maybeAccept_impl( node->aggregate, *this );
1933        maybeAccept_impl( node->member   , *this );
1934
1935        VISIT_END( node );
1936}
1937
1938template< typename pass_type >
1939Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
1940        MUTATE_START( node );
1941
1942        indexerScopedMutate( node->env      , *this );
1943        indexerScopedMutate( node->result   , *this );
1944        maybeMutate_impl   ( node->aggregate, *this );
1945        maybeMutate_impl   ( node->member   , *this );
1946
1947        MUTATE_END( Expression, node );
1948}
1949
1950//--------------------------------------------------------------------------
1951// MemberExpr
1952template< typename pass_type >
1953void PassVisitor< pass_type >::visit( MemberExpr * node ) {
1954        VISIT_START( node );
1955
1956        indexerScopedAccept( node->result   , *this );
1957        maybeAccept_impl   ( node->aggregate, *this );
1958
1959        VISIT_END( node );
1960}
1961
1962template< typename pass_type >
1963void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
1964        VISIT_START( node );
1965
1966        maybeAccept_impl( node->result   , *this );
1967        maybeAccept_impl( node->aggregate, *this );
1968
1969        VISIT_END( node );
1970}
1971
1972template< typename pass_type >
1973Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
1974        MUTATE_START( node );
1975
1976        indexerScopedMutate( node->env      , *this );
1977        indexerScopedMutate( node->result   , *this );
1978        maybeMutate_impl   ( node->aggregate, *this );
1979
1980        MUTATE_END( Expression, node );
1981}
1982
1983//--------------------------------------------------------------------------
1984// VariableExpr
1985template< typename pass_type >
1986void PassVisitor< pass_type >::visit( VariableExpr * node ) {
1987        VISIT_START( node );
1988
1989        indexerScopedAccept( node->result, *this );
1990
1991        VISIT_END( node );
1992}
1993
1994template< typename pass_type >
1995void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
1996        VISIT_START( node );
1997
1998        maybeAccept_impl( node->result, *this );
1999
2000        VISIT_END( node );
2001}
2002
2003template< typename pass_type >
2004Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
2005        MUTATE_START( node );
2006
2007        indexerScopedMutate( node->env   , *this );
2008        indexerScopedMutate( node->result, *this );
2009
2010        MUTATE_END( Expression, node );
2011}
2012
2013//--------------------------------------------------------------------------
2014// ConstantExpr
2015template< typename pass_type >
2016void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
2017        VISIT_START( node );
2018
2019        indexerScopedAccept( node->result   , *this );
2020        maybeAccept_impl   ( &node->constant, *this );
2021
2022        VISIT_END( node );
2023}
2024
2025template< typename pass_type >
2026void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
2027        VISIT_START( node );
2028
2029        maybeAccept_impl( node->result   , *this );
2030        maybeAccept_impl( &node->constant, *this );
2031
2032        VISIT_END( node );
2033}
2034
2035template< typename pass_type >
2036Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
2037        MUTATE_START( node );
2038
2039        indexerScopedMutate( node->env   , *this );
2040        indexerScopedMutate( node->result, *this );
2041        Constant * ptr = &node->constant;
2042        maybeMutate_impl( ptr, *this );
2043        node->constant = *ptr;
2044
2045        MUTATE_END( Expression, node );
2046}
2047
2048//--------------------------------------------------------------------------
2049// SizeofExpr
2050template< typename pass_type >
2051void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
2052        VISIT_START( node );
2053
2054        indexerScopedAccept( node->result, *this );
2055        if ( node->get_isType() ) {
2056                maybeAccept_impl( node->type, *this );
2057        } else {
2058                maybeAccept_impl( node->expr, *this );
2059        }
2060
2061        VISIT_END( node );
2062}
2063
2064template< typename pass_type >
2065void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
2066        VISIT_START( node );
2067
2068        maybeAccept_impl( node->result, *this );
2069        if ( node->get_isType() ) {
2070                maybeAccept_impl( node->type, *this );
2071        } else {
2072                maybeAccept_impl( node->expr, *this );
2073        }
2074
2075        VISIT_END( node );
2076}
2077
2078template< typename pass_type >
2079Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
2080        MUTATE_START( node );
2081
2082        indexerScopedMutate( node->env   , *this );
2083        indexerScopedMutate( node->result, *this );
2084        if ( node->get_isType() ) {
2085                maybeMutate_impl( node->type, *this );
2086        } else {
2087                maybeMutate_impl( node->expr, *this );
2088        }
2089
2090        MUTATE_END( Expression, node );
2091}
2092
2093//--------------------------------------------------------------------------
2094// AlignofExpr
2095template< typename pass_type >
2096void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
2097        VISIT_START( node );
2098
2099        indexerScopedAccept( node->result, *this );
2100        if ( node->get_isType() ) {
2101                maybeAccept_impl( node->type, *this );
2102        } else {
2103                maybeAccept_impl( node->expr, *this );
2104        }
2105
2106        VISIT_END( node );
2107}
2108
2109template< typename pass_type >
2110void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
2111        VISIT_START( node );
2112
2113        maybeAccept_impl( node->result, *this );
2114        if ( node->get_isType() ) {
2115                maybeAccept_impl( node->type, *this );
2116        } else {
2117                maybeAccept_impl( node->expr, *this );
2118        }
2119
2120        VISIT_END( node );
2121}
2122
2123template< typename pass_type >
2124Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
2125        MUTATE_START( node );
2126
2127        indexerScopedMutate( node->env   , *this );
2128        indexerScopedMutate( node->result, *this );
2129        if ( node->get_isType() ) {
2130                maybeMutate_impl( node->type, *this );
2131        } else {
2132                maybeMutate_impl( node->expr, *this );
2133        }
2134
2135        MUTATE_END( Expression, node );
2136}
2137
2138//--------------------------------------------------------------------------
2139// UntypedOffsetofExpr
2140template< typename pass_type >
2141void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
2142        VISIT_START( node );
2143
2144        indexerScopedAccept( node->result, *this );
2145        maybeAccept_impl   ( node->type  , *this );
2146
2147        VISIT_END( node );
2148}
2149
2150template< typename pass_type >
2151void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
2152        VISIT_START( node );
2153
2154        maybeAccept_impl( node->result, *this );
2155        maybeAccept_impl( node->type  , *this );
2156
2157        VISIT_END( node );
2158}
2159
2160template< typename pass_type >
2161Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
2162        MUTATE_START( node );
2163
2164        indexerScopedMutate( node->env   , *this );
2165        indexerScopedMutate( node->result, *this );
2166        maybeMutate_impl   ( node->type  , *this );
2167
2168        MUTATE_END( Expression, node );
2169}
2170
2171//--------------------------------------------------------------------------
2172// OffsetofExpr
2173template< typename pass_type >
2174void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
2175        VISIT_START( node );
2176
2177        indexerScopedAccept( node->result, *this );
2178        maybeAccept_impl   ( node->type  , *this );
2179
2180        VISIT_END( node );
2181}
2182
2183template< typename pass_type >
2184void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
2185        VISIT_START( node );
2186
2187        maybeAccept_impl( node->result, *this );
2188        maybeAccept_impl( node->type  , *this );
2189
2190        VISIT_END( node );
2191}
2192
2193template< typename pass_type >
2194Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
2195        MUTATE_START( node );
2196
2197        indexerScopedMutate( node->env   , *this );
2198        indexerScopedMutate( node->result, *this );
2199        maybeMutate_impl   ( node->type  , *this );
2200
2201        MUTATE_END( Expression, node );
2202}
2203
2204//--------------------------------------------------------------------------
2205// OffsetPackExpr
2206template< typename pass_type >
2207void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
2208        VISIT_START( node );
2209
2210        indexerScopedAccept( node->result, *this );
2211        maybeAccept_impl   ( node->type  , *this );
2212
2213        VISIT_END( node );
2214}
2215
2216template< typename pass_type >
2217void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
2218        VISIT_START( node );
2219
2220        maybeAccept_impl( node->result, *this );
2221        maybeAccept_impl( node->type  , *this );
2222
2223        VISIT_END( node );
2224}
2225
2226template< typename pass_type >
2227Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
2228        MUTATE_START( node );
2229
2230        indexerScopedMutate( node->env   , *this );
2231        indexerScopedMutate( node->result, *this );
2232        maybeMutate_impl   ( node->type  , *this );
2233
2234        MUTATE_END( Expression, node );
2235}
2236
2237//--------------------------------------------------------------------------
2238// AttrExpr
2239template< typename pass_type >
2240void PassVisitor< pass_type >::visit( AttrExpr * node ) {
2241        VISIT_START( node );
2242
2243        indexerScopedAccept( node->result, *this );
2244        if ( node->get_isType() ) {
2245                maybeAccept_impl( node->type, *this );
2246        } else {
2247                maybeAccept_impl( node->expr, *this );
2248        }
2249
2250        VISIT_END( node );
2251}
2252
2253template< typename pass_type >
2254void PassVisitor< pass_type >::visit( const AttrExpr * node ) {
2255        VISIT_START( node );
2256
2257        maybeAccept_impl( node->result, *this );
2258        if ( node->get_isType() ) {
2259                maybeAccept_impl( node->type, *this );
2260        } else {
2261                maybeAccept_impl( node->expr, *this );
2262        }
2263
2264        VISIT_END( node );
2265}
2266
2267template< typename pass_type >
2268Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
2269        MUTATE_START( node );
2270
2271        indexerScopedMutate( node->env   , *this );
2272        indexerScopedMutate( node->result, *this );
2273        if ( node->get_isType() ) {
2274                maybeMutate_impl( node->type, *this );
2275        } else {
2276                maybeMutate_impl( node->expr, *this );
2277        }
2278
2279        MUTATE_END( Expression, node );
2280}
2281
2282//--------------------------------------------------------------------------
2283// LogicalExpr
2284template< typename pass_type >
2285void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
2286        VISIT_START( node );
2287
2288        indexerScopedAccept( node->result, *this );
2289        maybeAccept_impl   ( node->arg1  , *this );
2290        maybeAccept_impl   ( node->arg2  , *this );
2291
2292        VISIT_END( node );
2293}
2294
2295template< typename pass_type >
2296void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
2297        VISIT_START( node );
2298
2299        maybeAccept_impl( node->result, *this );
2300        maybeAccept_impl( node->arg1  , *this );
2301        maybeAccept_impl( node->arg2  , *this );
2302
2303        VISIT_END( node );
2304}
2305
2306template< typename pass_type >
2307Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
2308        MUTATE_START( node );
2309
2310        indexerScopedMutate( node->env   , *this );
2311        indexerScopedMutate( node->result, *this );
2312        maybeMutate_impl   ( node->arg1  , *this );
2313        maybeMutate_impl   ( node->arg2  , *this );
2314
2315        MUTATE_END( Expression, node );
2316}
2317
2318//--------------------------------------------------------------------------
2319// ConditionalExpr
2320template< typename pass_type >
2321void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
2322        VISIT_START( node );
2323
2324        indexerScopedAccept( node->result, *this );
2325        maybeAccept_impl        ( node->arg1  , *this );
2326        maybeAccept_impl        ( node->arg2  , *this );
2327        maybeAccept_impl        ( node->arg3  , *this );
2328
2329        VISIT_END( node );
2330}
2331
2332template< typename pass_type >
2333void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
2334        VISIT_START( node );
2335
2336        maybeAccept_impl( node->result, *this );
2337        maybeAccept_impl( node->arg1  , *this );
2338        maybeAccept_impl( node->arg2  , *this );
2339        maybeAccept_impl( node->arg3  , *this );
2340
2341        VISIT_END( node );
2342}
2343
2344template< typename pass_type >
2345Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
2346        MUTATE_START( node );
2347
2348        indexerScopedMutate( node->env   , *this );
2349        indexerScopedMutate( node->result, *this );
2350        maybeMutate_impl   ( node->arg1  , *this );
2351        maybeMutate_impl   ( node->arg2  , *this );
2352        maybeMutate_impl   ( node->arg3  , *this );
2353
2354        MUTATE_END( Expression, node );
2355}
2356
2357//--------------------------------------------------------------------------
2358// CommaExpr
2359template< typename pass_type >
2360void PassVisitor< pass_type >::visit( CommaExpr * node ) {
2361        VISIT_START( node );
2362
2363        indexerScopedAccept( node->result, *this );
2364        maybeAccept_impl   ( node->arg1  , *this );
2365        maybeAccept_impl   ( node->arg2  , *this );
2366
2367        VISIT_END( node );
2368}
2369
2370template< typename pass_type >
2371void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
2372        VISIT_START( node );
2373
2374        maybeAccept_impl( node->result, *this );
2375        maybeAccept_impl( node->arg1  , *this );
2376        maybeAccept_impl( node->arg2  , *this );
2377
2378        VISIT_END( node );
2379}
2380
2381template< typename pass_type >
2382Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
2383        MUTATE_START( node );
2384
2385        indexerScopedMutate( node->env   , *this );
2386        indexerScopedMutate( node->result, *this );
2387        maybeMutate_impl   ( node->arg1  , *this );
2388        maybeMutate_impl   ( node->arg2  , *this );
2389
2390        MUTATE_END( Expression, node );
2391}
2392
2393//--------------------------------------------------------------------------
2394// TypeExpr
2395template< typename pass_type >
2396void PassVisitor< pass_type >::visit( TypeExpr * node ) {
2397        VISIT_START( node );
2398
2399        indexerScopedAccept( node->result, *this );
2400        maybeAccept_impl   ( node->type, *this );
2401
2402        VISIT_END( node );
2403}
2404
2405template< typename pass_type >
2406void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
2407        VISIT_START( node );
2408
2409        maybeAccept_impl( node->result, *this );
2410        maybeAccept_impl( node->type, *this );
2411
2412        VISIT_END( node );
2413}
2414
2415template< typename pass_type >
2416Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
2417        MUTATE_START( node );
2418
2419        indexerScopedMutate( node->env   , *this );
2420        indexerScopedMutate( node->result, *this );
2421        maybeMutate_impl   ( node->type  , *this );
2422
2423        MUTATE_END( Expression, node );
2424}
2425
2426//--------------------------------------------------------------------------
2427// AsmExpr
2428template< typename pass_type >
2429void PassVisitor< pass_type >::visit( AsmExpr * node ) {
2430        VISIT_START( node );
2431
2432        indexerScopedAccept( node->result    , *this );
2433        maybeAccept_impl   ( node->inout     , *this );
2434        maybeAccept_impl   ( node->constraint, *this );
2435        maybeAccept_impl   ( node->operand   , *this );
2436
2437        VISIT_END( node );
2438}
2439
2440template< typename pass_type >
2441void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
2442        VISIT_START( node );
2443
2444        maybeAccept_impl( node->result    , *this );
2445        maybeAccept_impl( node->inout     , *this );
2446        maybeAccept_impl( node->constraint, *this );
2447        maybeAccept_impl( node->operand   , *this );
2448
2449        VISIT_END( node );
2450}
2451
2452template< typename pass_type >
2453Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
2454        MUTATE_START( node );
2455
2456        indexerScopedMutate( node->env       , *this );
2457        indexerScopedMutate( node->result    , *this );
2458        maybeMutate_impl   ( node->inout     , *this );
2459        maybeMutate_impl   ( node->constraint, *this );
2460        maybeMutate_impl   ( node->operand   , *this );
2461
2462        MUTATE_END( Expression, node );
2463}
2464
2465//--------------------------------------------------------------------------
2466// ImplicitCopyCtorExpr
2467template< typename pass_type >
2468void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
2469        VISIT_START( node );
2470
2471        indexerScopedAccept( node->result    , *this );
2472        maybeAccept_impl   ( node->callExpr  , *this );
2473
2474        VISIT_END( node );
2475}
2476
2477template< typename pass_type >
2478void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
2479        VISIT_START( node );
2480
2481        maybeAccept_impl( node->result    , *this );
2482        maybeAccept_impl( node->callExpr  , *this );
2483
2484        VISIT_END( node );
2485}
2486
2487template< typename pass_type >
2488Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
2489        MUTATE_START( node );
2490
2491        indexerScopedMutate( node->env       , *this );
2492        indexerScopedMutate( node->result    , *this );
2493        maybeMutate_impl   ( node->callExpr  , *this );
2494
2495        MUTATE_END( Expression, node );
2496}
2497
2498//--------------------------------------------------------------------------
2499// ConstructorExpr
2500template< typename pass_type >
2501void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
2502        VISIT_START( node );
2503
2504        indexerScopedAccept( node->result  , *this );
2505        maybeAccept_impl   ( node->callExpr, *this );
2506
2507        VISIT_END( node );
2508}
2509
2510template< typename pass_type >
2511void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
2512        VISIT_START( node );
2513
2514        maybeAccept_impl( node->result  , *this );
2515        maybeAccept_impl( node->callExpr, *this );
2516
2517        VISIT_END( node );
2518}
2519
2520template< typename pass_type >
2521Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
2522        MUTATE_START( node );
2523
2524        indexerScopedMutate( node->env     , *this );
2525        indexerScopedMutate( node->result  , *this );
2526        maybeMutate_impl   ( node->callExpr, *this );
2527
2528        MUTATE_END( Expression, node );
2529}
2530
2531//--------------------------------------------------------------------------
2532// CompoundLiteralExpr
2533template< typename pass_type >
2534void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
2535        VISIT_START( node );
2536
2537        indexerScopedAccept( node->result     , *this );
2538        maybeAccept_impl   ( node->initializer, *this );
2539
2540        VISIT_END( node );
2541}
2542
2543template< typename pass_type >
2544void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
2545        VISIT_START( node );
2546
2547        maybeAccept_impl( node->result     , *this );
2548        maybeAccept_impl( node->initializer, *this );
2549
2550        VISIT_END( node );
2551}
2552
2553template< typename pass_type >
2554Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
2555        MUTATE_START( node );
2556
2557        indexerScopedMutate( node->env        , *this );
2558        indexerScopedMutate( node->result     , *this );
2559        maybeMutate_impl     ( node->initializer, *this );
2560
2561        MUTATE_END( Expression, node );
2562}
2563
2564//--------------------------------------------------------------------------
2565// RangeExpr
2566template< typename pass_type >
2567void PassVisitor< pass_type >::visit( RangeExpr * node ) {
2568        VISIT_START( node );
2569
2570        indexerScopedAccept( node->result, *this );
2571        maybeAccept_impl   ( node->low   , *this );
2572        maybeAccept_impl   ( node->high  , *this );
2573
2574        VISIT_END( node );
2575}
2576
2577template< typename pass_type >
2578void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
2579        VISIT_START( node );
2580
2581        maybeAccept_impl( node->result, *this );
2582        maybeAccept_impl( node->low   , *this );
2583        maybeAccept_impl( node->high  , *this );
2584
2585        VISIT_END( node );
2586}
2587
2588template< typename pass_type >
2589Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
2590        MUTATE_START( node );
2591
2592        indexerScopedMutate( node->env   , *this );
2593        indexerScopedMutate( node->result, *this );
2594        maybeMutate_impl   ( node->low   , *this );
2595        maybeMutate_impl   ( node->high  , *this );
2596
2597        MUTATE_END( Expression, node );
2598}
2599
2600//--------------------------------------------------------------------------
2601// UntypedTupleExpr
2602template< typename pass_type >
2603void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
2604        VISIT_START( node );
2605
2606        indexerScopedAccept( node->result, *this );
2607        maybeAccept_impl   ( node->exprs , *this );
2608
2609        VISIT_END( node );
2610}
2611
2612template< typename pass_type >
2613void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
2614        VISIT_START( node );
2615
2616        maybeAccept_impl( node->result, *this );
2617        maybeAccept_impl( node->exprs , *this );
2618
2619        VISIT_END( node );
2620}
2621
2622template< typename pass_type >
2623Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
2624        MUTATE_START( node );
2625
2626        indexerScopedMutate( node->env   , *this );
2627        indexerScopedMutate( node->result, *this );
2628        maybeMutate_impl   ( node->exprs , *this );
2629
2630        MUTATE_END( Expression, node );
2631}
2632
2633//--------------------------------------------------------------------------
2634// TupleExpr
2635template< typename pass_type >
2636void PassVisitor< pass_type >::visit( TupleExpr * node ) {
2637        VISIT_START( node );
2638
2639        indexerScopedAccept( node->result, *this );
2640        maybeAccept_impl   ( node->exprs , *this );
2641
2642        VISIT_END( node );
2643}
2644
2645template< typename pass_type >
2646void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
2647        VISIT_START( node );
2648
2649        maybeAccept_impl( node->result, *this );
2650        maybeAccept_impl( node->exprs , *this );
2651
2652        VISIT_END( node );
2653}
2654
2655template< typename pass_type >
2656Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
2657        MUTATE_START( node );
2658
2659        indexerScopedMutate( node->env   , *this );
2660        indexerScopedMutate( node->result, *this );
2661        maybeMutate_impl   ( node->exprs , *this );
2662
2663        MUTATE_END( Expression, node );
2664}
2665
2666//--------------------------------------------------------------------------
2667// TupleIndexExpr
2668template< typename pass_type >
2669void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
2670        VISIT_START( node );
2671
2672        indexerScopedAccept( node->result, *this );
2673        maybeAccept_impl   ( node->tuple , *this );
2674
2675        VISIT_END( node );
2676}
2677
2678template< typename pass_type >
2679void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
2680        VISIT_START( node );
2681
2682        maybeAccept_impl( node->result, *this );
2683        maybeAccept_impl( node->tuple , *this );
2684
2685        VISIT_END( node );
2686}
2687
2688template< typename pass_type >
2689Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
2690        MUTATE_START( node );
2691
2692        indexerScopedMutate( node->env   , *this );
2693        indexerScopedMutate( node->result, *this );
2694        maybeMutate_impl   ( node->tuple , *this );
2695
2696        MUTATE_END( Expression, node );
2697}
2698
2699//--------------------------------------------------------------------------
2700// TupleAssignExpr
2701template< typename pass_type >
2702void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
2703        VISIT_START( node );
2704
2705        indexerScopedAccept( node->result  , *this );
2706        maybeAccept_impl   ( node->stmtExpr, *this );
2707
2708        VISIT_END( node );
2709}
2710
2711template< typename pass_type >
2712void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
2713        VISIT_START( node );
2714
2715        maybeAccept_impl( node->result  , *this );
2716        maybeAccept_impl( node->stmtExpr, *this );
2717
2718        VISIT_END( node );
2719}
2720
2721template< typename pass_type >
2722Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
2723        MUTATE_START( node );
2724
2725        indexerScopedMutate( node->env     , *this );
2726        indexerScopedMutate( node->result  , *this );
2727        maybeMutate_impl   ( node->stmtExpr, *this );
2728
2729        MUTATE_END( Expression, node );
2730}
2731
2732//--------------------------------------------------------------------------
2733// StmtExpr
2734template< typename pass_type >
2735void PassVisitor< pass_type >::visit( StmtExpr * node ) {
2736        VISIT_START( node );
2737
2738        // don't want statements from outer CompoundStmts to be added to this StmtExpr
2739        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
2740        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
2741        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
2742
2743        indexerScopedAccept( node->result     , *this );
2744        maybeAccept_impl   ( node->statements , *this );
2745        maybeAccept_impl   ( node->returnDecls, *this );
2746        maybeAccept_impl   ( node->dtors      , *this );
2747
2748        VISIT_END( node );
2749}
2750
2751template< typename pass_type >
2752void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
2753        VISIT_START( node );
2754
2755        maybeAccept_impl( node->result     , *this );
2756        maybeAccept_impl( node->statements , *this );
2757        maybeAccept_impl( node->returnDecls, *this );
2758        maybeAccept_impl( node->dtors      , *this );
2759
2760        VISIT_END( node );
2761}
2762
2763template< typename pass_type >
2764Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
2765        MUTATE_START( node );
2766
2767        // don't want statements from outer CompoundStmts to be added to this StmtExpr
2768        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
2769        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
2770        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
2771
2772        indexerScopedMutate( node->result     , *this );
2773        maybeMutate_impl   ( node->statements , *this );
2774        maybeMutate_impl   ( node->returnDecls, *this );
2775        maybeMutate_impl   ( node->dtors      , *this );
2776
2777        MUTATE_END( Expression, node );
2778}
2779
2780//--------------------------------------------------------------------------
2781// UniqueExpr
2782template< typename pass_type >
2783void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
2784        VISIT_START( node );
2785
2786        indexerScopedAccept( node->result, *this );
2787        maybeAccept_impl   ( node->expr  , *this );
2788
2789        VISIT_END( node );
2790}
2791
2792template< typename pass_type >
2793void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
2794        VISIT_START( node );
2795
2796        maybeAccept_impl( node->result, *this );
2797        maybeAccept_impl( node->expr  , *this );
2798
2799        VISIT_END( node );
2800}
2801
2802template< typename pass_type >
2803Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
2804        MUTATE_START( node );
2805
2806        indexerScopedMutate( node->env   , *this );
2807        indexerScopedMutate( node->result, *this );
2808        maybeMutate_impl   ( node->expr  , *this );
2809
2810        MUTATE_END( Expression, node );
2811}
2812
2813//--------------------------------------------------------------------------
2814// UntypedInitExpr
2815template< typename pass_type >
2816void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
2817        VISIT_START( node );
2818
2819        indexerScopedAccept( node->result, *this );
2820        maybeAccept_impl   ( node->expr  , *this );
2821        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
2822
2823        VISIT_END( node );
2824}
2825
2826template< typename pass_type >
2827void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
2828        VISIT_START( node );
2829
2830        maybeAccept_impl( node->result, *this );
2831        maybeAccept_impl( node->expr  , *this );
2832        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
2833
2834        VISIT_END( node );
2835}
2836
2837template< typename pass_type >
2838Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) {
2839        MUTATE_START( node );
2840
2841        indexerScopedMutate( node->env   , *this );
2842        indexerScopedMutate( node->result, *this );
2843        maybeMutate_impl   ( node->expr  , *this );
2844        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
2845
2846        MUTATE_END( Expression, node );
2847}
2848
2849//--------------------------------------------------------------------------
2850// InitExpr
2851template< typename pass_type >
2852void PassVisitor< pass_type >::visit( InitExpr * node ) {
2853        VISIT_START( node );
2854
2855        indexerScopedAccept( node->result, *this );
2856        maybeAccept_impl   ( node->expr  , *this );
2857        maybeAccept_impl   ( node->designation, *this );
2858
2859        VISIT_END( node );
2860}
2861
2862template< typename pass_type >
2863void PassVisitor< pass_type >::visit( const InitExpr * node ) {
2864        VISIT_START( node );
2865
2866        maybeAccept_impl( node->result, *this );
2867        maybeAccept_impl( node->expr  , *this );
2868        maybeAccept_impl( node->designation, *this );
2869
2870        VISIT_END( node );
2871}
2872
2873template< typename pass_type >
2874Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
2875        MUTATE_START( node );
2876
2877        indexerScopedMutate( node->env   , *this );
2878        indexerScopedMutate( node->result, *this );
2879        maybeMutate_impl   ( node->expr  , *this );
2880        maybeMutate_impl   ( node->designation, *this );
2881
2882        MUTATE_END( Expression, node );
2883}
2884
2885//--------------------------------------------------------------------------
2886// DeletedExpr
2887template< typename pass_type >
2888void PassVisitor< pass_type >::visit( DeletedExpr * node ) {
2889        VISIT_START( node );
2890
2891        indexerScopedAccept( node->result, *this );
2892        maybeAccept_impl( node->expr, *this );
2893        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
2894
2895        VISIT_END( node );
2896}
2897
2898template< typename pass_type >
2899void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
2900        VISIT_START( node );
2901
2902        maybeAccept_impl( node->result, *this );
2903        maybeAccept_impl( node->expr, *this );
2904        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
2905
2906        VISIT_END( node );
2907}
2908
2909template< typename pass_type >
2910Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) {
2911        MUTATE_START( node );
2912
2913        indexerScopedMutate( node->env, *this );
2914        indexerScopedMutate( node->result, *this );
2915        maybeMutate_impl( node->expr, *this );
2916
2917        MUTATE_END( Expression, node );
2918}
2919
2920//--------------------------------------------------------------------------
2921// DefaultArgExpr
2922template< typename pass_type >
2923void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
2924        VISIT_START( node );
2925
2926        indexerScopedAccept( node->result, *this );
2927        maybeAccept_impl( node->expr, *this );
2928
2929        VISIT_END( node );
2930}
2931
2932template< typename pass_type >
2933void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
2934        VISIT_START( node );
2935
2936        maybeAccept_impl( node->result, *this );
2937        maybeAccept_impl( node->expr, *this );
2938
2939        VISIT_END( node );
2940}
2941
2942template< typename pass_type >
2943Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
2944        MUTATE_START( node );
2945
2946        indexerScopedMutate( node->env, *this );
2947        indexerScopedMutate( node->result, *this );
2948        maybeMutate_impl( node->expr, *this );
2949
2950        MUTATE_END( Expression, node );
2951}
2952
2953//--------------------------------------------------------------------------
2954// GenericExpr
2955template< typename pass_type >
2956void PassVisitor< pass_type >::visit( GenericExpr * node ) {
2957        VISIT_START( node );
2958
2959        indexerScopedAccept( node->result, *this );
2960        maybeAccept_impl( node->control, *this );
2961        for ( GenericExpr::Association & assoc : node->associations ) {
2962                indexerScopedAccept( assoc.type, *this );
2963                maybeAccept_impl( assoc.expr, *this );
2964        }
2965
2966        VISIT_END( node );
2967}
2968
2969template< typename pass_type >
2970void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
2971        VISIT_START( node );
2972
2973        maybeAccept_impl( node->result, *this );
2974        maybeAccept_impl( node->control, *this );
2975        for ( const GenericExpr::Association & assoc : node->associations ) {
2976                maybeAccept_impl( assoc.type, *this );
2977                maybeAccept_impl( assoc.expr, *this );
2978        }
2979
2980        VISIT_END( node );
2981}
2982
2983template< typename pass_type >
2984Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
2985        MUTATE_START( node );
2986
2987        indexerScopedMutate( node->env, *this );
2988        indexerScopedMutate( node->result, *this );
2989        maybeMutate_impl( node->control, *this );
2990        for ( GenericExpr::Association & assoc : node->associations ) {
2991                indexerScopedMutate( assoc.type, *this );
2992                maybeMutate_impl( assoc.expr, *this );
2993        }
2994
2995        MUTATE_END( Expression, node );
2996}
2997
2998//--------------------------------------------------------------------------
2999// VoidType
3000template< typename pass_type >
3001void PassVisitor< pass_type >::visit( VoidType * node ) {
3002        VISIT_START( node );
3003
3004        maybeAccept_impl( node->forall, *this );
3005
3006        VISIT_END( node );
3007}
3008
3009template< typename pass_type >
3010void PassVisitor< pass_type >::visit( const VoidType * node ) {
3011        VISIT_START( node );
3012
3013        maybeAccept_impl( node->forall, *this );
3014
3015        VISIT_END( node );
3016}
3017
3018template< typename pass_type >
3019Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
3020        MUTATE_START( node );
3021
3022        maybeMutate_impl( node->forall, *this );
3023
3024        MUTATE_END( Type, node );
3025}
3026
3027//--------------------------------------------------------------------------
3028// BasicType
3029template< typename pass_type >
3030void PassVisitor< pass_type >::visit( BasicType * node ) {
3031        VISIT_START( node );
3032
3033        maybeAccept_impl( node->forall, *this );
3034
3035        VISIT_END( node );
3036}
3037
3038template< typename pass_type >
3039void PassVisitor< pass_type >::visit( const BasicType * node ) {
3040        VISIT_START( node );
3041
3042        maybeAccept_impl( node->forall, *this );
3043
3044        VISIT_END( node );
3045}
3046
3047template< typename pass_type >
3048Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
3049        MUTATE_START( node );
3050
3051        maybeMutate_impl( node->forall, *this );
3052
3053        MUTATE_END( Type, node );
3054}
3055
3056//--------------------------------------------------------------------------
3057// PointerType
3058template< typename pass_type >
3059void PassVisitor< pass_type >::visit( PointerType * node ) {
3060        VISIT_START( node );
3061
3062        maybeAccept_impl( node->forall, *this );
3063        // xxx - should PointerType visit/mutate dimension?
3064        maybeAccept_impl( node->base, *this );
3065
3066        VISIT_END( node );
3067}
3068
3069template< typename pass_type >
3070void PassVisitor< pass_type >::visit( const PointerType * node ) {
3071        VISIT_START( node );
3072
3073        maybeAccept_impl( node->forall, *this );
3074        // xxx - should PointerType visit/mutate dimension?
3075        maybeAccept_impl( node->base, *this );
3076
3077        VISIT_END( node );
3078}
3079
3080template< typename pass_type >
3081Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
3082        MUTATE_START( node );
3083
3084        maybeMutate_impl( node->forall, *this );
3085        // xxx - should PointerType visit/mutate dimension?
3086        maybeMutate_impl( node->base, *this );
3087
3088        MUTATE_END( Type, node );
3089}
3090
3091//--------------------------------------------------------------------------
3092// ArrayType
3093template< typename pass_type >
3094void PassVisitor< pass_type >::visit( ArrayType * node ) {
3095        VISIT_START( node );
3096
3097        maybeAccept_impl( node->forall, *this );
3098        maybeAccept_impl( node->dimension, *this );
3099        maybeAccept_impl( node->base, *this );
3100
3101        VISIT_END( node );
3102}
3103
3104template< typename pass_type >
3105void PassVisitor< pass_type >::visit( const ArrayType * node ) {
3106        VISIT_START( node );
3107
3108        maybeAccept_impl( node->forall, *this );
3109        maybeAccept_impl( node->dimension, *this );
3110        maybeAccept_impl( node->base, *this );
3111
3112        VISIT_END( node );
3113}
3114
3115template< typename pass_type >
3116Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
3117        MUTATE_START( node );
3118
3119        maybeMutate_impl( node->forall, *this );
3120        maybeMutate_impl( node->dimension, *this );
3121        maybeMutate_impl( node->base, *this );
3122
3123        MUTATE_END( Type, node );
3124}
3125
3126//--------------------------------------------------------------------------
3127// ReferenceType
3128template< typename pass_type >
3129void PassVisitor< pass_type >::visit( ReferenceType * node ) {
3130        VISIT_START( node );
3131
3132        maybeAccept_impl( node->forall, *this );
3133        maybeAccept_impl( node->base, *this );
3134
3135        VISIT_END( node );
3136}
3137
3138template< typename pass_type >
3139void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
3140        VISIT_START( node );
3141
3142        maybeAccept_impl( node->forall, *this );
3143        maybeAccept_impl( node->base, *this );
3144
3145        VISIT_END( node );
3146}
3147
3148template< typename pass_type >
3149Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
3150        MUTATE_START( node );
3151
3152        maybeMutate_impl( node->forall, *this );
3153        maybeMutate_impl( node->base, *this );
3154
3155        MUTATE_END( Type, node );
3156}
3157
3158//--------------------------------------------------------------------------
3159// QualifiedType
3160template< typename pass_type >
3161void PassVisitor< pass_type >::visit( QualifiedType * node ) {
3162        VISIT_START( node );
3163
3164        maybeAccept_impl( node->forall, *this );
3165        maybeAccept_impl( node->parent, *this );
3166        maybeAccept_impl( node->child, *this );
3167
3168        VISIT_END( node );
3169}
3170
3171template< typename pass_type >
3172void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
3173        VISIT_START( node );
3174
3175        maybeAccept_impl( node->forall, *this );
3176        maybeAccept_impl( node->parent, *this );
3177        maybeAccept_impl( node->child, *this );
3178
3179        VISIT_END( node );
3180}
3181
3182template< typename pass_type >
3183Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
3184        MUTATE_START( node );
3185
3186        maybeMutate_impl( node->forall, *this );
3187        maybeMutate_impl( node->parent, *this );
3188        maybeMutate_impl( node->child, *this );
3189
3190        MUTATE_END( Type, node );
3191}
3192
3193//--------------------------------------------------------------------------
3194// FunctionType
3195template< typename pass_type >
3196void PassVisitor< pass_type >::visit( FunctionType * node ) {
3197        VISIT_START( node );
3198
3199        maybeAccept_impl( node->forall, *this );
3200        maybeAccept_impl( node->returnVals, *this );
3201        maybeAccept_impl( node->parameters, *this );
3202
3203        VISIT_END( node );
3204}
3205
3206template< typename pass_type >
3207void PassVisitor< pass_type >::visit( const FunctionType * node ) {
3208        VISIT_START( node );
3209
3210        maybeAccept_impl( node->forall, *this );
3211        maybeAccept_impl( node->returnVals, *this );
3212        maybeAccept_impl( node->parameters, *this );
3213
3214        VISIT_END( node );
3215}
3216
3217template< typename pass_type >
3218Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
3219        MUTATE_START( node );
3220
3221        maybeMutate_impl( node->forall, *this );
3222        maybeMutate_impl( node->returnVals, *this );
3223        maybeMutate_impl( node->parameters, *this );
3224
3225        MUTATE_END( Type, node );
3226}
3227
3228//--------------------------------------------------------------------------
3229// StructInstType
3230template< typename pass_type >
3231void PassVisitor< pass_type >::visit( StructInstType * node ) {
3232        VISIT_START( node );
3233
3234        indexerAddStruct( node->name );
3235
3236        {
3237                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
3238                maybeAccept_impl( node->forall    , *this );
3239                maybeAccept_impl( node->parameters, *this );
3240        }
3241
3242        VISIT_END( node );
3243}
3244
3245template< typename pass_type >
3246void PassVisitor< pass_type >::visit( const StructInstType * node ) {
3247        VISIT_START( node );
3248
3249        maybeAccept_impl( node->forall    , *this );
3250        maybeAccept_impl( node->parameters, *this );
3251
3252        VISIT_END( node );
3253}
3254
3255template< typename pass_type >
3256Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
3257        MUTATE_START( node );
3258
3259        indexerAddStruct( node->name );
3260
3261        {
3262                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
3263                maybeMutate_impl( node->forall    , *this );
3264                maybeMutate_impl( node->parameters, *this );
3265        }
3266
3267        MUTATE_END( Type, node );
3268}
3269
3270//--------------------------------------------------------------------------
3271// UnionInstType
3272template< typename pass_type >
3273void PassVisitor< pass_type >::visit( UnionInstType * node ) {
3274        VISIT_START( node );
3275
3276        indexerAddStruct( node->name );
3277
3278        {
3279                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
3280                maybeAccept_impl( node->forall    , *this );
3281                maybeAccept_impl( node->parameters, *this );
3282        }
3283
3284        VISIT_END( node );
3285}
3286
3287template< typename pass_type >
3288void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
3289        VISIT_START( node );
3290
3291        maybeAccept_impl( node->forall    , *this );
3292        maybeAccept_impl( node->parameters, *this );
3293
3294        VISIT_END( node );
3295}
3296
3297template< typename pass_type >
3298Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
3299        MUTATE_START( node );
3300
3301        indexerAddStruct( node->name );
3302
3303        {
3304                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
3305                maybeMutate_impl( node->forall    , *this );
3306                maybeMutate_impl( node->parameters, *this );
3307        }
3308
3309        MUTATE_END( Type, node );
3310}
3311
3312//--------------------------------------------------------------------------
3313// EnumInstType
3314template< typename pass_type >
3315void PassVisitor< pass_type >::visit( EnumInstType * node ) {
3316        VISIT_START( node );
3317
3318        maybeAccept_impl( node->forall, *this );
3319        maybeAccept_impl( node->parameters, *this );
3320
3321        VISIT_END( node );
3322}
3323
3324template< typename pass_type >
3325void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
3326        VISIT_START( node );
3327
3328        maybeAccept_impl( node->forall, *this );
3329        maybeAccept_impl( node->parameters, *this );
3330
3331        VISIT_END( node );
3332}
3333
3334template< typename pass_type >
3335Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
3336        MUTATE_START( node );
3337
3338        maybeMutate_impl( node->forall, *this );
3339        maybeMutate_impl( node->parameters, *this );
3340
3341        MUTATE_END( Type, node );
3342}
3343
3344//--------------------------------------------------------------------------
3345// TraitInstType
3346template< typename pass_type >
3347void PassVisitor< pass_type >::visit( TraitInstType * node ) {
3348        VISIT_START( node );
3349
3350        maybeAccept_impl( node->forall    , *this );
3351        maybeAccept_impl( node->parameters, *this );
3352
3353        VISIT_END( node );
3354}
3355
3356template< typename pass_type >
3357void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
3358        VISIT_START( node );
3359
3360        maybeAccept_impl( node->forall    , *this );
3361        maybeAccept_impl( node->parameters, *this );
3362
3363        VISIT_END( node );
3364}
3365
3366template< typename pass_type >
3367Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
3368        MUTATE_START( node );
3369
3370        maybeMutate_impl( node->forall    , *this );
3371        maybeMutate_impl( node->parameters, *this );
3372
3373        MUTATE_END( Type, node );
3374}
3375
3376//--------------------------------------------------------------------------
3377// TypeInstType
3378template< typename pass_type >
3379void PassVisitor< pass_type >::visit( TypeInstType * node ) {
3380        VISIT_START( node );
3381
3382        maybeAccept_impl( node->forall    , *this );
3383        maybeAccept_impl( node->parameters, *this );
3384
3385        VISIT_END( node );
3386}
3387
3388template< typename pass_type >
3389void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
3390        VISIT_START( node );
3391
3392        maybeAccept_impl( node->forall    , *this );
3393        maybeAccept_impl( node->parameters, *this );
3394
3395        VISIT_END( node );
3396}
3397
3398template< typename pass_type >
3399Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
3400        MUTATE_START( node );
3401
3402        maybeMutate_impl( node->forall    , *this );
3403        maybeMutate_impl( node->parameters, *this );
3404
3405        MUTATE_END( Type, node );
3406}
3407
3408//--------------------------------------------------------------------------
3409// TupleType
3410template< typename pass_type >
3411void PassVisitor< pass_type >::visit( TupleType * node ) {
3412        VISIT_START( node );
3413
3414        maybeAccept_impl( node->forall, *this );
3415        maybeAccept_impl( node->types, *this );
3416        maybeAccept_impl( node->members, *this );
3417
3418        VISIT_END( node );
3419}
3420
3421template< typename pass_type >
3422void PassVisitor< pass_type >::visit( const TupleType * node ) {
3423        VISIT_START( node );
3424
3425        maybeAccept_impl( node->forall, *this );
3426        maybeAccept_impl( node->types, *this );
3427        maybeAccept_impl( node->members, *this );
3428
3429        VISIT_END( node );
3430}
3431
3432template< typename pass_type >
3433Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
3434        MUTATE_START( node );
3435
3436        maybeMutate_impl( node->forall, *this );
3437        maybeMutate_impl( node->types, *this );
3438        maybeMutate_impl( node->members, *this );
3439
3440        MUTATE_END( Type, node );
3441}
3442
3443//--------------------------------------------------------------------------
3444// TypeofType
3445template< typename pass_type >
3446void PassVisitor< pass_type >::visit( TypeofType * node ) {
3447        VISIT_START( node );
3448
3449        assert( node->expr );
3450        maybeAccept_impl( node->expr, *this );
3451
3452        VISIT_END( node );
3453}
3454
3455template< typename pass_type >
3456void PassVisitor< pass_type >::visit( const TypeofType * node ) {
3457        VISIT_START( node );
3458
3459        assert( node->expr );
3460        maybeAccept_impl( node->expr, *this );
3461
3462        VISIT_END( node );
3463}
3464
3465template< typename pass_type >
3466Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
3467        MUTATE_START( node );
3468
3469        assert( node->expr );
3470        maybeMutate_impl( node->expr, *this );
3471
3472        MUTATE_END( Type, node );
3473}
3474
3475//--------------------------------------------------------------------------
3476// AttrType
3477template< typename pass_type >
3478void PassVisitor< pass_type >::visit( AttrType * node ) {
3479        VISIT_START( node );
3480
3481        if ( node->isType ) {
3482                assert( node->type );
3483                maybeAccept_impl( node->type, *this );
3484        } else {
3485                assert( node->expr );
3486                maybeAccept_impl( node->expr, *this );
3487        } // if
3488
3489        VISIT_END( node );
3490}
3491
3492template< typename pass_type >
3493void PassVisitor< pass_type >::visit( const AttrType * node ) {
3494        VISIT_START( node );
3495
3496        if ( node->isType ) {
3497                assert( node->type );
3498                maybeAccept_impl( node->type, *this );
3499        } else {
3500                assert( node->expr );
3501                maybeAccept_impl( node->expr, *this );
3502        } // if
3503
3504        VISIT_END( node );
3505}
3506
3507template< typename pass_type >
3508Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
3509        MUTATE_START( node );
3510
3511        if ( node->isType ) {
3512                assert( node->type );
3513                maybeMutate_impl( node->type, *this );
3514        } else {
3515                assert( node->expr );
3516                maybeMutate_impl( node->expr, *this );
3517        } // if
3518
3519        MUTATE_END( Type, node );
3520}
3521
3522//--------------------------------------------------------------------------
3523// VarArgsType
3524template< typename pass_type >
3525void PassVisitor< pass_type >::visit( VarArgsType * node ) {
3526        VISIT_START( node );
3527
3528        maybeAccept_impl( node->forall, *this );
3529
3530        VISIT_END( node );
3531}
3532
3533template< typename pass_type >
3534void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
3535        VISIT_START( node );
3536
3537        maybeAccept_impl( node->forall, *this );
3538
3539        VISIT_END( node );
3540}
3541
3542template< typename pass_type >
3543Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
3544        MUTATE_START( node );
3545
3546        maybeMutate_impl( node->forall, *this );
3547
3548        MUTATE_END( Type, node );
3549}
3550
3551//--------------------------------------------------------------------------
3552// ZeroType
3553template< typename pass_type >
3554void PassVisitor< pass_type >::visit( ZeroType * node ) {
3555        VISIT_START( node );
3556
3557        maybeAccept_impl( node->forall, *this );
3558
3559        VISIT_END( node );
3560}
3561
3562template< typename pass_type >
3563void PassVisitor< pass_type >::visit( const ZeroType * node ) {
3564        VISIT_START( node );
3565
3566        maybeAccept_impl( node->forall, *this );
3567
3568        VISIT_END( node );
3569}
3570
3571template< typename pass_type >
3572Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
3573        MUTATE_START( node );
3574
3575        maybeMutate_impl( node->forall, *this );
3576
3577        MUTATE_END( Type, node );
3578}
3579
3580//--------------------------------------------------------------------------
3581// OneType
3582template< typename pass_type >
3583void PassVisitor< pass_type >::visit( OneType * node ) {
3584        VISIT_START( node );
3585
3586        maybeAccept_impl( node->forall, *this );
3587
3588        VISIT_END( node );
3589}
3590
3591template< typename pass_type >
3592void PassVisitor< pass_type >::visit( const OneType * node ) {
3593        VISIT_START( node );
3594
3595        maybeAccept_impl( node->forall, *this );
3596
3597        VISIT_END( node );
3598}
3599
3600template< typename pass_type >
3601Type * PassVisitor< pass_type >::mutate( OneType * node ) {
3602        MUTATE_START( node );
3603
3604        maybeMutate_impl( node->forall, *this );
3605
3606        MUTATE_END( Type, node );
3607}
3608
3609//--------------------------------------------------------------------------
3610// GlobalScopeType
3611template< typename pass_type >
3612void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
3613        VISIT_START( node );
3614
3615        maybeAccept_impl( node->forall, *this );
3616
3617        VISIT_END( node );
3618}
3619
3620template< typename pass_type >
3621void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
3622        VISIT_START( node );
3623
3624        maybeAccept_impl( node->forall, *this );
3625
3626        VISIT_END( node );
3627}
3628
3629template< typename pass_type >
3630Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
3631        MUTATE_START( node );
3632
3633        maybeMutate_impl( node->forall, *this );
3634
3635        MUTATE_END( Type, node );
3636}
3637
3638//--------------------------------------------------------------------------
3639// Designation
3640template< typename pass_type >
3641void PassVisitor< pass_type >::visit( Designation * node ) {
3642        VISIT_START( node );
3643
3644        maybeAccept_impl( node->designators, *this );
3645
3646        VISIT_END( node );
3647}
3648
3649template< typename pass_type >
3650void PassVisitor< pass_type >::visit( const Designation * node ) {
3651        VISIT_START( node );
3652
3653        maybeAccept_impl( node->designators, *this );
3654
3655        VISIT_END( node );
3656}
3657
3658template< typename pass_type >
3659Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
3660        MUTATE_START( node );
3661
3662        maybeMutate_impl( node->designators, *this );
3663
3664        MUTATE_END( Designation, node );
3665}
3666
3667//--------------------------------------------------------------------------
3668// SingleInit
3669template< typename pass_type >
3670void PassVisitor< pass_type >::visit( SingleInit * node ) {
3671        VISIT_START( node );
3672
3673        visitExpression( node->value );
3674
3675        VISIT_END( node );
3676}
3677
3678template< typename pass_type >
3679void PassVisitor< pass_type >::visit( const SingleInit * node ) {
3680        VISIT_START( node );
3681
3682        visitExpression( node->value );
3683
3684        VISIT_END( node );
3685}
3686
3687template< typename pass_type >
3688Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
3689        MUTATE_START( node );
3690
3691        node->value = mutateExpression( node->value );
3692
3693        MUTATE_END( Initializer, node );
3694}
3695
3696//--------------------------------------------------------------------------
3697// ListInit
3698template< typename pass_type >
3699void PassVisitor< pass_type >::visit( ListInit * node ) {
3700        VISIT_START( node );
3701
3702        maybeAccept_impl( node->designations, *this );
3703        maybeAccept_impl( node->initializers, *this );
3704
3705        VISIT_END( node );
3706}
3707
3708template< typename pass_type >
3709void PassVisitor< pass_type >::visit( const ListInit * node ) {
3710        VISIT_START( node );
3711
3712        maybeAccept_impl( node->designations, *this );
3713        maybeAccept_impl( node->initializers, *this );
3714
3715        VISIT_END( node );
3716}
3717
3718template< typename pass_type >
3719Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
3720        MUTATE_START( node );
3721
3722        maybeMutate_impl( node->designations, *this );
3723        maybeMutate_impl( node->initializers, *this );
3724
3725        MUTATE_END( Initializer, node );
3726}
3727
3728//--------------------------------------------------------------------------
3729// ConstructorInit
3730template< typename pass_type >
3731void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
3732        VISIT_START( node );
3733
3734        maybeAccept_impl( node->ctor, *this );
3735        maybeAccept_impl( node->dtor, *this );
3736        maybeAccept_impl( node->init, *this );
3737
3738        VISIT_END( node );
3739}
3740
3741template< typename pass_type >
3742void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
3743        VISIT_START( node );
3744
3745        maybeAccept_impl( node->ctor, *this );
3746        maybeAccept_impl( node->dtor, *this );
3747        maybeAccept_impl( node->init, *this );
3748
3749        VISIT_END( node );
3750}
3751
3752template< typename pass_type >
3753Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
3754        MUTATE_START( node );
3755
3756        maybeMutate_impl( node->ctor, *this );
3757        maybeMutate_impl( node->dtor, *this );
3758        maybeMutate_impl( node->init, *this );
3759
3760        MUTATE_END( Initializer, node );
3761}
3762
3763//--------------------------------------------------------------------------
3764// Attribute
3765template< typename pass_type >
3766void PassVisitor< pass_type >::visit( Constant * node ) {
3767        VISIT_START( node );
3768
3769        VISIT_END( node );
3770}
3771
3772template< typename pass_type >
3773void PassVisitor< pass_type >::visit( const Constant * node ) {
3774        VISIT_START( node );
3775
3776        VISIT_END( node );
3777}
3778
3779template< typename pass_type >
3780Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
3781        MUTATE_START( node );
3782
3783        MUTATE_END( Constant, node );
3784}
3785
3786//--------------------------------------------------------------------------
3787// Attribute
3788template< typename pass_type >
3789void PassVisitor< pass_type >::visit( Attribute * node ) {
3790        VISIT_START( node );
3791
3792        maybeAccept_impl( node->parameters, *this );
3793
3794        VISIT_END( node );
3795}
3796
3797template< typename pass_type >
3798void PassVisitor< pass_type >::visit( const Attribute * node ) {
3799        VISIT_START( node );
3800
3801        maybeAccept_impl( node->parameters, *this );
3802
3803        VISIT_END( node );
3804}
3805
3806template< typename pass_type >
3807Attribute * PassVisitor< pass_type >::mutate( Attribute * node  )  {
3808        MUTATE_START( node );
3809
3810        maybeMutate_impl( node->parameters, *this );
3811
3812        MUTATE_END( Attribute, node );
3813}
3814
3815//--------------------------------------------------------------------------
3816// TypeSubstitution
3817template< typename pass_type >
3818TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
3819        MUTATE_START( node );
3820
3821        for ( auto & p : node->typeEnv ) {
3822                indexerScopedMutate( p.second, *this );
3823        }
3824        for ( auto & p : node->varEnv ) {
3825                indexerScopedMutate( p.second, *this );
3826        }
3827
3828        MUTATE_END( TypeSubstitution, node );
3829}
3830
3831#undef VISIT_START
3832#undef VISIT_END
3833
3834#undef MUTATE_START
3835#undef MUTATE_END
Note: See TracBrowser for help on using the repository browser.