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

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

Replaced SemanticErrorException::isEmpty with ...::throwIfNonEmpty. This is how it was used in every context and it saves a bit of text (if not two lines) at every use. I considered putting this function in the header for better inlining, but this should have at least the same preformance as the last version.

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