source: src/AST/Pass.impl.hpp @ 490fb92e

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 490fb92e was 490fb92e, checked in by Fangren Yu <f37yu@…>, 3 years ago

move FixInit? to new ast

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