source: src/AST/Pass.impl.hpp@ 9749d2fa

ADT ast-experimental
Last change on this file since 9749d2fa was d0bdb18, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Removed extra scope calls in the new Pass. Added some documentation on the core's possible special members.

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