source: src/Common/PassVisitor.impl.h @ 9dcb653

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 9dcb653 was 9dcb653, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Clean pass visitor and enabled indexer features

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