source: src/AST/Pass.impl.hpp @ 044ae62

ADT
Last change on this file since 044ae62 was 044ae62, checked in by JiadaL <j82liang@…>, 12 months ago

Merge branch 'master' into ADT

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