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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since ef9988b was 7ff3e522, checked in by Andrew Beach <ajbeach@…>, 5 years ago

{pass_t Pass::pass; => core_t Pass::core;} To avoid confusion about which pass we are talking about.

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