source: src/AST/Pass.impl.hpp@ 085f67a

ADT ast-experimental
Last change on this file since 085f67a was 6e1e2d0, checked in by caparsons <caparson@…>, 2 years ago

resolved merge conflicts

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