source: src/AST/Pass.impl.hpp@ d6c464d

ADT
Last change on this file since d6c464d was 561354f, checked in by JiadaL <j82liang@…>, 2 years ago

Save progress

  • Property mode set to 100644
File size: 66.0 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
696 // maybe_accept( node, &EnumDecl::data_constructors );
697 // maybe_accept( node, &EnumDecl::data_union );
698 // maybe_accept( node, &EnumDecl::tag );
699 // maybe_accept( node, &EnumDecl::tag_union );
700 } else {
701 maybe_accept( node, &EnumDecl::base );
702 maybe_accept( node, &EnumDecl::params );
703 maybe_accept( node, &EnumDecl::members );
704 maybe_accept( node, &EnumDecl::attributes );
705
706 // maybe_accept( node, &EnumDecl::data_constructors );
707 // maybe_accept( node, &EnumDecl::data_union );
708 // maybe_accept( node, &EnumDecl::tag );
709 // maybe_accept( node, &EnumDecl::tag_union );
710 }
711 }
712
713 VISIT_END( Decl, node );
714}
715
716template< typename core_t >
717const ast::Decl * ast::Pass< core_t >::visit( const ast::AdtDecl * node ) {
718 VISIT_START( node );
719
720 __pass::symtab::addAdt( core, 0, node );
721
722 if ( __visit_children() ) {
723 guard_symtab guard { *this };
724 maybe_accept( node, &AdtDecl::params );
725 maybe_accept( node, &AdtDecl::members );
726 maybe_accept( node, &AdtDecl::attributes );
727
728 maybe_accept( node, &AdtDecl::data_constructors );
729 maybe_accept( node, &AdtDecl::data_union );
730 maybe_accept( node, &AdtDecl::tag );
731 maybe_accept( node, &AdtDecl::tag_union );
732 }
733
734 VISIT_END( Decl, node );
735}
736
737//--------------------------------------------------------------------------
738// TraitDecl
739template< typename core_t >
740const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
741 VISIT_START( node );
742
743 if ( __visit_children() ) {
744 guard_symtab guard { *this };
745 maybe_accept( node, &TraitDecl::params );
746 maybe_accept( node, &TraitDecl::members );
747 maybe_accept( node, &TraitDecl::attributes );
748 }
749
750 __pass::symtab::addTrait( core, 0, node );
751
752 VISIT_END( Decl, node );
753}
754
755//--------------------------------------------------------------------------
756// TypeDecl
757template< typename core_t >
758const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
759 VISIT_START( node );
760
761 if ( __visit_children() ) {
762 guard_symtab guard { *this };
763 maybe_accept( node, &TypeDecl::base );
764 }
765
766 // see A NOTE ON THE ORDER OF TRAVERSAL, above
767 // note that assertions come after the type is added to the symtab, since they are not part of the type proper
768 // and may depend on the type itself
769 __pass::symtab::addType( core, 0, node );
770
771 if ( __visit_children() ) {
772 maybe_accept( node, &TypeDecl::assertions );
773
774 {
775 guard_symtab guard { *this };
776 maybe_accept( node, &TypeDecl::init );
777 }
778 }
779
780 VISIT_END( Decl, node );
781}
782
783//--------------------------------------------------------------------------
784// TypedefDecl
785template< typename core_t >
786const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
787 VISIT_START( node );
788
789 if ( __visit_children() ) {
790 guard_symtab guard { *this };
791 maybe_accept( node, &TypedefDecl::base );
792 }
793
794 __pass::symtab::addType( core, 0, node );
795
796 if ( __visit_children() ) {
797 maybe_accept( node, &TypedefDecl::assertions );
798 }
799
800 VISIT_END( Decl, node );
801}
802
803//--------------------------------------------------------------------------
804// AsmDecl
805template< typename core_t >
806const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
807 VISIT_START( node );
808
809 if ( __visit_children() ) {
810 maybe_accept( node, &AsmDecl::stmt );
811 }
812
813 VISIT_END( AsmDecl, node );
814}
815
816//--------------------------------------------------------------------------
817// DirectiveDecl
818template< typename core_t >
819const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) {
820 VISIT_START( node );
821
822 if ( __visit_children() ) {
823 maybe_accept( node, &DirectiveDecl::stmt );
824 }
825
826 VISIT_END( DirectiveDecl, node );
827}
828
829//--------------------------------------------------------------------------
830// StaticAssertDecl
831template< typename core_t >
832const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
833 VISIT_START( node );
834
835 if ( __visit_children() ) {
836 maybe_accept_top( node, &StaticAssertDecl::cond );
837 maybe_accept( node, &StaticAssertDecl::msg );
838 }
839
840 VISIT_END( StaticAssertDecl, node );
841}
842
843//--------------------------------------------------------------------------
844// InlineMemberDecl
845template< typename core_t >
846const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) {
847 VISIT_START( node );
848
849 if ( __visit_children() ) {
850 {
851 guard_symtab guard { *this };
852 maybe_accept( node, &InlineMemberDecl::type );
853 }
854 }
855
856 VISIT_END( DeclWithType, node );
857}
858
859//--------------------------------------------------------------------------
860// CompoundStmt
861template< typename core_t >
862const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
863 VISIT_START( node );
864
865 if ( __visit_children() ) {
866 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
867 auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
868 if ( enterScope ) {
869 __pass::symtab::enter(core, 0);
870 }
871 }, [this, leaveScope = !this->atFunctionTop]() {
872 if ( leaveScope ) {
873 __pass::symtab::leave(core, 0);
874 }
875 });
876 ValueGuard< bool > guard2( atFunctionTop );
877 atFunctionTop = false;
878 guard_scope guard3 { *this };
879 maybe_accept( node, &CompoundStmt::kids );
880 }
881
882 VISIT_END( CompoundStmt, node );
883}
884
885//--------------------------------------------------------------------------
886// ExprStmt
887template< typename core_t >
888const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
889 VISIT_START( node );
890
891 if ( __visit_children() ) {
892 maybe_accept_top( node, &ExprStmt::expr );
893 }
894
895 VISIT_END( Stmt, node );
896}
897
898//--------------------------------------------------------------------------
899// AsmStmt
900template< typename core_t >
901const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
902 VISIT_START( node )
903
904 if ( __visit_children() ) {
905 maybe_accept( node, &AsmStmt::instruction );
906 maybe_accept( node, &AsmStmt::output );
907 maybe_accept( node, &AsmStmt::input );
908 maybe_accept( node, &AsmStmt::clobber );
909 }
910
911 VISIT_END( Stmt, node );
912}
913
914//--------------------------------------------------------------------------
915// DirectiveStmt
916template< typename core_t >
917const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
918 VISIT_START( node )
919
920 VISIT_END( Stmt, node );
921}
922
923//--------------------------------------------------------------------------
924// IfStmt
925template< typename core_t >
926const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
927 VISIT_START( node );
928
929 if ( __visit_children() ) {
930 // if statements introduce a level of scope (for the initialization)
931 guard_symtab guard { *this };
932 maybe_accept( node, &IfStmt::inits );
933 maybe_accept_top( node, &IfStmt::cond );
934 maybe_accept_as_compound( node, &IfStmt::then );
935 maybe_accept_as_compound( node, &IfStmt::else_ );
936 }
937
938 VISIT_END( Stmt, node );
939}
940
941//--------------------------------------------------------------------------
942// WhileDoStmt
943template< typename core_t >
944const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileDoStmt * node ) {
945 VISIT_START( node );
946
947 if ( __visit_children() ) {
948 // while statements introduce a level of scope (for the initialization)
949 guard_symtab guard { *this };
950 maybe_accept( node, &WhileDoStmt::inits );
951 maybe_accept_top( node, &WhileDoStmt::cond );
952 maybe_accept_as_compound( node, &WhileDoStmt::body );
953 }
954
955 VISIT_END( Stmt, node );
956}
957
958//--------------------------------------------------------------------------
959// ForStmt
960template< typename core_t >
961const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
962 VISIT_START( node );
963
964 if ( __visit_children() ) {
965 // for statements introduce a level of scope (for the initialization)
966 guard_symtab guard { *this };
967 // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
968 maybe_accept( node, &ForStmt::inits );
969 maybe_accept_top( node, &ForStmt::cond );
970 maybe_accept_top( node, &ForStmt::inc );
971 maybe_accept_as_compound( node, &ForStmt::body );
972 }
973
974 VISIT_END( Stmt, node );
975}
976
977//--------------------------------------------------------------------------
978// SwitchStmt
979template< typename core_t >
980const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
981 VISIT_START( node );
982
983 if ( __visit_children() ) {
984 maybe_accept_top( node, &SwitchStmt::cond );
985 maybe_accept( node, &SwitchStmt::cases );
986 }
987
988 VISIT_END( Stmt, node );
989}
990
991//--------------------------------------------------------------------------
992// CaseClause
993template< typename core_t >
994const ast::CaseClause * ast::Pass< core_t >::visit( const ast::CaseClause * node ) {
995 VISIT_START( node );
996
997 if ( __visit_children() ) {
998 maybe_accept_top( node, &CaseClause::cond );
999 maybe_accept( node, &CaseClause::stmts );
1000 }
1001
1002 VISIT_END( CaseClause, node );
1003}
1004
1005//--------------------------------------------------------------------------
1006// BranchStmt
1007template< typename core_t >
1008const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
1009 VISIT_START( node );
1010 VISIT_END( Stmt, node );
1011}
1012
1013//--------------------------------------------------------------------------
1014// ReturnStmt
1015template< typename core_t >
1016const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
1017 VISIT_START( node );
1018
1019 if ( __visit_children() ) {
1020 maybe_accept_top( node, &ReturnStmt::expr );
1021 }
1022
1023 VISIT_END( Stmt, node );
1024}
1025
1026//--------------------------------------------------------------------------
1027// ThrowStmt
1028template< typename core_t >
1029const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
1030 VISIT_START( node );
1031
1032 if ( __visit_children() ) {
1033 maybe_accept( node, &ThrowStmt::expr );
1034 maybe_accept( node, &ThrowStmt::target );
1035 }
1036
1037 VISIT_END( Stmt, node );
1038}
1039
1040//--------------------------------------------------------------------------
1041// TryStmt
1042template< typename core_t >
1043const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
1044 VISIT_START( node );
1045
1046 if ( __visit_children() ) {
1047 maybe_accept( node, &TryStmt::body );
1048 maybe_accept( node, &TryStmt::handlers );
1049 maybe_accept( node, &TryStmt::finally );
1050 }
1051
1052 VISIT_END( Stmt, node );
1053}
1054
1055//--------------------------------------------------------------------------
1056// CatchClause
1057template< typename core_t >
1058const ast::CatchClause * ast::Pass< core_t >::visit( const ast::CatchClause * node ) {
1059 VISIT_START( node );
1060
1061 if ( __visit_children() ) {
1062 // catch statements introduce a level of scope (for the caught exception)
1063 guard_symtab guard { *this };
1064 maybe_accept( node, &CatchClause::decl );
1065 maybe_accept_top( node, &CatchClause::cond );
1066 maybe_accept_as_compound( node, &CatchClause::body );
1067 }
1068
1069 VISIT_END( CatchClause, node );
1070}
1071
1072//--------------------------------------------------------------------------
1073// FinallyClause
1074template< typename core_t >
1075const ast::FinallyClause * ast::Pass< core_t >::visit( const ast::FinallyClause * node ) {
1076 VISIT_START( node );
1077
1078 if ( __visit_children() ) {
1079 maybe_accept( node, &FinallyClause::body );
1080 }
1081
1082 VISIT_END( FinallyClause, node );
1083}
1084
1085//--------------------------------------------------------------------------
1086// FinallyStmt
1087template< typename core_t >
1088const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
1089 VISIT_START( node );
1090
1091 if ( __visit_children() ) {
1092 maybe_accept( node, &SuspendStmt::then );
1093 }
1094
1095 VISIT_END( Stmt, node );
1096}
1097
1098//--------------------------------------------------------------------------
1099// WaitForStmt
1100template< typename core_t >
1101const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
1102 VISIT_START( node );
1103
1104 if ( __visit_children() ) {
1105 maybe_accept( node, &WaitForStmt::clauses );
1106 maybe_accept( node, &WaitForStmt::timeout_time );
1107 maybe_accept( node, &WaitForStmt::timeout_stmt );
1108 maybe_accept( node, &WaitForStmt::timeout_cond );
1109 maybe_accept( node, &WaitForStmt::else_stmt );
1110 maybe_accept( node, &WaitForStmt::else_cond );
1111 }
1112
1113 VISIT_END( Stmt, node );
1114}
1115
1116//--------------------------------------------------------------------------
1117// WaitForClause
1118template< typename core_t >
1119const ast::WaitForClause * ast::Pass< core_t >::visit( const ast::WaitForClause * node ) {
1120 VISIT_START( node );
1121
1122 if ( __visit_children() ) {
1123 maybe_accept( node, &WaitForClause::target_func );
1124 maybe_accept( node, &WaitForClause::target_args );
1125 maybe_accept( node, &WaitForClause::stmt );
1126 maybe_accept( node, &WaitForClause::cond );
1127 }
1128
1129 VISIT_END( WaitForClause, node );
1130}
1131
1132//--------------------------------------------------------------------------
1133// WithStmt
1134template< typename core_t >
1135const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
1136 VISIT_START( node );
1137
1138 if ( __visit_children() ) {
1139 maybe_accept( node, &WithStmt::exprs );
1140 {
1141 // catch statements introduce a level of scope (for the caught exception)
1142 guard_symtab guard { *this };
1143 __pass::symtab::addWith( core, 0, node->exprs, node );
1144 maybe_accept( node, &WithStmt::stmt );
1145 }
1146 }
1147
1148 VISIT_END( Stmt, node );
1149}
1150
1151//--------------------------------------------------------------------------
1152// NullStmt
1153template< typename core_t >
1154const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
1155 VISIT_START( node );
1156 VISIT_END( NullStmt, node );
1157}
1158
1159//--------------------------------------------------------------------------
1160// DeclStmt
1161template< typename core_t >
1162const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
1163 VISIT_START( node );
1164
1165 if ( __visit_children() ) {
1166 maybe_accept( node, &DeclStmt::decl );
1167 }
1168
1169 VISIT_END( Stmt, node );
1170}
1171
1172//--------------------------------------------------------------------------
1173// ImplicitCtorDtorStmt
1174template< typename core_t >
1175const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
1176 VISIT_START( node );
1177
1178 // For now this isn't visited, it is unclear if this causes problem
1179 // if all tests are known to pass, remove this code
1180 if ( __visit_children() ) {
1181 maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
1182 }
1183
1184 VISIT_END( Stmt, node );
1185}
1186
1187//--------------------------------------------------------------------------
1188// MutexStmt
1189template< typename core_t >
1190const ast::Stmt * ast::Pass< core_t >::visit( const ast::MutexStmt * node ) {
1191 VISIT_START( node );
1192
1193 if ( __visit_children() ) {
1194 // mutex statements introduce a level of scope (for the initialization)
1195 guard_symtab guard { *this };
1196 maybe_accept( node, &MutexStmt::stmt );
1197 maybe_accept( node, &MutexStmt::mutexObjs );
1198 }
1199
1200 VISIT_END( Stmt, node );
1201}
1202
1203//--------------------------------------------------------------------------
1204// ApplicationExpr
1205template< typename core_t >
1206const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
1207 VISIT_START( node );
1208
1209 if ( __visit_children() ) {
1210 {
1211 guard_symtab guard { *this };
1212 maybe_accept( node, &ApplicationExpr::result );
1213 }
1214 maybe_accept( node, &ApplicationExpr::func );
1215 maybe_accept( node, &ApplicationExpr::args );
1216 }
1217
1218 VISIT_END( Expr, node );
1219}
1220
1221//--------------------------------------------------------------------------
1222// UntypedExpr
1223template< typename core_t >
1224const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
1225 VISIT_START( node );
1226
1227 if ( __visit_children() ) {
1228 {
1229 guard_symtab guard { *this };
1230 maybe_accept( node, &UntypedExpr::result );
1231 }
1232
1233 maybe_accept( node, &UntypedExpr::args );
1234 }
1235
1236 VISIT_END( Expr, node );
1237}
1238
1239//--------------------------------------------------------------------------
1240// NameExpr
1241template< typename core_t >
1242const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
1243 VISIT_START( node );
1244
1245 if ( __visit_children() ) {
1246 guard_symtab guard { *this };
1247 maybe_accept( node, &NameExpr::result );
1248 }
1249
1250 VISIT_END( Expr, node );
1251}
1252
1253//--------------------------------------------------------------------------
1254// QualifiedNameExpr
1255template< typename core_t >
1256const ast::Expr * ast::Pass< core_t >::visit( const ast::QualifiedNameExpr * node ) {
1257 VISIT_START( node );
1258 if ( __visit_children() ) {
1259 guard_symtab guard { *this };
1260 maybe_accept( node, &QualifiedNameExpr::type_decl );
1261 }
1262 VISIT_END( Expr, node );
1263}
1264
1265//--------------------------------------------------------------------------
1266// CastExpr
1267template< typename core_t >
1268const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
1269 VISIT_START( node );
1270
1271 if ( __visit_children() ) {
1272 {
1273 guard_symtab guard { *this };
1274 maybe_accept( node, &CastExpr::result );
1275 }
1276 maybe_accept( node, &CastExpr::arg );
1277 }
1278
1279 VISIT_END( Expr, node );
1280}
1281
1282//--------------------------------------------------------------------------
1283// KeywordCastExpr
1284template< typename core_t >
1285const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
1286 VISIT_START( node );
1287
1288 if ( __visit_children() ) {
1289 {
1290 guard_symtab guard { *this };
1291 maybe_accept( node, &KeywordCastExpr::result );
1292 }
1293 maybe_accept( node, &KeywordCastExpr::arg );
1294 }
1295
1296 VISIT_END( Expr, node );
1297}
1298
1299//--------------------------------------------------------------------------
1300// VirtualCastExpr
1301template< typename core_t >
1302const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
1303 VISIT_START( node );
1304
1305 if ( __visit_children() ) {
1306 {
1307 guard_symtab guard { *this };
1308 maybe_accept( node, &VirtualCastExpr::result );
1309 }
1310 maybe_accept( node, &VirtualCastExpr::arg );
1311 }
1312
1313 VISIT_END( Expr, node );
1314}
1315
1316//--------------------------------------------------------------------------
1317// AddressExpr
1318template< typename core_t >
1319const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
1320 VISIT_START( node );
1321
1322 if ( __visit_children() ) {
1323 {
1324 guard_symtab guard { *this };
1325 maybe_accept( node, &AddressExpr::result );
1326 }
1327 maybe_accept( node, &AddressExpr::arg );
1328 }
1329
1330 VISIT_END( Expr, node );
1331}
1332
1333//--------------------------------------------------------------------------
1334// LabelAddressExpr
1335template< typename core_t >
1336const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
1337 VISIT_START( node );
1338
1339 if ( __visit_children() ) {
1340 guard_symtab guard { *this };
1341 maybe_accept( node, &LabelAddressExpr::result );
1342 }
1343
1344 VISIT_END( Expr, node );
1345}
1346
1347//--------------------------------------------------------------------------
1348// UntypedMemberExpr
1349template< typename core_t >
1350const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
1351 VISIT_START( node );
1352
1353 if ( __visit_children() ) {
1354 {
1355 guard_symtab guard { *this };
1356 maybe_accept( node, &UntypedMemberExpr::result );
1357 }
1358 maybe_accept( node, &UntypedMemberExpr::aggregate );
1359 maybe_accept( node, &UntypedMemberExpr::member );
1360 }
1361
1362 VISIT_END( Expr, node );
1363}
1364
1365//--------------------------------------------------------------------------
1366// MemberExpr
1367template< typename core_t >
1368const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
1369 VISIT_START( node );
1370
1371 if ( __visit_children() ) {
1372 {
1373 guard_symtab guard { *this };
1374 maybe_accept( node, &MemberExpr::result );
1375 }
1376 maybe_accept( node, &MemberExpr::aggregate );
1377 }
1378
1379 VISIT_END( Expr, node );
1380}
1381
1382//--------------------------------------------------------------------------
1383// VariableExpr
1384template< typename core_t >
1385const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
1386 VISIT_START( node );
1387
1388 if ( __visit_children() ) {
1389 guard_symtab guard { *this };
1390 maybe_accept( node, &VariableExpr::result );
1391 }
1392
1393 VISIT_END( Expr, node );
1394}
1395
1396//--------------------------------------------------------------------------
1397// ConstantExpr
1398template< typename core_t >
1399const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
1400 VISIT_START( node );
1401
1402 if ( __visit_children() ) {
1403 guard_symtab guard { *this };
1404 maybe_accept( node, &ConstantExpr::result );
1405 }
1406
1407 VISIT_END( Expr, node );
1408}
1409
1410//--------------------------------------------------------------------------
1411// SizeofExpr
1412template< typename core_t >
1413const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
1414 VISIT_START( node );
1415
1416 if ( __visit_children() ) {
1417 {
1418 guard_symtab guard { *this };
1419 maybe_accept( node, &SizeofExpr::result );
1420 }
1421 if ( node->type ) {
1422 maybe_accept( node, &SizeofExpr::type );
1423 } else {
1424 maybe_accept( node, &SizeofExpr::expr );
1425 }
1426 }
1427
1428 VISIT_END( Expr, node );
1429}
1430
1431//--------------------------------------------------------------------------
1432// AlignofExpr
1433template< typename core_t >
1434const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
1435 VISIT_START( node );
1436
1437 if ( __visit_children() ) {
1438 {
1439 guard_symtab guard { *this };
1440 maybe_accept( node, &AlignofExpr::result );
1441 }
1442 if ( node->type ) {
1443 maybe_accept( node, &AlignofExpr::type );
1444 } else {
1445 maybe_accept( node, &AlignofExpr::expr );
1446 }
1447 }
1448
1449 VISIT_END( Expr, node );
1450}
1451
1452//--------------------------------------------------------------------------
1453// UntypedOffsetofExpr
1454template< typename core_t >
1455const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
1456 VISIT_START( node );
1457
1458 if ( __visit_children() ) {
1459 {
1460 guard_symtab guard { *this };
1461 maybe_accept( node, &UntypedOffsetofExpr::result );
1462 }
1463 maybe_accept( node, &UntypedOffsetofExpr::type );
1464 }
1465
1466 VISIT_END( Expr, node );
1467}
1468
1469//--------------------------------------------------------------------------
1470// OffsetofExpr
1471template< typename core_t >
1472const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
1473 VISIT_START( node );
1474
1475 if ( __visit_children() ) {
1476 {
1477 guard_symtab guard { *this };
1478 maybe_accept( node, &OffsetofExpr::result );
1479 }
1480 maybe_accept( node, &OffsetofExpr::type );
1481 }
1482
1483 VISIT_END( Expr, node );
1484}
1485
1486//--------------------------------------------------------------------------
1487// OffsetPackExpr
1488template< typename core_t >
1489const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
1490 VISIT_START( node );
1491
1492 if ( __visit_children() ) {
1493 {
1494 guard_symtab guard { *this };
1495 maybe_accept( node, &OffsetPackExpr::result );
1496 }
1497 maybe_accept( node, &OffsetPackExpr::type );
1498 }
1499
1500 VISIT_END( Expr, node );
1501}
1502
1503//--------------------------------------------------------------------------
1504// LogicalExpr
1505template< typename core_t >
1506const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
1507 VISIT_START( node );
1508
1509 if ( __visit_children() ) {
1510 {
1511 guard_symtab guard { *this };
1512 maybe_accept( node, &LogicalExpr::result );
1513 }
1514 maybe_accept( node, &LogicalExpr::arg1 );
1515 maybe_accept( node, &LogicalExpr::arg2 );
1516 }
1517
1518 VISIT_END( Expr, node );
1519}
1520
1521//--------------------------------------------------------------------------
1522// ConditionalExpr
1523template< typename core_t >
1524const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
1525 VISIT_START( node );
1526
1527 if ( __visit_children() ) {
1528 {
1529 guard_symtab guard { *this };
1530 maybe_accept( node, &ConditionalExpr::result );
1531 }
1532 maybe_accept( node, &ConditionalExpr::arg1 );
1533 maybe_accept( node, &ConditionalExpr::arg2 );
1534 maybe_accept( node, &ConditionalExpr::arg3 );
1535 }
1536
1537 VISIT_END( Expr, node );
1538}
1539
1540//--------------------------------------------------------------------------
1541// CommaExpr
1542template< typename core_t >
1543const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
1544 VISIT_START( node );
1545
1546 if ( __visit_children() ) {
1547 {
1548 guard_symtab guard { *this };
1549 maybe_accept( node, &CommaExpr::result );
1550 }
1551 maybe_accept( node, &CommaExpr::arg1 );
1552 maybe_accept( node, &CommaExpr::arg2 );
1553 }
1554
1555 VISIT_END( Expr, node );
1556}
1557
1558//--------------------------------------------------------------------------
1559// TypeExpr
1560template< typename core_t >
1561const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
1562 VISIT_START( node );
1563
1564 if ( __visit_children() ) {
1565 {
1566 guard_symtab guard { *this };
1567 maybe_accept( node, &TypeExpr::result );
1568 }
1569 maybe_accept( node, &TypeExpr::type );
1570 }
1571
1572 VISIT_END( Expr, node );
1573}
1574
1575//--------------------------------------------------------------------------
1576// DimensionExpr
1577template< typename core_t >
1578const ast::Expr * ast::Pass< core_t >::visit( const ast::DimensionExpr * node ) {
1579 VISIT_START( node );
1580
1581 if ( __visit_children() ) {
1582 guard_symtab guard { *this };
1583 maybe_accept( node, &DimensionExpr::result );
1584 }
1585
1586 VISIT_END( Expr, node );
1587}
1588
1589//--------------------------------------------------------------------------
1590// AsmExpr
1591template< typename core_t >
1592const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
1593 VISIT_START( node );
1594
1595 if ( __visit_children() ) {
1596 {
1597 guard_symtab guard { *this };
1598 maybe_accept( node, &AsmExpr::result );
1599 }
1600 maybe_accept( node, &AsmExpr::constraint );
1601 maybe_accept( node, &AsmExpr::operand );
1602 }
1603
1604 VISIT_END( Expr, node );
1605}
1606
1607//--------------------------------------------------------------------------
1608// ImplicitCopyCtorExpr
1609template< typename core_t >
1610const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
1611 VISIT_START( node );
1612
1613 if ( __visit_children() ) {
1614 {
1615 guard_symtab guard { *this };
1616 maybe_accept( node, &ImplicitCopyCtorExpr::result );
1617 }
1618 maybe_accept( node, &ImplicitCopyCtorExpr::callExpr );
1619 }
1620
1621 VISIT_END( Expr, node );
1622}
1623
1624//--------------------------------------------------------------------------
1625// ConstructorExpr
1626template< typename core_t >
1627const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
1628 VISIT_START( node );
1629
1630 if ( __visit_children() ) {
1631 {
1632 guard_symtab guard { *this };
1633 maybe_accept( node, &ConstructorExpr::result );
1634 }
1635 maybe_accept( node, &ConstructorExpr::callExpr );
1636 }
1637
1638 VISIT_END( Expr, node );
1639}
1640
1641//--------------------------------------------------------------------------
1642// CompoundLiteralExpr
1643template< typename core_t >
1644const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
1645 VISIT_START( node );
1646
1647 if ( __visit_children() ) {
1648 {
1649 guard_symtab guard { *this };
1650 maybe_accept( node, &CompoundLiteralExpr::result );
1651 }
1652 maybe_accept( node, &CompoundLiteralExpr::init );
1653 }
1654
1655 VISIT_END( Expr, node );
1656}
1657
1658//--------------------------------------------------------------------------
1659// RangeExpr
1660template< typename core_t >
1661const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
1662 VISIT_START( node );
1663
1664 if ( __visit_children() ) {
1665 {
1666 guard_symtab guard { *this };
1667 maybe_accept( node, &RangeExpr::result );
1668 }
1669 maybe_accept( node, &RangeExpr::low );
1670 maybe_accept( node, &RangeExpr::high );
1671 }
1672
1673 VISIT_END( Expr, node );
1674}
1675
1676//--------------------------------------------------------------------------
1677// UntypedTupleExpr
1678template< typename core_t >
1679const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
1680 VISIT_START( node );
1681
1682 if ( __visit_children() ) {
1683 {
1684 guard_symtab guard { *this };
1685 maybe_accept( node, &UntypedTupleExpr::result );
1686 }
1687 maybe_accept( node, &UntypedTupleExpr::exprs );
1688 }
1689
1690 VISIT_END( Expr, node );
1691}
1692
1693//--------------------------------------------------------------------------
1694// TupleExpr
1695template< typename core_t >
1696const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
1697 VISIT_START( node );
1698
1699 if ( __visit_children() ) {
1700 {
1701 guard_symtab guard { *this };
1702 maybe_accept( node, &TupleExpr::result );
1703 }
1704 maybe_accept( node, &TupleExpr::exprs );
1705 }
1706
1707 VISIT_END( Expr, node );
1708}
1709
1710//--------------------------------------------------------------------------
1711// TupleIndexExpr
1712template< typename core_t >
1713const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
1714 VISIT_START( node );
1715
1716 if ( __visit_children() ) {
1717 {
1718 guard_symtab guard { *this };
1719 maybe_accept( node, &TupleIndexExpr::result );
1720 }
1721 maybe_accept( node, &TupleIndexExpr::tuple );
1722 }
1723
1724 VISIT_END( Expr, node );
1725}
1726
1727//--------------------------------------------------------------------------
1728// TupleAssignExpr
1729template< typename core_t >
1730const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
1731 VISIT_START( node );
1732
1733 if ( __visit_children() ) {
1734 {
1735 guard_symtab guard { *this };
1736 maybe_accept( node, &TupleAssignExpr::result );
1737 }
1738 maybe_accept( node, &TupleAssignExpr::stmtExpr );
1739 }
1740
1741 VISIT_END( Expr, node );
1742}
1743
1744//--------------------------------------------------------------------------
1745// StmtExpr
1746template< typename core_t >
1747const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
1748 VISIT_START( node );
1749
1750 if ( __visit_children() ) {
1751 // don't want statements from outer CompoundStmts to be added to this StmtExpr
1752 // get the stmts that will need to be spliced in
1753 auto stmts_before = __pass::stmtsToAddBefore( core, 0);
1754 auto stmts_after = __pass::stmtsToAddAfter ( core, 0);
1755
1756 // These may be modified by subnode but most be restored once we exit this statemnet.
1757 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
1758 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
1759 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after );
1760
1761 {
1762 guard_symtab guard { *this };
1763 maybe_accept( node, &StmtExpr::result );
1764 }
1765 maybe_accept( node, &StmtExpr::stmts );
1766 maybe_accept( node, &StmtExpr::returnDecls );
1767 maybe_accept( node, &StmtExpr::dtors );
1768 }
1769
1770 VISIT_END( Expr, node );
1771}
1772
1773//--------------------------------------------------------------------------
1774// UniqueExpr
1775template< typename core_t >
1776const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
1777 VISIT_START( node );
1778
1779 if ( __visit_children() ) {
1780 {
1781 guard_symtab guard { *this };
1782 maybe_accept( node, &UniqueExpr::result );
1783 }
1784 maybe_accept( node, &UniqueExpr::expr );
1785 }
1786
1787 VISIT_END( Expr, node );
1788}
1789
1790//--------------------------------------------------------------------------
1791// UntypedInitExpr
1792template< typename core_t >
1793const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
1794 VISIT_START( node );
1795
1796 if ( __visit_children() ) {
1797 {
1798 guard_symtab guard { *this };
1799 maybe_accept( node, &UntypedInitExpr::result );
1800 }
1801 maybe_accept( node, &UntypedInitExpr::expr );
1802 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
1803 }
1804
1805 VISIT_END( Expr, node );
1806}
1807
1808//--------------------------------------------------------------------------
1809// InitExpr
1810template< typename core_t >
1811const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
1812 VISIT_START( node );
1813
1814 if ( __visit_children() ) {
1815 {
1816 guard_symtab guard { *this };
1817 maybe_accept( node, &InitExpr::result );
1818 }
1819 maybe_accept( node, &InitExpr::expr );
1820 maybe_accept( node, &InitExpr::designation );
1821 }
1822
1823 VISIT_END( Expr, node );
1824}
1825
1826//--------------------------------------------------------------------------
1827// DeletedExpr
1828template< typename core_t >
1829const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
1830 VISIT_START( node );
1831
1832 if ( __visit_children() ) {
1833 {
1834 guard_symtab guard { *this };
1835 maybe_accept( node, &DeletedExpr::result );
1836 }
1837 maybe_accept( node, &DeletedExpr::expr );
1838 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
1839 }
1840
1841 VISIT_END( Expr, node );
1842}
1843
1844//--------------------------------------------------------------------------
1845// DefaultArgExpr
1846template< typename core_t >
1847const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
1848 VISIT_START( node );
1849
1850 if ( __visit_children() ) {
1851 {
1852 guard_symtab guard { *this };
1853 maybe_accept( node, &DefaultArgExpr::result );
1854 }
1855 maybe_accept( node, &DefaultArgExpr::expr );
1856 }
1857
1858 VISIT_END( Expr, node );
1859}
1860
1861//--------------------------------------------------------------------------
1862// GenericExpr
1863template< typename core_t >
1864const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
1865 VISIT_START( node );
1866
1867 if ( __visit_children() ) {
1868 {
1869 guard_symtab guard { *this };
1870 maybe_accept( node, &GenericExpr::result );
1871 }
1872 maybe_accept( node, &GenericExpr::control );
1873
1874 std::vector<GenericExpr::Association> new_kids;
1875 new_kids.reserve(node->associations.size());
1876 bool mutated = false;
1877 for( const auto & assoc : node->associations ) {
1878 const Type * type = nullptr;
1879 if( assoc.type ) {
1880 guard_symtab guard { *this };
1881 type = assoc.type->accept( *this );
1882 if( type != assoc.type ) mutated = true;
1883 }
1884 const Expr * expr = nullptr;
1885 if( assoc.expr ) {
1886 expr = assoc.expr->accept( *this );
1887 if( expr != assoc.expr ) mutated = true;
1888 }
1889 new_kids.emplace_back( type, expr );
1890 }
1891
1892 if(mutated) {
1893 auto n = __pass::mutate<core_t>(node);
1894 n->associations = std::move( new_kids );
1895 node = n;
1896 }
1897 }
1898
1899 VISIT_END( Expr, node );
1900}
1901
1902//--------------------------------------------------------------------------
1903// VoidType
1904template< typename core_t >
1905const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
1906 VISIT_START( node );
1907
1908 VISIT_END( Type, node );
1909}
1910
1911//--------------------------------------------------------------------------
1912// BasicType
1913template< typename core_t >
1914const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
1915 VISIT_START( node );
1916
1917 VISIT_END( Type, node );
1918}
1919
1920//--------------------------------------------------------------------------
1921// PointerType
1922template< typename core_t >
1923const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
1924 VISIT_START( node );
1925
1926 if ( __visit_children() ) {
1927 maybe_accept( node, &PointerType::dimension );
1928 maybe_accept( node, &PointerType::base );
1929 }
1930
1931 VISIT_END( Type, node );
1932}
1933
1934//--------------------------------------------------------------------------
1935// ArrayType
1936template< typename core_t >
1937const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
1938 VISIT_START( node );
1939
1940 if ( __visit_children() ) {
1941 maybe_accept( node, &ArrayType::dimension );
1942 maybe_accept( node, &ArrayType::base );
1943 }
1944
1945 VISIT_END( Type, node );
1946}
1947
1948//--------------------------------------------------------------------------
1949// ReferenceType
1950template< typename core_t >
1951const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
1952 VISIT_START( node );
1953
1954 if ( __visit_children() ) {
1955 maybe_accept( node, &ReferenceType::base );
1956 }
1957
1958 VISIT_END( Type, node );
1959}
1960
1961//--------------------------------------------------------------------------
1962// QualifiedType
1963template< typename core_t >
1964const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
1965 VISIT_START( node );
1966
1967 if ( __visit_children() ) {
1968 maybe_accept( node, &QualifiedType::parent );
1969 maybe_accept( node, &QualifiedType::child );
1970 }
1971
1972 VISIT_END( Type, node );
1973}
1974
1975//--------------------------------------------------------------------------
1976// FunctionType
1977template< typename core_t >
1978const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
1979 VISIT_START( node );
1980
1981 if ( __visit_children() ) {
1982 // guard_forall_subs forall_guard { *this, node };
1983 // mutate_forall( node );
1984 maybe_accept( node, &FunctionType::assertions );
1985 maybe_accept( node, &FunctionType::returns );
1986 maybe_accept( node, &FunctionType::params );
1987 }
1988
1989 VISIT_END( Type, node );
1990}
1991
1992//--------------------------------------------------------------------------
1993// StructInstType
1994template< typename core_t >
1995const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
1996 VISIT_START( node );
1997
1998 __pass::symtab::addStruct( core, 0, node->name );
1999
2000 if ( __visit_children() ) {
2001 guard_symtab guard { *this };
2002 maybe_accept( node, &StructInstType::params );
2003 }
2004
2005 VISIT_END( Type, node );
2006}
2007
2008//--------------------------------------------------------------------------
2009// UnionInstType
2010template< typename core_t >
2011const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
2012 VISIT_START( node );
2013
2014 __pass::symtab::addUnion( core, 0, node->name );
2015
2016 if ( __visit_children() ) {
2017 guard_symtab guard { *this };
2018 maybe_accept( node, &UnionInstType::params );
2019 }
2020
2021 VISIT_END( Type, node );
2022}
2023
2024//--------------------------------------------------------------------------
2025// EnumInstType
2026template< typename core_t >
2027const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
2028 VISIT_START( node );
2029
2030 if ( __visit_children() ) {
2031 maybe_accept( node, &EnumInstType::params );
2032 }
2033
2034 VISIT_END( Type, node );
2035}
2036
2037//--------------------------------------------------------------------------
2038// TraitInstType
2039template< typename core_t >
2040const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
2041 VISIT_START( node );
2042
2043 if ( __visit_children() ) {
2044 maybe_accept( node, &TraitInstType::params );
2045 }
2046
2047 VISIT_END( Type, node );
2048}
2049
2050//--------------------------------------------------------------------------
2051// TypeInstType
2052template< typename core_t >
2053const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
2054 VISIT_START( node );
2055
2056 if ( __visit_children() ) {
2057 {
2058 maybe_accept( node, &TypeInstType::params );
2059 }
2060 // ensure that base re-bound if doing substitution
2061 __pass::forall::replace( core, 0, node );
2062 }
2063
2064 VISIT_END( Type, node );
2065}
2066
2067//--------------------------------------------------------------------------
2068// TupleType
2069template< typename core_t >
2070const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
2071 VISIT_START( node );
2072
2073 if ( __visit_children() ) {
2074 maybe_accept( node, &TupleType::types );
2075 }
2076
2077 VISIT_END( Type, node );
2078}
2079
2080//--------------------------------------------------------------------------
2081// TypeofType
2082template< typename core_t >
2083const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
2084 VISIT_START( node );
2085
2086 if ( __visit_children() ) {
2087 maybe_accept( node, &TypeofType::expr );
2088 }
2089
2090 VISIT_END( Type, node );
2091}
2092
2093//--------------------------------------------------------------------------
2094// VTableType
2095template< typename core_t >
2096const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
2097 VISIT_START( node );
2098
2099 if ( __visit_children() ) {
2100 maybe_accept( node, &VTableType::base );
2101 }
2102
2103 VISIT_END( Type, node );
2104}
2105
2106//--------------------------------------------------------------------------
2107// VarArgsType
2108template< typename core_t >
2109const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
2110 VISIT_START( node );
2111
2112 VISIT_END( Type, node );
2113}
2114
2115//--------------------------------------------------------------------------
2116// ZeroType
2117template< typename core_t >
2118const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
2119 VISIT_START( node );
2120
2121 VISIT_END( Type, node );
2122}
2123
2124//--------------------------------------------------------------------------
2125// OneType
2126template< typename core_t >
2127const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
2128 VISIT_START( node );
2129
2130 VISIT_END( Type, node );
2131}
2132
2133//--------------------------------------------------------------------------
2134// GlobalScopeType
2135template< typename core_t >
2136const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
2137 VISIT_START( node );
2138
2139 VISIT_END( Type, node );
2140}
2141
2142
2143//--------------------------------------------------------------------------
2144// Designation
2145template< typename core_t >
2146const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
2147 VISIT_START( node );
2148
2149 if ( __visit_children() ) {
2150 maybe_accept( node, &Designation::designators );
2151 }
2152
2153 VISIT_END( Designation, node );
2154}
2155
2156//--------------------------------------------------------------------------
2157// SingleInit
2158template< typename core_t >
2159const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
2160 VISIT_START( node );
2161
2162 if ( __visit_children() ) {
2163 maybe_accept_top( node, &SingleInit::value );
2164 }
2165
2166 VISIT_END( Init, node );
2167}
2168
2169//--------------------------------------------------------------------------
2170// ListInit
2171template< typename core_t >
2172const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
2173 VISIT_START( node );
2174
2175 if ( __visit_children() ) {
2176 maybe_accept( node, &ListInit::designations );
2177 maybe_accept( node, &ListInit::initializers );
2178 }
2179
2180 VISIT_END( Init, node );
2181}
2182
2183//--------------------------------------------------------------------------
2184// ConstructorInit
2185template< typename core_t >
2186const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
2187 VISIT_START( node );
2188
2189 if ( __visit_children() ) {
2190 maybe_accept( node, &ConstructorInit::ctor );
2191 maybe_accept( node, &ConstructorInit::dtor );
2192 maybe_accept( node, &ConstructorInit::init );
2193 }
2194
2195 VISIT_END( Init, node );
2196}
2197
2198//--------------------------------------------------------------------------
2199// Attribute
2200template< typename core_t >
2201const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node ) {
2202 VISIT_START( node );
2203
2204 if ( __visit_children() ) {
2205 maybe_accept( node, &Attribute::params );
2206 }
2207
2208 VISIT_END( Attribute, node );
2209}
2210
2211//--------------------------------------------------------------------------
2212// TypeSubstitution
2213template< typename core_t >
2214const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
2215 VISIT_START( node );
2216
2217 if ( __visit_children() ) {
2218 bool mutated = false;
2219 ast::TypeSubstitution::TypeMap new_map;
2220 for ( const auto & p : node->typeMap ) {
2221 guard_symtab guard { *this };
2222 auto new_node = p.second->accept( *this );
2223 if (new_node != p.second) mutated = true;
2224 new_map.insert({ p.first, new_node });
2225 }
2226 if (mutated) {
2227 auto new_node = __pass::mutate<core_t>( node );
2228 new_node->typeMap.swap( new_map );
2229 node = new_node;
2230 }
2231 }
2232
2233 VISIT_END( TypeSubstitution, node );
2234}
2235
2236#undef VISIT_START
2237#undef VISIT_END
Note: See TracBrowser for help on using the repository browser.