source: src/AST/Pass.impl.hpp @ f5dbc8d

Last change on this file since f5dbc8d was b6f2e7ab, checked in by Andrew Beach <ajbeach@…>, 5 weeks ago

Removed SizeofExpr::expr and AlignofExpr::expr, expressions that would be stored there are wrapped in TypeofType? and stored in the type field. Some special cases to hide the typeof in code generation were added. In addition, initializer length is calculated in more cases so that the full type of more arrays is known sooner. Other than that, most of the code changes were just stripping out the conditional code and checks no longer needed. Some tests had to be updated, because the typeof is not hidden in dumps and the resolver replaces known typeof expressions with the type. The extension case caused some concern but it appears that just hides warnings in the expression which no longer exists.

  • 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 guard0 = __pass::make_location_guard( core, node, 0 ); \
30        /* back-up the visit children */ \
31        __attribute__((unused)) auto guard1 = __pass::make_visit_children_guard( core, 0 ); \
32        /* setup the scope for passes that want to run code at exit */ \
33        __attribute__((unused)) auto guard2 = __pass::make_value_guard( 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::BasicKind::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                maybe_accept( node, &EnumDecl::base        );
563                maybe_accept( node, &EnumDecl::params      );
564                maybe_accept( node, &EnumDecl::members     );
565                maybe_accept( node, &EnumDecl::attributes  );
566                maybe_accept( node, &EnumDecl::inlinedDecl );
567        }
568
569        VISIT_END( Decl, node );
570}
571
572//--------------------------------------------------------------------------
573// TraitDecl
574template< typename core_t >
575const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
576        VISIT_START( node );
577
578        if ( __visit_children() ) {
579                guard_symtab guard { *this };
580                maybe_accept( node, &TraitDecl::params     );
581                maybe_accept( node, &TraitDecl::members    );
582                maybe_accept( node, &TraitDecl::attributes );
583        }
584
585        __pass::symtab::addTrait( core, 0, node );
586
587        VISIT_END( Decl, node );
588}
589
590//--------------------------------------------------------------------------
591// TypeDecl
592template< typename core_t >
593const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
594        VISIT_START( node );
595
596        if ( __visit_children() ) {
597                guard_symtab guard { *this };
598                maybe_accept( node, &TypeDecl::base   );
599        }
600
601        // see A NOTE ON THE ORDER OF TRAVERSAL, above
602        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
603        // and may depend on the type itself
604        __pass::symtab::addType( core, 0, node );
605
606        if ( __visit_children() ) {
607                maybe_accept( node, &TypeDecl::assertions );
608
609                {
610                        guard_symtab guard { *this };
611                        maybe_accept( node, &TypeDecl::init );
612                }
613        }
614
615        VISIT_END( Decl, node );
616}
617
618//--------------------------------------------------------------------------
619// TypedefDecl
620template< typename core_t >
621const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
622        VISIT_START( node );
623
624        if ( __visit_children() ) {
625                guard_symtab guard { *this };
626                maybe_accept( node, &TypedefDecl::base   );
627        }
628
629        __pass::symtab::addType( core, 0, node );
630
631        if ( __visit_children() ) {
632                maybe_accept( node, &TypedefDecl::assertions );
633        }
634
635        VISIT_END( Decl, node );
636}
637
638//--------------------------------------------------------------------------
639// AsmDecl
640template< typename core_t >
641const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
642        VISIT_START( node );
643
644        if ( __visit_children() ) {
645                maybe_accept( node, &AsmDecl::stmt );
646        }
647
648        VISIT_END( AsmDecl, node );
649}
650
651//--------------------------------------------------------------------------
652// DirectiveDecl
653template< typename core_t >
654const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) {
655        VISIT_START( node );
656
657        if ( __visit_children() ) {
658                maybe_accept( node, &DirectiveDecl::stmt );
659        }
660
661        VISIT_END( DirectiveDecl, node );
662}
663
664//--------------------------------------------------------------------------
665// StaticAssertDecl
666template< typename core_t >
667const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
668        VISIT_START( node );
669
670        if ( __visit_children() ) {
671                maybe_accept_top( node, &StaticAssertDecl::cond );
672                maybe_accept( node, &StaticAssertDecl::msg  );
673        }
674
675        VISIT_END( StaticAssertDecl, node );
676}
677
678//--------------------------------------------------------------------------
679// InlineMemberDecl
680template< typename core_t >
681const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) {
682        VISIT_START( node );
683
684        if ( __visit_children() ) {
685                {
686                        guard_symtab guard { *this };
687                        maybe_accept( node, &InlineMemberDecl::type );
688                }
689        }
690
691        VISIT_END( DeclWithType, node );
692}
693
694//--------------------------------------------------------------------------
695// CompoundStmt
696template< typename core_t >
697const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
698        VISIT_START( node );
699
700        if ( __visit_children() ) {
701                // Do not enter (or leave) a new symbol table scope if atFunctionTop.
702                // But always enter (and leave) a new general scope.
703                if ( atFunctionTop ) {
704                        ValueGuard< bool > guard1( atFunctionTop );
705                        atFunctionTop = false;
706                        guard_scope guard2( *this );
707                        maybe_accept( node, &CompoundStmt::kids );
708                } else {
709                        guard_symtab guard1( *this );
710                        guard_scope guard2( *this );
711                        maybe_accept( node, &CompoundStmt::kids );
712                }
713        }
714
715        VISIT_END( CompoundStmt, node );
716}
717
718//--------------------------------------------------------------------------
719// ExprStmt
720template< typename core_t >
721const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
722        VISIT_START( node );
723
724        if ( __visit_children() ) {
725                maybe_accept_top( node, &ExprStmt::expr );
726        }
727
728        VISIT_END( Stmt, node );
729}
730
731//--------------------------------------------------------------------------
732// AsmStmt
733template< typename core_t >
734const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
735        VISIT_START( node )
736
737        if ( __visit_children() ) {
738                maybe_accept( node, &AsmStmt::instruction );
739                maybe_accept( node, &AsmStmt::output      );
740                maybe_accept( node, &AsmStmt::input       );
741                maybe_accept( node, &AsmStmt::clobber     );
742        }
743
744        VISIT_END( Stmt, node );
745}
746
747//--------------------------------------------------------------------------
748// DirectiveStmt
749template< typename core_t >
750const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
751        VISIT_START( node )
752
753        VISIT_END( Stmt, node );
754}
755
756//--------------------------------------------------------------------------
757// IfStmt
758template< typename core_t >
759const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
760        VISIT_START( node );
761
762        if ( __visit_children() ) {
763                // if statements introduce a level of scope (for the initialization)
764                guard_symtab guard { *this };
765                maybe_accept( node, &IfStmt::inits    );
766                maybe_accept_top( node, &IfStmt::cond     );
767                maybe_accept_as_compound( node, &IfStmt::then );
768                maybe_accept_as_compound( node, &IfStmt::else_ );
769        }
770
771        VISIT_END( Stmt, node );
772}
773
774//--------------------------------------------------------------------------
775// WhileDoStmt
776template< typename core_t >
777const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileDoStmt * node ) {
778        VISIT_START( node );
779
780        if ( __visit_children() ) {
781                // while statements introduce a level of scope (for the initialization)
782                guard_symtab guard { *this };
783                maybe_accept( node, &WhileDoStmt::inits );
784                maybe_accept_top( node, &WhileDoStmt::cond  );
785                maybe_accept_as_compound( node, &WhileDoStmt::body  );
786                maybe_accept_as_compound( node, &WhileDoStmt::else_ );
787        }
788
789        VISIT_END( Stmt, node );
790}
791
792//--------------------------------------------------------------------------
793// ForStmt
794template< typename core_t >
795const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
796        VISIT_START( node );
797
798        if ( __visit_children() ) {
799                // for statements introduce a level of scope (for the initialization)
800                guard_symtab guard { *this };
801                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
802                maybe_accept( node, &ForStmt::inits );
803                maybe_accept_top( node, &ForStmt::cond  );
804                maybe_accept_top( node, &ForStmt::inc   );
805                maybe_accept_top( node, &ForStmt::range_over );
806                maybe_accept_as_compound( node, &ForStmt::body  );
807                maybe_accept_as_compound( node, &ForStmt::else_ );
808        }
809
810        VISIT_END( Stmt, node );
811}
812
813//--------------------------------------------------------------------------
814// SwitchStmt
815template< typename core_t >
816const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
817        VISIT_START( node );
818
819        if ( __visit_children() ) {
820                maybe_accept_top( node, &SwitchStmt::cond  );
821                maybe_accept( node, &SwitchStmt::cases );
822        }
823
824        VISIT_END( Stmt, node );
825}
826
827//--------------------------------------------------------------------------
828// CaseClause
829template< typename core_t >
830const ast::CaseClause * ast::Pass< core_t >::visit( const ast::CaseClause * node ) {
831        VISIT_START( node );
832
833        if ( __visit_children() ) {
834                maybe_accept_top( node, &CaseClause::cond  );
835                maybe_accept( node, &CaseClause::stmts );
836        }
837
838        VISIT_END( CaseClause, node );
839}
840
841//--------------------------------------------------------------------------
842// BranchStmt
843template< typename core_t >
844const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
845        VISIT_START( node );
846        VISIT_END( Stmt, node );
847}
848
849//--------------------------------------------------------------------------
850// ReturnStmt
851template< typename core_t >
852const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
853        VISIT_START( node );
854
855        if ( __visit_children() ) {
856                maybe_accept_top( node, &ReturnStmt::expr );
857        }
858
859        VISIT_END( Stmt, node );
860}
861
862//--------------------------------------------------------------------------
863// ThrowStmt
864template< typename core_t >
865const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
866        VISIT_START( node );
867
868        if ( __visit_children() ) {
869                maybe_accept( node, &ThrowStmt::expr   );
870                maybe_accept( node, &ThrowStmt::target );
871        }
872
873        VISIT_END( Stmt, node );
874}
875
876//--------------------------------------------------------------------------
877// TryStmt
878template< typename core_t >
879const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
880        VISIT_START( node );
881
882        if ( __visit_children() ) {
883                maybe_accept( node, &TryStmt::body     );
884                maybe_accept( node, &TryStmt::handlers );
885                maybe_accept( node, &TryStmt::finally  );
886        }
887
888        VISIT_END( Stmt, node );
889}
890
891//--------------------------------------------------------------------------
892// CatchClause
893template< typename core_t >
894const ast::CatchClause * ast::Pass< core_t >::visit( const ast::CatchClause * node ) {
895        VISIT_START( node );
896
897        if ( __visit_children() ) {
898                // catch statements introduce a level of scope (for the caught exception)
899                guard_symtab guard { *this };
900                maybe_accept( node, &CatchClause::decl );
901                maybe_accept_top( node, &CatchClause::cond );
902                maybe_accept_as_compound( node, &CatchClause::body );
903        }
904
905        VISIT_END( CatchClause, node );
906}
907
908//--------------------------------------------------------------------------
909// FinallyClause
910template< typename core_t >
911const ast::FinallyClause * ast::Pass< core_t >::visit( const ast::FinallyClause * node ) {
912        VISIT_START( node );
913
914        if ( __visit_children() ) {
915                maybe_accept( node, &FinallyClause::body );
916        }
917
918        VISIT_END( FinallyClause, node );
919}
920
921//--------------------------------------------------------------------------
922// FinallyStmt
923template< typename core_t >
924const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
925        VISIT_START( node );
926
927        if ( __visit_children() ) {
928                maybe_accept( node, &SuspendStmt::then   );
929        }
930
931        VISIT_END( Stmt, node );
932}
933
934//--------------------------------------------------------------------------
935// WhenClause
936template< typename core_t >
937const ast::WhenClause * ast::Pass< core_t >::visit( const ast::WhenClause * node ) {
938        VISIT_START( node );
939
940        if ( __visit_children() ) {
941                maybe_accept( node, &WhenClause::target );
942                maybe_accept( node, &WhenClause::stmt );
943                maybe_accept( node, &WhenClause::when_cond );
944        }
945
946        VISIT_END( WhenClause, node );
947}
948
949//--------------------------------------------------------------------------
950// WaitForStmt
951template< typename core_t >
952const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
953        VISIT_START( node );
954
955        if ( __visit_children() ) {
956                maybe_accept( node, &WaitForStmt::clauses );
957                maybe_accept( node, &WaitForStmt::timeout_time );
958                maybe_accept( node, &WaitForStmt::timeout_stmt );
959                maybe_accept( node, &WaitForStmt::timeout_cond );
960                maybe_accept( node, &WaitForStmt::else_stmt );
961                maybe_accept( node, &WaitForStmt::else_cond );
962        }
963
964        VISIT_END( Stmt, node );
965}
966
967//--------------------------------------------------------------------------
968// WaitForClause
969template< typename core_t >
970const ast::WaitForClause * ast::Pass< core_t >::visit( const ast::WaitForClause * node ) {
971        VISIT_START( node );
972
973        if ( __visit_children() ) {
974                maybe_accept( node, &WaitForClause::target );
975                maybe_accept( node, &WaitForClause::target_args );
976                maybe_accept( node, &WaitForClause::stmt );
977                maybe_accept( node, &WaitForClause::when_cond );
978        }
979
980        VISIT_END( WaitForClause, node );
981}
982
983//--------------------------------------------------------------------------
984// WaitUntilStmt
985template< typename core_t >
986const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitUntilStmt * node ) {
987        VISIT_START( node );
988
989        if ( __visit_children() ) {
990                maybe_accept( node, &WaitUntilStmt::clauses );
991                maybe_accept( node, &WaitUntilStmt::timeout_time );
992                maybe_accept( node, &WaitUntilStmt::timeout_stmt );
993                maybe_accept( node, &WaitUntilStmt::timeout_cond );
994                maybe_accept( node, &WaitUntilStmt::else_stmt );
995                maybe_accept( node, &WaitUntilStmt::else_cond );
996        }
997
998        VISIT_END( Stmt, node );
999}
1000
1001//--------------------------------------------------------------------------
1002// WithStmt
1003template< typename core_t >
1004const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
1005        VISIT_START( node );
1006
1007        if ( __visit_children() ) {
1008                maybe_accept( node, &WithStmt::exprs );
1009                {
1010                        // catch statements introduce a level of scope (for the caught exception)
1011                        guard_symtab guard { *this };
1012                        __pass::symtab::addWith( core, 0, node->exprs, node );
1013                        maybe_accept( node, &WithStmt::stmt );
1014                }
1015        }
1016
1017        VISIT_END( Stmt, node );
1018}
1019
1020//--------------------------------------------------------------------------
1021// NullStmt
1022template< typename core_t >
1023const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
1024        VISIT_START( node );
1025        VISIT_END( NullStmt, node );
1026}
1027
1028//--------------------------------------------------------------------------
1029// DeclStmt
1030template< typename core_t >
1031const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
1032        VISIT_START( node );
1033
1034        if ( __visit_children() ) {
1035                maybe_accept( node, &DeclStmt::decl );
1036        }
1037
1038        VISIT_END( Stmt, node );
1039}
1040
1041//--------------------------------------------------------------------------
1042// ImplicitCtorDtorStmt
1043template< typename core_t >
1044const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
1045        VISIT_START( node );
1046
1047        // For now this isn't visited, it is unclear if this causes problem
1048        // if all tests are known to pass, remove this code
1049        if ( __visit_children() ) {
1050                maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
1051        }
1052
1053        VISIT_END( Stmt, node );
1054}
1055
1056//--------------------------------------------------------------------------
1057// MutexStmt
1058template< typename core_t >
1059const ast::Stmt * ast::Pass< core_t >::visit( const ast::MutexStmt * node ) {
1060        VISIT_START( node );
1061
1062        if ( __visit_children() ) {
1063                // mutex statements introduce a level of scope (for the initialization)
1064                guard_symtab guard { *this };
1065                maybe_accept( node, &MutexStmt::stmt );
1066                maybe_accept( node, &MutexStmt::mutexObjs );
1067        }
1068
1069        VISIT_END( Stmt, node );
1070}
1071
1072//--------------------------------------------------------------------------
1073// CorunStmt
1074template< typename core_t >
1075const ast::Stmt * ast::Pass< core_t >::visit( const ast::CorunStmt * node ) {
1076        VISIT_START( node );
1077
1078        if ( __visit_children() ) {
1079                maybe_accept( node, &CorunStmt::stmt );
1080        }
1081
1082        VISIT_END( Stmt, node );
1083}
1084
1085//--------------------------------------------------------------------------
1086// CoforStmt
1087template< typename core_t >
1088const ast::Stmt * ast::Pass< core_t >::visit( const ast::CoforStmt * node ) {
1089        VISIT_START( node );
1090
1091        if ( __visit_children() ) {
1092                // for statements introduce a level of scope (for the initialization)
1093                guard_symtab guard { *this };
1094                maybe_accept( node, &CoforStmt::inits );
1095                maybe_accept_top( node, &CoforStmt::cond  );
1096                maybe_accept_top( node, &CoforStmt::inc   );
1097                maybe_accept_as_compound( node, &CoforStmt::body  );
1098        }
1099
1100        VISIT_END( Stmt, node );
1101}
1102
1103//--------------------------------------------------------------------------
1104// ApplicationExpr
1105template< typename core_t >
1106const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
1107        VISIT_START( node );
1108
1109        if ( __visit_children() ) {
1110                {
1111                        guard_symtab guard { *this };
1112                        maybe_accept( node, &ApplicationExpr::result );
1113                }
1114                maybe_accept( node, &ApplicationExpr::func );
1115                maybe_accept( node, &ApplicationExpr::args );
1116        }
1117
1118        VISIT_END( Expr, node );
1119}
1120
1121//--------------------------------------------------------------------------
1122// UntypedExpr
1123template< typename core_t >
1124const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1125        VISIT_START( node );
1126
1127        if ( __visit_children() ) {
1128                {
1129                        guard_symtab guard { *this };
1130                        maybe_accept( node, &UntypedExpr::result );
1131                }
1132
1133                maybe_accept( node, &UntypedExpr::args );
1134        }
1135
1136        VISIT_END( Expr, node );
1137}
1138
1139//--------------------------------------------------------------------------
1140// NameExpr
1141template< typename core_t >
1142const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1143        VISIT_START( node );
1144
1145        if ( __visit_children() ) {
1146                guard_symtab guard { *this };
1147                maybe_accept( node, &NameExpr::result );
1148        }
1149
1150        VISIT_END( Expr, node );
1151}
1152
1153//--------------------------------------------------------------------------
1154// QualifiedNameExpr
1155template< typename core_t >
1156const ast::Expr * ast::Pass< core_t >::visit( const ast::QualifiedNameExpr * node ) {
1157        VISIT_START( node );
1158        if ( __visit_children() ) {
1159                guard_symtab guard { *this };
1160                maybe_accept( node, &QualifiedNameExpr::type_decl );
1161        }
1162        VISIT_END( Expr, node );
1163}
1164
1165//--------------------------------------------------------------------------
1166// CastExpr
1167template< typename core_t >
1168const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1169        VISIT_START( node );
1170
1171        if ( __visit_children() ) {
1172                {
1173                        guard_symtab guard { *this };
1174                        maybe_accept( node, &CastExpr::result );
1175                }
1176                maybe_accept( node, &CastExpr::arg );
1177        }
1178
1179        VISIT_END( Expr, node );
1180}
1181
1182//--------------------------------------------------------------------------
1183// KeywordCastExpr
1184template< typename core_t >
1185const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1186        VISIT_START( node );
1187
1188        if ( __visit_children() ) {
1189                {
1190                        guard_symtab guard { *this };
1191                        maybe_accept( node, &KeywordCastExpr::result );
1192                }
1193                maybe_accept( node, &KeywordCastExpr::arg );
1194        }
1195
1196        VISIT_END( Expr, node );
1197}
1198
1199//--------------------------------------------------------------------------
1200// VirtualCastExpr
1201template< typename core_t >
1202const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1203        VISIT_START( node );
1204
1205        if ( __visit_children() ) {
1206                {
1207                        guard_symtab guard { *this };
1208                        maybe_accept( node, &VirtualCastExpr::result );
1209                }
1210                maybe_accept( node, &VirtualCastExpr::arg );
1211        }
1212
1213        VISIT_END( Expr, node );
1214}
1215
1216//--------------------------------------------------------------------------
1217// AddressExpr
1218template< typename core_t >
1219const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1220        VISIT_START( node );
1221
1222        if ( __visit_children() ) {
1223                {
1224                        guard_symtab guard { *this };
1225                        maybe_accept( node, &AddressExpr::result );
1226                }
1227                maybe_accept( node, &AddressExpr::arg );
1228        }
1229
1230        VISIT_END( Expr, node );
1231}
1232
1233//--------------------------------------------------------------------------
1234// LabelAddressExpr
1235template< typename core_t >
1236const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1237        VISIT_START( node );
1238
1239        if ( __visit_children() ) {
1240                guard_symtab guard { *this };
1241                maybe_accept( node, &LabelAddressExpr::result );
1242        }
1243
1244        VISIT_END( Expr, node );
1245}
1246
1247//--------------------------------------------------------------------------
1248// UntypedMemberExpr
1249template< typename core_t >
1250const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1251        VISIT_START( node );
1252
1253        if ( __visit_children() ) {
1254                {
1255                        guard_symtab guard { *this };
1256                        maybe_accept( node, &UntypedMemberExpr::result );
1257                }
1258                maybe_accept( node, &UntypedMemberExpr::aggregate );
1259                maybe_accept( node, &UntypedMemberExpr::member    );
1260        }
1261
1262        VISIT_END( Expr, node );
1263}
1264
1265//--------------------------------------------------------------------------
1266// MemberExpr
1267template< typename core_t >
1268const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1269        VISIT_START( node );
1270
1271        if ( __visit_children() ) {
1272                {
1273                        guard_symtab guard { *this };
1274                        maybe_accept( node, &MemberExpr::result );
1275                }
1276                maybe_accept( node, &MemberExpr::aggregate );
1277        }
1278
1279        VISIT_END( Expr, node );
1280}
1281
1282//--------------------------------------------------------------------------
1283// VariableExpr
1284template< typename core_t >
1285const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1286        VISIT_START( node );
1287
1288        if ( __visit_children() ) {
1289                guard_symtab guard { *this };
1290                maybe_accept( node, &VariableExpr::result );
1291        }
1292
1293        VISIT_END( Expr, node );
1294}
1295
1296//--------------------------------------------------------------------------
1297// ConstantExpr
1298template< typename core_t >
1299const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1300        VISIT_START( node );
1301
1302        if ( __visit_children() ) {
1303                guard_symtab guard { *this };
1304                maybe_accept( node, &ConstantExpr::result );
1305        }
1306
1307        VISIT_END( Expr, node );
1308}
1309
1310//--------------------------------------------------------------------------
1311// SizeofExpr
1312template< typename core_t >
1313const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1314        VISIT_START( node );
1315
1316        if ( __visit_children() ) {
1317                {
1318                        guard_symtab guard { *this };
1319                        maybe_accept( node, &SizeofExpr::result );
1320                }
1321                maybe_accept( node, &SizeofExpr::type );
1322        }
1323
1324        VISIT_END( Expr, node );
1325}
1326
1327//--------------------------------------------------------------------------
1328// CountExpr
1329template< typename core_t >
1330const ast::Expr * ast::Pass< core_t >::visit( const ast::CountExpr * node ) {
1331        VISIT_START( node );
1332        if ( __visit_children() ) {
1333                {
1334                        guard_symtab guard { *this };
1335                        maybe_accept( node, &CountExpr::result );
1336                }
1337                if ( node->type ) {
1338                        maybe_accept( node, &CountExpr::type );
1339                } else {
1340                        maybe_accept( node, &CountExpr::expr );
1341                }
1342        }
1343        VISIT_END( Expr, node );
1344}
1345
1346//--------------------------------------------------------------------------
1347// AlignofExpr
1348template< typename core_t >
1349const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1350        VISIT_START( node );
1351
1352        if ( __visit_children() ) {
1353                {
1354                        guard_symtab guard { *this };
1355                        maybe_accept( node, &AlignofExpr::result );
1356                }
1357                maybe_accept( node, &AlignofExpr::type );
1358        }
1359
1360        VISIT_END( Expr, node );
1361}
1362
1363//--------------------------------------------------------------------------
1364// UntypedOffsetofExpr
1365template< typename core_t >
1366const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1367        VISIT_START( node );
1368
1369        if ( __visit_children() ) {
1370                {
1371                        guard_symtab guard { *this };
1372                        maybe_accept( node, &UntypedOffsetofExpr::result );
1373                }
1374                maybe_accept( node, &UntypedOffsetofExpr::type   );
1375        }
1376
1377        VISIT_END( Expr, node );
1378}
1379
1380//--------------------------------------------------------------------------
1381// OffsetofExpr
1382template< typename core_t >
1383const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1384        VISIT_START( node );
1385
1386        if ( __visit_children() ) {
1387                {
1388                        guard_symtab guard { *this };
1389                        maybe_accept( node, &OffsetofExpr::result );
1390                }
1391                maybe_accept( node, &OffsetofExpr::type   );
1392        }
1393
1394        VISIT_END( Expr, node );
1395}
1396
1397//--------------------------------------------------------------------------
1398// OffsetPackExpr
1399template< typename core_t >
1400const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1401        VISIT_START( node );
1402
1403        if ( __visit_children() ) {
1404                {
1405                        guard_symtab guard { *this };
1406                        maybe_accept( node, &OffsetPackExpr::result );
1407                }
1408                maybe_accept( node, &OffsetPackExpr::type   );
1409        }
1410
1411        VISIT_END( Expr, node );
1412}
1413
1414//--------------------------------------------------------------------------
1415// LogicalExpr
1416template< typename core_t >
1417const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1418        VISIT_START( node );
1419
1420        if ( __visit_children() ) {
1421                {
1422                        guard_symtab guard { *this };
1423                        maybe_accept( node, &LogicalExpr::result );
1424                }
1425                maybe_accept( node, &LogicalExpr::arg1 );
1426                maybe_accept( node, &LogicalExpr::arg2 );
1427        }
1428
1429        VISIT_END( Expr, node );
1430}
1431
1432//--------------------------------------------------------------------------
1433// ConditionalExpr
1434template< typename core_t >
1435const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1436        VISIT_START( node );
1437
1438        if ( __visit_children() ) {
1439                {
1440                        guard_symtab guard { *this };
1441                        maybe_accept( node, &ConditionalExpr::result );
1442                }
1443                maybe_accept( node, &ConditionalExpr::arg1 );
1444                maybe_accept( node, &ConditionalExpr::arg2 );
1445                maybe_accept( node, &ConditionalExpr::arg3 );
1446        }
1447
1448        VISIT_END( Expr, node );
1449}
1450
1451//--------------------------------------------------------------------------
1452// CommaExpr
1453template< typename core_t >
1454const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1455        VISIT_START( node );
1456
1457        if ( __visit_children() ) {
1458                {
1459                        guard_symtab guard { *this };
1460                        maybe_accept( node, &CommaExpr::result );
1461                }
1462                maybe_accept( node, &CommaExpr::arg1 );
1463                maybe_accept( node, &CommaExpr::arg2 );
1464        }
1465
1466        VISIT_END( Expr, node );
1467}
1468
1469//--------------------------------------------------------------------------
1470// TypeExpr
1471template< typename core_t >
1472const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1473        VISIT_START( node );
1474
1475        if ( __visit_children() ) {
1476                {
1477                        guard_symtab guard { *this };
1478                        maybe_accept( node, &TypeExpr::result );
1479                }
1480                maybe_accept( node, &TypeExpr::type );
1481        }
1482
1483        VISIT_END( Expr, node );
1484}
1485
1486//--------------------------------------------------------------------------
1487// DimensionExpr
1488template< typename core_t >
1489const ast::Expr * ast::Pass< core_t >::visit( const ast::DimensionExpr * node ) {
1490        VISIT_START( node );
1491
1492        if ( __visit_children() ) {
1493                guard_symtab guard { *this };
1494                maybe_accept( node, &DimensionExpr::result );
1495        }
1496
1497        VISIT_END( Expr, node );
1498}
1499
1500//--------------------------------------------------------------------------
1501// AsmExpr
1502template< typename core_t >
1503const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1504        VISIT_START( node );
1505
1506        if ( __visit_children() ) {
1507                {
1508                        guard_symtab guard { *this };
1509                        maybe_accept( node, &AsmExpr::result );
1510                }
1511                maybe_accept( node, &AsmExpr::constraint );
1512                maybe_accept( node, &AsmExpr::operand    );
1513        }
1514
1515        VISIT_END( Expr, node );
1516}
1517
1518//--------------------------------------------------------------------------
1519// ImplicitCopyCtorExpr
1520template< typename core_t >
1521const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1522        VISIT_START( node );
1523
1524        if ( __visit_children() ) {
1525                {
1526                        guard_symtab guard { *this };
1527                        maybe_accept( node, &ImplicitCopyCtorExpr::result );
1528                }
1529                maybe_accept( node, &ImplicitCopyCtorExpr::callExpr    );
1530        }
1531
1532        VISIT_END( Expr, node );
1533}
1534
1535//--------------------------------------------------------------------------
1536// ConstructorExpr
1537template< typename core_t >
1538const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1539        VISIT_START( node );
1540
1541        if ( __visit_children() ) {
1542                {
1543                        guard_symtab guard { *this };
1544                        maybe_accept( node, &ConstructorExpr::result );
1545                }
1546                maybe_accept( node, &ConstructorExpr::callExpr );
1547        }
1548
1549        VISIT_END( Expr, node );
1550}
1551
1552//--------------------------------------------------------------------------
1553// CompoundLiteralExpr
1554template< typename core_t >
1555const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1556        VISIT_START( node );
1557
1558        if ( __visit_children() ) {
1559                {
1560                        guard_symtab guard { *this };
1561                        maybe_accept( node, &CompoundLiteralExpr::result );
1562                }
1563                maybe_accept( node, &CompoundLiteralExpr::init );
1564        }
1565
1566        VISIT_END( Expr, node );
1567}
1568
1569//--------------------------------------------------------------------------
1570// RangeExpr
1571template< typename core_t >
1572const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1573        VISIT_START( node );
1574
1575        if ( __visit_children() ) {
1576                {
1577                        guard_symtab guard { *this };
1578                        maybe_accept( node, &RangeExpr::result );
1579                }
1580                maybe_accept( node, &RangeExpr::low    );
1581                maybe_accept( node, &RangeExpr::high   );
1582        }
1583
1584        VISIT_END( Expr, node );
1585}
1586
1587//--------------------------------------------------------------------------
1588// UntypedTupleExpr
1589template< typename core_t >
1590const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1591        VISIT_START( node );
1592
1593        if ( __visit_children() ) {
1594                {
1595                        guard_symtab guard { *this };
1596                        maybe_accept( node, &UntypedTupleExpr::result );
1597                }
1598                maybe_accept( node, &UntypedTupleExpr::exprs  );
1599        }
1600
1601        VISIT_END( Expr, node );
1602}
1603
1604//--------------------------------------------------------------------------
1605// TupleExpr
1606template< typename core_t >
1607const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1608        VISIT_START( node );
1609
1610        if ( __visit_children() ) {
1611                {
1612                        guard_symtab guard { *this };
1613                        maybe_accept( node, &TupleExpr::result );
1614                }
1615                maybe_accept( node, &TupleExpr::exprs  );
1616        }
1617
1618        VISIT_END( Expr, node );
1619}
1620
1621//--------------------------------------------------------------------------
1622// TupleIndexExpr
1623template< typename core_t >
1624const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1625        VISIT_START( node );
1626
1627        if ( __visit_children() ) {
1628                {
1629                        guard_symtab guard { *this };
1630                        maybe_accept( node, &TupleIndexExpr::result );
1631                }
1632                maybe_accept( node, &TupleIndexExpr::tuple  );
1633        }
1634
1635        VISIT_END( Expr, node );
1636}
1637
1638//--------------------------------------------------------------------------
1639// TupleAssignExpr
1640template< typename core_t >
1641const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1642        VISIT_START( node );
1643
1644        if ( __visit_children() ) {
1645                {
1646                        guard_symtab guard { *this };
1647                        maybe_accept( node, &TupleAssignExpr::result );
1648                }
1649                maybe_accept( node, &TupleAssignExpr::stmtExpr );
1650        }
1651
1652        VISIT_END( Expr, node );
1653}
1654
1655//--------------------------------------------------------------------------
1656// StmtExpr
1657template< typename core_t >
1658const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
1659        VISIT_START( node );
1660
1661        if ( __visit_children() ) {
1662                // don't want statements from outer CompoundStmts to be added to this StmtExpr
1663                // get the stmts that will need to be spliced in
1664                auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1665                auto stmts_after  = __pass::stmtsToAddAfter ( core, 0);
1666
1667                // These may be modified by subnode but most be restored once we exit this statemnet.
1668                ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
1669                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
1670                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
1671
1672                {
1673                        guard_symtab guard { *this };
1674                        maybe_accept( node, &StmtExpr::result );
1675                }
1676                maybe_accept( node, &StmtExpr::stmts       );
1677                maybe_accept( node, &StmtExpr::returnDecls );
1678                maybe_accept( node, &StmtExpr::dtors       );
1679        }
1680
1681        VISIT_END( Expr, node );
1682}
1683
1684//--------------------------------------------------------------------------
1685// UniqueExpr
1686template< typename core_t >
1687const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1688        VISIT_START( node );
1689
1690        if ( __visit_children() ) {
1691                {
1692                        guard_symtab guard { *this };
1693                        maybe_accept( node, &UniqueExpr::result );
1694                }
1695                maybe_accept( node, &UniqueExpr::expr   );
1696        }
1697
1698        VISIT_END( Expr, node );
1699}
1700
1701//--------------------------------------------------------------------------
1702// UntypedInitExpr
1703template< typename core_t >
1704const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1705        VISIT_START( node );
1706
1707        if ( __visit_children() ) {
1708                {
1709                        guard_symtab guard { *this };
1710                        maybe_accept( node, &UntypedInitExpr::result );
1711                }
1712                maybe_accept( node, &UntypedInitExpr::expr   );
1713                // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
1714        }
1715
1716        VISIT_END( Expr, node );
1717}
1718
1719//--------------------------------------------------------------------------
1720// InitExpr
1721template< typename core_t >
1722const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1723        VISIT_START( node );
1724
1725        if ( __visit_children() ) {
1726                {
1727                        guard_symtab guard { *this };
1728                        maybe_accept( node, &InitExpr::result );
1729                }
1730                maybe_accept( node, &InitExpr::expr   );
1731                maybe_accept( node, &InitExpr::designation );
1732        }
1733
1734        VISIT_END( Expr, node );
1735}
1736
1737//--------------------------------------------------------------------------
1738// DeletedExpr
1739template< typename core_t >
1740const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1741        VISIT_START( node );
1742
1743        if ( __visit_children() ) {
1744                {
1745                        guard_symtab guard { *this };
1746                        maybe_accept( node, &DeletedExpr::result );
1747                }
1748                maybe_accept( node, &DeletedExpr::expr );
1749                // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
1750        }
1751
1752        VISIT_END( Expr, node );
1753}
1754
1755//--------------------------------------------------------------------------
1756// DefaultArgExpr
1757template< typename core_t >
1758const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1759        VISIT_START( node );
1760
1761        if ( __visit_children() ) {
1762                {
1763                        guard_symtab guard { *this };
1764                        maybe_accept( node, &DefaultArgExpr::result );
1765                }
1766                maybe_accept( node, &DefaultArgExpr::expr );
1767        }
1768
1769        VISIT_END( Expr, node );
1770}
1771
1772//--------------------------------------------------------------------------
1773// GenericExpr
1774template< typename core_t >
1775const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1776        VISIT_START( node );
1777
1778        if ( __visit_children() ) {
1779                {
1780                        guard_symtab guard { *this };
1781                        maybe_accept( node, &GenericExpr::result );
1782                }
1783                maybe_accept( node, &GenericExpr::control );
1784
1785                std::vector<GenericExpr::Association> new_kids;
1786                new_kids.reserve(node->associations.size());
1787                bool mutated = false;
1788                for( const auto & assoc : node->associations ) {
1789                        const Type * type = nullptr;
1790                        if( assoc.type ) {
1791                                guard_symtab guard { *this };
1792                                type = assoc.type->accept( *this );
1793                                if( type != assoc.type ) mutated = true;
1794                        }
1795                        const Expr * expr = nullptr;
1796                        if( assoc.expr ) {
1797                                expr = assoc.expr->accept( *this );
1798                                if( expr != assoc.expr ) mutated = true;
1799                        }
1800                        new_kids.emplace_back( type, expr );
1801                }
1802
1803                if(mutated) {
1804                        auto n = __pass::mutate<core_t>(node);
1805                        n->associations = std::move( new_kids );
1806                        node = n;
1807                }
1808        }
1809
1810        VISIT_END( Expr, node );
1811}
1812
1813//--------------------------------------------------------------------------
1814// VoidType
1815template< typename core_t >
1816const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1817        VISIT_START( node );
1818
1819        VISIT_END( Type, node );
1820}
1821
1822//--------------------------------------------------------------------------
1823// BasicType
1824template< typename core_t >
1825const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1826        VISIT_START( node );
1827
1828        VISIT_END( Type, node );
1829}
1830
1831//--------------------------------------------------------------------------
1832// PointerType
1833template< typename core_t >
1834const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
1835        VISIT_START( node );
1836
1837        if ( __visit_children() ) {
1838                maybe_accept( node, &PointerType::dimension );
1839                maybe_accept( node, &PointerType::base );
1840        }
1841
1842        VISIT_END( Type, node );
1843}
1844
1845//--------------------------------------------------------------------------
1846// ArrayType
1847template< typename core_t >
1848const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
1849        VISIT_START( node );
1850
1851        if ( __visit_children() ) {
1852                maybe_accept( node, &ArrayType::dimension );
1853                maybe_accept( node, &ArrayType::base );
1854        }
1855
1856        VISIT_END( Type, node );
1857}
1858
1859//--------------------------------------------------------------------------
1860// ReferenceType
1861template< typename core_t >
1862const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
1863        VISIT_START( node );
1864
1865        if ( __visit_children() ) {
1866                maybe_accept( node, &ReferenceType::base );
1867        }
1868
1869        VISIT_END( Type, node );
1870}
1871
1872//--------------------------------------------------------------------------
1873// QualifiedType
1874template< typename core_t >
1875const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
1876        VISIT_START( node );
1877
1878        if ( __visit_children() ) {
1879                maybe_accept( node, &QualifiedType::parent );
1880                maybe_accept( node, &QualifiedType::child );
1881        }
1882
1883        VISIT_END( Type, node );
1884}
1885
1886//--------------------------------------------------------------------------
1887// FunctionType
1888template< typename core_t >
1889const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1890        VISIT_START( node );
1891
1892        if ( __visit_children() ) {
1893                // guard_forall_subs forall_guard { *this, node };
1894                // mutate_forall( node );
1895                maybe_accept( node, &FunctionType::assertions );
1896                maybe_accept( node, &FunctionType::returns );
1897                maybe_accept( node, &FunctionType::params  );
1898        }
1899
1900        VISIT_END( Type, node );
1901}
1902
1903//--------------------------------------------------------------------------
1904// StructInstType
1905template< typename core_t >
1906const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1907        VISIT_START( node );
1908
1909        __pass::symtab::addStructId( core, 0, node->name );
1910
1911        if ( __visit_children() ) {
1912                guard_symtab guard { *this };
1913                maybe_accept( node, &StructInstType::params );
1914        }
1915
1916        VISIT_END( Type, node );
1917}
1918
1919//--------------------------------------------------------------------------
1920// UnionInstType
1921template< typename core_t >
1922const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
1923        VISIT_START( node );
1924
1925        __pass::symtab::addUnionId( core, 0, node->name );
1926
1927        if ( __visit_children() ) {
1928                guard_symtab guard { *this };
1929                maybe_accept( node, &UnionInstType::params );
1930        }
1931
1932        VISIT_END( Type, node );
1933}
1934
1935//--------------------------------------------------------------------------
1936// EnumInstType
1937template< typename core_t >
1938const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
1939        VISIT_START( node );
1940
1941        if ( __visit_children() ) {
1942                maybe_accept( node, &EnumInstType::params );
1943        }
1944
1945        VISIT_END( Type, node );
1946}
1947
1948//--------------------------------------------------------------------------
1949// TraitInstType
1950template< typename core_t >
1951const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
1952        VISIT_START( node );
1953
1954        if ( __visit_children() ) {
1955                maybe_accept( node, &TraitInstType::params );
1956        }
1957
1958        VISIT_END( Type, node );
1959}
1960
1961//--------------------------------------------------------------------------
1962// TypeInstType
1963template< typename core_t >
1964const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
1965        VISIT_START( node );
1966
1967        if ( __visit_children() ) {
1968                {
1969                        maybe_accept( node, &TypeInstType::params );
1970                }
1971                // ensure that base re-bound if doing substitution
1972                __pass::forall::replace( core, 0, node );
1973        }
1974
1975        VISIT_END( Type, node );
1976}
1977
1978//--------------------------------------------------------------------------
1979// TupleType
1980template< typename core_t >
1981const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
1982        VISIT_START( node );
1983
1984        if ( __visit_children() ) {
1985                maybe_accept( node, &TupleType::types );
1986        }
1987
1988        VISIT_END( Type, node );
1989}
1990
1991//--------------------------------------------------------------------------
1992// TypeofType
1993template< typename core_t >
1994const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
1995        VISIT_START( node );
1996
1997        if ( __visit_children() ) {
1998                maybe_accept( node, &TypeofType::expr );
1999        }
2000
2001        VISIT_END( Type, node );
2002}
2003
2004//--------------------------------------------------------------------------
2005// VTableType
2006template< typename core_t >
2007const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
2008        VISIT_START( node );
2009
2010        if ( __visit_children() ) {
2011                maybe_accept( node, &VTableType::base );
2012        }
2013
2014        VISIT_END( Type, node );
2015}
2016
2017//--------------------------------------------------------------------------
2018// VarArgsType
2019template< typename core_t >
2020const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
2021        VISIT_START( node );
2022
2023        VISIT_END( Type, node );
2024}
2025
2026//--------------------------------------------------------------------------
2027// ZeroType
2028template< typename core_t >
2029const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
2030        VISIT_START( node );
2031
2032        VISIT_END( Type, node );
2033}
2034
2035//--------------------------------------------------------------------------
2036// OneType
2037template< typename core_t >
2038const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
2039        VISIT_START( node );
2040
2041        VISIT_END( Type, node );
2042}
2043
2044//--------------------------------------------------------------------------
2045// GlobalScopeType
2046template< typename core_t >
2047const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
2048        VISIT_START( node );
2049
2050        VISIT_END( Type, node );
2051}
2052
2053
2054//--------------------------------------------------------------------------
2055// Designation
2056template< typename core_t >
2057const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
2058        VISIT_START( node );
2059
2060        if ( __visit_children() ) {
2061                maybe_accept( node, &Designation::designators );
2062        }
2063
2064        VISIT_END( Designation, node );
2065}
2066
2067//--------------------------------------------------------------------------
2068// SingleInit
2069template< typename core_t >
2070const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
2071        VISIT_START( node );
2072
2073        if ( __visit_children() ) {
2074                maybe_accept_top( node, &SingleInit::value );
2075        }
2076
2077        VISIT_END( Init, node );
2078}
2079
2080//--------------------------------------------------------------------------
2081// ListInit
2082template< typename core_t >
2083const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
2084        VISIT_START( node );
2085
2086        if ( __visit_children() ) {
2087                maybe_accept( node, &ListInit::designations );
2088                maybe_accept( node, &ListInit::initializers );
2089        }
2090
2091        VISIT_END( Init, node );
2092}
2093
2094//--------------------------------------------------------------------------
2095// ConstructorInit
2096template< typename core_t >
2097const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
2098        VISIT_START( node );
2099
2100        if ( __visit_children() ) {
2101                maybe_accept( node, &ConstructorInit::ctor );
2102                maybe_accept( node, &ConstructorInit::dtor );
2103                maybe_accept( node, &ConstructorInit::init );
2104        }
2105
2106        VISIT_END( Init, node );
2107}
2108
2109//--------------------------------------------------------------------------
2110// Attribute
2111template< typename core_t >
2112const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node  )  {
2113        VISIT_START( node );
2114
2115        if ( __visit_children() ) {
2116                maybe_accept( node, &Attribute::params );
2117        }
2118
2119        VISIT_END( Attribute, node );
2120}
2121
2122//--------------------------------------------------------------------------
2123// TypeSubstitution
2124template< typename core_t >
2125const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
2126        VISIT_START( node );
2127
2128        if ( __visit_children() ) {
2129                bool mutated = false;
2130                ast::TypeSubstitution::TypeMap new_map;
2131                for ( const auto & p : node->typeMap ) {
2132                        guard_symtab guard { *this };
2133                        auto new_node = p.second->accept( *this );
2134                        if (new_node != p.second) mutated = true;
2135                        new_map.insert({ p.first, new_node });
2136                }
2137                if (mutated) {
2138                        auto new_node = __pass::mutate<core_t>( node );
2139                        new_node->typeMap.swap( new_map );
2140                        node = new_node;
2141                }
2142        }
2143
2144        VISIT_END( TypeSubstitution, node );
2145}
2146
2147#undef __pedantic_pass_assertf
2148#undef __pedantic_pass_assert
2149#undef VISIT_START
2150#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.