source: src/AST/Pass.impl.hpp @ 60f4919

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

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

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