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

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

Rename WithConstTypeSubstitution from env to typeSubs to avoid name collision.

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