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

ADT
Last change on this file since fa2c005 was fa2c005, checked in by JiadaL <j82liang@…>, 3 years ago

Finish Adt POC

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