source: src/AST/Pass.impl.hpp @ 8f06277

ADTast-experimental
Last change on this file since 8f06277 was 8f06277, checked in by Andrew Beach <ajbeach@…>, 16 months ago

Some clean-up in Common/utility.h. Deleted some unused declarations and moved others to one of two new headers.

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