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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since c6c682cf was c6c682cf, checked in by Andrew Beach <ajbeach@…>, 3 years ago

This should make the value of Pass[Visitor]::inFunction match the expected value.

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