source: src/AST/Pass.impl.hpp @ 331ee52c

ADTast-experimental
Last change on this file since 331ee52c was d0bdb18, checked in by Andrew Beach <ajbeach@…>, 18 months ago

Removed extra scope calls in the new Pass. Added some documentation on the core's possible special members.

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