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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 7a2a3af was 490fb92e, checked in by Fangren Yu <f37yu@…>, 5 years ago

move FixInit to new ast

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