source: src/AST/Pass.impl.hpp@ 34c32f0

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

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 60.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ast::Pass.impl.hpp --
8//
9// Author : Thierry Delisle
10// Created On : Thu May 09 15::37::05 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#pragma once
17// IWYU pragma: private, include "AST/Pass.hpp"
18
19#include <type_traits>
20#include <unordered_map>
21
22#include "AST/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<<<<<<< HEAD
1053 VISIT(
1054 maybe_accept( node, &MutexStmt::mutexObjs );
1055 {
1056 // mutex statements introduce a level of scope (for the initialization)
1057 guard_symtab guard { *this };
1058 maybe_accept( node, &MutexStmt::stmt );
1059
1060 }
1061 )
1062=======
1063 if ( __visit_children() ) {
1064 // mutex statements introduce a level of scope (for the initialization)
1065 guard_symtab guard { *this };
1066 maybe_accept( node, &MutexStmt::stmt );
1067 maybe_accept( node, &MutexStmt::mutexObjs );
1068 }
1069>>>>>>> e21f2536b7495654ded040259b42b7e2325b8360
1070
1071 VISIT_END( Stmt, node );
1072}
1073
1074//--------------------------------------------------------------------------
1075// ApplicationExpr
1076template< typename core_t >
1077const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
1078 VISIT_START( node );
1079
1080 if ( __visit_children() ) {
1081 {
1082 guard_symtab guard { *this };
1083 maybe_accept( node, &ApplicationExpr::result );
1084 }
1085 maybe_accept( node, &ApplicationExpr::func );
1086 maybe_accept( node, &ApplicationExpr::args );
1087 }
1088
1089 VISIT_END( Expr, node );
1090}
1091
1092//--------------------------------------------------------------------------
1093// UntypedExpr
1094template< typename core_t >
1095const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1096 VISIT_START( node );
1097
1098 if ( __visit_children() ) {
1099 {
1100 guard_symtab guard { *this };
1101 maybe_accept( node, &UntypedExpr::result );
1102 }
1103
1104 maybe_accept( node, &UntypedExpr::args );
1105 }
1106
1107 VISIT_END( Expr, node );
1108}
1109
1110//--------------------------------------------------------------------------
1111// NameExpr
1112template< typename core_t >
1113const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1114 VISIT_START( node );
1115
1116 if ( __visit_children() ) {
1117 guard_symtab guard { *this };
1118 maybe_accept( node, &NameExpr::result );
1119 }
1120
1121 VISIT_END( Expr, node );
1122}
1123
1124//--------------------------------------------------------------------------
1125// CastExpr
1126template< typename core_t >
1127const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1128 VISIT_START( node );
1129
1130 if ( __visit_children() ) {
1131 {
1132 guard_symtab guard { *this };
1133 maybe_accept( node, &CastExpr::result );
1134 }
1135 maybe_accept( node, &CastExpr::arg );
1136 }
1137
1138 VISIT_END( Expr, node );
1139}
1140
1141//--------------------------------------------------------------------------
1142// KeywordCastExpr
1143template< typename core_t >
1144const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1145 VISIT_START( node );
1146
1147 if ( __visit_children() ) {
1148 {
1149 guard_symtab guard { *this };
1150 maybe_accept( node, &KeywordCastExpr::result );
1151 }
1152 maybe_accept( node, &KeywordCastExpr::arg );
1153 }
1154
1155 VISIT_END( Expr, node );
1156}
1157
1158//--------------------------------------------------------------------------
1159// VirtualCastExpr
1160template< typename core_t >
1161const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1162 VISIT_START( node );
1163
1164 if ( __visit_children() ) {
1165 {
1166 guard_symtab guard { *this };
1167 maybe_accept( node, &VirtualCastExpr::result );
1168 }
1169 maybe_accept( node, &VirtualCastExpr::arg );
1170 }
1171
1172 VISIT_END( Expr, node );
1173}
1174
1175//--------------------------------------------------------------------------
1176// AddressExpr
1177template< typename core_t >
1178const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1179 VISIT_START( node );
1180
1181 if ( __visit_children() ) {
1182 {
1183 guard_symtab guard { *this };
1184 maybe_accept( node, &AddressExpr::result );
1185 }
1186 maybe_accept( node, &AddressExpr::arg );
1187 }
1188
1189 VISIT_END( Expr, node );
1190}
1191
1192//--------------------------------------------------------------------------
1193// LabelAddressExpr
1194template< typename core_t >
1195const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1196 VISIT_START( node );
1197
1198 if ( __visit_children() ) {
1199 guard_symtab guard { *this };
1200 maybe_accept( node, &LabelAddressExpr::result );
1201 }
1202
1203 VISIT_END( Expr, node );
1204}
1205
1206//--------------------------------------------------------------------------
1207// UntypedMemberExpr
1208template< typename core_t >
1209const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1210 VISIT_START( node );
1211
1212 if ( __visit_children() ) {
1213 {
1214 guard_symtab guard { *this };
1215 maybe_accept( node, &UntypedMemberExpr::result );
1216 }
1217 maybe_accept( node, &UntypedMemberExpr::aggregate );
1218 maybe_accept( node, &UntypedMemberExpr::member );
1219 }
1220
1221 VISIT_END( Expr, node );
1222}
1223
1224//--------------------------------------------------------------------------
1225// MemberExpr
1226template< typename core_t >
1227const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1228 VISIT_START( node );
1229
1230 if ( __visit_children() ) {
1231 {
1232 guard_symtab guard { *this };
1233 maybe_accept( node, &MemberExpr::result );
1234 }
1235 maybe_accept( node, &MemberExpr::aggregate );
1236 }
1237
1238 VISIT_END( Expr, node );
1239}
1240
1241//--------------------------------------------------------------------------
1242// VariableExpr
1243template< typename core_t >
1244const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1245 VISIT_START( node );
1246
1247 if ( __visit_children() ) {
1248 guard_symtab guard { *this };
1249 maybe_accept( node, &VariableExpr::result );
1250 }
1251
1252 VISIT_END( Expr, node );
1253}
1254
1255//--------------------------------------------------------------------------
1256// ConstantExpr
1257template< typename core_t >
1258const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1259 VISIT_START( node );
1260
1261 if ( __visit_children() ) {
1262 guard_symtab guard { *this };
1263 maybe_accept( node, &ConstantExpr::result );
1264 }
1265
1266 VISIT_END( Expr, node );
1267}
1268
1269//--------------------------------------------------------------------------
1270// SizeofExpr
1271template< typename core_t >
1272const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1273 VISIT_START( node );
1274
1275 if ( __visit_children() ) {
1276 {
1277 guard_symtab guard { *this };
1278 maybe_accept( node, &SizeofExpr::result );
1279 }
1280 if ( node->type ) {
1281 maybe_accept( node, &SizeofExpr::type );
1282 } else {
1283 maybe_accept( node, &SizeofExpr::expr );
1284 }
1285 }
1286
1287 VISIT_END( Expr, node );
1288}
1289
1290//--------------------------------------------------------------------------
1291// AlignofExpr
1292template< typename core_t >
1293const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1294 VISIT_START( node );
1295
1296 if ( __visit_children() ) {
1297 {
1298 guard_symtab guard { *this };
1299 maybe_accept( node, &AlignofExpr::result );
1300 }
1301 if ( node->type ) {
1302 maybe_accept( node, &AlignofExpr::type );
1303 } else {
1304 maybe_accept( node, &AlignofExpr::expr );
1305 }
1306 }
1307
1308 VISIT_END( Expr, node );
1309}
1310
1311//--------------------------------------------------------------------------
1312// UntypedOffsetofExpr
1313template< typename core_t >
1314const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1315 VISIT_START( node );
1316
1317 if ( __visit_children() ) {
1318 {
1319 guard_symtab guard { *this };
1320 maybe_accept( node, &UntypedOffsetofExpr::result );
1321 }
1322 maybe_accept( node, &UntypedOffsetofExpr::type );
1323 }
1324
1325 VISIT_END( Expr, node );
1326}
1327
1328//--------------------------------------------------------------------------
1329// OffsetofExpr
1330template< typename core_t >
1331const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1332 VISIT_START( node );
1333
1334 if ( __visit_children() ) {
1335 {
1336 guard_symtab guard { *this };
1337 maybe_accept( node, &OffsetofExpr::result );
1338 }
1339 maybe_accept( node, &OffsetofExpr::type );
1340 }
1341
1342 VISIT_END( Expr, node );
1343}
1344
1345//--------------------------------------------------------------------------
1346// OffsetPackExpr
1347template< typename core_t >
1348const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1349 VISIT_START( node );
1350
1351 if ( __visit_children() ) {
1352 {
1353 guard_symtab guard { *this };
1354 maybe_accept( node, &OffsetPackExpr::result );
1355 }
1356 maybe_accept( node, &OffsetPackExpr::type );
1357 }
1358
1359 VISIT_END( Expr, node );
1360}
1361
1362//--------------------------------------------------------------------------
1363// LogicalExpr
1364template< typename core_t >
1365const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1366 VISIT_START( node );
1367
1368 if ( __visit_children() ) {
1369 {
1370 guard_symtab guard { *this };
1371 maybe_accept( node, &LogicalExpr::result );
1372 }
1373 maybe_accept( node, &LogicalExpr::arg1 );
1374 maybe_accept( node, &LogicalExpr::arg2 );
1375 }
1376
1377 VISIT_END( Expr, node );
1378}
1379
1380//--------------------------------------------------------------------------
1381// ConditionalExpr
1382template< typename core_t >
1383const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1384 VISIT_START( node );
1385
1386 if ( __visit_children() ) {
1387 {
1388 guard_symtab guard { *this };
1389 maybe_accept( node, &ConditionalExpr::result );
1390 }
1391 maybe_accept( node, &ConditionalExpr::arg1 );
1392 maybe_accept( node, &ConditionalExpr::arg2 );
1393 maybe_accept( node, &ConditionalExpr::arg3 );
1394 }
1395
1396 VISIT_END( Expr, node );
1397}
1398
1399//--------------------------------------------------------------------------
1400// CommaExpr
1401template< typename core_t >
1402const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1403 VISIT_START( node );
1404
1405 if ( __visit_children() ) {
1406 {
1407 guard_symtab guard { *this };
1408 maybe_accept( node, &CommaExpr::result );
1409 }
1410 maybe_accept( node, &CommaExpr::arg1 );
1411 maybe_accept( node, &CommaExpr::arg2 );
1412 }
1413
1414 VISIT_END( Expr, node );
1415}
1416
1417//--------------------------------------------------------------------------
1418// TypeExpr
1419template< typename core_t >
1420const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1421 VISIT_START( node );
1422
1423 if ( __visit_children() ) {
1424 {
1425 guard_symtab guard { *this };
1426 maybe_accept( node, &TypeExpr::result );
1427 }
1428 maybe_accept( node, &TypeExpr::type );
1429 }
1430
1431 VISIT_END( Expr, node );
1432}
1433
1434//--------------------------------------------------------------------------
1435// AsmExpr
1436template< typename core_t >
1437const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1438 VISIT_START( node );
1439
1440 if ( __visit_children() ) {
1441 {
1442 guard_symtab guard { *this };
1443 maybe_accept( node, &AsmExpr::result );
1444 }
1445 maybe_accept( node, &AsmExpr::constraint );
1446 maybe_accept( node, &AsmExpr::operand );
1447 }
1448
1449 VISIT_END( Expr, node );
1450}
1451
1452//--------------------------------------------------------------------------
1453// ImplicitCopyCtorExpr
1454template< typename core_t >
1455const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1456 VISIT_START( node );
1457
1458 if ( __visit_children() ) {
1459 {
1460 guard_symtab guard { *this };
1461 maybe_accept( node, &ImplicitCopyCtorExpr::result );
1462 }
1463 maybe_accept( node, &ImplicitCopyCtorExpr::callExpr );
1464 }
1465
1466 VISIT_END( Expr, node );
1467}
1468
1469//--------------------------------------------------------------------------
1470// ConstructorExpr
1471template< typename core_t >
1472const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1473 VISIT_START( node );
1474
1475 if ( __visit_children() ) {
1476 {
1477 guard_symtab guard { *this };
1478 maybe_accept( node, &ConstructorExpr::result );
1479 }
1480 maybe_accept( node, &ConstructorExpr::callExpr );
1481 }
1482
1483 VISIT_END( Expr, node );
1484}
1485
1486//--------------------------------------------------------------------------
1487// CompoundLiteralExpr
1488template< typename core_t >
1489const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1490 VISIT_START( node );
1491
1492 if ( __visit_children() ) {
1493 {
1494 guard_symtab guard { *this };
1495 maybe_accept( node, &CompoundLiteralExpr::result );
1496 }
1497 maybe_accept( node, &CompoundLiteralExpr::init );
1498 }
1499
1500 VISIT_END( Expr, node );
1501}
1502
1503//--------------------------------------------------------------------------
1504// RangeExpr
1505template< typename core_t >
1506const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1507 VISIT_START( node );
1508
1509 if ( __visit_children() ) {
1510 {
1511 guard_symtab guard { *this };
1512 maybe_accept( node, &RangeExpr::result );
1513 }
1514 maybe_accept( node, &RangeExpr::low );
1515 maybe_accept( node, &RangeExpr::high );
1516 }
1517
1518 VISIT_END( Expr, node );
1519}
1520
1521//--------------------------------------------------------------------------
1522// UntypedTupleExpr
1523template< typename core_t >
1524const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1525 VISIT_START( node );
1526
1527 if ( __visit_children() ) {
1528 {
1529 guard_symtab guard { *this };
1530 maybe_accept( node, &UntypedTupleExpr::result );
1531 }
1532 maybe_accept( node, &UntypedTupleExpr::exprs );
1533 }
1534
1535 VISIT_END( Expr, node );
1536}
1537
1538//--------------------------------------------------------------------------
1539// TupleExpr
1540template< typename core_t >
1541const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1542 VISIT_START( node );
1543
1544 if ( __visit_children() ) {
1545 {
1546 guard_symtab guard { *this };
1547 maybe_accept( node, &TupleExpr::result );
1548 }
1549 maybe_accept( node, &TupleExpr::exprs );
1550 }
1551
1552 VISIT_END( Expr, node );
1553}
1554
1555//--------------------------------------------------------------------------
1556// TupleIndexExpr
1557template< typename core_t >
1558const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1559 VISIT_START( node );
1560
1561 if ( __visit_children() ) {
1562 {
1563 guard_symtab guard { *this };
1564 maybe_accept( node, &TupleIndexExpr::result );
1565 }
1566 maybe_accept( node, &TupleIndexExpr::tuple );
1567 }
1568
1569 VISIT_END( Expr, node );
1570}
1571
1572//--------------------------------------------------------------------------
1573// TupleAssignExpr
1574template< typename core_t >
1575const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1576 VISIT_START( node );
1577
1578 if ( __visit_children() ) {
1579 {
1580 guard_symtab guard { *this };
1581 maybe_accept( node, &TupleAssignExpr::result );
1582 }
1583 maybe_accept( node, &TupleAssignExpr::stmtExpr );
1584 }
1585
1586 VISIT_END( Expr, node );
1587}
1588
1589//--------------------------------------------------------------------------
1590// StmtExpr
1591template< typename core_t >
1592const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
1593 VISIT_START( node );
1594
1595 if ( __visit_children() ) {
1596 // don't want statements from outer CompoundStmts to be added to this StmtExpr
1597 // get the stmts that will need to be spliced in
1598 auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1599 auto stmts_after = __pass::stmtsToAddAfter ( core, 0);
1600
1601 // These may be modified by subnode but most be restored once we exit this statemnet.
1602 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
1603 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
1604 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after );
1605
1606 {
1607 guard_symtab guard { *this };
1608 maybe_accept( node, &StmtExpr::result );
1609 }
1610 maybe_accept( node, &StmtExpr::stmts );
1611 maybe_accept( node, &StmtExpr::returnDecls );
1612 maybe_accept( node, &StmtExpr::dtors );
1613 }
1614
1615 VISIT_END( Expr, node );
1616}
1617
1618//--------------------------------------------------------------------------
1619// UniqueExpr
1620template< typename core_t >
1621const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1622 VISIT_START( node );
1623
1624 if ( __visit_children() ) {
1625 {
1626 guard_symtab guard { *this };
1627 maybe_accept( node, &UniqueExpr::result );
1628 }
1629 maybe_accept( node, &UniqueExpr::expr );
1630 }
1631
1632 VISIT_END( Expr, node );
1633}
1634
1635//--------------------------------------------------------------------------
1636// UntypedInitExpr
1637template< typename core_t >
1638const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1639 VISIT_START( node );
1640
1641 if ( __visit_children() ) {
1642 {
1643 guard_symtab guard { *this };
1644 maybe_accept( node, &UntypedInitExpr::result );
1645 }
1646 maybe_accept( node, &UntypedInitExpr::expr );
1647 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
1648 }
1649
1650 VISIT_END( Expr, node );
1651}
1652
1653//--------------------------------------------------------------------------
1654// InitExpr
1655template< typename core_t >
1656const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1657 VISIT_START( node );
1658
1659 if ( __visit_children() ) {
1660 {
1661 guard_symtab guard { *this };
1662 maybe_accept( node, &InitExpr::result );
1663 }
1664 maybe_accept( node, &InitExpr::expr );
1665 maybe_accept( node, &InitExpr::designation );
1666 }
1667
1668 VISIT_END( Expr, node );
1669}
1670
1671//--------------------------------------------------------------------------
1672// DeletedExpr
1673template< typename core_t >
1674const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1675 VISIT_START( node );
1676
1677 if ( __visit_children() ) {
1678 {
1679 guard_symtab guard { *this };
1680 maybe_accept( node, &DeletedExpr::result );
1681 }
1682 maybe_accept( node, &DeletedExpr::expr );
1683 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
1684 }
1685
1686 VISIT_END( Expr, node );
1687}
1688
1689//--------------------------------------------------------------------------
1690// DefaultArgExpr
1691template< typename core_t >
1692const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1693 VISIT_START( node );
1694
1695 if ( __visit_children() ) {
1696 {
1697 guard_symtab guard { *this };
1698 maybe_accept( node, &DefaultArgExpr::result );
1699 }
1700 maybe_accept( node, &DefaultArgExpr::expr );
1701 }
1702
1703 VISIT_END( Expr, node );
1704}
1705
1706//--------------------------------------------------------------------------
1707// GenericExpr
1708template< typename core_t >
1709const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1710 VISIT_START( node );
1711
1712 if ( __visit_children() ) {
1713 {
1714 guard_symtab guard { *this };
1715 maybe_accept( node, &GenericExpr::result );
1716 }
1717 maybe_accept( node, &GenericExpr::control );
1718
1719 std::vector<GenericExpr::Association> new_kids;
1720 new_kids.reserve(node->associations.size());
1721 bool mutated = false;
1722 for( const auto & assoc : node->associations ) {
1723 const Type * type = nullptr;
1724 if( assoc.type ) {
1725 guard_symtab guard { *this };
1726 type = assoc.type->accept( *this );
1727 if( type != assoc.type ) mutated = true;
1728 }
1729 const Expr * expr = nullptr;
1730 if( assoc.expr ) {
1731 expr = assoc.expr->accept( *this );
1732 if( expr != assoc.expr ) mutated = true;
1733 }
1734 new_kids.emplace_back( type, expr );
1735 }
1736
1737 if(mutated) {
1738 auto n = __pass::mutate<core_t>(node);
1739 n->associations = std::move( new_kids );
1740 node = n;
1741 }
1742 }
1743
1744 VISIT_END( Expr, node );
1745}
1746
1747//--------------------------------------------------------------------------
1748// VoidType
1749template< typename core_t >
1750const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1751 VISIT_START( node );
1752
1753 VISIT_END( Type, node );
1754}
1755
1756//--------------------------------------------------------------------------
1757// BasicType
1758template< typename core_t >
1759const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1760 VISIT_START( node );
1761
1762 VISIT_END( Type, node );
1763}
1764
1765//--------------------------------------------------------------------------
1766// PointerType
1767template< typename core_t >
1768const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
1769 VISIT_START( node );
1770
1771 if ( __visit_children() ) {
1772 // xxx - should PointerType visit/mutate dimension?
1773 maybe_accept( node, &PointerType::base );
1774 }
1775
1776 VISIT_END( Type, node );
1777}
1778
1779//--------------------------------------------------------------------------
1780// ArrayType
1781template< typename core_t >
1782const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
1783 VISIT_START( node );
1784
1785 if ( __visit_children() ) {
1786 maybe_accept( node, &ArrayType::dimension );
1787 maybe_accept( node, &ArrayType::base );
1788 }
1789
1790 VISIT_END( Type, node );
1791}
1792
1793//--------------------------------------------------------------------------
1794// ReferenceType
1795template< typename core_t >
1796const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
1797 VISIT_START( node );
1798
1799 if ( __visit_children() ) {
1800 maybe_accept( node, &ReferenceType::base );
1801 }
1802
1803 VISIT_END( Type, node );
1804}
1805
1806//--------------------------------------------------------------------------
1807// QualifiedType
1808template< typename core_t >
1809const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
1810 VISIT_START( node );
1811
1812 if ( __visit_children() ) {
1813 maybe_accept( node, &QualifiedType::parent );
1814 maybe_accept( node, &QualifiedType::child );
1815 }
1816
1817 VISIT_END( Type, node );
1818}
1819
1820//--------------------------------------------------------------------------
1821// FunctionType
1822template< typename core_t >
1823const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1824 VISIT_START( node );
1825
1826 if ( __visit_children() ) {
1827 // guard_forall_subs forall_guard { *this, node };
1828 // mutate_forall( node );
1829 maybe_accept( node, &FunctionType::assertions );
1830 maybe_accept( node, &FunctionType::returns );
1831 maybe_accept( node, &FunctionType::params );
1832 }
1833
1834 VISIT_END( Type, node );
1835}
1836
1837//--------------------------------------------------------------------------
1838// StructInstType
1839template< typename core_t >
1840const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1841 VISIT_START( node );
1842
1843 __pass::symtab::addStruct( core, 0, node->name );
1844
1845 if ( __visit_children() ) {
1846 guard_symtab guard { *this };
1847 maybe_accept( node, &StructInstType::params );
1848 }
1849
1850 VISIT_END( Type, node );
1851}
1852
1853//--------------------------------------------------------------------------
1854// UnionInstType
1855template< typename core_t >
1856const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
1857 VISIT_START( node );
1858
1859 __pass::symtab::addUnion( core, 0, node->name );
1860
1861 if ( __visit_children() ) {
1862 guard_symtab guard { *this };
1863 maybe_accept( node, &UnionInstType::params );
1864 }
1865
1866 VISIT_END( Type, node );
1867}
1868
1869//--------------------------------------------------------------------------
1870// EnumInstType
1871template< typename core_t >
1872const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
1873 VISIT_START( node );
1874
1875 if ( __visit_children() ) {
1876 maybe_accept( node, &EnumInstType::params );
1877 }
1878
1879 VISIT_END( Type, node );
1880}
1881
1882//--------------------------------------------------------------------------
1883// TraitInstType
1884template< typename core_t >
1885const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
1886 VISIT_START( node );
1887
1888 if ( __visit_children() ) {
1889 maybe_accept( node, &TraitInstType::params );
1890 }
1891
1892 VISIT_END( Type, node );
1893}
1894
1895//--------------------------------------------------------------------------
1896// TypeInstType
1897template< typename core_t >
1898const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
1899 VISIT_START( node );
1900
1901 if ( __visit_children() ) {
1902 {
1903 maybe_accept( node, &TypeInstType::params );
1904 }
1905 // ensure that base re-bound if doing substitution
1906 __pass::forall::replace( core, 0, node );
1907 }
1908
1909 VISIT_END( Type, node );
1910}
1911
1912//--------------------------------------------------------------------------
1913// TupleType
1914template< typename core_t >
1915const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
1916 VISIT_START( node );
1917
1918 if ( __visit_children() ) {
1919 maybe_accept( node, &TupleType::types );
1920 maybe_accept( node, &TupleType::members );
1921 }
1922
1923 VISIT_END( Type, node );
1924}
1925
1926//--------------------------------------------------------------------------
1927// TypeofType
1928template< typename core_t >
1929const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
1930 VISIT_START( node );
1931
1932 if ( __visit_children() ) {
1933 maybe_accept( node, &TypeofType::expr );
1934 }
1935
1936 VISIT_END( Type, node );
1937}
1938
1939//--------------------------------------------------------------------------
1940// VTableType
1941template< typename core_t >
1942const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
1943 VISIT_START( node );
1944
1945 if ( __visit_children() ) {
1946 maybe_accept( node, &VTableType::base );
1947 }
1948
1949 VISIT_END( Type, node );
1950}
1951
1952//--------------------------------------------------------------------------
1953// VarArgsType
1954template< typename core_t >
1955const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
1956 VISIT_START( node );
1957
1958 VISIT_END( Type, node );
1959}
1960
1961//--------------------------------------------------------------------------
1962// ZeroType
1963template< typename core_t >
1964const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
1965 VISIT_START( node );
1966
1967 VISIT_END( Type, node );
1968}
1969
1970//--------------------------------------------------------------------------
1971// OneType
1972template< typename core_t >
1973const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
1974 VISIT_START( node );
1975
1976 VISIT_END( Type, node );
1977}
1978
1979//--------------------------------------------------------------------------
1980// GlobalScopeType
1981template< typename core_t >
1982const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
1983 VISIT_START( node );
1984
1985 VISIT_END( Type, node );
1986}
1987
1988
1989//--------------------------------------------------------------------------
1990// Designation
1991template< typename core_t >
1992const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
1993 VISIT_START( node );
1994
1995 if ( __visit_children() ) {
1996 maybe_accept( node, &Designation::designators );
1997 }
1998
1999 VISIT_END( Designation, node );
2000}
2001
2002//--------------------------------------------------------------------------
2003// SingleInit
2004template< typename core_t >
2005const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
2006 VISIT_START( node );
2007
2008 if ( __visit_children() ) {
2009 maybe_accept( node, &SingleInit::value );
2010 }
2011
2012 VISIT_END( Init, node );
2013}
2014
2015//--------------------------------------------------------------------------
2016// ListInit
2017template< typename core_t >
2018const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
2019 VISIT_START( node );
2020
2021 if ( __visit_children() ) {
2022 maybe_accept( node, &ListInit::designations );
2023 maybe_accept( node, &ListInit::initializers );
2024 }
2025
2026 VISIT_END( Init, node );
2027}
2028
2029//--------------------------------------------------------------------------
2030// ConstructorInit
2031template< typename core_t >
2032const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
2033 VISIT_START( node );
2034
2035 if ( __visit_children() ) {
2036 maybe_accept( node, &ConstructorInit::ctor );
2037 maybe_accept( node, &ConstructorInit::dtor );
2038 maybe_accept( node, &ConstructorInit::init );
2039 }
2040
2041 VISIT_END( Init, node );
2042}
2043
2044//--------------------------------------------------------------------------
2045// Attribute
2046template< typename core_t >
2047const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node ) {
2048 VISIT_START( node );
2049
2050 if ( __visit_children() ) {
2051 maybe_accept( node, &Attribute::params );
2052 }
2053
2054 VISIT_END( Attribute, node );
2055}
2056
2057//--------------------------------------------------------------------------
2058// TypeSubstitution
2059template< typename core_t >
2060const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
2061 VISIT_START( node );
2062
2063 if ( __visit_children() ) {
2064 {
2065 bool mutated = false;
2066 std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map;
2067 for ( const auto & p : node->typeEnv ) {
2068 guard_symtab guard { *this };
2069 auto new_node = p.second->accept( *this );
2070 if (new_node != p.second) mutated = true;
2071 new_map.insert({ p.first, new_node });
2072 }
2073 if (mutated) {
2074 auto new_node = __pass::mutate<core_t>( node );
2075 new_node->typeEnv.swap( new_map );
2076 node = new_node;
2077 }
2078 }
2079 }
2080
2081 VISIT_END( TypeSubstitution, node );
2082}
2083
2084#undef VISIT_START
2085#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.