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

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b2a11ba was b2a11ba, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Rename WithConstTypeSubstitution? from env to typeSubs to avoid name collision.

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