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

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since c274df2 was 675716e, checked in by tdelisle <tdelisle@…>, 5 years ago

Instrumented PassVisitor? to print average/max depth

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