source: src/AST/Pass.impl.hpp@ 628a7c5

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 628a7c5 was d3aa64f1, checked in by Fangren Yu <f37yu@…>, 5 years ago

pure visitor interface for new ast

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