source: src/AST/Pass.impl.hpp@ 5bf3976

ADT ast-experimental
Last change on this file since 5bf3976 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
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ast::Pass.impl.hpp --
8//
9// Author : Thierry Delisle
10// Created On : Thu May 09 15::37::05 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#pragma once
17// IWYU pragma: private, include "AST/Pass.hpp"
18
19#include <type_traits>
20#include <unordered_map>
21
22#include "AST/TranslationUnit.hpp"
23#include "AST/TypeSubstitution.hpp"
24
25#define VISIT_START( node ) \
26 using namespace ast; \
27 /* back-up the last known code location */ \
28 __attribute__((unused)) auto loc_guard = ast::__pass::make_location_guard( core, node, 0 ); \
29 /* back-up the visit children */ \
30 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \
31 /* setup the scope for passes that want to run code at exit */ \
32 __attribute__((unused)) ast::__pass::guard_value guard2( ast::__pass::at_cleanup (core, 0) ); \
33 /* begin tracing memory allocation if requested by this pass */ \
34 __pass::beginTrace( core, 0 ); \
35 /* call the implementation of the previsit of this pass */ \
36 __pass::previsit( core, node, 0 );
37
38#define VISIT_END( type, node ) \
39 /* call the implementation of the postvisit of this pass */ \
40 auto __return = __pass::postvisit( core, node, 0 ); \
41 assertf(__return, "post visit should never return null"); \
42 /* end tracing memory allocation if requested by this pass */ \
43 __pass::endTrace( core, 0 ); \
44 return __return;
45
46#ifdef PEDANTIC_PASS_ASSERT
47#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
48#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
49#else
50#define __pedantic_pass_assert(...)
51#define __pedantic_pass_assertf(...)
52#endif
53
54namespace ast {
55 template<typename node_t>
56 node_t * shallowCopy( const node_t * node );
57
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
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
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 ) {
73 if(empty(decls)) return;
74
75 std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
76 return new DeclStmt( decl->location, decl );
77 });
78 decls->clear();
79 if(mutated) *mutated = true;
80 }
81
82 template<typename it_t, template <class...> class container_t>
83 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * stmts, bool * mutated = nullptr ) {
84 if(empty(stmts)) return;
85
86 std::move(stmts->begin(), stmts->end(), it);
87 stmts->clear();
88 if(mutated) *mutated = true;
89 }
90
91 //------------------------------
92 /// Check if should be skipped, different for pointers and containers
93 template<typename node_t>
94 bool skip( const ast::ptr<node_t> & val) {
95 return !val;
96 }
97
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();
101 }
102
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 }
109
110 template<typename node_t>
111 const node_t & get( const node_t & val, long) {
112 return val;
113 }
114
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();
125 }
126 }
127
128 template< typename node_t >
129 template< typename object_t, typename super_t, typename field_t >
130 void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) {
131 object->*field = value;
132 }
133
134 template< typename core_t >
135 template< typename node_t >
136 auto ast::Pass< core_t >::call_accept( const node_t * node )
137 -> typename ast::Pass< core_t >::template generic_call_accept_result<node_t>::type
138 {
139 __pedantic_pass_assert( __visit_children() );
140 __pedantic_pass_assert( node );
141
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
145 auto nval = node->accept( *this );
146 __pass::result1<
147 typename std::remove_pointer< decltype( node->accept(*this) ) >::type
148 > res;
149 res.differs = nval != node;
150 res.value = nval;
151 return res;
152 }
153
154 template< typename core_t >
155 __pass::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
156 __pedantic_pass_assert( __visit_children() );
157 __pedantic_pass_assert( expr );
158
159 auto nval = expr->accept( *this );
160 return { nval != expr, nval };
161 }
162
163 template< typename core_t >
164 __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
165 __pedantic_pass_assert( __visit_children() );
166 __pedantic_pass_assert( stmt );
167
168 const ast::Stmt * nval = stmt->accept( *this );
169 return { nval != stmt, nval };
170 }
171
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
186 template< typename core_t >
187 __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
188 __pedantic_pass_assert( __visit_children() );
189 __pedantic_pass_assert( stmt );
190
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
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 );
199
200 // These may be modified by subnode but most be restored once we exit this statemnet.
201 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::typeSubs( core, 0 ) );
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 );
206
207 // Now is the time to actually visit the node
208 const ast::Stmt * nstmt = stmt->accept( *this );
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) ) {
212 return { nstmt != stmt, nstmt };
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
221 ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
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
228 compound->kids.emplace_back( nstmt );
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
234 return {true, compound};
235 }
236
237 template< template <class...> class container_t >
238 template< typename object_t, typename super_t, typename field_t >
239 void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
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;
246 for (delta & d : values) {
247 if ( d.is_old ) {
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 {
252 nvals.push_back( std::move(d.new_val) );
253 }
254 }
255
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;
285 }
286
287 template< typename core_t >
288 template< template <class...> class container_t >
289 __pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
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
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 );
304
305 // These may be modified by subnode but most be restored once we exit this statemnet.
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 );
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
316 __pass::resultNstmt<container_t> new_kids;
317 for( auto value : enumerate( statements ) ) {
318 try {
319 size_t i = value.idx;
320 const Stmt * stmt = value.val;
321 __pedantic_pass_assert( stmt );
322 const ast::Stmt * new_stmt = stmt->accept( *this );
323 assert( new_stmt );
324 if(new_stmt != stmt ) { new_kids.differs = true; }
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
332 new_kids.take_all( decls_before );
333 new_kids.take_all( stmts_before );
334
335 // Now add the statement if there is one
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 }
341
342 // Take all the declarations that go before
343 new_kids.take_all( decls_after );
344 new_kids.take_all( stmts_after );
345 }
346 catch ( SemanticErrorException &e ) {
347 errors.append( e );
348 }
349 }
350 pass_visitor_stats.depth--;
351 if ( !errors.isEmpty() ) { throw errors; }
352
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 >
358 void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
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'
365 if( values[i] != nullptr ) swap(container[i], values[i]);
366 }
367
368 // Now the original containers should still have the unchanged values
369 // but also contain the new values
370 }
371
372 template< typename core_t >
373 template< template <class...> class container_t, typename node_t >
374 __pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
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;
384 container_t<ptr<node_t>> new_kids;
385 for ( const node_t * node : container ) {
386 try {
387 __pedantic_pass_assert( node );
388 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
389 if(new_stmt != node ) {
390 mutated = true;
391 new_kids.emplace_back( new_stmt );
392 } else {
393 new_kids.emplace_back( nullptr );
394 }
395
396 }
397 catch( SemanticErrorException &e ) {
398 errors.append( e );
399 }
400 }
401
402 __pedantic_pass_assert( new_kids.size() == container.size() );
403 pass_visitor_stats.depth--;
404 if ( ! errors.isEmpty() ) { throw errors; }
405
406 return ast::__pass::resultN<container_t, node_t>{ mutated, new_kids };
407 }
408
409 template< typename core_t >
410 template<typename node_t, typename super_t, typename field_t>
411 void ast::Pass< core_t >::maybe_accept(
412 const node_t * & parent,
413 field_t super_t::*field
414 ) {
415 static_assert( std::is_base_of<super_t, node_t>::value, "Error deducing member object" );
416
417 if(__pass::skip(parent->*field)) return;
418 const auto & old_val = __pass::get(parent->*field, 0);
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
424 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value /* || std::is_same<int, decltype(old_val)>::value */, "ERROR");
425
426 if( new_val.differs ) {
427 auto new_parent = __pass::mutate<core_t>(parent);
428 new_val.apply(new_parent, field);
429 parent = new_parent;
430 }
431 }
432
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
457 template< typename core_t >
458 template<typename node_t, typename super_t, typename field_t>
459 void ast::Pass< core_t >::maybe_accept_as_compound(
460 const node_t * & parent,
461 field_t super_t::*child
462 ) {
463 static_assert( std::is_base_of<super_t, node_t>::value, "Error deducing member object" );
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
474 if( new_val.differs ) {
475 auto new_parent = __pass::mutate<core_t>(parent);
476 new_val.apply( new_parent, child );
477 parent = new_parent;
478 }
479 }
480
481}
482
483//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
484//========================================================================================================================================================================
485//========================================================================================================================================================================
486//========================================================================================================================================================================
487//========================================================================================================================================================================
488//========================================================================================================================================================================
489//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
490
491template< typename core_t >
492inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< core_t > & visitor ) {
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
500 auto decls_before = __pass::declsToAddBefore( visitor.core, 0);
501 auto decls_after = __pass::declsToAddAfter ( visitor.core, 0);
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 ) {
521 if (__pass::on_error (visitor.core, *i, 0))
522 errors.append( e );
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
532template< typename core_t >
533inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) {
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 }
541}
542
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
562template< typename core_t >
563const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::ObjectDecl * node ) {
564 VISIT_START( node );
565
566 if ( __visit_children() ) {
567 {
568 guard_symtab guard { *this };
569 maybe_accept( node, &ObjectDecl::type );
570 }
571 maybe_accept( node, &ObjectDecl::init );
572 maybe_accept( node, &ObjectDecl::bitfieldWidth );
573 maybe_accept( node, &ObjectDecl::attributes );
574 }
575
576 __pass::symtab::addId( core, 0, node );
577
578 VISIT_END( DeclWithType, node );
579}
580
581//--------------------------------------------------------------------------
582// FunctionDecl
583template< typename core_t >
584const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::FunctionDecl * node ) {
585 VISIT_START( node );
586
587 __pass::symtab::addId( core, 0, node );
588
589 if ( __visit_children() ) {
590 maybe_accept( node, &FunctionDecl::withExprs );
591 }
592 {
593 // with clause introduces a level of scope (for the with expression members).
594 // with clause exprs are added to the symbol table before parameters so that parameters
595 // shadow with exprs and not the other way around.
596 guard_symtab guard { *this };
597 __pass::symtab::addWith( core, 0, node->withExprs, node );
598 {
599 guard_symtab guard { *this };
600 // implicit add __func__ identifier as specified in the C manual 6.4.2.2
601 // This is a C name and so has C linkage.
602 static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{
603 CodeLocation{}, "__func__",
604 new ast::ArrayType{
605 new ast::BasicType{ ast::BasicType::Char, ast::CV::Const },
606 nullptr, VariableLen, DynamicDim
607 },
608 nullptr,
609 ast::Storage::Classes(),
610 ast::Linkage::C,
611 } };
612 __pass::symtab::addId( core, 0, func );
613 if ( __visit_children() ) {
614 maybe_accept( node, &FunctionDecl::type_params );
615 maybe_accept( node, &FunctionDecl::assertions );
616 maybe_accept( node, &FunctionDecl::params );
617 maybe_accept( node, &FunctionDecl::returns );
618 maybe_accept( node, &FunctionDecl::type );
619 maybe_accept( node, &FunctionDecl::attributes );
620 // First remember that we are now within a function.
621 ValueGuard< bool > oldInFunction( inFunction );
622 inFunction = true;
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;
627 maybe_accept( node, &FunctionDecl::stmts );
628 }
629 }
630 }
631
632 VISIT_END( DeclWithType, node );
633}
634
635//--------------------------------------------------------------------------
636// StructDecl
637template< typename core_t >
638const ast::Decl * ast::Pass< core_t >::visit( const ast::StructDecl * node ) {
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
643 __pass::symtab::addStructFwd( core, 0, node );
644
645 if ( __visit_children() ) {
646 guard_symtab guard { * this };
647 maybe_accept( node, &StructDecl::params );
648 maybe_accept( node, &StructDecl::members );
649 maybe_accept( node, &StructDecl::attributes );
650 }
651
652 // this addition replaces the forward declaration
653 __pass::symtab::addStruct( core, 0, node );
654
655 VISIT_END( Decl, node );
656}
657
658//--------------------------------------------------------------------------
659// UnionDecl
660template< typename core_t >
661const ast::Decl * ast::Pass< core_t >::visit( const ast::UnionDecl * node ) {
662 VISIT_START( node );
663
664 // make up a forward declaration and add it before processing the members
665 __pass::symtab::addUnionFwd( core, 0, node );
666
667 if ( __visit_children() ) {
668 guard_symtab guard { * this };
669 maybe_accept( node, &UnionDecl::params );
670 maybe_accept( node, &UnionDecl::members );
671 maybe_accept( node, &UnionDecl::attributes );
672 }
673
674 __pass::symtab::addUnion( core, 0, node );
675
676 VISIT_END( Decl, node );
677}
678
679//--------------------------------------------------------------------------
680// EnumDecl
681template< typename core_t >
682const ast::Decl * ast::Pass< core_t >::visit( const ast::EnumDecl * node ) {
683 VISIT_START( node );
684
685 __pass::symtab::addEnum( core, 0, node );
686
687 if ( __visit_children() ) {
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 }
700 }
701
702 VISIT_END( Decl, node );
703}
704
705//--------------------------------------------------------------------------
706// TraitDecl
707template< typename core_t >
708const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
709 VISIT_START( node );
710
711 if ( __visit_children() ) {
712 guard_symtab guard { *this };
713 maybe_accept( node, &TraitDecl::params );
714 maybe_accept( node, &TraitDecl::members );
715 maybe_accept( node, &TraitDecl::attributes );
716 }
717
718 __pass::symtab::addTrait( core, 0, node );
719
720 VISIT_END( Decl, node );
721}
722
723//--------------------------------------------------------------------------
724// TypeDecl
725template< typename core_t >
726const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
727 VISIT_START( node );
728
729 if ( __visit_children() ) {
730 guard_symtab guard { *this };
731 maybe_accept( node, &TypeDecl::base );
732 }
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
737 __pass::symtab::addType( core, 0, node );
738
739 if ( __visit_children() ) {
740 maybe_accept( node, &TypeDecl::assertions );
741
742 {
743 guard_symtab guard { *this };
744 maybe_accept( node, &TypeDecl::init );
745 }
746 }
747
748 VISIT_END( Decl, node );
749}
750
751//--------------------------------------------------------------------------
752// TypedefDecl
753template< typename core_t >
754const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
755 VISIT_START( node );
756
757 if ( __visit_children() ) {
758 guard_symtab guard { *this };
759 maybe_accept( node, &TypedefDecl::base );
760 }
761
762 __pass::symtab::addType( core, 0, node );
763
764 if ( __visit_children() ) {
765 maybe_accept( node, &TypedefDecl::assertions );
766 }
767
768 VISIT_END( Decl, node );
769}
770
771//--------------------------------------------------------------------------
772// AsmDecl
773template< typename core_t >
774const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
775 VISIT_START( node );
776
777 if ( __visit_children() ) {
778 maybe_accept( node, &AsmDecl::stmt );
779 }
780
781 VISIT_END( AsmDecl, node );
782}
783
784//--------------------------------------------------------------------------
785// DirectiveDecl
786template< typename core_t >
787const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) {
788 VISIT_START( node );
789
790 if ( __visit_children() ) {
791 maybe_accept( node, &DirectiveDecl::stmt );
792 }
793
794 VISIT_END( DirectiveDecl, node );
795}
796
797//--------------------------------------------------------------------------
798// StaticAssertDecl
799template< typename core_t >
800const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
801 VISIT_START( node );
802
803 if ( __visit_children() ) {
804 maybe_accept_top( node, &StaticAssertDecl::cond );
805 maybe_accept( node, &StaticAssertDecl::msg );
806 }
807
808 VISIT_END( StaticAssertDecl, node );
809}
810
811//--------------------------------------------------------------------------
812// InlineMemberDecl
813template< typename core_t >
814const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) {
815 VISIT_START( node );
816
817 if ( __visit_children() ) {
818 {
819 guard_symtab guard { *this };
820 maybe_accept( node, &InlineMemberDecl::type );
821 }
822 }
823
824 VISIT_END( DeclWithType, node );
825}
826
827//--------------------------------------------------------------------------
828// CompoundStmt
829template< typename core_t >
830const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
831 VISIT_START( node );
832
833 if ( __visit_children() ) {
834 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
835 auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
836 if ( enterScope ) {
837 __pass::symtab::enter(core, 0);
838 }
839 }, [this, leaveScope = !this->atFunctionTop]() {
840 if ( leaveScope ) {
841 __pass::symtab::leave(core, 0);
842 }
843 });
844 ValueGuard< bool > guard2( atFunctionTop );
845 atFunctionTop = false;
846 guard_scope guard3 { *this };
847 maybe_accept( node, &CompoundStmt::kids );
848 }
849
850 VISIT_END( CompoundStmt, node );
851}
852
853//--------------------------------------------------------------------------
854// ExprStmt
855template< typename core_t >
856const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
857 VISIT_START( node );
858
859 if ( __visit_children() ) {
860 maybe_accept_top( node, &ExprStmt::expr );
861 }
862
863 VISIT_END( Stmt, node );
864}
865
866//--------------------------------------------------------------------------
867// AsmStmt
868template< typename core_t >
869const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
870 VISIT_START( node )
871
872 if ( __visit_children() ) {
873 maybe_accept( node, &AsmStmt::instruction );
874 maybe_accept( node, &AsmStmt::output );
875 maybe_accept( node, &AsmStmt::input );
876 maybe_accept( node, &AsmStmt::clobber );
877 }
878
879 VISIT_END( Stmt, node );
880}
881
882//--------------------------------------------------------------------------
883// DirectiveStmt
884template< typename core_t >
885const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
886 VISIT_START( node )
887
888 VISIT_END( Stmt, node );
889}
890
891//--------------------------------------------------------------------------
892// IfStmt
893template< typename core_t >
894const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
895 VISIT_START( node );
896
897 if ( __visit_children() ) {
898 // if statements introduce a level of scope (for the initialization)
899 guard_symtab guard { *this };
900 maybe_accept( node, &IfStmt::inits );
901 maybe_accept_top( node, &IfStmt::cond );
902 maybe_accept_as_compound( node, &IfStmt::then );
903 maybe_accept_as_compound( node, &IfStmt::else_ );
904 }
905
906 VISIT_END( Stmt, node );
907}
908
909//--------------------------------------------------------------------------
910// WhileDoStmt
911template< typename core_t >
912const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileDoStmt * node ) {
913 VISIT_START( node );
914
915 if ( __visit_children() ) {
916 // while statements introduce a level of scope (for the initialization)
917 guard_symtab guard { *this };
918 maybe_accept( node, &WhileDoStmt::inits );
919 maybe_accept_top( node, &WhileDoStmt::cond );
920 maybe_accept_as_compound( node, &WhileDoStmt::body );
921 }
922
923 VISIT_END( Stmt, node );
924}
925
926//--------------------------------------------------------------------------
927// ForStmt
928template< typename core_t >
929const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
930 VISIT_START( node );
931
932 if ( __visit_children() ) {
933 // for statements introduce a level of scope (for the initialization)
934 guard_symtab guard { *this };
935 // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
936 maybe_accept( node, &ForStmt::inits );
937 maybe_accept_top( node, &ForStmt::cond );
938 maybe_accept_top( node, &ForStmt::inc );
939 maybe_accept_as_compound( node, &ForStmt::body );
940 }
941
942 VISIT_END( Stmt, node );
943}
944
945//--------------------------------------------------------------------------
946// SwitchStmt
947template< typename core_t >
948const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
949 VISIT_START( node );
950
951 if ( __visit_children() ) {
952 maybe_accept_top( node, &SwitchStmt::cond );
953 maybe_accept( node, &SwitchStmt::cases );
954 }
955
956 VISIT_END( Stmt, node );
957}
958
959//--------------------------------------------------------------------------
960// CaseClause
961template< typename core_t >
962const ast::CaseClause * ast::Pass< core_t >::visit( const ast::CaseClause * node ) {
963 VISIT_START( node );
964
965 if ( __visit_children() ) {
966 maybe_accept_top( node, &CaseClause::cond );
967 maybe_accept( node, &CaseClause::stmts );
968 }
969
970 VISIT_END( CaseClause, node );
971}
972
973//--------------------------------------------------------------------------
974// BranchStmt
975template< typename core_t >
976const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
977 VISIT_START( node );
978 VISIT_END( Stmt, node );
979}
980
981//--------------------------------------------------------------------------
982// ReturnStmt
983template< typename core_t >
984const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
985 VISIT_START( node );
986
987 if ( __visit_children() ) {
988 maybe_accept_top( node, &ReturnStmt::expr );
989 }
990
991 VISIT_END( Stmt, node );
992}
993
994//--------------------------------------------------------------------------
995// ThrowStmt
996template< typename core_t >
997const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
998 VISIT_START( node );
999
1000 if ( __visit_children() ) {
1001 maybe_accept( node, &ThrowStmt::expr );
1002 maybe_accept( node, &ThrowStmt::target );
1003 }
1004
1005 VISIT_END( Stmt, node );
1006}
1007
1008//--------------------------------------------------------------------------
1009// TryStmt
1010template< typename core_t >
1011const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
1012 VISIT_START( node );
1013
1014 if ( __visit_children() ) {
1015 maybe_accept( node, &TryStmt::body );
1016 maybe_accept( node, &TryStmt::handlers );
1017 maybe_accept( node, &TryStmt::finally );
1018 }
1019
1020 VISIT_END( Stmt, node );
1021}
1022
1023//--------------------------------------------------------------------------
1024// CatchClause
1025template< typename core_t >
1026const ast::CatchClause * ast::Pass< core_t >::visit( const ast::CatchClause * node ) {
1027 VISIT_START( node );
1028
1029 if ( __visit_children() ) {
1030 // catch statements introduce a level of scope (for the caught exception)
1031 guard_symtab guard { *this };
1032 maybe_accept( node, &CatchClause::decl );
1033 maybe_accept_top( node, &CatchClause::cond );
1034 maybe_accept_as_compound( node, &CatchClause::body );
1035 }
1036
1037 VISIT_END( CatchClause, node );
1038}
1039
1040//--------------------------------------------------------------------------
1041// FinallyClause
1042template< typename core_t >
1043const ast::FinallyClause * ast::Pass< core_t >::visit( const ast::FinallyClause * node ) {
1044 VISIT_START( node );
1045
1046 if ( __visit_children() ) {
1047 maybe_accept( node, &FinallyClause::body );
1048 }
1049
1050 VISIT_END( FinallyClause, node );
1051}
1052
1053//--------------------------------------------------------------------------
1054// FinallyStmt
1055template< typename core_t >
1056const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
1057 VISIT_START( node );
1058
1059 if ( __visit_children() ) {
1060 maybe_accept( node, &SuspendStmt::then );
1061 }
1062
1063 VISIT_END( Stmt, node );
1064}
1065
1066//--------------------------------------------------------------------------
1067// WaitForStmt
1068template< typename core_t >
1069const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
1070 VISIT_START( node );
1071
1072 if ( __visit_children() ) {
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 );
1079 }
1080
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 );
1089
1090 if ( __visit_children() ) {
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 );
1095 }
1096
1097 VISIT_END( WaitForClause, node );
1098}
1099
1100//--------------------------------------------------------------------------
1101// WithStmt
1102template< typename core_t >
1103const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
1104 VISIT_START( node );
1105
1106 if ( __visit_children() ) {
1107 maybe_accept( node, &WithStmt::exprs );
1108 {
1109 // catch statements introduce a level of scope (for the caught exception)
1110 guard_symtab guard { *this };
1111 __pass::symtab::addWith( core, 0, node->exprs, node );
1112 maybe_accept( node, &WithStmt::stmt );
1113 }
1114 }
1115
1116 VISIT_END( Stmt, node );
1117}
1118
1119//--------------------------------------------------------------------------
1120// NullStmt
1121template< typename core_t >
1122const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
1123 VISIT_START( node );
1124 VISIT_END( NullStmt, node );
1125}
1126
1127//--------------------------------------------------------------------------
1128// DeclStmt
1129template< typename core_t >
1130const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
1131 VISIT_START( node );
1132
1133 if ( __visit_children() ) {
1134 maybe_accept( node, &DeclStmt::decl );
1135 }
1136
1137 VISIT_END( Stmt, node );
1138}
1139
1140//--------------------------------------------------------------------------
1141// ImplicitCtorDtorStmt
1142template< typename core_t >
1143const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
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
1148 if ( __visit_children() ) {
1149 maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
1150 }
1151
1152 VISIT_END( Stmt, node );
1153}
1154
1155//--------------------------------------------------------------------------
1156// MutexStmt
1157template< typename core_t >
1158const ast::Stmt * ast::Pass< core_t >::visit( const ast::MutexStmt * node ) {
1159 VISIT_START( node );
1160
1161 if ( __visit_children() ) {
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 );
1166 }
1167
1168 VISIT_END( Stmt, node );
1169}
1170
1171//--------------------------------------------------------------------------
1172// ApplicationExpr
1173template< typename core_t >
1174const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
1175 VISIT_START( node );
1176
1177 if ( __visit_children() ) {
1178 {
1179 guard_symtab guard { *this };
1180 maybe_accept( node, &ApplicationExpr::result );
1181 }
1182 maybe_accept( node, &ApplicationExpr::func );
1183 maybe_accept( node, &ApplicationExpr::args );
1184 }
1185
1186 VISIT_END( Expr, node );
1187}
1188
1189//--------------------------------------------------------------------------
1190// UntypedExpr
1191template< typename core_t >
1192const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1193 VISIT_START( node );
1194
1195 if ( __visit_children() ) {
1196 {
1197 guard_symtab guard { *this };
1198 maybe_accept( node, &UntypedExpr::result );
1199 }
1200
1201 maybe_accept( node, &UntypedExpr::args );
1202 }
1203
1204 VISIT_END( Expr, node );
1205}
1206
1207//--------------------------------------------------------------------------
1208// NameExpr
1209template< typename core_t >
1210const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1211 VISIT_START( node );
1212
1213 if ( __visit_children() ) {
1214 guard_symtab guard { *this };
1215 maybe_accept( node, &NameExpr::result );
1216 }
1217
1218 VISIT_END( Expr, node );
1219}
1220
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
1233//--------------------------------------------------------------------------
1234// CastExpr
1235template< typename core_t >
1236const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1237 VISIT_START( node );
1238
1239 if ( __visit_children() ) {
1240 {
1241 guard_symtab guard { *this };
1242 maybe_accept( node, &CastExpr::result );
1243 }
1244 maybe_accept( node, &CastExpr::arg );
1245 }
1246
1247 VISIT_END( Expr, node );
1248}
1249
1250//--------------------------------------------------------------------------
1251// KeywordCastExpr
1252template< typename core_t >
1253const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1254 VISIT_START( node );
1255
1256 if ( __visit_children() ) {
1257 {
1258 guard_symtab guard { *this };
1259 maybe_accept( node, &KeywordCastExpr::result );
1260 }
1261 maybe_accept( node, &KeywordCastExpr::arg );
1262 }
1263
1264 VISIT_END( Expr, node );
1265}
1266
1267//--------------------------------------------------------------------------
1268// VirtualCastExpr
1269template< typename core_t >
1270const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1271 VISIT_START( node );
1272
1273 if ( __visit_children() ) {
1274 {
1275 guard_symtab guard { *this };
1276 maybe_accept( node, &VirtualCastExpr::result );
1277 }
1278 maybe_accept( node, &VirtualCastExpr::arg );
1279 }
1280
1281 VISIT_END( Expr, node );
1282}
1283
1284//--------------------------------------------------------------------------
1285// AddressExpr
1286template< typename core_t >
1287const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1288 VISIT_START( node );
1289
1290 if ( __visit_children() ) {
1291 {
1292 guard_symtab guard { *this };
1293 maybe_accept( node, &AddressExpr::result );
1294 }
1295 maybe_accept( node, &AddressExpr::arg );
1296 }
1297
1298 VISIT_END( Expr, node );
1299}
1300
1301//--------------------------------------------------------------------------
1302// LabelAddressExpr
1303template< typename core_t >
1304const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1305 VISIT_START( node );
1306
1307 if ( __visit_children() ) {
1308 guard_symtab guard { *this };
1309 maybe_accept( node, &LabelAddressExpr::result );
1310 }
1311
1312 VISIT_END( Expr, node );
1313}
1314
1315//--------------------------------------------------------------------------
1316// UntypedMemberExpr
1317template< typename core_t >
1318const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1319 VISIT_START( node );
1320
1321 if ( __visit_children() ) {
1322 {
1323 guard_symtab guard { *this };
1324 maybe_accept( node, &UntypedMemberExpr::result );
1325 }
1326 maybe_accept( node, &UntypedMemberExpr::aggregate );
1327 maybe_accept( node, &UntypedMemberExpr::member );
1328 }
1329
1330 VISIT_END( Expr, node );
1331}
1332
1333//--------------------------------------------------------------------------
1334// MemberExpr
1335template< typename core_t >
1336const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1337 VISIT_START( node );
1338
1339 if ( __visit_children() ) {
1340 {
1341 guard_symtab guard { *this };
1342 maybe_accept( node, &MemberExpr::result );
1343 }
1344 maybe_accept( node, &MemberExpr::aggregate );
1345 }
1346
1347 VISIT_END( Expr, node );
1348}
1349
1350//--------------------------------------------------------------------------
1351// VariableExpr
1352template< typename core_t >
1353const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1354 VISIT_START( node );
1355
1356 if ( __visit_children() ) {
1357 guard_symtab guard { *this };
1358 maybe_accept( node, &VariableExpr::result );
1359 }
1360
1361 VISIT_END( Expr, node );
1362}
1363
1364//--------------------------------------------------------------------------
1365// ConstantExpr
1366template< typename core_t >
1367const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1368 VISIT_START( node );
1369
1370 if ( __visit_children() ) {
1371 guard_symtab guard { *this };
1372 maybe_accept( node, &ConstantExpr::result );
1373 }
1374
1375 VISIT_END( Expr, node );
1376}
1377
1378//--------------------------------------------------------------------------
1379// SizeofExpr
1380template< typename core_t >
1381const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1382 VISIT_START( node );
1383
1384 if ( __visit_children() ) {
1385 {
1386 guard_symtab guard { *this };
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 }
1394 }
1395
1396 VISIT_END( Expr, node );
1397}
1398
1399//--------------------------------------------------------------------------
1400// AlignofExpr
1401template< typename core_t >
1402const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1403 VISIT_START( node );
1404
1405 if ( __visit_children() ) {
1406 {
1407 guard_symtab guard { *this };
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 }
1415 }
1416
1417 VISIT_END( Expr, node );
1418}
1419
1420//--------------------------------------------------------------------------
1421// UntypedOffsetofExpr
1422template< typename core_t >
1423const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1424 VISIT_START( node );
1425
1426 if ( __visit_children() ) {
1427 {
1428 guard_symtab guard { *this };
1429 maybe_accept( node, &UntypedOffsetofExpr::result );
1430 }
1431 maybe_accept( node, &UntypedOffsetofExpr::type );
1432 }
1433
1434 VISIT_END( Expr, node );
1435}
1436
1437//--------------------------------------------------------------------------
1438// OffsetofExpr
1439template< typename core_t >
1440const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1441 VISIT_START( node );
1442
1443 if ( __visit_children() ) {
1444 {
1445 guard_symtab guard { *this };
1446 maybe_accept( node, &OffsetofExpr::result );
1447 }
1448 maybe_accept( node, &OffsetofExpr::type );
1449 }
1450
1451 VISIT_END( Expr, node );
1452}
1453
1454//--------------------------------------------------------------------------
1455// OffsetPackExpr
1456template< typename core_t >
1457const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1458 VISIT_START( node );
1459
1460 if ( __visit_children() ) {
1461 {
1462 guard_symtab guard { *this };
1463 maybe_accept( node, &OffsetPackExpr::result );
1464 }
1465 maybe_accept( node, &OffsetPackExpr::type );
1466 }
1467
1468 VISIT_END( Expr, node );
1469}
1470
1471//--------------------------------------------------------------------------
1472// LogicalExpr
1473template< typename core_t >
1474const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1475 VISIT_START( node );
1476
1477 if ( __visit_children() ) {
1478 {
1479 guard_symtab guard { *this };
1480 maybe_accept( node, &LogicalExpr::result );
1481 }
1482 maybe_accept( node, &LogicalExpr::arg1 );
1483 maybe_accept( node, &LogicalExpr::arg2 );
1484 }
1485
1486 VISIT_END( Expr, node );
1487}
1488
1489//--------------------------------------------------------------------------
1490// ConditionalExpr
1491template< typename core_t >
1492const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1493 VISIT_START( node );
1494
1495 if ( __visit_children() ) {
1496 {
1497 guard_symtab guard { *this };
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 );
1503 }
1504
1505 VISIT_END( Expr, node );
1506}
1507
1508//--------------------------------------------------------------------------
1509// CommaExpr
1510template< typename core_t >
1511const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1512 VISIT_START( node );
1513
1514 if ( __visit_children() ) {
1515 {
1516 guard_symtab guard { *this };
1517 maybe_accept( node, &CommaExpr::result );
1518 }
1519 maybe_accept( node, &CommaExpr::arg1 );
1520 maybe_accept( node, &CommaExpr::arg2 );
1521 }
1522
1523 VISIT_END( Expr, node );
1524}
1525
1526//--------------------------------------------------------------------------
1527// TypeExpr
1528template< typename core_t >
1529const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1530 VISIT_START( node );
1531
1532 if ( __visit_children() ) {
1533 {
1534 guard_symtab guard { *this };
1535 maybe_accept( node, &TypeExpr::result );
1536 }
1537 maybe_accept( node, &TypeExpr::type );
1538 }
1539
1540 VISIT_END( Expr, node );
1541}
1542
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
1557//--------------------------------------------------------------------------
1558// AsmExpr
1559template< typename core_t >
1560const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1561 VISIT_START( node );
1562
1563 if ( __visit_children() ) {
1564 {
1565 guard_symtab guard { *this };
1566 maybe_accept( node, &AsmExpr::result );
1567 }
1568 maybe_accept( node, &AsmExpr::constraint );
1569 maybe_accept( node, &AsmExpr::operand );
1570 }
1571
1572 VISIT_END( Expr, node );
1573}
1574
1575//--------------------------------------------------------------------------
1576// ImplicitCopyCtorExpr
1577template< typename core_t >
1578const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1579 VISIT_START( node );
1580
1581 if ( __visit_children() ) {
1582 {
1583 guard_symtab guard { *this };
1584 maybe_accept( node, &ImplicitCopyCtorExpr::result );
1585 }
1586 maybe_accept( node, &ImplicitCopyCtorExpr::callExpr );
1587 }
1588
1589 VISIT_END( Expr, node );
1590}
1591
1592//--------------------------------------------------------------------------
1593// ConstructorExpr
1594template< typename core_t >
1595const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1596 VISIT_START( node );
1597
1598 if ( __visit_children() ) {
1599 {
1600 guard_symtab guard { *this };
1601 maybe_accept( node, &ConstructorExpr::result );
1602 }
1603 maybe_accept( node, &ConstructorExpr::callExpr );
1604 }
1605
1606 VISIT_END( Expr, node );
1607}
1608
1609//--------------------------------------------------------------------------
1610// CompoundLiteralExpr
1611template< typename core_t >
1612const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1613 VISIT_START( node );
1614
1615 if ( __visit_children() ) {
1616 {
1617 guard_symtab guard { *this };
1618 maybe_accept( node, &CompoundLiteralExpr::result );
1619 }
1620 maybe_accept( node, &CompoundLiteralExpr::init );
1621 }
1622
1623 VISIT_END( Expr, node );
1624}
1625
1626//--------------------------------------------------------------------------
1627// RangeExpr
1628template< typename core_t >
1629const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1630 VISIT_START( node );
1631
1632 if ( __visit_children() ) {
1633 {
1634 guard_symtab guard { *this };
1635 maybe_accept( node, &RangeExpr::result );
1636 }
1637 maybe_accept( node, &RangeExpr::low );
1638 maybe_accept( node, &RangeExpr::high );
1639 }
1640
1641 VISIT_END( Expr, node );
1642}
1643
1644//--------------------------------------------------------------------------
1645// UntypedTupleExpr
1646template< typename core_t >
1647const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1648 VISIT_START( node );
1649
1650 if ( __visit_children() ) {
1651 {
1652 guard_symtab guard { *this };
1653 maybe_accept( node, &UntypedTupleExpr::result );
1654 }
1655 maybe_accept( node, &UntypedTupleExpr::exprs );
1656 }
1657
1658 VISIT_END( Expr, node );
1659}
1660
1661//--------------------------------------------------------------------------
1662// TupleExpr
1663template< typename core_t >
1664const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1665 VISIT_START( node );
1666
1667 if ( __visit_children() ) {
1668 {
1669 guard_symtab guard { *this };
1670 maybe_accept( node, &TupleExpr::result );
1671 }
1672 maybe_accept( node, &TupleExpr::exprs );
1673 }
1674
1675 VISIT_END( Expr, node );
1676}
1677
1678//--------------------------------------------------------------------------
1679// TupleIndexExpr
1680template< typename core_t >
1681const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1682 VISIT_START( node );
1683
1684 if ( __visit_children() ) {
1685 {
1686 guard_symtab guard { *this };
1687 maybe_accept( node, &TupleIndexExpr::result );
1688 }
1689 maybe_accept( node, &TupleIndexExpr::tuple );
1690 }
1691
1692 VISIT_END( Expr, node );
1693}
1694
1695//--------------------------------------------------------------------------
1696// TupleAssignExpr
1697template< typename core_t >
1698const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1699 VISIT_START( node );
1700
1701 if ( __visit_children() ) {
1702 {
1703 guard_symtab guard { *this };
1704 maybe_accept( node, &TupleAssignExpr::result );
1705 }
1706 maybe_accept( node, &TupleAssignExpr::stmtExpr );
1707 }
1708
1709 VISIT_END( Expr, node );
1710}
1711
1712//--------------------------------------------------------------------------
1713// StmtExpr
1714template< typename core_t >
1715const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
1716 VISIT_START( node );
1717
1718 if ( __visit_children() ) {
1719 // don't want statements from outer CompoundStmts to be added to this StmtExpr
1720 // get the stmts that will need to be spliced in
1721 auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1722 auto stmts_after = __pass::stmtsToAddAfter ( core, 0);
1723
1724 // These may be modified by subnode but most be restored once we exit this statemnet.
1725 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
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 {
1730 guard_symtab guard { *this };
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 );
1736 }
1737
1738 VISIT_END( Expr, node );
1739}
1740
1741//--------------------------------------------------------------------------
1742// UniqueExpr
1743template< typename core_t >
1744const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1745 VISIT_START( node );
1746
1747 if ( __visit_children() ) {
1748 {
1749 guard_symtab guard { *this };
1750 maybe_accept( node, &UniqueExpr::result );
1751 }
1752 maybe_accept( node, &UniqueExpr::expr );
1753 }
1754
1755 VISIT_END( Expr, node );
1756}
1757
1758//--------------------------------------------------------------------------
1759// UntypedInitExpr
1760template< typename core_t >
1761const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1762 VISIT_START( node );
1763
1764 if ( __visit_children() ) {
1765 {
1766 guard_symtab guard { *this };
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.
1771 }
1772
1773 VISIT_END( Expr, node );
1774}
1775
1776//--------------------------------------------------------------------------
1777// InitExpr
1778template< typename core_t >
1779const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1780 VISIT_START( node );
1781
1782 if ( __visit_children() ) {
1783 {
1784 guard_symtab guard { *this };
1785 maybe_accept( node, &InitExpr::result );
1786 }
1787 maybe_accept( node, &InitExpr::expr );
1788 maybe_accept( node, &InitExpr::designation );
1789 }
1790
1791 VISIT_END( Expr, node );
1792}
1793
1794//--------------------------------------------------------------------------
1795// DeletedExpr
1796template< typename core_t >
1797const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1798 VISIT_START( node );
1799
1800 if ( __visit_children() ) {
1801 {
1802 guard_symtab guard { *this };
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.
1807 }
1808
1809 VISIT_END( Expr, node );
1810}
1811
1812//--------------------------------------------------------------------------
1813// DefaultArgExpr
1814template< typename core_t >
1815const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1816 VISIT_START( node );
1817
1818 if ( __visit_children() ) {
1819 {
1820 guard_symtab guard { *this };
1821 maybe_accept( node, &DefaultArgExpr::result );
1822 }
1823 maybe_accept( node, &DefaultArgExpr::expr );
1824 }
1825
1826 VISIT_END( Expr, node );
1827}
1828
1829//--------------------------------------------------------------------------
1830// GenericExpr
1831template< typename core_t >
1832const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1833 VISIT_START( node );
1834
1835 if ( __visit_children() ) {
1836 {
1837 guard_symtab guard { *this };
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 ) {
1846 const Type * type = nullptr;
1847 if( assoc.type ) {
1848 guard_symtab guard { *this };
1849 type = assoc.type->accept( *this );
1850 if( type != assoc.type ) mutated = true;
1851 }
1852 const Expr * expr = nullptr;
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) {
1861 auto n = __pass::mutate<core_t>(node);
1862 n->associations = std::move( new_kids );
1863 node = n;
1864 }
1865 }
1866
1867 VISIT_END( Expr, node );
1868}
1869
1870//--------------------------------------------------------------------------
1871// VoidType
1872template< typename core_t >
1873const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1874 VISIT_START( node );
1875
1876 VISIT_END( Type, node );
1877}
1878
1879//--------------------------------------------------------------------------
1880// BasicType
1881template< typename core_t >
1882const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1883 VISIT_START( node );
1884
1885 VISIT_END( Type, node );
1886}
1887
1888//--------------------------------------------------------------------------
1889// PointerType
1890template< typename core_t >
1891const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
1892 VISIT_START( node );
1893
1894 if ( __visit_children() ) {
1895 maybe_accept( node, &PointerType::dimension );
1896 maybe_accept( node, &PointerType::base );
1897 }
1898
1899 VISIT_END( Type, node );
1900}
1901
1902//--------------------------------------------------------------------------
1903// ArrayType
1904template< typename core_t >
1905const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
1906 VISIT_START( node );
1907
1908 if ( __visit_children() ) {
1909 maybe_accept( node, &ArrayType::dimension );
1910 maybe_accept( node, &ArrayType::base );
1911 }
1912
1913 VISIT_END( Type, node );
1914}
1915
1916//--------------------------------------------------------------------------
1917// ReferenceType
1918template< typename core_t >
1919const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
1920 VISIT_START( node );
1921
1922 if ( __visit_children() ) {
1923 maybe_accept( node, &ReferenceType::base );
1924 }
1925
1926 VISIT_END( Type, node );
1927}
1928
1929//--------------------------------------------------------------------------
1930// QualifiedType
1931template< typename core_t >
1932const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
1933 VISIT_START( node );
1934
1935 if ( __visit_children() ) {
1936 maybe_accept( node, &QualifiedType::parent );
1937 maybe_accept( node, &QualifiedType::child );
1938 }
1939
1940 VISIT_END( Type, node );
1941}
1942
1943//--------------------------------------------------------------------------
1944// FunctionType
1945template< typename core_t >
1946const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1947 VISIT_START( node );
1948
1949 if ( __visit_children() ) {
1950 // guard_forall_subs forall_guard { *this, node };
1951 // mutate_forall( node );
1952 maybe_accept( node, &FunctionType::assertions );
1953 maybe_accept( node, &FunctionType::returns );
1954 maybe_accept( node, &FunctionType::params );
1955 }
1956
1957 VISIT_END( Type, node );
1958}
1959
1960//--------------------------------------------------------------------------
1961// StructInstType
1962template< typename core_t >
1963const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1964 VISIT_START( node );
1965
1966 __pass::symtab::addStruct( core, 0, node->name );
1967
1968 if ( __visit_children() ) {
1969 guard_symtab guard { *this };
1970 maybe_accept( node, &StructInstType::params );
1971 }
1972
1973 VISIT_END( Type, node );
1974}
1975
1976//--------------------------------------------------------------------------
1977// UnionInstType
1978template< typename core_t >
1979const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
1980 VISIT_START( node );
1981
1982 __pass::symtab::addUnion( core, 0, node->name );
1983
1984 if ( __visit_children() ) {
1985 guard_symtab guard { *this };
1986 maybe_accept( node, &UnionInstType::params );
1987 }
1988
1989 VISIT_END( Type, node );
1990}
1991
1992//--------------------------------------------------------------------------
1993// EnumInstType
1994template< typename core_t >
1995const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
1996 VISIT_START( node );
1997
1998 if ( __visit_children() ) {
1999 maybe_accept( node, &EnumInstType::params );
2000 }
2001
2002 VISIT_END( Type, node );
2003}
2004
2005//--------------------------------------------------------------------------
2006// TraitInstType
2007template< typename core_t >
2008const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
2009 VISIT_START( node );
2010
2011 if ( __visit_children() ) {
2012 maybe_accept( node, &TraitInstType::params );
2013 }
2014
2015 VISIT_END( Type, node );
2016}
2017
2018//--------------------------------------------------------------------------
2019// TypeInstType
2020template< typename core_t >
2021const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
2022 VISIT_START( node );
2023
2024 if ( __visit_children() ) {
2025 {
2026 maybe_accept( node, &TypeInstType::params );
2027 }
2028 // ensure that base re-bound if doing substitution
2029 __pass::forall::replace( core, 0, node );
2030 }
2031
2032 VISIT_END( Type, node );
2033}
2034
2035//--------------------------------------------------------------------------
2036// TupleType
2037template< typename core_t >
2038const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
2039 VISIT_START( node );
2040
2041 if ( __visit_children() ) {
2042 maybe_accept( node, &TupleType::types );
2043 maybe_accept( node, &TupleType::members );
2044 }
2045
2046 VISIT_END( Type, node );
2047}
2048
2049//--------------------------------------------------------------------------
2050// TypeofType
2051template< typename core_t >
2052const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
2053 VISIT_START( node );
2054
2055 if ( __visit_children() ) {
2056 maybe_accept( node, &TypeofType::expr );
2057 }
2058
2059 VISIT_END( Type, node );
2060}
2061
2062//--------------------------------------------------------------------------
2063// VTableType
2064template< typename core_t >
2065const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
2066 VISIT_START( node );
2067
2068 if ( __visit_children() ) {
2069 maybe_accept( node, &VTableType::base );
2070 }
2071
2072 VISIT_END( Type, node );
2073}
2074
2075//--------------------------------------------------------------------------
2076// VarArgsType
2077template< typename core_t >
2078const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
2079 VISIT_START( node );
2080
2081 VISIT_END( Type, node );
2082}
2083
2084//--------------------------------------------------------------------------
2085// ZeroType
2086template< typename core_t >
2087const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
2088 VISIT_START( node );
2089
2090 VISIT_END( Type, node );
2091}
2092
2093//--------------------------------------------------------------------------
2094// OneType
2095template< typename core_t >
2096const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
2097 VISIT_START( node );
2098
2099 VISIT_END( Type, node );
2100}
2101
2102//--------------------------------------------------------------------------
2103// GlobalScopeType
2104template< typename core_t >
2105const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
2106 VISIT_START( node );
2107
2108 VISIT_END( Type, node );
2109}
2110
2111
2112//--------------------------------------------------------------------------
2113// Designation
2114template< typename core_t >
2115const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
2116 VISIT_START( node );
2117
2118 if ( __visit_children() ) {
2119 maybe_accept( node, &Designation::designators );
2120 }
2121
2122 VISIT_END( Designation, node );
2123}
2124
2125//--------------------------------------------------------------------------
2126// SingleInit
2127template< typename core_t >
2128const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
2129 VISIT_START( node );
2130
2131 if ( __visit_children() ) {
2132 maybe_accept_top( node, &SingleInit::value );
2133 }
2134
2135 VISIT_END( Init, node );
2136}
2137
2138//--------------------------------------------------------------------------
2139// ListInit
2140template< typename core_t >
2141const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
2142 VISIT_START( node );
2143
2144 if ( __visit_children() ) {
2145 maybe_accept( node, &ListInit::designations );
2146 maybe_accept( node, &ListInit::initializers );
2147 }
2148
2149 VISIT_END( Init, node );
2150}
2151
2152//--------------------------------------------------------------------------
2153// ConstructorInit
2154template< typename core_t >
2155const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
2156 VISIT_START( node );
2157
2158 if ( __visit_children() ) {
2159 maybe_accept( node, &ConstructorInit::ctor );
2160 maybe_accept( node, &ConstructorInit::dtor );
2161 maybe_accept( node, &ConstructorInit::init );
2162 }
2163
2164 VISIT_END( Init, node );
2165}
2166
2167//--------------------------------------------------------------------------
2168// Attribute
2169template< typename core_t >
2170const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node ) {
2171 VISIT_START( node );
2172
2173 if ( __visit_children() ) {
2174 maybe_accept( node, &Attribute::params );
2175 }
2176
2177 VISIT_END( Attribute, node );
2178}
2179
2180//--------------------------------------------------------------------------
2181// TypeSubstitution
2182template< typename core_t >
2183const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
2184 VISIT_START( node );
2185
2186 if ( __visit_children() ) {
2187 bool mutated = false;
2188 ast::TypeSubstitution::TypeMap new_map;
2189 for ( const auto & p : node->typeMap ) {
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 );
2197 new_node->typeMap.swap( new_map );
2198 node = new_node;
2199 }
2200 }
2201
2202 VISIT_END( TypeSubstitution, node );
2203}
2204
2205#undef VISIT_START
2206#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.