source: src/AST/Pass.impl.hpp@ 729c991

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 729c991 was ab1a9ea, checked in by caparsons <caparson@…>, 4 years ago

fixed merge

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