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

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 c86f587 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
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ast::Pass.impl.hpp --
8//
9// Author : Thierry Delisle
10// Created On : Thu May 09 15::37::05 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#pragma once
17// IWYU pragma: private, include "AST/Pass.hpp"
18
19#include <type_traits>
20#include <unordered_map>
21
22#include "AST/TypeSubstitution.hpp"
23// #include "AST/Copy.hpp"
24
25#define VISIT_START( node ) \
26 using namespace ast; \
27 /* back-up the visit children */ \
28 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \
29 /* setup the scope for passes that want to run code at exit */ \
30 __attribute__((unused)) ast::__pass::guard_value guard2( ast::__pass::at_cleanup (core, 0) ); \
31 /* begin tracing memory allocation if requested by this pass */ \
32 __pass::beginTrace( core, 0 ); \
33 /* call the implementation of the previsit of this pass */ \
34 __pass::previsit( core, node, 0 );
35
36#define VISIT( code... ) \
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 */ \
45 auto __return = __pass::postvisit( core, node, 0 ); \
46 assertf(__return, "post visit should never return null"); \
47 /* end tracing memory allocation if requested by this pass */ \
48 __pass::endTrace( core, 0 ); \
49 return __return;
50
51#ifdef PEDANTIC_PASS_ASSERT
52#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
53#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
54#else
55#define __pedantic_pass_assert(...)
56#define __pedantic_pass_assertf(...)
57#endif
58
59namespace ast {
60 template<typename node_t>
61 node_t * shallowCopy( const node_t * node );
62
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
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
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 ) {
78 if(empty(decls)) return;
79
80 std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
81 return new DeclStmt( decl->location, decl );
82 });
83 decls->clear();
84 if(mutated) *mutated = true;
85 }
86
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 ) {
89 if(empty(decls)) return;
90
91 std::move(decls->begin(), decls->end(), it);
92 decls->clear();
93 if(mutated) *mutated = true;
94 }
95
96 //------------------------------
97 /// Check if should be skipped, different for pointers and containers
98 template<typename node_t>
99 bool skip( const ast::ptr<node_t> & val) {
100 return !val;
101 }
102
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();
106 }
107
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 }
114
115 template<typename node_t>
116 const node_t & get( const node_t & val, long) {
117 return val;
118 }
119
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();
131 }
132 }
133
134 template< typename core_t >
135 template< typename node_t >
136 auto ast::Pass< core_t >::call_accept( const node_t * node )
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 {
143 __pedantic_pass_assert( __visit_children() );
144 __pedantic_pass_assert( node );
145
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
149 return node->accept( *this );
150 }
151
152 template< typename core_t >
153 const ast::Expr * ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
154 __pedantic_pass_assert( __visit_children() );
155 __pedantic_pass_assert( expr );
156
157 const ast::TypeSubstitution ** env_ptr = __pass::env( core, 0);
158 if ( env_ptr && expr->env ) {
159 *env_ptr = expr->env;
160 }
161
162 return expr->accept( *this );
163 }
164
165 template< typename core_t >
166 const ast::Stmt * ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
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
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);
178
179 // These may be modified by subnode but most be restored once we exit this statemnet.
180 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::env( core, 0) );
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 );
185
186 // Now is the time to actually visit the node
187 const ast::Stmt * nstmt = stmt->accept( *this );
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
200 ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
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
207 compound->kids.emplace_back( nstmt );
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
216 template< typename core_t >
217 template< template <class...> class container_t >
218 container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
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
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);
233
234 // These may be modified by subnode but most be restored once we exit this statemnet.
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 );
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;
246 container_t< ptr<Stmt> > new_kids;
247 for( const Stmt * stmt : statements ) {
248 try {
249 __pedantic_pass_assert( stmt );
250 const ast::Stmt * new_stmt = stmt->accept( *this );
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
279 return mutated ? new_kids : container_t< ptr<Stmt> >();
280 }
281
282 template< typename core_t >
283 template< template <class...> class container_t, typename node_t >
284 container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
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 );
298 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
299 if(new_stmt != node ) mutated = true;
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
310 return mutated ? new_kids : container_t< ast::ptr<node_t> >();
311 }
312
313 template< typename core_t >
314 template<typename node_t, typename parent_t, typename child_t>
315 void ast::Pass< core_t >::maybe_accept(
316 const node_t * & parent,
317 child_t parent_t::*child
318 ) {
319 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );
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) ) {
331 // auto new_parent = mutate(parent);
332 auto new_parent = __pass::mutate<core_t>(parent);
333 new_parent->*child = new_val;
334 parent = new_parent;
335 }
336 }
337
338
339 template< typename core_t >
340 template< typename node_t >
341 void ast::Pass< core_t >::mutate_forall( const node_t *& node ) {
342 if ( auto subs = __pass::forall::subs( core, 0 ) ) {
343 // tracking TypeDecl substitution, full clone
344 if ( node->forall.empty() ) return;
345
346 node_t * mut = __pass::mutate<core_t>( node );
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 }
354}
355
356//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
357//========================================================================================================================================================================
358//========================================================================================================================================================================
359//========================================================================================================================================================================
360//========================================================================================================================================================================
361//========================================================================================================================================================================
362//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
363
364template< typename core_t >
365inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< core_t > & visitor ) {
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
373 auto decls_before = __pass::declsToAddBefore( visitor.core, 0);
374 auto decls_after = __pass::declsToAddAfter ( visitor.core, 0);
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
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
423template< typename core_t >
424const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::ObjectDecl * node ) {
425 VISIT_START( node );
426
427 VISIT(
428 {
429 guard_symtab guard { *this };
430 maybe_accept( node, &ObjectDecl::type );
431 }
432 maybe_accept( node, &ObjectDecl::init );
433 maybe_accept( node, &ObjectDecl::bitfieldWidth );
434 maybe_accept( node, &ObjectDecl::attributes );
435 )
436
437 __pass::symtab::addId( core, 0, node );
438
439 VISIT_END( DeclWithType, node );
440}
441
442//--------------------------------------------------------------------------
443// FunctionDecl
444template< typename core_t >
445const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::FunctionDecl * node ) {
446 VISIT_START( node );
447
448 __pass::symtab::addId( core, 0, node );
449
450 VISIT(maybe_accept( node, &FunctionDecl::withExprs );)
451 {
452 // with clause introduces a level of scope (for the with expression members).
453 // with clause exprs are added to the symbol table before parameters so that parameters
454 // shadow with exprs and not the other way around.
455 guard_symtab guard { *this };
456 __pass::symtab::addWith( core, 0, node->withExprs, node );
457 {
458 guard_symtab guard { *this };
459 // implicit add __func__ identifier as specified in the C manual 6.4.2.2
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 },
464 nullptr, VariableLen, DynamicDim
465 }
466 } };
467 __pass::symtab::addId( core, 0, func );
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;
474 maybe_accept( node, &FunctionDecl::stmts );
475 maybe_accept( node, &FunctionDecl::attributes );
476 )
477 }
478 }
479
480 VISIT_END( DeclWithType, node );
481}
482
483//--------------------------------------------------------------------------
484// StructDecl
485template< typename core_t >
486const ast::Decl * ast::Pass< core_t >::visit( const ast::StructDecl * node ) {
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
491 __pass::symtab::addStructFwd( core, 0, node );
492
493 VISIT({
494 guard_symtab guard { * this };
495 maybe_accept( node, &StructDecl::params );
496 maybe_accept( node, &StructDecl::members );
497 })
498
499 // this addition replaces the forward declaration
500 __pass::symtab::addStruct( core, 0, node );
501
502 VISIT_END( Decl, node );
503}
504
505//--------------------------------------------------------------------------
506// UnionDecl
507template< typename core_t >
508const ast::Decl * ast::Pass< core_t >::visit( const ast::UnionDecl * node ) {
509 VISIT_START( node );
510
511 // make up a forward declaration and add it before processing the members
512 __pass::symtab::addUnionFwd( core, 0, node );
513
514 VISIT({
515 guard_symtab guard { * this };
516 maybe_accept( node, &UnionDecl::params );
517 maybe_accept( node, &UnionDecl::members );
518 })
519
520 __pass::symtab::addUnion( core, 0, node );
521
522 VISIT_END( Decl, node );
523}
524
525//--------------------------------------------------------------------------
526// EnumDecl
527template< typename core_t >
528const ast::Decl * ast::Pass< core_t >::visit( const ast::EnumDecl * node ) {
529 VISIT_START( node );
530
531 __pass::symtab::addEnum( core, 0, node );
532
533 VISIT(
534 // unlike structs, traits, and unions, enums inject their members into the global scope
535 maybe_accept( node, &EnumDecl::params );
536 maybe_accept( node, &EnumDecl::members );
537 )
538
539 VISIT_END( Decl, node );
540}
541
542//--------------------------------------------------------------------------
543// TraitDecl
544template< typename core_t >
545const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
546 VISIT_START( node );
547
548 VISIT({
549 guard_symtab guard { *this };
550 maybe_accept( node, &TraitDecl::params );
551 maybe_accept( node, &TraitDecl::members );
552 })
553
554 __pass::symtab::addTrait( core, 0, node );
555
556 VISIT_END( Decl, node );
557}
558
559//--------------------------------------------------------------------------
560// TypeDecl
561template< typename core_t >
562const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
563 VISIT_START( node );
564
565 VISIT({
566 guard_symtab guard { *this };
567 maybe_accept( node, &TypeDecl::params );
568 maybe_accept( node, &TypeDecl::base );
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
574 __pass::symtab::addType( core, 0, node );
575
576 VISIT(
577 maybe_accept( node, &TypeDecl::assertions );
578
579 {
580 guard_symtab guard { *this };
581 maybe_accept( node, &TypeDecl::init );
582 }
583 )
584
585 VISIT_END( Decl, node );
586}
587
588//--------------------------------------------------------------------------
589// TypedefDecl
590template< typename core_t >
591const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
592 VISIT_START( node );
593
594 VISIT({
595 guard_symtab guard { *this };
596 maybe_accept( node, &TypedefDecl::params );
597 maybe_accept( node, &TypedefDecl::base );
598 })
599
600 __pass::symtab::addType( core, 0, node );
601
602 VISIT( maybe_accept( node, &TypedefDecl::assertions ); )
603
604 VISIT_END( Decl, node );
605}
606
607//--------------------------------------------------------------------------
608// AsmDecl
609template< typename core_t >
610const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
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
622template< typename core_t >
623const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
624 VISIT_START( node );
625
626 VISIT(
627 maybe_accept( node, &StaticAssertDecl::cond );
628 maybe_accept( node, &StaticAssertDecl::msg );
629 )
630
631 VISIT_END( StaticAssertDecl, node );
632}
633
634//--------------------------------------------------------------------------
635// CompoundStmt
636template< typename core_t >
637const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
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
641 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() {
642 if ( ! inFunctionCpy ) __pass::symtab::enter(core, 0);
643 }, [this, inFunctionCpy = this->inFunction]() {
644 if ( ! inFunctionCpy ) __pass::symtab::leave(core, 0);
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
654//--------------------------------------------------------------------------
655// ExprStmt
656template< typename core_t >
657const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
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
669template< typename core_t >
670const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
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
685template< typename core_t >
686const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
687 VISIT_START( node )
688
689 VISIT_END( Stmt, node );
690}
691
692//--------------------------------------------------------------------------
693// IfStmt
694template< typename core_t >
695const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
696 VISIT_START( node );
697
698 VISIT({
699 // if statements introduce a level of scope (for the initialization)
700 guard_symtab guard { *this };
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 })
706
707 VISIT_END( Stmt, node );
708}
709
710//--------------------------------------------------------------------------
711// WhileStmt
712template< typename core_t >
713const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileStmt * node ) {
714 VISIT_START( node );
715
716 VISIT({
717 // while statements introduce a level of scope (for the initialization)
718 guard_symtab guard { *this };
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}
726
727//--------------------------------------------------------------------------
728// ForStmt
729template< typename core_t >
730const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
731 VISIT_START( node );
732
733 VISIT({
734 // for statements introduce a level of scope (for the initialization)
735 guard_symtab guard { *this };
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
747template< typename core_t >
748const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
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
761template< typename core_t >
762const ast::Stmt * ast::Pass< core_t >::visit( const ast::CaseStmt * node ) {
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
775template< typename core_t >
776const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
777 VISIT_START( node );
778 VISIT_END( Stmt, node );
779}
780
781//--------------------------------------------------------------------------
782// ReturnStmt
783template< typename core_t >
784const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
785 VISIT_START( node );
786
787 VISIT(
788 maybe_accept( node, &ReturnStmt::expr );
789 )
790
791 VISIT_END( Stmt, node );
792}
793
794//--------------------------------------------------------------------------
795// ThrowStmt
796template< typename core_t >
797const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
798 VISIT_START( node );
799
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
810template< typename core_t >
811const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
812 VISIT_START( node );
813
814 VISIT(
815 maybe_accept( node, &TryStmt::body );
816 maybe_accept( node, &TryStmt::handlers );
817 maybe_accept( node, &TryStmt::finally );
818 )
819
820 VISIT_END( Stmt, node );
821}
822
823//--------------------------------------------------------------------------
824// CatchStmt
825template< typename core_t >
826const ast::Stmt * ast::Pass< core_t >::visit( const ast::CatchStmt * node ) {
827 VISIT_START( node );
828
829 VISIT({
830 // catch statements introduce a level of scope (for the caught exception)
831 guard_symtab guard { *this };
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
842template< typename core_t >
843const ast::Stmt * ast::Pass< core_t >::visit( const ast::FinallyStmt * node ) {
844 VISIT_START( node );
845
846 VISIT(
847 maybe_accept( node, &FinallyStmt::body );
848 )
849
850 VISIT_END( Stmt, node );
851}
852
853//--------------------------------------------------------------------------
854// FinallyStmt
855template< typename core_t >
856const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
857 VISIT_START( node );
858
859 VISIT(
860 maybe_accept( node, &SuspendStmt::then );
861 )
862
863 VISIT_END( Stmt, node );
864}
865
866//--------------------------------------------------------------------------
867// WaitForStmt
868template< typename core_t >
869const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
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
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
885 const Expr * func = clause.target.func ? clause.target.func->accept(*this) : nullptr;
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
896 const Stmt * stmt = clause.stmt ? clause.stmt->accept(*this) : nullptr;
897 if(stmt != clause.stmt) mutated = true;
898
899 const Expr * cond = clause.cond ? clause.cond->accept(*this) : nullptr;
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) {
906 auto n = __pass::mutate<core_t>(node);
907 n->clauses = std::move( new_clauses );
908 node = n;
909 }
910 })
911
912 #define maybe_accept(field) \
913 if(node->field) { \
914 auto nval = call_accept( node->field ); \
915 if(nval != node->field ) { \
916 auto nparent = __pass::mutate<core_t>(node); \
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
937template< typename core_t >
938const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
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)
945 guard_symtab guard { *this };
946 __pass::symtab::addWith( core, 0, node->exprs, node );
947 maybe_accept( node, &WithStmt::stmt );
948 }
949 )
950 VISIT_END( Stmt, node );
951}
952
953//--------------------------------------------------------------------------
954// NullStmt
955template< typename core_t >
956const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
957 VISIT_START( node );
958 VISIT_END( NullStmt, node );
959}
960
961//--------------------------------------------------------------------------
962// DeclStmt
963template< typename core_t >
964const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
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
976template< typename core_t >
977const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
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
982 VISIT(
983 maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
984 )
985
986 VISIT_END( Stmt, node );
987}
988
989//--------------------------------------------------------------------------
990// ApplicationExpr
991template< typename core_t >
992const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
993 VISIT_START( node );
994
995 VISIT(
996 {
997 guard_symtab guard { *this };
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
1009template< typename core_t >
1010const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1011 VISIT_START( node );
1012
1013 VISIT(
1014 {
1015 guard_symtab guard { *this };
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
1027template< typename core_t >
1028const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1029 VISIT_START( node );
1030
1031 VISIT({
1032 guard_symtab guard { *this };
1033 maybe_accept( node, &NameExpr::result );
1034 })
1035
1036 VISIT_END( Expr, node );
1037}
1038
1039//--------------------------------------------------------------------------
1040// CastExpr
1041template< typename core_t >
1042const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1043 VISIT_START( node );
1044
1045 VISIT({
1046 guard_symtab guard { *this };
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
1057template< typename core_t >
1058const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1059 VISIT_START( node );
1060
1061 VISIT({
1062 guard_symtab guard { *this };
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
1073template< typename core_t >
1074const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1075 VISIT_START( node );
1076
1077 VISIT({
1078 guard_symtab guard { *this };
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
1089template< typename core_t >
1090const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1091 VISIT_START( node );
1092
1093 VISIT({
1094 guard_symtab guard { *this };
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
1105template< typename core_t >
1106const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1107 VISIT_START( node );
1108
1109 VISIT({
1110 guard_symtab guard { *this };
1111 maybe_accept( node, &LabelAddressExpr::result );
1112 })
1113
1114 VISIT_END( Expr, node );
1115}
1116
1117//--------------------------------------------------------------------------
1118// UntypedMemberExpr
1119template< typename core_t >
1120const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1121 VISIT_START( node );
1122
1123 VISIT({
1124 guard_symtab guard { *this };
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
1136template< typename core_t >
1137const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1138 VISIT_START( node );
1139
1140 VISIT({
1141 guard_symtab guard { *this };
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
1152template< typename core_t >
1153const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1154 VISIT_START( node );
1155
1156 VISIT({
1157 guard_symtab guard { *this };
1158 maybe_accept( node, &VariableExpr::result );
1159 })
1160
1161 VISIT_END( Expr, node );
1162}
1163
1164//--------------------------------------------------------------------------
1165// ConstantExpr
1166template< typename core_t >
1167const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1168 VISIT_START( node );
1169
1170 VISIT({
1171 guard_symtab guard { *this };
1172 maybe_accept( node, &ConstantExpr::result );
1173 })
1174
1175 VISIT_END( Expr, node );
1176}
1177
1178//--------------------------------------------------------------------------
1179// SizeofExpr
1180template< typename core_t >
1181const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1182 VISIT_START( node );
1183
1184 VISIT({
1185 guard_symtab guard { *this };
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
1200template< typename core_t >
1201const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1202 VISIT_START( node );
1203
1204 VISIT({
1205 guard_symtab guard { *this };
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
1220template< typename core_t >
1221const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1222 VISIT_START( node );
1223
1224 VISIT({
1225 guard_symtab guard { *this };
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
1236template< typename core_t >
1237const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1238 VISIT_START( node );
1239
1240 VISIT({
1241 guard_symtab guard { *this };
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
1252template< typename core_t >
1253const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1254 VISIT_START( node );
1255
1256 VISIT({
1257 guard_symtab guard { *this };
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
1268template< typename core_t >
1269const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1270 VISIT_START( node );
1271
1272 VISIT({
1273 guard_symtab guard { *this };
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
1285template< typename core_t >
1286const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1287 VISIT_START( node );
1288
1289 VISIT({
1290 guard_symtab guard { *this };
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}
1300
1301//--------------------------------------------------------------------------
1302// CommaExpr
1303template< typename core_t >
1304const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1305 VISIT_START( node );
1306
1307 VISIT({
1308 guard_symtab guard { *this };
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
1320template< typename core_t >
1321const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1322 VISIT_START( node );
1323
1324 VISIT({
1325 guard_symtab guard { *this };
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
1336template< typename core_t >
1337const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1338 VISIT_START( node );
1339
1340 VISIT({
1341 guard_symtab guard { *this };
1342 maybe_accept( node, &AsmExpr::result );
1343 }
1344 maybe_accept( node, &AsmExpr::constraint );
1345 maybe_accept( node, &AsmExpr::operand );
1346 )
1347
1348 VISIT_END( Expr, node );
1349}
1350
1351//--------------------------------------------------------------------------
1352// ImplicitCopyCtorExpr
1353template< typename core_t >
1354const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1355 VISIT_START( node );
1356
1357 VISIT({
1358 guard_symtab guard { *this };
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
1369template< typename core_t >
1370const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1371 VISIT_START( node );
1372
1373 VISIT({
1374 guard_symtab guard { *this };
1375 maybe_accept( node, &ConstructorExpr::result );
1376 }
1377 maybe_accept( node, &ConstructorExpr::callExpr );
1378 )
1379
1380 VISIT_END( Expr, node );
1381}
1382
1383//--------------------------------------------------------------------------
1384// CompoundLiteralExpr
1385template< typename core_t >
1386const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1387 VISIT_START( node );
1388
1389 VISIT({
1390 guard_symtab guard { *this };
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
1401template< typename core_t >
1402const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1403 VISIT_START( node );
1404
1405 VISIT({
1406 guard_symtab guard { *this };
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
1418template< typename core_t >
1419const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1420 VISIT_START( node );
1421
1422 VISIT({
1423 guard_symtab guard { *this };
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
1434template< typename core_t >
1435const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1436 VISIT_START( node );
1437
1438 VISIT({
1439 guard_symtab guard { *this };
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
1450template< typename core_t >
1451const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1452 VISIT_START( node );
1453
1454 VISIT({
1455 guard_symtab guard { *this };
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
1466template< typename core_t >
1467const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1468 VISIT_START( node );
1469
1470 VISIT({
1471 guard_symtab guard { *this };
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
1482template< typename core_t >
1483const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
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
1488 auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1489 auto stmts_after = __pass::stmtsToAddAfter ( core, 0);
1490
1491 // These may be modified by subnode but most be restored once we exit this statemnet.
1492 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::env( core, 0) );
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 {
1497 guard_symtab guard { *this };
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
1510template< typename core_t >
1511const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1512 VISIT_START( node );
1513
1514 VISIT({
1515 guard_symtab guard { *this };
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
1526template< typename core_t >
1527const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1528 VISIT_START( node );
1529
1530 VISIT({
1531 guard_symtab guard { *this };
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
1543template< typename core_t >
1544const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1545 VISIT_START( node );
1546
1547 VISIT({
1548 guard_symtab guard { *this };
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
1560template< typename core_t >
1561const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1562 VISIT_START( node );
1563
1564 VISIT({
1565 guard_symtab guard { *this };
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
1577template< typename core_t >
1578const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1579 VISIT_START( node );
1580
1581 VISIT({
1582 guard_symtab guard { *this };
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
1593template< typename core_t >
1594const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1595 VISIT_START( node );
1596
1597 VISIT({
1598 guard_symtab guard { *this };
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 ) {
1607 const Type * type = nullptr;
1608 if( assoc.type ) {
1609 guard_symtab guard { *this };
1610 type = assoc.type->accept( *this );
1611 if( type != assoc.type ) mutated = true;
1612 }
1613 const Expr * expr = nullptr;
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) {
1622 auto n = __pass::mutate<core_t>(node);
1623 n->associations = std::move( new_kids );
1624 node = n;
1625 }
1626 )
1627
1628 VISIT_END( Expr, node );
1629}
1630
1631//--------------------------------------------------------------------------
1632// VoidType
1633template< typename core_t >
1634const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1635 VISIT_START( node );
1636
1637 VISIT_END( Type, node );
1638}
1639
1640//--------------------------------------------------------------------------
1641// BasicType
1642template< typename core_t >
1643const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1644 VISIT_START( node );
1645
1646 VISIT_END( Type, node );
1647}
1648
1649//--------------------------------------------------------------------------
1650// PointerType
1651template< typename core_t >
1652const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
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
1665template< typename core_t >
1666const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
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
1679template< typename core_t >
1680const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
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
1692template< typename core_t >
1693const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
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
1706template< typename core_t >
1707const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1708 VISIT_START( node );
1709
1710 VISIT({
1711 guard_forall_subs forall_guard { *this, node };
1712 mutate_forall( node );
1713 maybe_accept( node, &FunctionType::returns );
1714 maybe_accept( node, &FunctionType::params );
1715 })
1716
1717 VISIT_END( Type, node );
1718}
1719
1720//--------------------------------------------------------------------------
1721// StructInstType
1722template< typename core_t >
1723const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1724 VISIT_START( node );
1725
1726 __pass::symtab::addStruct( core, 0, node->name );
1727
1728 VISIT({
1729 guard_symtab guard { *this };
1730 guard_forall_subs forall_guard { *this, node };
1731 mutate_forall( node );
1732 maybe_accept( node, &StructInstType::params );
1733 })
1734
1735 VISIT_END( Type, node );
1736}
1737
1738//--------------------------------------------------------------------------
1739// UnionInstType
1740template< typename core_t >
1741const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
1742 VISIT_START( node );
1743
1744 __pass::symtab::addUnion( core, 0, node->name );
1745
1746 VISIT({
1747 guard_symtab guard { *this };
1748 guard_forall_subs forall_guard { *this, node };
1749 mutate_forall( node );
1750 maybe_accept( node, &UnionInstType::params );
1751 })
1752
1753 VISIT_END( Type, node );
1754}
1755
1756//--------------------------------------------------------------------------
1757// EnumInstType
1758template< typename core_t >
1759const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
1760 VISIT_START( node );
1761
1762 VISIT({
1763 guard_forall_subs forall_guard { *this, node };
1764 mutate_forall( node );
1765 maybe_accept( node, &EnumInstType::params );
1766 })
1767
1768 VISIT_END( Type, node );
1769}
1770
1771//--------------------------------------------------------------------------
1772// TraitInstType
1773template< typename core_t >
1774const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
1775 VISIT_START( node );
1776
1777 VISIT({
1778 guard_forall_subs forall_guard { *this, node };
1779 mutate_forall( node );
1780 maybe_accept( node, &TraitInstType::params );
1781 })
1782
1783 VISIT_END( Type, node );
1784}
1785
1786//--------------------------------------------------------------------------
1787// TypeInstType
1788template< typename core_t >
1789const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
1790 VISIT_START( node );
1791
1792 VISIT(
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
1799 __pass::forall::replace( core, 0, node );
1800 )
1801
1802 VISIT_END( Type, node );
1803}
1804
1805//--------------------------------------------------------------------------
1806// TupleType
1807template< typename core_t >
1808const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
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
1821template< typename core_t >
1822const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
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
1834template< typename core_t >
1835const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
1836 VISIT_START( node );
1837
1838 VISIT_END( Type, node );
1839}
1840
1841//--------------------------------------------------------------------------
1842// ZeroType
1843template< typename core_t >
1844const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
1845 VISIT_START( node );
1846
1847 VISIT_END( Type, node );
1848}
1849
1850//--------------------------------------------------------------------------
1851// OneType
1852template< typename core_t >
1853const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
1854 VISIT_START( node );
1855
1856 VISIT_END( Type, node );
1857}
1858
1859//--------------------------------------------------------------------------
1860// GlobalScopeType
1861template< typename core_t >
1862const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
1863 VISIT_START( node );
1864
1865 VISIT_END( Type, node );
1866}
1867
1868
1869//--------------------------------------------------------------------------
1870// Designation
1871template< typename core_t >
1872const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
1873 VISIT_START( node );
1874
1875 VISIT( maybe_accept( node, &Designation::designators ); )
1876
1877 VISIT_END( Designation, node );
1878}
1879
1880//--------------------------------------------------------------------------
1881// SingleInit
1882template< typename core_t >
1883const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
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
1895template< typename core_t >
1896const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
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
1909template< typename core_t >
1910const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
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
1922//--------------------------------------------------------------------------
1923// Attribute
1924template< typename core_t >
1925const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node ) {
1926 VISIT_START( node );
1927
1928 VISIT(
1929 maybe_accept( node, &Attribute::params );
1930 )
1931
1932 VISIT_END( Attribute, node );
1933}
1934
1935//--------------------------------------------------------------------------
1936// TypeSubstitution
1937template< typename core_t >
1938const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
1939 VISIT_START( node );
1940
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 ) {
1946 guard_symtab guard { *this };
1947 auto new_node = p.second->accept( *this );
1948 if (new_node != p.second) mutated = true;
1949 new_map.insert({ p.first, new_node });
1950 }
1951 if (mutated) {
1952 auto new_node = __pass::mutate<core_t>( node );
1953 new_node->typeEnv.swap( new_map );
1954 node = new_node;
1955 }
1956 }
1957
1958 {
1959 bool mutated = false;
1960 std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
1961 for ( const auto & p : node->varEnv ) {
1962 guard_symtab guard { *this };
1963 auto new_node = p.second->accept( *this );
1964 if (new_node != p.second) mutated = true;
1965 new_map.insert({ p.first, new_node });
1966 }
1967 if (mutated) {
1968 auto new_node = __pass::mutate<core_t>( node );
1969 new_node->varEnv.swap( new_map );
1970 node = new_node;
1971 }
1972 }
1973 )
1974
1975 VISIT_END( TypeSubstitution, node );
1976}
1977
1978#undef VISIT_START
1979#undef VISIT
1980#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.