source: src/AST/Pass.impl.hpp@ 7a2a3af

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 7a2a3af was 490fb92e, checked in by Fangren Yu <f37yu@…>, 5 years ago

move FixInit to new ast

  • Property mode set to 100644
File size: 58.1 KB
RevLine 
[04124c4]1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[e0016a5]7// ast::Pass.impl.hpp --
[04124c4]8//
9// Author : Thierry Delisle
10// Created On : Thu May 09 15::37::05 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
[f47f887]16#pragma once
[04124c4]17// IWYU pragma: private, include "AST/Pass.hpp"
[f47f887]18
[6d51bd7]19#include <type_traits>
20#include <unordered_map>
21
[c671112]22#include "AST/TypeSubstitution.hpp"
23
[f47f887]24#define VISIT_START( node ) \
[04124c4]25 using namespace ast; \
[f47f887]26 /* back-up the visit children */ \
[7ff3e522]27 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \
[f47f887]28 /* setup the scope for passes that want to run code at exit */ \
[7ff3e522]29 __attribute__((unused)) ast::__pass::guard_value guard2( ast::__pass::at_cleanup (core, 0) ); \
[c15085d]30 /* begin tracing memory allocation if requested by this pass */ \
[7ff3e522]31 __pass::beginTrace( core, 0 ); \
[f47f887]32 /* call the implementation of the previsit of this pass */ \
[7ff3e522]33 __pass::previsit( core, node, 0 );
[f47f887]34
[6d51bd7]35#define VISIT( code... ) \
[f47f887]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 */ \
[7ff3e522]44 auto __return = __pass::postvisit( core, node, 0 ); \
[f47f887]45 assertf(__return, "post visit should never return null"); \
[c15085d]46 /* end tracing memory allocation if requested by this pass */ \
[7ff3e522]47 __pass::endTrace( core, 0 ); \
[f47f887]48 return __return;
49
50#ifdef PEDANTIC_PASS_ASSERT
[6d51bd7]51#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
52#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
[f47f887]53#else
[6d51bd7]54#define __pedantic_pass_assert(...)
[f47f887]55#define __pedantic_pass_assertf(...)
56#endif
57
58namespace ast {
[d3aa64f1]59 template<typename node_t>
60 node_t * shallowCopy( const node_t * node );
61
[f47f887]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
[d3aa64f1]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
[6d51bd7]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 ) {
[f47f887]77 if(empty(decls)) return;
78
[6d51bd7]79 std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
[8a5530c]80 return new DeclStmt( decl->location, decl );
[f47f887]81 });
82 decls->clear();
83 if(mutated) *mutated = true;
84 }
85
[6d51bd7]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 ) {
[f47f887]88 if(empty(decls)) return;
89
90 std::move(decls->begin(), decls->end(), it);
91 decls->clear();
92 if(mutated) *mutated = true;
93 }
94
[6d51bd7]95 //------------------------------
96 /// Check if should be skipped, different for pointers and containers
[f47f887]97 template<typename node_t>
[6d51bd7]98 bool skip( const ast::ptr<node_t> & val) {
99 return !val;
[f47f887]100 }
101
[6d51bd7]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();
[f47f887]105 }
106
[6d51bd7]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 }
[f47f887]113
[6d51bd7]114 template<typename node_t>
115 const node_t & get( const node_t & val, long) {
116 return val;
117 }
[f47f887]118
[6d51bd7]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();
[f47f887]130 }
131 }
132
[7ff3e522]133 template< typename core_t >
[f47f887]134 template< typename node_t >
[7ff3e522]135 auto ast::Pass< core_t >::call_accept( const node_t * node )
[8a5530c]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 {
[f47f887]142 __pedantic_pass_assert( __visit_children() );
[e0e9a0b]143 __pedantic_pass_assert( node );
[f47f887]144
[6d51bd7]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
[f47f887]148 return node->accept( *this );
149 }
150
[7ff3e522]151 template< typename core_t >
152 const ast::Expr * ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
[f47f887]153 __pedantic_pass_assert( __visit_children() );
154 __pedantic_pass_assert( expr );
155
[b2a11ba]156 const ast::TypeSubstitution ** typeSubs_ptr = __pass::typeSubs( core, 0 );
157 if ( typeSubs_ptr && expr->env ) {
158 *typeSubs_ptr = expr->env;
[f47f887]159 }
160
161 return expr->accept( *this );
162 }
163
[7ff3e522]164 template< typename core_t >
165 const ast::Stmt * ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
[f47f887]166 __pedantic_pass_assert( __visit_children() );
167 __pedantic_pass_assert( stmt );
168
[490fb92e]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
[f47f887]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
[7ff3e522]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);
[f47f887]185
186 // These may be modified by subnode but most be restored once we exit this statemnet.
[b2a11ba]187 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::typeSubs( core, 0 ) );
[23f99e1]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 );
[f47f887]192
193 // Now is the time to actually visit the node
[6d51bd7]194 const ast::Stmt * nstmt = stmt->accept( *this );
[f47f887]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
[6d51bd7]207 ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
[f47f887]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
[6d51bd7]214 compound->kids.emplace_back( nstmt );
[f47f887]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
[7ff3e522]223 template< typename core_t >
[6d51bd7]224 template< template <class...> class container_t >
[7ff3e522]225 container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
[f47f887]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
[7ff3e522]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);
[f47f887]240
241 // These may be modified by subnode but most be restored once we exit this statemnet.
[23f99e1]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 );
[f47f887]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;
[04124c4]253 container_t< ptr<Stmt> > new_kids;
254 for( const Stmt * stmt : statements ) {
[f47f887]255 try {
256 __pedantic_pass_assert( stmt );
[6d51bd7]257 const ast::Stmt * new_stmt = stmt->accept( *this );
[f47f887]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
[6d51bd7]286 return mutated ? new_kids : container_t< ptr<Stmt> >();
[f47f887]287 }
288
[7ff3e522]289 template< typename core_t >
[6d51bd7]290 template< template <class...> class container_t, typename node_t >
[7ff3e522]291 container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
[f47f887]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 );
[6d51bd7]305 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
306 if(new_stmt != node ) mutated = true;
[f47f887]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
[6d51bd7]317 return mutated ? new_kids : container_t< ast::ptr<node_t> >();
318 }
319
[7ff3e522]320 template< typename core_t >
[6d51bd7]321 template<typename node_t, typename parent_t, typename child_t>
[7ff3e522]322 void ast::Pass< core_t >::maybe_accept(
[6d51bd7]323 const node_t * & parent,
324 child_t parent_t::*child
325 ) {
[8a5530c]326 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );
[6d51bd7]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) ) {
[d3aa64f1]338 auto new_parent = __pass::mutate<core_t>(parent);
[6d51bd7]339 new_parent->*child = new_val;
340 parent = new_parent;
341 }
[f47f887]342 }
[6d51bd7]343
[490fb92e]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
[e0e9a0b]368
[7ff3e522]369 template< typename core_t >
[e0e9a0b]370 template< typename node_t >
[7ff3e522]371 void ast::Pass< core_t >::mutate_forall( const node_t *& node ) {
372 if ( auto subs = __pass::forall::subs( core, 0 ) ) {
[e0e9a0b]373 // tracking TypeDecl substitution, full clone
374 if ( node->forall.empty() ) return;
375
[d3aa64f1]376 node_t * mut = __pass::mutate<core_t>( node );
[e0e9a0b]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 }
[f47f887]384}
385
386//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
387//========================================================================================================================================================================
388//========================================================================================================================================================================
389//========================================================================================================================================================================
390//========================================================================================================================================================================
391//========================================================================================================================================================================
392//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
393
[7ff3e522]394template< typename core_t >
395inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< core_t > & visitor ) {
[04124c4]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
[7ff3e522]403 auto decls_before = __pass::declsToAddBefore( visitor.core, 0);
404 auto decls_after = __pass::declsToAddAfter ( visitor.core, 0);
[04124c4]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
[f47f887]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
[7ff3e522]453template< typename core_t >
454const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::ObjectDecl * node ) {
[f47f887]455 VISIT_START( node );
456
457 VISIT(
458 {
[0e42794]459 guard_symtab guard { *this };
[23f99e1]460 maybe_accept( node, &ObjectDecl::type );
[f47f887]461 }
[23f99e1]462 maybe_accept( node, &ObjectDecl::init );
463 maybe_accept( node, &ObjectDecl::bitfieldWidth );
464 maybe_accept( node, &ObjectDecl::attributes );
[f47f887]465 )
466
[7ff3e522]467 __pass::symtab::addId( core, 0, node );
[f47f887]468
[04124c4]469 VISIT_END( DeclWithType, node );
[f47f887]470}
471
[23f99e1]472//--------------------------------------------------------------------------
473// FunctionDecl
[7ff3e522]474template< typename core_t >
475const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::FunctionDecl * node ) {
[23f99e1]476 VISIT_START( node );
477
[7ff3e522]478 __pass::symtab::addId( core, 0, node );
[23f99e1]479
480 VISIT(maybe_accept( node, &FunctionDecl::withExprs );)
481 {
482 // with clause introduces a level of scope (for the with expression members).
[0e42794]483 // with clause exprs are added to the symbol table before parameters so that parameters
[23f99e1]484 // shadow with exprs and not the other way around.
[0e42794]485 guard_symtab guard { *this };
[7ff3e522]486 __pass::symtab::addWith( core, 0, node->withExprs, node );
[23f99e1]487 {
[0e42794]488 guard_symtab guard { *this };
[23f99e1]489 // implicit add __func__ identifier as specified in the C manual 6.4.2.2
[9ea38de]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 },
[8a5530c]494 nullptr, VariableLen, DynamicDim
[9ea38de]495 }
496 } };
[7ff3e522]497 __pass::symtab::addId( core, 0, func );
[23f99e1]498 VISIT(
[954c954]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
[23f99e1]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;
[8a5530c]508 maybe_accept( node, &FunctionDecl::stmts );
[23f99e1]509 maybe_accept( node, &FunctionDecl::attributes );
510 )
511 }
512 }
513
514 VISIT_END( DeclWithType, node );
515}
516
517//--------------------------------------------------------------------------
518// StructDecl
[7ff3e522]519template< typename core_t >
520const ast::Decl * ast::Pass< core_t >::visit( const ast::StructDecl * node ) {
[23f99e1]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
[7ff3e522]525 __pass::symtab::addStructFwd( core, 0, node );
[23f99e1]526
527 VISIT({
[0e42794]528 guard_symtab guard { * this };
[87701b6]529 maybe_accept( node, &StructDecl::params );
530 maybe_accept( node, &StructDecl::members );
[23f99e1]531 })
532
533 // this addition replaces the forward declaration
[7ff3e522]534 __pass::symtab::addStruct( core, 0, node );
[23f99e1]535
536 VISIT_END( Decl, node );
537}
538
539//--------------------------------------------------------------------------
540// UnionDecl
[7ff3e522]541template< typename core_t >
542const ast::Decl * ast::Pass< core_t >::visit( const ast::UnionDecl * node ) {
[23f99e1]543 VISIT_START( node );
544
545 // make up a forward declaration and add it before processing the members
[7ff3e522]546 __pass::symtab::addUnionFwd( core, 0, node );
[23f99e1]547
548 VISIT({
[0e42794]549 guard_symtab guard { * this };
[87701b6]550 maybe_accept( node, &UnionDecl::params );
551 maybe_accept( node, &UnionDecl::members );
[23f99e1]552 })
553
[7ff3e522]554 __pass::symtab::addUnion( core, 0, node );
[23f99e1]555
556 VISIT_END( Decl, node );
557}
558
559//--------------------------------------------------------------------------
560// EnumDecl
[7ff3e522]561template< typename core_t >
562const ast::Decl * ast::Pass< core_t >::visit( const ast::EnumDecl * node ) {
[23f99e1]563 VISIT_START( node );
564
[7ff3e522]565 __pass::symtab::addEnum( core, 0, node );
[23f99e1]566
567 VISIT(
568 // unlike structs, traits, and unions, enums inject their members into the global scope
[87701b6]569 maybe_accept( node, &EnumDecl::params );
570 maybe_accept( node, &EnumDecl::members );
[23f99e1]571 )
572
573 VISIT_END( Decl, node );
574}
575
576//--------------------------------------------------------------------------
577// TraitDecl
[7ff3e522]578template< typename core_t >
579const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
[23f99e1]580 VISIT_START( node );
581
582 VISIT({
[0e42794]583 guard_symtab guard { *this };
[87701b6]584 maybe_accept( node, &TraitDecl::params );
585 maybe_accept( node, &TraitDecl::members );
[23f99e1]586 })
587
[7ff3e522]588 __pass::symtab::addTrait( core, 0, node );
[23f99e1]589
590 VISIT_END( Decl, node );
591}
592
593//--------------------------------------------------------------------------
594// TypeDecl
[7ff3e522]595template< typename core_t >
596const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
[23f99e1]597 VISIT_START( node );
598
599 VISIT({
[0e42794]600 guard_symtab guard { *this };
[87701b6]601 maybe_accept( node, &TypeDecl::params );
602 maybe_accept( node, &TypeDecl::base );
[23f99e1]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
[7ff3e522]608 __pass::symtab::addType( core, 0, node );
[23f99e1]609
610 VISIT(
[8a5530c]611 maybe_accept( node, &TypeDecl::assertions );
[23f99e1]612
613 {
[0e42794]614 guard_symtab guard { *this };
[23f99e1]615 maybe_accept( node, &TypeDecl::init );
616 }
617 )
618
619 VISIT_END( Decl, node );
620}
621
622//--------------------------------------------------------------------------
623// TypedefDecl
[7ff3e522]624template< typename core_t >
625const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
[23f99e1]626 VISIT_START( node );
627
628 VISIT({
[0e42794]629 guard_symtab guard { *this };
[87701b6]630 maybe_accept( node, &TypedefDecl::params );
631 maybe_accept( node, &TypedefDecl::base );
[23f99e1]632 })
633
[7ff3e522]634 __pass::symtab::addType( core, 0, node );
[23f99e1]635
[17a0228a]636 VISIT( maybe_accept( node, &TypedefDecl::assertions ); )
[23f99e1]637
638 VISIT_END( Decl, node );
639}
640
641//--------------------------------------------------------------------------
642// AsmDecl
[7ff3e522]643template< typename core_t >
644const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
[23f99e1]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
[7ff3e522]656template< typename core_t >
657const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
[23f99e1]658 VISIT_START( node );
659
660 VISIT(
[112fe04]661 maybe_accept( node, &StaticAssertDecl::cond );
662 maybe_accept( node, &StaticAssertDecl::msg );
[23f99e1]663 )
664
665 VISIT_END( StaticAssertDecl, node );
666}
667
668//--------------------------------------------------------------------------
669// CompoundStmt
[7ff3e522]670template< typename core_t >
671const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
[23f99e1]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
[9ea38de]675 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() {
[7ff3e522]676 if ( ! inFunctionCpy ) __pass::symtab::enter(core, 0);
[9ea38de]677 }, [this, inFunctionCpy = this->inFunction]() {
[7ff3e522]678 if ( ! inFunctionCpy ) __pass::symtab::leave(core, 0);
[23f99e1]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
[8a5530c]688//--------------------------------------------------------------------------
689// ExprStmt
[7ff3e522]690template< typename core_t >
691const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
[8a5530c]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
[7ff3e522]703template< typename core_t >
704const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
[8a5530c]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
[7ff3e522]719template< typename core_t >
720const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
[8a5530c]721 VISIT_START( node )
722
723 VISIT_END( Stmt, node );
724}
725
726//--------------------------------------------------------------------------
727// IfStmt
[7ff3e522]728template< typename core_t >
729const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
[8a5530c]730 VISIT_START( node );
[17a0228a]731
[8a5530c]732 VISIT({
733 // if statements introduce a level of scope (for the initialization)
[0e42794]734 guard_symtab guard { *this };
[8a5530c]735 maybe_accept( node, &IfStmt::inits );
736 maybe_accept( node, &IfStmt::cond );
[490fb92e]737 maybe_accept_as_compound( node, &IfStmt::thenPart );
738 maybe_accept_as_compound( node, &IfStmt::elsePart );
[8a5530c]739 })
[17a0228a]740
[8a5530c]741 VISIT_END( Stmt, node );
742}
743
744//--------------------------------------------------------------------------
745// WhileStmt
[7ff3e522]746template< typename core_t >
747const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileStmt * node ) {
[8a5530c]748 VISIT_START( node );
749
750 VISIT({
751 // while statements introduce a level of scope (for the initialization)
[0e42794]752 guard_symtab guard { *this };
[8a5530c]753 maybe_accept( node, &WhileStmt::inits );
754 maybe_accept( node, &WhileStmt::cond );
[490fb92e]755 maybe_accept_as_compound( node, &WhileStmt::body );
[8a5530c]756 })
757
758 VISIT_END( Stmt, node );
759}
[23f99e1]760
[87701b6]761//--------------------------------------------------------------------------
762// ForStmt
[7ff3e522]763template< typename core_t >
764const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
[87701b6]765 VISIT_START( node );
766
767 VISIT({
768 // for statements introduce a level of scope (for the initialization)
[0e42794]769 guard_symtab guard { *this };
[490fb92e]770 // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
[87701b6]771 maybe_accept( node, &ForStmt::inits );
772 maybe_accept( node, &ForStmt::cond );
773 maybe_accept( node, &ForStmt::inc );
[490fb92e]774 maybe_accept_as_compound( node, &ForStmt::body );
[87701b6]775 })
776
777 VISIT_END( Stmt, node );
778}
779
780//--------------------------------------------------------------------------
781// SwitchStmt
[7ff3e522]782template< typename core_t >
783const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
[87701b6]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
[7ff3e522]796template< typename core_t >
797const ast::Stmt * ast::Pass< core_t >::visit( const ast::CaseStmt * node ) {
[87701b6]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
[7ff3e522]810template< typename core_t >
811const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
[87701b6]812 VISIT_START( node );
813 VISIT_END( Stmt, node );
814}
815
816//--------------------------------------------------------------------------
817// ReturnStmt
[7ff3e522]818template< typename core_t >
819const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
[87701b6]820 VISIT_START( node );
821
[e61207e7]822 VISIT(
823 maybe_accept( node, &ReturnStmt::expr );
824 )
[87701b6]825
826 VISIT_END( Stmt, node );
827}
828
829//--------------------------------------------------------------------------
830// ThrowStmt
[7ff3e522]831template< typename core_t >
832const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
[e61207e7]833 VISIT_START( node );
[87701b6]834
[e61207e7]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
[7ff3e522]845template< typename core_t >
846const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
[87701b6]847 VISIT_START( node );
848
[e61207e7]849 VISIT(
[acd80b4]850 maybe_accept( node, &TryStmt::body );
851 maybe_accept( node, &TryStmt::handlers );
852 maybe_accept( node, &TryStmt::finally );
[e61207e7]853 )
[87701b6]854
[e61207e7]855 VISIT_END( Stmt, node );
[87701b6]856}
857
[10a1225]858//--------------------------------------------------------------------------
859// CatchStmt
[7ff3e522]860template< typename core_t >
861const ast::Stmt * ast::Pass< core_t >::visit( const ast::CatchStmt * node ) {
[10a1225]862 VISIT_START( node );
863
864 VISIT({
865 // catch statements introduce a level of scope (for the caught exception)
[0e42794]866 guard_symtab guard { *this };
[10a1225]867 maybe_accept( node, &CatchStmt::decl );
868 maybe_accept( node, &CatchStmt::cond );
[490fb92e]869 maybe_accept_as_compound( node, &CatchStmt::body );
[10a1225]870 })
871
872 VISIT_END( Stmt, node );
873}
874
875//--------------------------------------------------------------------------
876// FinallyStmt
[7ff3e522]877template< typename core_t >
878const ast::Stmt * ast::Pass< core_t >::visit( const ast::FinallyStmt * node ) {
[10a1225]879 VISIT_START( node );
880
881 VISIT(
882 maybe_accept( node, &FinallyStmt::body );
883 )
884
885 VISIT_END( Stmt, node );
886}
887
[37cdd97]888//--------------------------------------------------------------------------
889// FinallyStmt
[7ff3e522]890template< typename core_t >
891const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
[37cdd97]892 VISIT_START( node );
893
894 VISIT(
895 maybe_accept( node, &SuspendStmt::then );
896 )
897
898 VISIT_END( Stmt, node );
899}
900
[10a1225]901//--------------------------------------------------------------------------
902// WaitForStmt
[7ff3e522]903template< typename core_t >
904const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
[10a1225]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
[e0016a5]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
[b0abc8a0]920 const Expr * func = clause.target.func ? clause.target.func->accept(*this) : nullptr;
[e0016a5]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
[b0abc8a0]931 const Stmt * stmt = clause.stmt ? clause.stmt->accept(*this) : nullptr;
[e0016a5]932 if(stmt != clause.stmt) mutated = true;
933
[b0abc8a0]934 const Expr * cond = clause.cond ? clause.cond->accept(*this) : nullptr;
[e0016a5]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) {
[d3aa64f1]941 auto n = __pass::mutate<core_t>(node);
[e0016a5]942 n->clauses = std::move( new_clauses );
943 node = n;
944 }
945 })
946
[10a1225]947 #define maybe_accept(field) \
948 if(node->field) { \
949 auto nval = call_accept( node->field ); \
950 if(nval != node->field ) { \
[d3aa64f1]951 auto nparent = __pass::mutate<core_t>(node); \
[10a1225]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
[7ff3e522]972template< typename core_t >
973const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
[10a1225]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)
[0e42794]980 guard_symtab guard { *this };
[7ff3e522]981 __pass::symtab::addWith( core, 0, node->exprs, node );
[10a1225]982 maybe_accept( node, &WithStmt::stmt );
983 }
984 )
985 VISIT_END( Stmt, node );
986}
987
988//--------------------------------------------------------------------------
989// NullStmt
[7ff3e522]990template< typename core_t >
991const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
[10a1225]992 VISIT_START( node );
993 VISIT_END( NullStmt, node );
994}
995
996//--------------------------------------------------------------------------
997// DeclStmt
[7ff3e522]998template< typename core_t >
999const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
[10a1225]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
[7ff3e522]1011template< typename core_t >
1012const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
[10a1225]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
[c570806]1017 VISIT(
1018 maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
1019 )
[10a1225]1020
1021 VISIT_END( Stmt, node );
1022}
1023
[17a0228a]1024//--------------------------------------------------------------------------
1025// ApplicationExpr
[7ff3e522]1026template< typename core_t >
1027const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
[17a0228a]1028 VISIT_START( node );
1029
1030 VISIT(
1031 {
[0e42794]1032 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1044template< typename core_t >
1045const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
[17a0228a]1046 VISIT_START( node );
1047
1048 VISIT(
1049 {
[0e42794]1050 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1062template< typename core_t >
1063const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
[17a0228a]1064 VISIT_START( node );
1065
1066 VISIT({
[0e42794]1067 guard_symtab guard { *this };
[17a0228a]1068 maybe_accept( node, &NameExpr::result );
1069 })
1070
1071 VISIT_END( Expr, node );
1072}
1073
1074//--------------------------------------------------------------------------
1075// CastExpr
[7ff3e522]1076template< typename core_t >
1077const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
[17a0228a]1078 VISIT_START( node );
1079
1080 VISIT({
[0e42794]1081 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1092template< typename core_t >
1093const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
[17a0228a]1094 VISIT_START( node );
1095
1096 VISIT({
[0e42794]1097 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1108template< typename core_t >
1109const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
[17a0228a]1110 VISIT_START( node );
1111
1112 VISIT({
[0e42794]1113 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1124template< typename core_t >
1125const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
[17a0228a]1126 VISIT_START( node );
1127
1128 VISIT({
[0e42794]1129 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1140template< typename core_t >
1141const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
[17a0228a]1142 VISIT_START( node );
1143
1144 VISIT({
[0e42794]1145 guard_symtab guard { *this };
[17a0228a]1146 maybe_accept( node, &LabelAddressExpr::result );
1147 })
1148
1149 VISIT_END( Expr, node );
1150}
1151
1152//--------------------------------------------------------------------------
1153// UntypedMemberExpr
[7ff3e522]1154template< typename core_t >
1155const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
[17a0228a]1156 VISIT_START( node );
1157
1158 VISIT({
[0e42794]1159 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1171template< typename core_t >
1172const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
[17a0228a]1173 VISIT_START( node );
1174
1175 VISIT({
[0e42794]1176 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1187template< typename core_t >
1188const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
[17a0228a]1189 VISIT_START( node );
1190
1191 VISIT({
[0e42794]1192 guard_symtab guard { *this };
[17a0228a]1193 maybe_accept( node, &VariableExpr::result );
1194 })
1195
1196 VISIT_END( Expr, node );
1197}
1198
1199//--------------------------------------------------------------------------
1200// ConstantExpr
[7ff3e522]1201template< typename core_t >
1202const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
[17a0228a]1203 VISIT_START( node );
1204
1205 VISIT({
[0e42794]1206 guard_symtab guard { *this };
[17a0228a]1207 maybe_accept( node, &ConstantExpr::result );
1208 })
1209
1210 VISIT_END( Expr, node );
1211}
1212
1213//--------------------------------------------------------------------------
1214// SizeofExpr
[7ff3e522]1215template< typename core_t >
1216const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
[17a0228a]1217 VISIT_START( node );
1218
1219 VISIT({
[0e42794]1220 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1235template< typename core_t >
1236const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
[17a0228a]1237 VISIT_START( node );
1238
1239 VISIT({
[0e42794]1240 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1255template< typename core_t >
1256const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
[17a0228a]1257 VISIT_START( node );
1258
1259 VISIT({
[0e42794]1260 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1271template< typename core_t >
1272const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
[17a0228a]1273 VISIT_START( node );
1274
1275 VISIT({
[0e42794]1276 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1287template< typename core_t >
1288const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
[17a0228a]1289 VISIT_START( node );
1290
1291 VISIT({
[0e42794]1292 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1303template< typename core_t >
1304const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
[17a0228a]1305 VISIT_START( node );
1306
1307 VISIT({
[0e42794]1308 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1320template< typename core_t >
1321const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
[17a0228a]1322 VISIT_START( node );
1323
1324 VISIT({
[0e42794]1325 guard_symtab guard { *this };
[17a0228a]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}
[10a1225]1335
[17a0228a]1336//--------------------------------------------------------------------------
1337// CommaExpr
[7ff3e522]1338template< typename core_t >
1339const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
[17a0228a]1340 VISIT_START( node );
1341
1342 VISIT({
[0e42794]1343 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1355template< typename core_t >
1356const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
[17a0228a]1357 VISIT_START( node );
1358
1359 VISIT({
[0e42794]1360 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1371template< typename core_t >
1372const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
[17a0228a]1373 VISIT_START( node );
[10a1225]1374
[17a0228a]1375 VISIT({
[0e42794]1376 guard_symtab guard { *this };
[17a0228a]1377 maybe_accept( node, &AsmExpr::result );
1378 }
1379 maybe_accept( node, &AsmExpr::constraint );
1380 maybe_accept( node, &AsmExpr::operand );
1381 )
[10a1225]1382
[17a0228a]1383 VISIT_END( Expr, node );
1384}
[10a1225]1385
[17a0228a]1386//--------------------------------------------------------------------------
1387// ImplicitCopyCtorExpr
[7ff3e522]1388template< typename core_t >
1389const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
[17a0228a]1390 VISIT_START( node );
1391
1392 VISIT({
[0e42794]1393 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1404template< typename core_t >
1405const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
[17a0228a]1406 VISIT_START( node );
1407
1408 VISIT({
[0e42794]1409 guard_symtab guard { *this };
[17a0228a]1410 maybe_accept( node, &ConstructorExpr::result );
1411 }
1412 maybe_accept( node, &ConstructorExpr::callExpr );
1413 )
[10a1225]1414
[17a0228a]1415 VISIT_END( Expr, node );
1416}
1417
1418//--------------------------------------------------------------------------
1419// CompoundLiteralExpr
[7ff3e522]1420template< typename core_t >
1421const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
[17a0228a]1422 VISIT_START( node );
1423
1424 VISIT({
[0e42794]1425 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1436template< typename core_t >
1437const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
[17a0228a]1438 VISIT_START( node );
1439
1440 VISIT({
[0e42794]1441 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1453template< typename core_t >
1454const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
[17a0228a]1455 VISIT_START( node );
1456
1457 VISIT({
[0e42794]1458 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1469template< typename core_t >
1470const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
[17a0228a]1471 VISIT_START( node );
1472
1473 VISIT({
[0e42794]1474 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1485template< typename core_t >
1486const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
[17a0228a]1487 VISIT_START( node );
1488
1489 VISIT({
[0e42794]1490 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1501template< typename core_t >
1502const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
[17a0228a]1503 VISIT_START( node );
1504
1505 VISIT({
[0e42794]1506 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1517template< typename core_t >
1518const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
[17a0228a]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
[7ff3e522]1523 auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1524 auto stmts_after = __pass::stmtsToAddAfter ( core, 0);
[17a0228a]1525
1526 // These may be modified by subnode but most be restored once we exit this statemnet.
[b2a11ba]1527 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
[17a0228a]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 {
[0e42794]1532 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1545template< typename core_t >
1546const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
[17a0228a]1547 VISIT_START( node );
1548
1549 VISIT({
[0e42794]1550 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1561template< typename core_t >
1562const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
[17a0228a]1563 VISIT_START( node );
1564
1565 VISIT({
[0e42794]1566 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1578template< typename core_t >
1579const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
[17a0228a]1580 VISIT_START( node );
1581
1582 VISIT({
[0e42794]1583 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1595template< typename core_t >
1596const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
[17a0228a]1597 VISIT_START( node );
1598
1599 VISIT({
[0e42794]1600 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1612template< typename core_t >
1613const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
[17a0228a]1614 VISIT_START( node );
1615
1616 VISIT({
[0e42794]1617 guard_symtab guard { *this };
[17a0228a]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
[7ff3e522]1628template< typename core_t >
1629const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
[17a0228a]1630 VISIT_START( node );
1631
1632 VISIT({
[0e42794]1633 guard_symtab guard { *this };
[17a0228a]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 ) {
[b0abc8a0]1642 const Type * type = nullptr;
[17a0228a]1643 if( assoc.type ) {
[0e42794]1644 guard_symtab guard { *this };
[17a0228a]1645 type = assoc.type->accept( *this );
1646 if( type != assoc.type ) mutated = true;
1647 }
[b0abc8a0]1648 const Expr * expr = nullptr;
[17a0228a]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) {
[d3aa64f1]1657 auto n = __pass::mutate<core_t>(node);
[17a0228a]1658 n->associations = std::move( new_kids );
1659 node = n;
1660 }
1661 )
1662
1663 VISIT_END( Expr, node );
1664}
[10a1225]1665
[e0016a5]1666//--------------------------------------------------------------------------
1667// VoidType
[7ff3e522]1668template< typename core_t >
1669const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
[e0016a5]1670 VISIT_START( node );
[10a1225]1671
[e0016a5]1672 VISIT_END( Type, node );
1673}
[10a1225]1674
[e0016a5]1675//--------------------------------------------------------------------------
1676// BasicType
[7ff3e522]1677template< typename core_t >
1678const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
[e0016a5]1679 VISIT_START( node );
1680
1681 VISIT_END( Type, node );
1682}
1683
1684//--------------------------------------------------------------------------
1685// PointerType
[7ff3e522]1686template< typename core_t >
1687const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
[e0016a5]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
[7ff3e522]1700template< typename core_t >
1701const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
[e0016a5]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
[7ff3e522]1714template< typename core_t >
1715const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
[e0016a5]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
[7ff3e522]1727template< typename core_t >
1728const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
[e0016a5]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
[7ff3e522]1741template< typename core_t >
1742const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
[e0016a5]1743 VISIT_START( node );
1744
[e0e9a0b]1745 VISIT({
1746 guard_forall_subs forall_guard { *this, node };
1747 mutate_forall( node );
[e0016a5]1748 maybe_accept( node, &FunctionType::returns );
1749 maybe_accept( node, &FunctionType::params );
[e0e9a0b]1750 })
[e0016a5]1751
1752 VISIT_END( Type, node );
1753}
1754
1755//--------------------------------------------------------------------------
1756// StructInstType
[7ff3e522]1757template< typename core_t >
1758const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
[e0016a5]1759 VISIT_START( node );
1760
[7ff3e522]1761 __pass::symtab::addStruct( core, 0, node->name );
[e0016a5]1762
1763 VISIT({
[0e42794]1764 guard_symtab guard { *this };
[e0e9a0b]1765 guard_forall_subs forall_guard { *this, node };
1766 mutate_forall( node );
[e0016a5]1767 maybe_accept( node, &StructInstType::params );
1768 })
1769
1770 VISIT_END( Type, node );
1771}
1772
1773//--------------------------------------------------------------------------
1774// UnionInstType
[7ff3e522]1775template< typename core_t >
1776const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
[e0016a5]1777 VISIT_START( node );
1778
[7ff3e522]1779 __pass::symtab::addUnion( core, 0, node->name );
[e0016a5]1780
[e0e9a0b]1781 VISIT({
[0e42794]1782 guard_symtab guard { *this };
[e0e9a0b]1783 guard_forall_subs forall_guard { *this, node };
1784 mutate_forall( node );
[e0016a5]1785 maybe_accept( node, &UnionInstType::params );
[e0e9a0b]1786 })
[e0016a5]1787
1788 VISIT_END( Type, node );
1789}
1790
1791//--------------------------------------------------------------------------
1792// EnumInstType
[7ff3e522]1793template< typename core_t >
1794const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
[e0016a5]1795 VISIT_START( node );
1796
[e0e9a0b]1797 VISIT({
1798 guard_forall_subs forall_guard { *this, node };
1799 mutate_forall( node );
[e0016a5]1800 maybe_accept( node, &EnumInstType::params );
[e0e9a0b]1801 })
[e0016a5]1802
1803 VISIT_END( Type, node );
1804}
1805
1806//--------------------------------------------------------------------------
1807// TraitInstType
[7ff3e522]1808template< typename core_t >
1809const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
[e0016a5]1810 VISIT_START( node );
1811
[e0e9a0b]1812 VISIT({
1813 guard_forall_subs forall_guard { *this, node };
1814 mutate_forall( node );
[e0016a5]1815 maybe_accept( node, &TraitInstType::params );
[e0e9a0b]1816 })
[e0016a5]1817
1818 VISIT_END( Type, node );
1819}
1820
1821//--------------------------------------------------------------------------
1822// TypeInstType
[7ff3e522]1823template< typename core_t >
1824const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
[e0016a5]1825 VISIT_START( node );
1826
1827 VISIT(
[e0e9a0b]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
[7ff3e522]1834 __pass::forall::replace( core, 0, node );
[e0016a5]1835 )
1836
1837 VISIT_END( Type, node );
1838}
1839
1840//--------------------------------------------------------------------------
1841// TupleType
[7ff3e522]1842template< typename core_t >
1843const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
[e0016a5]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
[7ff3e522]1856template< typename core_t >
1857const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
[e0016a5]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
[7ff3e522]1869template< typename core_t >
1870const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
[e0016a5]1871 VISIT_START( node );
1872
1873 VISIT_END( Type, node );
1874}
1875
1876//--------------------------------------------------------------------------
1877// ZeroType
[7ff3e522]1878template< typename core_t >
1879const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
[e0016a5]1880 VISIT_START( node );
1881
1882 VISIT_END( Type, node );
1883}
1884
1885//--------------------------------------------------------------------------
1886// OneType
[7ff3e522]1887template< typename core_t >
1888const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
[e0016a5]1889 VISIT_START( node );
1890
1891 VISIT_END( Type, node );
1892}
1893
1894//--------------------------------------------------------------------------
1895// GlobalScopeType
[7ff3e522]1896template< typename core_t >
1897const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
[e0016a5]1898 VISIT_START( node );
1899
1900 VISIT_END( Type, node );
1901}
1902
1903
1904//--------------------------------------------------------------------------
1905// Designation
[7ff3e522]1906template< typename core_t >
1907const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
[e0016a5]1908 VISIT_START( node );
1909
1910 VISIT( maybe_accept( node, &Designation::designators ); )
1911
1912 VISIT_END( Designation, node );
1913}
[10a1225]1914
[6d51bd7]1915//--------------------------------------------------------------------------
1916// SingleInit
[7ff3e522]1917template< typename core_t >
1918const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
[6d51bd7]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
[7ff3e522]1930template< typename core_t >
1931const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
[6d51bd7]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
[7ff3e522]1944template< typename core_t >
1945const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
[6d51bd7]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
[f47f887]1957//--------------------------------------------------------------------------
1958// Attribute
[7ff3e522]1959template< typename core_t >
1960const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node ) {
[6d51bd7]1961 VISIT_START( node );
[f47f887]1962
1963 VISIT(
[489bacf]1964 maybe_accept( node, &Attribute::params );
[f47f887]1965 )
1966
[8a5530c]1967 VISIT_END( Attribute, node );
[f47f887]1968}
1969
1970//--------------------------------------------------------------------------
1971// TypeSubstitution
[7ff3e522]1972template< typename core_t >
1973const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
[6d51bd7]1974 VISIT_START( node );
[f47f887]1975
[6d51bd7]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 ) {
[0e42794]1981 guard_symtab guard { *this };
[6d51bd7]1982 auto new_node = p.second->accept( *this );
[417117e]1983 if (new_node != p.second) mutated = true;
[6d51bd7]1984 new_map.insert({ p.first, new_node });
1985 }
1986 if (mutated) {
[d3aa64f1]1987 auto new_node = __pass::mutate<core_t>( node );
[6d51bd7]1988 new_node->typeEnv.swap( new_map );
1989 node = new_node;
1990 }
1991 }
[f47f887]1992
[6d51bd7]1993 {
1994 bool mutated = false;
1995 std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
1996 for ( const auto & p : node->varEnv ) {
[0e42794]1997 guard_symtab guard { *this };
[6d51bd7]1998 auto new_node = p.second->accept( *this );
[417117e]1999 if (new_node != p.second) mutated = true;
[6d51bd7]2000 new_map.insert({ p.first, new_node });
2001 }
2002 if (mutated) {
[d3aa64f1]2003 auto new_node = __pass::mutate<core_t>( node );
[6d51bd7]2004 new_node->varEnv.swap( new_map );
2005 node = new_node;
2006 }
2007 }
2008 )
[f47f887]2009
[6d51bd7]2010 VISIT_END( TypeSubstitution, node );
[f47f887]2011}
2012
2013#undef VISIT_START
2014#undef VISIT
[112fe04]2015#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.