source: src/AST/Pass.impl.hpp @ 8fd53b6e

Last change on this file since 8fd53b6e was dc58e5d, checked in by JiadaL <j82liang@…>, 3 months ago

Small cleanup

  • Property mode set to 100644
File size: 62.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ast::Pass.impl.hpp --
8//
9// Author           : Thierry Delisle
10// Created On       : Thu May 09 15::37::05 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count     :
14//
15
16#pragma once
17// IWYU pragma: private, include "AST/Pass.hpp"
18
19#include <type_traits>
20#include <unordered_map>
21
22#include "AST/Copy.hpp"
23#include "AST/TranslationUnit.hpp"
24#include "AST/TypeSubstitution.hpp"
25
26#define VISIT_START( node ) \
27        using namespace ast; \
28        /* back-up the last known code location */ \
29        __attribute__((unused)) auto loc_guard = ast::__pass::make_location_guard( core, node, 0 ); \
30        /* back-up the visit children */ \
31        __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \
32        /* setup the scope for passes that want to run code at exit */ \
33        __attribute__((unused)) ast::__pass::guard_value          guard2( ast::__pass::at_cleanup    (core, 0) ); \
34        /* begin tracing memory allocation if requested by this pass */ \
35        __pass::beginTrace( core, 0 ); \
36        /* call the implementation of the previsit of this pass */ \
37        __pass::previsit( core, node, 0 );
38
39#define VISIT_END( type, node ) \
40        /* call the implementation of the postvisit of this pass */ \
41        auto __return = __pass::postvisit( core, node, 0 ); \
42        assertf(__return, "post visit should never return null"); \
43        /* end tracing memory allocation if requested by this pass */ \
44        __pass::endTrace( core, 0 ); \
45        return __return;
46
47#ifdef PEDANTIC_PASS_ASSERT
48#define __pedantic_pass_assert(...) assert(__VA_ARGS__)
49#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
50#else
51#define __pedantic_pass_assert(...)
52#define __pedantic_pass_assertf(...)
53#endif
54
55namespace ast::__pass {
56        // Check if this is either a null pointer or a pointer to an empty container
57        template<typename T>
58        static inline bool empty( T * ptr ) {
59                return !ptr || ptr->empty();
60        }
61
62        template< typename core_t, typename node_t >
63        static inline node_t* mutate(const node_t *node) {
64                return std::is_base_of<PureVisitor, core_t>::value ? ::ast::shallowCopy(node) : ::ast::mutate(node);
65        }
66
67        //------------------------------
68        template<typename it_t, template <class...> class container_t>
69        static inline void take_all( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) {
70                if ( empty( decls ) ) return;
71
72                std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
73                                return new DeclStmt( decl->location, decl );
74                        });
75                decls->clear();
76                if ( mutated ) *mutated = true;
77        }
78
79        template<typename it_t, template <class...> class container_t>
80        static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * stmts, bool * mutated = nullptr ) {
81                if ( empty( stmts ) ) return;
82
83                std::move(stmts->begin(), stmts->end(), it);
84                stmts->clear();
85                if ( mutated ) *mutated = true;
86        }
87
88        //------------------------------
89        /// Check if should be skipped, different for pointers and containers
90        template<typename node_t>
91        bool skip( const ast::ptr<node_t> & val ) {
92                return !val;
93        }
94
95        template< template <class...> class container_t, typename node_t >
96        bool skip( const container_t<ast::ptr< node_t >> & val ) {
97                return val.empty();
98        }
99
100        //------------------------------
101        /// Get the value to visit, different for pointers and containers
102        template<typename node_t>
103        auto get( const ast::ptr<node_t> & val, int ) -> decltype(val.get()) {
104                return val.get();
105        }
106
107        template<typename node_t>
108        const node_t & get( const node_t & val, long ) {
109                return val;
110        }
111}
112
113template< typename core_t >
114template< typename node_t >
115auto ast::Pass< core_t >::call_accept( const node_t * node ) ->
116                ast::Pass< core_t >::call_accept_result_t<node_t> {
117        __pedantic_pass_assert( __visit_children() );
118        __pedantic_pass_assert( node );
119
120        auto nval = node->accept( *this );
121        return { nval != node, nval };
122}
123
124template< typename core_t >
125ast::__pass::template result1<ast::Expr> ast::Pass< core_t >::call_accept_top( const ast::Expr * expr ) {
126        __pedantic_pass_assert( __visit_children() );
127        __pedantic_pass_assert( expr );
128
129        const ast::TypeSubstitution ** typeSubs_ptr = __pass::typeSubs( core, 0 );
130        if ( typeSubs_ptr && expr->env ) {
131                *typeSubs_ptr = expr->env;
132        }
133
134        auto nval = expr->accept( *this );
135        return { nval != expr, nval };
136}
137
138template< typename core_t >
139ast::__pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
140        __pedantic_pass_assert( __visit_children() );
141        __pedantic_pass_assert( stmt );
142
143        // add a few useful symbols to the scope
144        using __pass::empty;
145
146        // get the stmts/decls that will need to be spliced in
147        auto stmts_before = __pass::stmtsToAddBefore( core, 0 );
148        auto stmts_after  = __pass::stmtsToAddAfter ( core, 0 );
149        auto decls_before = __pass::declsToAddBefore( core, 0 );
150        auto decls_after  = __pass::declsToAddAfter ( core, 0 );
151
152        // These may be modified by subnode but most be restored once we exit this statemnet.
153        ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::typeSubs( core, 0 ) );
154        ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
155        ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
156        ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) >::type > __old_stmts_before( decls_before );
157        ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) >::type > __old_stmts_after ( decls_after  );
158
159        // Now is the time to actually visit the node
160        const ast::Stmt * nstmt = stmt->accept( *this );
161
162        // If the pass doesn't want to add anything then we are done
163        if ( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) {
164                return { nstmt != stmt, nstmt };
165        }
166
167        // Make sure that it is either adding statements or declartions but not both
168        // this is because otherwise the order would be awkward to predict
169        assert(( empty( stmts_before ) && empty( stmts_after ))
170            || ( empty( decls_before ) && empty( decls_after )) );
171
172        // Create a new Compound Statement to hold the new decls/stmts
173        ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
174
175        // Take all the declarations that go before
176        __pass::take_all( std::back_inserter( compound->kids ), decls_before );
177        __pass::take_all( std::back_inserter( compound->kids ), stmts_before );
178
179        // Insert the original declaration
180        compound->kids.emplace_back( nstmt );
181
182        // Insert all the declarations that go before
183        __pass::take_all( std::back_inserter( compound->kids ), decls_after );
184        __pass::take_all( std::back_inserter( compound->kids ), stmts_after );
185
186        return { true, compound };
187}
188
189template< typename core_t >
190template< template <class...> class container_t >
191ast::__pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
192        __pedantic_pass_assert( __visit_children() );
193        __pedantic_pass_assert( !statements.empty() );
194
195        // We are going to aggregate errors for all these statements
196        SemanticErrorException errors;
197
198        // add a few useful symbols to the scope
199        using __pass::empty;
200
201        // get the stmts/decls that will need to be spliced in
202        auto stmts_before = __pass::stmtsToAddBefore( core, 0 );
203        auto stmts_after  = __pass::stmtsToAddAfter ( core, 0 );
204        auto decls_before = __pass::declsToAddBefore( core, 0 );
205        auto decls_after  = __pass::declsToAddAfter ( core, 0 );
206
207        // These may be modified by subnode but most be restored once we exit this statemnet.
208        ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
209        ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
210        ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) >::type > __old_stmts_before( decls_before );
211        ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) >::type > __old_stmts_after ( decls_after  );
212
213        // update pass statitistics
214        pass_visitor_stats.depth++;
215        pass_visitor_stats.max->push(pass_visitor_stats.depth);
216        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
217
218        __pass::resultNstmt<container_t> new_kids;
219        for ( auto value : enumerate( statements ) ) {
220                try {
221                        size_t i = value.idx;
222                        const Stmt * stmt = value.val;
223                        __pedantic_pass_assert( stmt );
224                        const ast::Stmt * new_stmt = stmt->accept( *this );
225                        assert( new_stmt );
226
227                        // Make sure that it is either adding statements or declartions but not both
228                        // this is because otherwise the order would be awkward to predict
229                        assert(( empty( stmts_before ) && empty( stmts_after ))
230                            || ( empty( decls_before ) && empty( decls_after )) );
231
232                        // Take all the statements which should have gone after, N/A for first iteration
233                        new_kids.take_all( decls_before );
234                        new_kids.take_all( stmts_before );
235
236                        // Now add the statement if there is one
237                        if ( new_stmt != stmt ) {
238                                new_kids.differs = true;
239                                new_kids.values.emplace_back( new_stmt );
240                        } else {
241                                new_kids.values.emplace_back( i );
242                        }
243
244                        // Take all the declarations that go before
245                        new_kids.take_all( decls_after );
246                        new_kids.take_all( stmts_after );
247                } catch ( SemanticErrorException &e ) {
248                        errors.append( e );
249                }
250        }
251        pass_visitor_stats.depth--;
252        if ( !errors.isEmpty() ) { throw errors; }
253
254        return new_kids;
255}
256
257template< typename core_t >
258template< template <class...> class container_t, typename node_t >
259ast::__pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
260        __pedantic_pass_assert( __visit_children() );
261        __pedantic_pass_assert( !container.empty() );
262
263        // Collect errors from processing all these nodes.
264        SemanticErrorException errors;
265
266        pass_visitor_stats.depth++;
267        pass_visitor_stats.max->push(pass_visitor_stats.depth);
268        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
269
270        bool mutated = false;
271        container_t<ptr<node_t>> new_kids;
272        for ( const node_t * node : container ) {
273                try {
274                        __pedantic_pass_assert( node );
275                        const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
276                        if ( new_stmt != node ) {
277                                mutated = true;
278                                new_kids.emplace_back( new_stmt );
279                        } else {
280                                new_kids.emplace_back( nullptr );
281                        }
282                } catch ( SemanticErrorException &e ) {
283                        errors.append( e );
284                }
285        }
286
287        __pedantic_pass_assert( new_kids.size() == container.size() );
288        pass_visitor_stats.depth--;
289        if ( !errors.isEmpty() ) { throw errors; }
290
291        return ast::__pass::resultN<container_t, node_t>{ mutated, new_kids };
292}
293
294template< typename core_t >
295template<typename node_t, typename super_t, typename field_t>
296void ast::Pass< core_t >::maybe_accept(
297        const node_t * & parent,
298        field_t super_t::*field
299) {
300        static_assert( std::is_base_of<super_t, node_t>::value, "Error deducing member object" );
301
302        if ( __pass::skip( parent->*field ) ) return;
303        const auto & old_val = __pass::get(parent->*field, 0);
304
305        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
306
307        auto result = call_accept( old_val );
308        if ( result.differs ) {
309                auto new_parent = __pass::mutate<core_t>(parent);
310                result.apply( new_parent, field );
311                parent = new_parent;
312        }
313}
314
315template< typename core_t >
316template<typename node_t, typename super_t, typename field_t>
317void ast::Pass< core_t >::maybe_accept_top(
318        const node_t * & parent,
319        field_t super_t::*field
320) {
321        static_assert( std::is_base_of<super_t, node_t>::value, "Error deducing member object" );
322
323        if ( __pass::skip( parent->*field ) ) return;
324        const auto & old_val = __pass::get(parent->*field, 0);
325
326        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
327
328        auto result = call_accept_top( old_val );
329        if ( result.differs ) {
330                auto new_parent = __pass::mutate<core_t>(parent);
331                result.apply( new_parent, field );
332                parent = new_parent;
333        }
334}
335
336template< typename core_t >
337template<typename node_t, typename super_t, typename field_t>
338void ast::Pass< core_t >::maybe_accept_as_compound(
339        const node_t * & parent,
340        field_t super_t::*child
341) {
342        static_assert( std::is_base_of<super_t, node_t>::value, "Error deducing member object" );
343
344        if ( __pass::skip( parent->*child ) ) return;
345        const auto & old_val = __pass::get(parent->*child, 0);
346
347        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
348
349        auto result = call_accept_as_compound( old_val );
350        if ( result.differs ) {
351                auto new_parent = __pass::mutate<core_t>(parent);
352                result.apply( new_parent, child );
353                parent = new_parent;
354        }
355}
356
357//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
358//========================================================================================================================================================================
359//========================================================================================================================================================================
360//========================================================================================================================================================================
361//========================================================================================================================================================================
362//========================================================================================================================================================================
363//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
364
365template< typename core_t >
366inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< core_t > & visitor ) {
367        // We are going to aggregate errors for all these statements
368        SemanticErrorException errors;
369
370        // add a few useful symbols to the scope
371        using __pass::empty;
372
373        // get the stmts/decls that will need to be spliced in
374        auto decls_before = __pass::declsToAddBefore( visitor.core, 0);
375        auto decls_after  = __pass::declsToAddAfter ( visitor.core, 0);
376
377        // update pass statitistics
378        pass_visitor_stats.depth++;
379        pass_visitor_stats.max->push(pass_visitor_stats.depth);
380        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
381
382        for ( std::list< ast::ptr<ast::Decl> >::iterator i = decls.begin(); ; ++i ) {
383                // splice in new declarations after previous decl
384                if ( !empty( decls_after ) ) { decls.splice( i, *decls_after ); }
385
386                if ( i == decls.end() ) break;
387
388                try {
389                        // run visitor on declaration
390                        ast::ptr<ast::Decl> & node = *i;
391                        assert( node );
392                        node = node->accept( visitor );
393                }
394                catch( SemanticErrorException &e ) {
395                        if (__pass::on_error (visitor.core, *i, 0))
396                                errors.append( e );
397                }
398
399                // splice in new declarations before current decl
400                if ( !empty( decls_before ) ) { decls.splice( i, *decls_before ); }
401        }
402        pass_visitor_stats.depth--;
403        if ( !errors.isEmpty() ) { throw errors; }
404}
405
406template< typename core_t >
407inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) {
408        if ( auto ptr = __pass::translationUnit( visitor.core, 0 ) ) {
409                ValueGuard<const TranslationUnit *> guard( *ptr );
410                *ptr = &unit;
411                return ast::accept_all( unit.decls, visitor );
412        } else {
413                return ast::accept_all( unit.decls, visitor );
414        }
415}
416
417// A NOTE ON THE ORDER OF TRAVERSAL
418//
419// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
420// no such thing as a recursive type or typedef.
421//
422//             typedef struct { T *x; } T; // never allowed
423//
424// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
425// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
426// declaration).
427//
428//             struct T { struct T *x; }; // allowed
429//
430// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
431// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
432// queried later in this pass.
433
434//--------------------------------------------------------------------------
435// ObjectDecl
436template< typename core_t >
437const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::ObjectDecl * node ) {
438        VISIT_START( node );
439
440        if ( __visit_children() ) {
441                {
442                        guard_symtab guard { *this };
443                        maybe_accept( node, &ObjectDecl::type );
444                }
445                maybe_accept( node, &ObjectDecl::init          );
446                maybe_accept( node, &ObjectDecl::bitfieldWidth );
447                maybe_accept( node, &ObjectDecl::attributes    );
448        }
449
450        __pass::symtab::addId( core, 0, node );
451
452        VISIT_END( DeclWithType, node );
453}
454
455//--------------------------------------------------------------------------
456// FunctionDecl
457template< typename core_t >
458const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::FunctionDecl * node ) {
459        VISIT_START( node );
460
461        __pass::symtab::addId( core, 0, node );
462
463        if ( __visit_children() ) {
464                maybe_accept( node, &FunctionDecl::withExprs );
465        }
466        {
467                // with clause introduces a level of scope (for the with expression members).
468                // with clause exprs are added to the symbol table before parameters so that parameters
469                // shadow with exprs and not the other way around.
470                guard_symtab guard { *this };
471                __pass::symtab::addWith( core, 0, node->withExprs, node );
472                {
473                        guard_symtab guard { *this };
474                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
475                        // This is a C name and so has C linkage.
476                        static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{
477                                CodeLocation{}, "__func__",
478                                new ast::ArrayType{
479                                        new ast::BasicType{ ast::BasicType::Char, ast::CV::Const },
480                                        nullptr, VariableLen, DynamicDim
481                                },
482                                nullptr,
483                                ast::Storage::Classes(),
484                                ast::Linkage::C,
485                        } };
486                        __pass::symtab::addId( core, 0, func );
487                        if ( __visit_children() ) {
488                                maybe_accept( node, &FunctionDecl::type_params );
489                                maybe_accept( node, &FunctionDecl::assertions );
490                                maybe_accept( node, &FunctionDecl::params );
491                                maybe_accept( node, &FunctionDecl::returns );
492                                maybe_accept( node, &FunctionDecl::type );
493                                maybe_accept( node, &FunctionDecl::attributes );
494                                // First remember that we are now within a function.
495                                ValueGuard< bool > oldInFunction( inFunction );
496                                inFunction = true;
497                                // The function body needs to have the same scope as parameters.
498                                // A CompoundStmt will not enter a new scope if atFunctionTop is true.
499                                ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
500                                atFunctionTop = true;
501                                maybe_accept( node, &FunctionDecl::stmts );
502                        }
503                }
504        }
505
506        VISIT_END( DeclWithType, node );
507}
508
509//--------------------------------------------------------------------------
510// StructDecl
511template< typename core_t >
512const ast::Decl * ast::Pass< core_t >::visit( const ast::StructDecl * node ) {
513        VISIT_START( node );
514
515        // make up a forward declaration and add it before processing the members
516        // needs to be on the heap because addStruct saves the pointer
517        __pass::symtab::addStructFwd( core, 0, node );
518
519        if ( __visit_children() ) {
520                guard_symtab guard { * this };
521                maybe_accept( node, &StructDecl::params     );
522                maybe_accept( node, &StructDecl::members    );
523                maybe_accept( node, &StructDecl::attributes );
524        }
525
526        // this addition replaces the forward declaration
527        __pass::symtab::addStruct( core, 0, node );
528
529        VISIT_END( Decl, node );
530}
531
532//--------------------------------------------------------------------------
533// UnionDecl
534template< typename core_t >
535const ast::Decl * ast::Pass< core_t >::visit( const ast::UnionDecl * node ) {
536        VISIT_START( node );
537
538        // make up a forward declaration and add it before processing the members
539        __pass::symtab::addUnionFwd( core, 0, node );
540
541        if ( __visit_children() ) {
542                guard_symtab guard { * this };
543                maybe_accept( node, &UnionDecl::params     );
544                maybe_accept( node, &UnionDecl::members    );
545                maybe_accept( node, &UnionDecl::attributes );
546        }
547
548        __pass::symtab::addUnion( core, 0, node );
549
550        VISIT_END( Decl, node );
551}
552
553//--------------------------------------------------------------------------
554// EnumDecl
555template< typename core_t >
556const ast::Decl * ast::Pass< core_t >::visit( const ast::EnumDecl * node ) {
557        VISIT_START( node );
558
559        __pass::symtab::addEnum( core, 0, node );
560
561        if ( __visit_children() ) {
562                if ( node->hide == ast::EnumDecl::EnumHiding::Hide ) {
563                        guard_symtab guard { *this };
564                        maybe_accept( node, &EnumDecl::base );
565                        maybe_accept( node, &EnumDecl::params     );
566                        maybe_accept( node, &EnumDecl::members    );
567                        maybe_accept( node, &EnumDecl::attributes );
568                } else {
569                        maybe_accept( node, &EnumDecl::base );
570                        maybe_accept( node, &EnumDecl::params     );
571                        maybe_accept( node, &EnumDecl::members    );
572                        maybe_accept( node, &EnumDecl::attributes );
573                }
574        }
575
576        VISIT_END( Decl, node );
577}
578
579//--------------------------------------------------------------------------
580// TraitDecl
581template< typename core_t >
582const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
583        VISIT_START( node );
584
585        if ( __visit_children() ) {
586                guard_symtab guard { *this };
587                maybe_accept( node, &TraitDecl::params     );
588                maybe_accept( node, &TraitDecl::members    );
589                maybe_accept( node, &TraitDecl::attributes );
590        }
591
592        __pass::symtab::addTrait( core, 0, node );
593
594        VISIT_END( Decl, node );
595}
596
597//--------------------------------------------------------------------------
598// TypeDecl
599template< typename core_t >
600const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
601        VISIT_START( node );
602
603        if ( __visit_children() ) {
604                guard_symtab guard { *this };
605                maybe_accept( node, &TypeDecl::base   );
606        }
607
608        // see A NOTE ON THE ORDER OF TRAVERSAL, above
609        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
610        // and may depend on the type itself
611        __pass::symtab::addType( core, 0, node );
612
613        if ( __visit_children() ) {
614                maybe_accept( node, &TypeDecl::assertions );
615
616                {
617                        guard_symtab guard { *this };
618                        maybe_accept( node, &TypeDecl::init );
619                }
620        }
621
622        VISIT_END( Decl, node );
623}
624
625//--------------------------------------------------------------------------
626// TypedefDecl
627template< typename core_t >
628const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
629        VISIT_START( node );
630
631        if ( __visit_children() ) {
632                guard_symtab guard { *this };
633                maybe_accept( node, &TypedefDecl::base   );
634        }
635
636        __pass::symtab::addType( core, 0, node );
637
638        if ( __visit_children() ) {
639                maybe_accept( node, &TypedefDecl::assertions );
640        }
641
642        VISIT_END( Decl, node );
643}
644
645//--------------------------------------------------------------------------
646// AsmDecl
647template< typename core_t >
648const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
649        VISIT_START( node );
650
651        if ( __visit_children() ) {
652                maybe_accept( node, &AsmDecl::stmt );
653        }
654
655        VISIT_END( AsmDecl, node );
656}
657
658//--------------------------------------------------------------------------
659// DirectiveDecl
660template< typename core_t >
661const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) {
662        VISIT_START( node );
663
664        if ( __visit_children() ) {
665                maybe_accept( node, &DirectiveDecl::stmt );
666        }
667
668        VISIT_END( DirectiveDecl, node );
669}
670
671//--------------------------------------------------------------------------
672// StaticAssertDecl
673template< typename core_t >
674const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
675        VISIT_START( node );
676
677        if ( __visit_children() ) {
678                maybe_accept_top( node, &StaticAssertDecl::cond );
679                maybe_accept( node, &StaticAssertDecl::msg  );
680        }
681
682        VISIT_END( StaticAssertDecl, node );
683}
684
685//--------------------------------------------------------------------------
686// InlineMemberDecl
687template< typename core_t >
688const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) {
689        VISIT_START( node );
690
691        if ( __visit_children() ) {
692                {
693                        guard_symtab guard { *this };
694                        maybe_accept( node, &InlineMemberDecl::type );
695                }
696        }
697
698        VISIT_END( DeclWithType, node );
699}
700
701//--------------------------------------------------------------------------
702// CompoundStmt
703template< typename core_t >
704const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
705        VISIT_START( node );
706
707        if ( __visit_children() ) {
708                // Do not enter (or leave) a new symbol table scope if atFunctionTop.
709                // But always enter (and leave) a new general scope.
710                if ( atFunctionTop ) {
711                        ValueGuard< bool > guard1( atFunctionTop );
712                        atFunctionTop = false;
713                        guard_scope guard2( *this );
714                        maybe_accept( node, &CompoundStmt::kids );
715                } else {
716                        guard_symtab guard1( *this );
717                        guard_scope guard2( *this );
718                        maybe_accept( node, &CompoundStmt::kids );
719                }
720        }
721
722        VISIT_END( CompoundStmt, node );
723}
724
725//--------------------------------------------------------------------------
726// ExprStmt
727template< typename core_t >
728const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
729        VISIT_START( node );
730
731        if ( __visit_children() ) {
732                maybe_accept_top( node, &ExprStmt::expr );
733        }
734
735        VISIT_END( Stmt, node );
736}
737
738//--------------------------------------------------------------------------
739// AsmStmt
740template< typename core_t >
741const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
742        VISIT_START( node )
743
744        if ( __visit_children() ) {
745                maybe_accept( node, &AsmStmt::instruction );
746                maybe_accept( node, &AsmStmt::output      );
747                maybe_accept( node, &AsmStmt::input       );
748                maybe_accept( node, &AsmStmt::clobber     );
749        }
750
751        VISIT_END( Stmt, node );
752}
753
754//--------------------------------------------------------------------------
755// DirectiveStmt
756template< typename core_t >
757const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
758        VISIT_START( node )
759
760        VISIT_END( Stmt, node );
761}
762
763//--------------------------------------------------------------------------
764// IfStmt
765template< typename core_t >
766const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
767        VISIT_START( node );
768
769        if ( __visit_children() ) {
770                // if statements introduce a level of scope (for the initialization)
771                guard_symtab guard { *this };
772                maybe_accept( node, &IfStmt::inits    );
773                maybe_accept_top( node, &IfStmt::cond     );
774                maybe_accept_as_compound( node, &IfStmt::then );
775                maybe_accept_as_compound( node, &IfStmt::else_ );
776        }
777
778        VISIT_END( Stmt, node );
779}
780
781//--------------------------------------------------------------------------
782// WhileDoStmt
783template< typename core_t >
784const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileDoStmt * node ) {
785        VISIT_START( node );
786
787        if ( __visit_children() ) {
788                // while statements introduce a level of scope (for the initialization)
789                guard_symtab guard { *this };
790                maybe_accept( node, &WhileDoStmt::inits );
791                maybe_accept_top( node, &WhileDoStmt::cond  );
792                maybe_accept_as_compound( node, &WhileDoStmt::body  );
793        }
794
795        VISIT_END( Stmt, node );
796}
797
798//--------------------------------------------------------------------------
799// ForStmt
800template< typename core_t >
801const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
802        VISIT_START( node );
803
804        if ( __visit_children() ) {
805                // for statements introduce a level of scope (for the initialization)
806                guard_symtab guard { *this };
807                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
808                maybe_accept( node, &ForStmt::inits );
809                maybe_accept_top( node, &ForStmt::cond  );
810                maybe_accept_top( node, &ForStmt::inc   );
811                maybe_accept_as_compound( node, &ForStmt::body  );
812        }
813
814        VISIT_END( Stmt, node );
815}
816
817//--------------------------------------------------------------------------
818// SwitchStmt
819template< typename core_t >
820const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
821        VISIT_START( node );
822
823        if ( __visit_children() ) {
824                maybe_accept_top( node, &SwitchStmt::cond  );
825                maybe_accept( node, &SwitchStmt::cases );
826        }
827
828        VISIT_END( Stmt, node );
829}
830
831//--------------------------------------------------------------------------
832// CaseClause
833template< typename core_t >
834const ast::CaseClause * ast::Pass< core_t >::visit( const ast::CaseClause * node ) {
835        VISIT_START( node );
836
837        if ( __visit_children() ) {
838                maybe_accept_top( node, &CaseClause::cond  );
839                maybe_accept( node, &CaseClause::stmts );
840        }
841
842        VISIT_END( CaseClause, node );
843}
844
845//--------------------------------------------------------------------------
846// BranchStmt
847template< typename core_t >
848const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
849        VISIT_START( node );
850        VISIT_END( Stmt, node );
851}
852
853//--------------------------------------------------------------------------
854// ReturnStmt
855template< typename core_t >
856const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
857        VISIT_START( node );
858
859        if ( __visit_children() ) {
860                maybe_accept_top( node, &ReturnStmt::expr );
861        }
862
863        VISIT_END( Stmt, node );
864}
865
866//--------------------------------------------------------------------------
867// ThrowStmt
868template< typename core_t >
869const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
870        VISIT_START( node );
871
872        if ( __visit_children() ) {
873                maybe_accept( node, &ThrowStmt::expr   );
874                maybe_accept( node, &ThrowStmt::target );
875        }
876
877        VISIT_END( Stmt, node );
878}
879
880//--------------------------------------------------------------------------
881// TryStmt
882template< typename core_t >
883const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
884        VISIT_START( node );
885
886        if ( __visit_children() ) {
887                maybe_accept( node, &TryStmt::body     );
888                maybe_accept( node, &TryStmt::handlers );
889                maybe_accept( node, &TryStmt::finally  );
890        }
891
892        VISIT_END( Stmt, node );
893}
894
895//--------------------------------------------------------------------------
896// CatchClause
897template< typename core_t >
898const ast::CatchClause * ast::Pass< core_t >::visit( const ast::CatchClause * node ) {
899        VISIT_START( node );
900
901        if ( __visit_children() ) {
902                // catch statements introduce a level of scope (for the caught exception)
903                guard_symtab guard { *this };
904                maybe_accept( node, &CatchClause::decl );
905                maybe_accept_top( node, &CatchClause::cond );
906                maybe_accept_as_compound( node, &CatchClause::body );
907        }
908
909        VISIT_END( CatchClause, node );
910}
911
912//--------------------------------------------------------------------------
913// FinallyClause
914template< typename core_t >
915const ast::FinallyClause * ast::Pass< core_t >::visit( const ast::FinallyClause * node ) {
916        VISIT_START( node );
917
918        if ( __visit_children() ) {
919                maybe_accept( node, &FinallyClause::body );
920        }
921
922        VISIT_END( FinallyClause, node );
923}
924
925//--------------------------------------------------------------------------
926// FinallyStmt
927template< typename core_t >
928const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
929        VISIT_START( node );
930
931        if ( __visit_children() ) {
932                maybe_accept( node, &SuspendStmt::then   );
933        }
934
935        VISIT_END( Stmt, node );
936}
937
938//--------------------------------------------------------------------------
939// WhenClause
940template< typename core_t >
941const ast::WhenClause * ast::Pass< core_t >::visit( const ast::WhenClause * node ) {
942        VISIT_START( node );
943
944        if ( __visit_children() ) {
945                maybe_accept( node, &WhenClause::target );
946                maybe_accept( node, &WhenClause::stmt );
947                maybe_accept( node, &WhenClause::when_cond );
948        }
949
950        VISIT_END( WhenClause, node );
951}
952
953//--------------------------------------------------------------------------
954// WaitForStmt
955template< typename core_t >
956const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
957        VISIT_START( node );
958
959        if ( __visit_children() ) {
960                maybe_accept( node, &WaitForStmt::clauses );
961                maybe_accept( node, &WaitForStmt::timeout_time );
962                maybe_accept( node, &WaitForStmt::timeout_stmt );
963                maybe_accept( node, &WaitForStmt::timeout_cond );
964                maybe_accept( node, &WaitForStmt::else_stmt );
965                maybe_accept( node, &WaitForStmt::else_cond );
966        }
967
968        VISIT_END( Stmt, node );
969}
970
971//--------------------------------------------------------------------------
972// WaitForClause
973template< typename core_t >
974const ast::WaitForClause * ast::Pass< core_t >::visit( const ast::WaitForClause * node ) {
975        VISIT_START( node );
976
977        if ( __visit_children() ) {
978                maybe_accept( node, &WaitForClause::target );
979                maybe_accept( node, &WaitForClause::target_args );
980                maybe_accept( node, &WaitForClause::stmt );
981                maybe_accept( node, &WaitForClause::when_cond );
982        }
983
984        VISIT_END( WaitForClause, node );
985}
986
987//--------------------------------------------------------------------------
988// WaitUntilStmt
989template< typename core_t >
990const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitUntilStmt * node ) {
991        VISIT_START( node );
992
993        if ( __visit_children() ) {
994                maybe_accept( node, &WaitUntilStmt::clauses );
995                maybe_accept( node, &WaitUntilStmt::timeout_time );
996                maybe_accept( node, &WaitUntilStmt::timeout_stmt );
997                maybe_accept( node, &WaitUntilStmt::timeout_cond );
998                maybe_accept( node, &WaitUntilStmt::else_stmt );
999                maybe_accept( node, &WaitUntilStmt::else_cond );
1000        }
1001
1002        VISIT_END( Stmt, node );
1003}
1004
1005//--------------------------------------------------------------------------
1006// WithStmt
1007template< typename core_t >
1008const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
1009        VISIT_START( node );
1010
1011        if ( __visit_children() ) {
1012                maybe_accept( node, &WithStmt::exprs );
1013                {
1014                        // catch statements introduce a level of scope (for the caught exception)
1015                        guard_symtab guard { *this };
1016                        __pass::symtab::addWith( core, 0, node->exprs, node );
1017                        maybe_accept( node, &WithStmt::stmt );
1018                }
1019        }
1020
1021        VISIT_END( Stmt, node );
1022}
1023
1024//--------------------------------------------------------------------------
1025// NullStmt
1026template< typename core_t >
1027const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
1028        VISIT_START( node );
1029        VISIT_END( NullStmt, node );
1030}
1031
1032//--------------------------------------------------------------------------
1033// DeclStmt
1034template< typename core_t >
1035const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
1036        VISIT_START( node );
1037
1038        if ( __visit_children() ) {
1039                maybe_accept( node, &DeclStmt::decl );
1040        }
1041
1042        VISIT_END( Stmt, node );
1043}
1044
1045//--------------------------------------------------------------------------
1046// ImplicitCtorDtorStmt
1047template< typename core_t >
1048const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
1049        VISIT_START( node );
1050
1051        // For now this isn't visited, it is unclear if this causes problem
1052        // if all tests are known to pass, remove this code
1053        if ( __visit_children() ) {
1054                maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
1055        }
1056
1057        VISIT_END( Stmt, node );
1058}
1059
1060//--------------------------------------------------------------------------
1061// MutexStmt
1062template< typename core_t >
1063const ast::Stmt * ast::Pass< core_t >::visit( const ast::MutexStmt * node ) {
1064        VISIT_START( node );
1065
1066        if ( __visit_children() ) {
1067                // mutex statements introduce a level of scope (for the initialization)
1068                guard_symtab guard { *this };
1069                maybe_accept( node, &MutexStmt::stmt );
1070                maybe_accept( node, &MutexStmt::mutexObjs );
1071        }
1072
1073        VISIT_END( Stmt, node );
1074}
1075
1076//--------------------------------------------------------------------------
1077// CorunStmt
1078template< typename core_t >
1079const ast::Stmt * ast::Pass< core_t >::visit( const ast::CorunStmt * node ) {
1080        VISIT_START( node );
1081
1082        if ( __visit_children() ) {
1083                maybe_accept( node, &CorunStmt::stmt );
1084        }
1085
1086        VISIT_END( Stmt, node );
1087}
1088
1089//--------------------------------------------------------------------------
1090// CoforStmt
1091template< typename core_t >
1092const ast::Stmt * ast::Pass< core_t >::visit( const ast::CoforStmt * node ) {
1093        VISIT_START( node );
1094
1095        if ( __visit_children() ) {
1096                // for statements introduce a level of scope (for the initialization)
1097                guard_symtab guard { *this };
1098                maybe_accept( node, &CoforStmt::inits );
1099                maybe_accept_top( node, &CoforStmt::cond  );
1100                maybe_accept_top( node, &CoforStmt::inc   );
1101                maybe_accept_as_compound( node, &CoforStmt::body  );
1102        }
1103
1104        VISIT_END( Stmt, node );
1105}
1106
1107//--------------------------------------------------------------------------
1108// ApplicationExpr
1109template< typename core_t >
1110const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
1111        VISIT_START( node );
1112
1113        if ( __visit_children() ) {
1114                {
1115                        guard_symtab guard { *this };
1116                        maybe_accept( node, &ApplicationExpr::result );
1117                }
1118                maybe_accept( node, &ApplicationExpr::func );
1119                maybe_accept( node, &ApplicationExpr::args );
1120        }
1121
1122        VISIT_END( Expr, node );
1123}
1124
1125//--------------------------------------------------------------------------
1126// UntypedExpr
1127template< typename core_t >
1128const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1129        VISIT_START( node );
1130
1131        if ( __visit_children() ) {
1132                {
1133                        guard_symtab guard { *this };
1134                        maybe_accept( node, &UntypedExpr::result );
1135                }
1136
1137                maybe_accept( node, &UntypedExpr::args );
1138        }
1139
1140        VISIT_END( Expr, node );
1141}
1142
1143//--------------------------------------------------------------------------
1144// NameExpr
1145template< typename core_t >
1146const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1147        VISIT_START( node );
1148
1149        if ( __visit_children() ) {
1150                guard_symtab guard { *this };
1151                maybe_accept( node, &NameExpr::result );
1152        }
1153
1154        VISIT_END( Expr, node );
1155}
1156
1157//--------------------------------------------------------------------------
1158// QualifiedNameExpr
1159template< typename core_t >
1160const ast::Expr * ast::Pass< core_t >::visit( const ast::QualifiedNameExpr * node ) {
1161        VISIT_START( node );
1162        if ( __visit_children() ) {
1163                guard_symtab guard { *this };
1164                maybe_accept( node, &QualifiedNameExpr::type_decl );
1165        }
1166        VISIT_END( Expr, node );
1167}
1168
1169//--------------------------------------------------------------------------
1170// CastExpr
1171template< typename core_t >
1172const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1173        VISIT_START( node );
1174
1175        if ( __visit_children() ) {
1176                {
1177                        guard_symtab guard { *this };
1178                        maybe_accept( node, &CastExpr::result );
1179                }
1180                maybe_accept( node, &CastExpr::arg );
1181        }
1182
1183        VISIT_END( Expr, node );
1184}
1185
1186//--------------------------------------------------------------------------
1187// KeywordCastExpr
1188template< typename core_t >
1189const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1190        VISIT_START( node );
1191
1192        if ( __visit_children() ) {
1193                {
1194                        guard_symtab guard { *this };
1195                        maybe_accept( node, &KeywordCastExpr::result );
1196                }
1197                maybe_accept( node, &KeywordCastExpr::arg );
1198        }
1199
1200        VISIT_END( Expr, node );
1201}
1202
1203//--------------------------------------------------------------------------
1204// VirtualCastExpr
1205template< typename core_t >
1206const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1207        VISIT_START( node );
1208
1209        if ( __visit_children() ) {
1210                {
1211                        guard_symtab guard { *this };
1212                        maybe_accept( node, &VirtualCastExpr::result );
1213                }
1214                maybe_accept( node, &VirtualCastExpr::arg );
1215        }
1216
1217        VISIT_END( Expr, node );
1218}
1219
1220//--------------------------------------------------------------------------
1221// AddressExpr
1222template< typename core_t >
1223const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1224        VISIT_START( node );
1225
1226        if ( __visit_children() ) {
1227                {
1228                        guard_symtab guard { *this };
1229                        maybe_accept( node, &AddressExpr::result );
1230                }
1231                maybe_accept( node, &AddressExpr::arg );
1232        }
1233
1234        VISIT_END( Expr, node );
1235}
1236
1237//--------------------------------------------------------------------------
1238// LabelAddressExpr
1239template< typename core_t >
1240const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1241        VISIT_START( node );
1242
1243        if ( __visit_children() ) {
1244                guard_symtab guard { *this };
1245                maybe_accept( node, &LabelAddressExpr::result );
1246        }
1247
1248        VISIT_END( Expr, node );
1249}
1250
1251//--------------------------------------------------------------------------
1252// UntypedMemberExpr
1253template< typename core_t >
1254const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1255        VISIT_START( node );
1256
1257        if ( __visit_children() ) {
1258                {
1259                        guard_symtab guard { *this };
1260                        maybe_accept( node, &UntypedMemberExpr::result );
1261                }
1262                maybe_accept( node, &UntypedMemberExpr::aggregate );
1263                maybe_accept( node, &UntypedMemberExpr::member    );
1264        }
1265
1266        VISIT_END( Expr, node );
1267}
1268
1269//--------------------------------------------------------------------------
1270// MemberExpr
1271template< typename core_t >
1272const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1273        VISIT_START( node );
1274
1275        if ( __visit_children() ) {
1276                {
1277                        guard_symtab guard { *this };
1278                        maybe_accept( node, &MemberExpr::result );
1279                }
1280                maybe_accept( node, &MemberExpr::aggregate );
1281        }
1282
1283        VISIT_END( Expr, node );
1284}
1285
1286//--------------------------------------------------------------------------
1287// VariableExpr
1288template< typename core_t >
1289const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1290        VISIT_START( node );
1291
1292        if ( __visit_children() ) {
1293                guard_symtab guard { *this };
1294                maybe_accept( node, &VariableExpr::result );
1295        }
1296
1297        VISIT_END( Expr, node );
1298}
1299
1300//--------------------------------------------------------------------------
1301// ConstantExpr
1302template< typename core_t >
1303const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1304        VISIT_START( node );
1305
1306        if ( __visit_children() ) {
1307                guard_symtab guard { *this };
1308                maybe_accept( node, &ConstantExpr::result );
1309        }
1310
1311        VISIT_END( Expr, node );
1312}
1313
1314//--------------------------------------------------------------------------
1315// SizeofExpr
1316template< typename core_t >
1317const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1318        VISIT_START( node );
1319
1320        if ( __visit_children() ) {
1321                {
1322                        guard_symtab guard { *this };
1323                        maybe_accept( node, &SizeofExpr::result );
1324                }
1325                if ( node->type ) {
1326                        maybe_accept( node, &SizeofExpr::type );
1327                } else {
1328                        maybe_accept( node, &SizeofExpr::expr );
1329                }
1330        }
1331
1332        VISIT_END( Expr, node );
1333}
1334
1335//--------------------------------------------------------------------------
1336// AlignofExpr
1337template< typename core_t >
1338const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1339        VISIT_START( node );
1340
1341        if ( __visit_children() ) {
1342                {
1343                        guard_symtab guard { *this };
1344                        maybe_accept( node, &AlignofExpr::result );
1345                }
1346                if ( node->type ) {
1347                        maybe_accept( node, &AlignofExpr::type );
1348                } else {
1349                        maybe_accept( node, &AlignofExpr::expr );
1350                }
1351        }
1352
1353        VISIT_END( Expr, node );
1354}
1355
1356//--------------------------------------------------------------------------
1357// UntypedOffsetofExpr
1358template< typename core_t >
1359const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1360        VISIT_START( node );
1361
1362        if ( __visit_children() ) {
1363                {
1364                        guard_symtab guard { *this };
1365                        maybe_accept( node, &UntypedOffsetofExpr::result );
1366                }
1367                maybe_accept( node, &UntypedOffsetofExpr::type   );
1368        }
1369
1370        VISIT_END( Expr, node );
1371}
1372
1373//--------------------------------------------------------------------------
1374// OffsetofExpr
1375template< typename core_t >
1376const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1377        VISIT_START( node );
1378
1379        if ( __visit_children() ) {
1380                {
1381                        guard_symtab guard { *this };
1382                        maybe_accept( node, &OffsetofExpr::result );
1383                }
1384                maybe_accept( node, &OffsetofExpr::type   );
1385        }
1386
1387        VISIT_END( Expr, node );
1388}
1389
1390//--------------------------------------------------------------------------
1391// OffsetPackExpr
1392template< typename core_t >
1393const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1394        VISIT_START( node );
1395
1396        if ( __visit_children() ) {
1397                {
1398                        guard_symtab guard { *this };
1399                        maybe_accept( node, &OffsetPackExpr::result );
1400                }
1401                maybe_accept( node, &OffsetPackExpr::type   );
1402        }
1403
1404        VISIT_END( Expr, node );
1405}
1406
1407//--------------------------------------------------------------------------
1408// LogicalExpr
1409template< typename core_t >
1410const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1411        VISIT_START( node );
1412
1413        if ( __visit_children() ) {
1414                {
1415                        guard_symtab guard { *this };
1416                        maybe_accept( node, &LogicalExpr::result );
1417                }
1418                maybe_accept( node, &LogicalExpr::arg1 );
1419                maybe_accept( node, &LogicalExpr::arg2 );
1420        }
1421
1422        VISIT_END( Expr, node );
1423}
1424
1425//--------------------------------------------------------------------------
1426// ConditionalExpr
1427template< typename core_t >
1428const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1429        VISIT_START( node );
1430
1431        if ( __visit_children() ) {
1432                {
1433                        guard_symtab guard { *this };
1434                        maybe_accept( node, &ConditionalExpr::result );
1435                }
1436                maybe_accept( node, &ConditionalExpr::arg1 );
1437                maybe_accept( node, &ConditionalExpr::arg2 );
1438                maybe_accept( node, &ConditionalExpr::arg3 );
1439        }
1440
1441        VISIT_END( Expr, node );
1442}
1443
1444//--------------------------------------------------------------------------
1445// CommaExpr
1446template< typename core_t >
1447const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1448        VISIT_START( node );
1449
1450        if ( __visit_children() ) {
1451                {
1452                        guard_symtab guard { *this };
1453                        maybe_accept( node, &CommaExpr::result );
1454                }
1455                maybe_accept( node, &CommaExpr::arg1 );
1456                maybe_accept( node, &CommaExpr::arg2 );
1457        }
1458
1459        VISIT_END( Expr, node );
1460}
1461
1462//--------------------------------------------------------------------------
1463// TypeExpr
1464template< typename core_t >
1465const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1466        VISIT_START( node );
1467
1468        if ( __visit_children() ) {
1469                {
1470                        guard_symtab guard { *this };
1471                        maybe_accept( node, &TypeExpr::result );
1472                }
1473                maybe_accept( node, &TypeExpr::type );
1474        }
1475
1476        VISIT_END( Expr, node );
1477}
1478
1479//--------------------------------------------------------------------------
1480// DimensionExpr
1481template< typename core_t >
1482const ast::Expr * ast::Pass< core_t >::visit( const ast::DimensionExpr * node ) {
1483        VISIT_START( node );
1484
1485        if ( __visit_children() ) {
1486                guard_symtab guard { *this };
1487                maybe_accept( node, &DimensionExpr::result );
1488        }
1489
1490        VISIT_END( Expr, node );
1491}
1492
1493//--------------------------------------------------------------------------
1494// AsmExpr
1495template< typename core_t >
1496const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1497        VISIT_START( node );
1498
1499        if ( __visit_children() ) {
1500                {
1501                        guard_symtab guard { *this };
1502                        maybe_accept( node, &AsmExpr::result );
1503                }
1504                maybe_accept( node, &AsmExpr::constraint );
1505                maybe_accept( node, &AsmExpr::operand    );
1506        }
1507
1508        VISIT_END( Expr, node );
1509}
1510
1511//--------------------------------------------------------------------------
1512// ImplicitCopyCtorExpr
1513template< typename core_t >
1514const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1515        VISIT_START( node );
1516
1517        if ( __visit_children() ) {
1518                {
1519                        guard_symtab guard { *this };
1520                        maybe_accept( node, &ImplicitCopyCtorExpr::result );
1521                }
1522                maybe_accept( node, &ImplicitCopyCtorExpr::callExpr    );
1523        }
1524
1525        VISIT_END( Expr, node );
1526}
1527
1528//--------------------------------------------------------------------------
1529// ConstructorExpr
1530template< typename core_t >
1531const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1532        VISIT_START( node );
1533
1534        if ( __visit_children() ) {
1535                {
1536                        guard_symtab guard { *this };
1537                        maybe_accept( node, &ConstructorExpr::result );
1538                }
1539                maybe_accept( node, &ConstructorExpr::callExpr );
1540        }
1541
1542        VISIT_END( Expr, node );
1543}
1544
1545//--------------------------------------------------------------------------
1546// CompoundLiteralExpr
1547template< typename core_t >
1548const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1549        VISIT_START( node );
1550
1551        if ( __visit_children() ) {
1552                {
1553                        guard_symtab guard { *this };
1554                        maybe_accept( node, &CompoundLiteralExpr::result );
1555                }
1556                maybe_accept( node, &CompoundLiteralExpr::init );
1557        }
1558
1559        VISIT_END( Expr, node );
1560}
1561
1562//--------------------------------------------------------------------------
1563// RangeExpr
1564template< typename core_t >
1565const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1566        VISIT_START( node );
1567
1568        if ( __visit_children() ) {
1569                {
1570                        guard_symtab guard { *this };
1571                        maybe_accept( node, &RangeExpr::result );
1572                }
1573                maybe_accept( node, &RangeExpr::low    );
1574                maybe_accept( node, &RangeExpr::high   );
1575        }
1576
1577        VISIT_END( Expr, node );
1578}
1579
1580//--------------------------------------------------------------------------
1581// UntypedTupleExpr
1582template< typename core_t >
1583const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1584        VISIT_START( node );
1585
1586        if ( __visit_children() ) {
1587                {
1588                        guard_symtab guard { *this };
1589                        maybe_accept( node, &UntypedTupleExpr::result );
1590                }
1591                maybe_accept( node, &UntypedTupleExpr::exprs  );
1592        }
1593
1594        VISIT_END( Expr, node );
1595}
1596
1597//--------------------------------------------------------------------------
1598// TupleExpr
1599template< typename core_t >
1600const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1601        VISIT_START( node );
1602
1603        if ( __visit_children() ) {
1604                {
1605                        guard_symtab guard { *this };
1606                        maybe_accept( node, &TupleExpr::result );
1607                }
1608                maybe_accept( node, &TupleExpr::exprs  );
1609        }
1610
1611        VISIT_END( Expr, node );
1612}
1613
1614//--------------------------------------------------------------------------
1615// TupleIndexExpr
1616template< typename core_t >
1617const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1618        VISIT_START( node );
1619
1620        if ( __visit_children() ) {
1621                {
1622                        guard_symtab guard { *this };
1623                        maybe_accept( node, &TupleIndexExpr::result );
1624                }
1625                maybe_accept( node, &TupleIndexExpr::tuple  );
1626        }
1627
1628        VISIT_END( Expr, node );
1629}
1630
1631//--------------------------------------------------------------------------
1632// TupleAssignExpr
1633template< typename core_t >
1634const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1635        VISIT_START( node );
1636
1637        if ( __visit_children() ) {
1638                {
1639                        guard_symtab guard { *this };
1640                        maybe_accept( node, &TupleAssignExpr::result );
1641                }
1642                maybe_accept( node, &TupleAssignExpr::stmtExpr );
1643        }
1644
1645        VISIT_END( Expr, node );
1646}
1647
1648//--------------------------------------------------------------------------
1649// StmtExpr
1650template< typename core_t >
1651const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
1652        VISIT_START( node );
1653
1654        if ( __visit_children() ) {
1655                // don't want statements from outer CompoundStmts to be added to this StmtExpr
1656                // get the stmts that will need to be spliced in
1657                auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1658                auto stmts_after  = __pass::stmtsToAddAfter ( core, 0);
1659
1660                // These may be modified by subnode but most be restored once we exit this statemnet.
1661                ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
1662                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
1663                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
1664
1665                {
1666                        guard_symtab guard { *this };
1667                        maybe_accept( node, &StmtExpr::result );
1668                }
1669                maybe_accept( node, &StmtExpr::stmts       );
1670                maybe_accept( node, &StmtExpr::returnDecls );
1671                maybe_accept( node, &StmtExpr::dtors       );
1672        }
1673
1674        VISIT_END( Expr, node );
1675}
1676
1677//--------------------------------------------------------------------------
1678// UniqueExpr
1679template< typename core_t >
1680const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1681        VISIT_START( node );
1682
1683        if ( __visit_children() ) {
1684                {
1685                        guard_symtab guard { *this };
1686                        maybe_accept( node, &UniqueExpr::result );
1687                }
1688                maybe_accept( node, &UniqueExpr::expr   );
1689        }
1690
1691        VISIT_END( Expr, node );
1692}
1693
1694//--------------------------------------------------------------------------
1695// UntypedInitExpr
1696template< typename core_t >
1697const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1698        VISIT_START( node );
1699
1700        if ( __visit_children() ) {
1701                {
1702                        guard_symtab guard { *this };
1703                        maybe_accept( node, &UntypedInitExpr::result );
1704                }
1705                maybe_accept( node, &UntypedInitExpr::expr   );
1706                // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
1707        }
1708
1709        VISIT_END( Expr, node );
1710}
1711
1712//--------------------------------------------------------------------------
1713// InitExpr
1714template< typename core_t >
1715const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1716        VISIT_START( node );
1717
1718        if ( __visit_children() ) {
1719                {
1720                        guard_symtab guard { *this };
1721                        maybe_accept( node, &InitExpr::result );
1722                }
1723                maybe_accept( node, &InitExpr::expr   );
1724                maybe_accept( node, &InitExpr::designation );
1725        }
1726
1727        VISIT_END( Expr, node );
1728}
1729
1730//--------------------------------------------------------------------------
1731// DeletedExpr
1732template< typename core_t >
1733const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1734        VISIT_START( node );
1735
1736        if ( __visit_children() ) {
1737                {
1738                        guard_symtab guard { *this };
1739                        maybe_accept( node, &DeletedExpr::result );
1740                }
1741                maybe_accept( node, &DeletedExpr::expr );
1742                // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
1743        }
1744
1745        VISIT_END( Expr, node );
1746}
1747
1748//--------------------------------------------------------------------------
1749// DefaultArgExpr
1750template< typename core_t >
1751const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1752        VISIT_START( node );
1753
1754        if ( __visit_children() ) {
1755                {
1756                        guard_symtab guard { *this };
1757                        maybe_accept( node, &DefaultArgExpr::result );
1758                }
1759                maybe_accept( node, &DefaultArgExpr::expr );
1760        }
1761
1762        VISIT_END( Expr, node );
1763}
1764
1765//--------------------------------------------------------------------------
1766// GenericExpr
1767template< typename core_t >
1768const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1769        VISIT_START( node );
1770
1771        if ( __visit_children() ) {
1772                {
1773                        guard_symtab guard { *this };
1774                        maybe_accept( node, &GenericExpr::result );
1775                }
1776                maybe_accept( node, &GenericExpr::control );
1777
1778                std::vector<GenericExpr::Association> new_kids;
1779                new_kids.reserve(node->associations.size());
1780                bool mutated = false;
1781                for( const auto & assoc : node->associations ) {
1782                        const Type * type = nullptr;
1783                        if( assoc.type ) {
1784                                guard_symtab guard { *this };
1785                                type = assoc.type->accept( *this );
1786                                if( type != assoc.type ) mutated = true;
1787                        }
1788                        const Expr * expr = nullptr;
1789                        if( assoc.expr ) {
1790                                expr = assoc.expr->accept( *this );
1791                                if( expr != assoc.expr ) mutated = true;
1792                        }
1793                        new_kids.emplace_back( type, expr );
1794                }
1795
1796                if(mutated) {
1797                        auto n = __pass::mutate<core_t>(node);
1798                        n->associations = std::move( new_kids );
1799                        node = n;
1800                }
1801        }
1802
1803        VISIT_END( Expr, node );
1804}
1805
1806//--------------------------------------------------------------------------
1807// VoidType
1808template< typename core_t >
1809const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1810        VISIT_START( node );
1811
1812        VISIT_END( Type, node );
1813}
1814
1815//--------------------------------------------------------------------------
1816// BasicType
1817template< typename core_t >
1818const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1819        VISIT_START( node );
1820
1821        VISIT_END( Type, node );
1822}
1823
1824//--------------------------------------------------------------------------
1825// PointerType
1826template< typename core_t >
1827const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
1828        VISIT_START( node );
1829
1830        if ( __visit_children() ) {
1831                maybe_accept( node, &PointerType::dimension );
1832                maybe_accept( node, &PointerType::base );
1833        }
1834
1835        VISIT_END( Type, node );
1836}
1837
1838//--------------------------------------------------------------------------
1839// ArrayType
1840template< typename core_t >
1841const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
1842        VISIT_START( node );
1843
1844        if ( __visit_children() ) {
1845                maybe_accept( node, &ArrayType::dimension );
1846                maybe_accept( node, &ArrayType::base );
1847        }
1848
1849        VISIT_END( Type, node );
1850}
1851
1852//--------------------------------------------------------------------------
1853// ReferenceType
1854template< typename core_t >
1855const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
1856        VISIT_START( node );
1857
1858        if ( __visit_children() ) {
1859                maybe_accept( node, &ReferenceType::base );
1860        }
1861
1862        VISIT_END( Type, node );
1863}
1864
1865//--------------------------------------------------------------------------
1866// QualifiedType
1867template< typename core_t >
1868const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
1869        VISIT_START( node );
1870
1871        if ( __visit_children() ) {
1872                maybe_accept( node, &QualifiedType::parent );
1873                maybe_accept( node, &QualifiedType::child );
1874        }
1875
1876        VISIT_END( Type, node );
1877}
1878
1879//--------------------------------------------------------------------------
1880// FunctionType
1881template< typename core_t >
1882const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1883        VISIT_START( node );
1884
1885        if ( __visit_children() ) {
1886                // guard_forall_subs forall_guard { *this, node };
1887                // mutate_forall( node );
1888                maybe_accept( node, &FunctionType::assertions );
1889                maybe_accept( node, &FunctionType::returns );
1890                maybe_accept( node, &FunctionType::params  );
1891        }
1892
1893        VISIT_END( Type, node );
1894}
1895
1896//--------------------------------------------------------------------------
1897// StructInstType
1898template< typename core_t >
1899const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1900        VISIT_START( node );
1901
1902        __pass::symtab::addStructId( core, 0, node->name );
1903
1904        if ( __visit_children() ) {
1905                guard_symtab guard { *this };
1906                maybe_accept( node, &StructInstType::params );
1907        }
1908
1909        VISIT_END( Type, node );
1910}
1911
1912//--------------------------------------------------------------------------
1913// UnionInstType
1914template< typename core_t >
1915const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
1916        VISIT_START( node );
1917
1918        __pass::symtab::addUnionId( core, 0, node->name );
1919
1920        if ( __visit_children() ) {
1921                guard_symtab guard { *this };
1922                maybe_accept( node, &UnionInstType::params );
1923        }
1924
1925        VISIT_END( Type, node );
1926}
1927
1928//--------------------------------------------------------------------------
1929// EnumInstType
1930template< typename core_t >
1931const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
1932        VISIT_START( node );
1933
1934        if ( __visit_children() ) {
1935                maybe_accept( node, &EnumInstType::params );
1936        }
1937
1938        VISIT_END( Type, node );
1939}
1940
1941//--------------------------------------------------------------------------
1942// EnumAttrType
1943template< typename core_t >
1944const ast::Type * ast::Pass< core_t >::visit( const ast::EnumAttrType * node ) {
1945        VISIT_START( node );
1946        VISIT_END( Type, node );
1947}
1948
1949//--------------------------------------------------------------------------
1950// TraitInstType
1951template< typename core_t >
1952const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
1953        VISIT_START( node );
1954
1955        if ( __visit_children() ) {
1956                maybe_accept( node, &TraitInstType::params );
1957        }
1958
1959        VISIT_END( Type, node );
1960}
1961
1962//--------------------------------------------------------------------------
1963// TypeInstType
1964template< typename core_t >
1965const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
1966        VISIT_START( node );
1967
1968        if ( __visit_children() ) {
1969                {
1970                        maybe_accept( node, &TypeInstType::params );
1971                }
1972                // ensure that base re-bound if doing substitution
1973                __pass::forall::replace( core, 0, node );
1974        }
1975
1976        VISIT_END( Type, node );
1977}
1978
1979//--------------------------------------------------------------------------
1980// TupleType
1981template< typename core_t >
1982const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
1983        VISIT_START( node );
1984
1985        if ( __visit_children() ) {
1986                maybe_accept( node, &TupleType::types );
1987        }
1988
1989        VISIT_END( Type, node );
1990}
1991
1992//--------------------------------------------------------------------------
1993// TypeofType
1994template< typename core_t >
1995const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
1996        VISIT_START( node );
1997
1998        if ( __visit_children() ) {
1999                maybe_accept( node, &TypeofType::expr );
2000        }
2001
2002        VISIT_END( Type, node );
2003}
2004
2005//--------------------------------------------------------------------------
2006// VTableType
2007template< typename core_t >
2008const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
2009        VISIT_START( node );
2010
2011        if ( __visit_children() ) {
2012                maybe_accept( node, &VTableType::base );
2013        }
2014
2015        VISIT_END( Type, node );
2016}
2017
2018//--------------------------------------------------------------------------
2019// VarArgsType
2020template< typename core_t >
2021const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
2022        VISIT_START( node );
2023
2024        VISIT_END( Type, node );
2025}
2026
2027//--------------------------------------------------------------------------
2028// ZeroType
2029template< typename core_t >
2030const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
2031        VISIT_START( node );
2032
2033        VISIT_END( Type, node );
2034}
2035
2036//--------------------------------------------------------------------------
2037// OneType
2038template< typename core_t >
2039const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
2040        VISIT_START( node );
2041
2042        VISIT_END( Type, node );
2043}
2044
2045//--------------------------------------------------------------------------
2046// GlobalScopeType
2047template< typename core_t >
2048const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
2049        VISIT_START( node );
2050
2051        VISIT_END( Type, node );
2052}
2053
2054
2055//--------------------------------------------------------------------------
2056// Designation
2057template< typename core_t >
2058const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
2059        VISIT_START( node );
2060
2061        if ( __visit_children() ) {
2062                maybe_accept( node, &Designation::designators );
2063        }
2064
2065        VISIT_END( Designation, node );
2066}
2067
2068//--------------------------------------------------------------------------
2069// SingleInit
2070template< typename core_t >
2071const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
2072        VISIT_START( node );
2073
2074        if ( __visit_children() ) {
2075                maybe_accept_top( node, &SingleInit::value );
2076        }
2077
2078        VISIT_END( Init, node );
2079}
2080
2081//--------------------------------------------------------------------------
2082// ListInit
2083template< typename core_t >
2084const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
2085        VISIT_START( node );
2086
2087        if ( __visit_children() ) {
2088                maybe_accept( node, &ListInit::designations );
2089                maybe_accept( node, &ListInit::initializers );
2090        }
2091
2092        VISIT_END( Init, node );
2093}
2094
2095//--------------------------------------------------------------------------
2096// ConstructorInit
2097template< typename core_t >
2098const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
2099        VISIT_START( node );
2100
2101        if ( __visit_children() ) {
2102                maybe_accept( node, &ConstructorInit::ctor );
2103                maybe_accept( node, &ConstructorInit::dtor );
2104                maybe_accept( node, &ConstructorInit::init );
2105        }
2106
2107        VISIT_END( Init, node );
2108}
2109
2110//--------------------------------------------------------------------------
2111// Attribute
2112template< typename core_t >
2113const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node  )  {
2114        VISIT_START( node );
2115
2116        if ( __visit_children() ) {
2117                maybe_accept( node, &Attribute::params );
2118        }
2119
2120        VISIT_END( Attribute, node );
2121}
2122
2123//--------------------------------------------------------------------------
2124// TypeSubstitution
2125template< typename core_t >
2126const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
2127        VISIT_START( node );
2128
2129        if ( __visit_children() ) {
2130                bool mutated = false;
2131                ast::TypeSubstitution::TypeMap new_map;
2132                for ( const auto & p : node->typeMap ) {
2133                        guard_symtab guard { *this };
2134                        auto new_node = p.second->accept( *this );
2135                        if (new_node != p.second) mutated = true;
2136                        new_map.insert({ p.first, new_node });
2137                }
2138                if (mutated) {
2139                        auto new_node = __pass::mutate<core_t>( node );
2140                        new_node->typeMap.swap( new_map );
2141                        node = new_node;
2142                }
2143        }
2144
2145        VISIT_END( TypeSubstitution, node );
2146}
2147
2148#undef __pedantic_pass_assertf
2149#undef __pedantic_pass_assert
2150#undef VISIT_START
2151#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.