source: src/AST/Pass.impl.hpp@ 417117e

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 417117e was 417117e, checked in by Aaron Moss <a3moss@…>, 6 years ago

Assorted cleanup

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