source: src/AST/Pass.impl.hpp@ 6adeb5f

ADT ast-experimental
Last change on this file since 6adeb5f was fac05b3, checked in by Andrew Beach <ajbeach@…>, 2 years ago

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