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

Last change on this file since c16cc99 was 148f836e, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Cleaned up namespacing, indentation and whitespacing in Pass.impl.hpp.

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