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

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since b0d9ff7 was b0d9ff7, checked in by JiadaL <j82liang@…>, 2 years ago

Fix up the QualifiedNameExpr?. It should now work on both old AST and new AST. There are some known bugs to fix so make all-tests will fail.

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