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

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since ffec1bf was ffec1bf, checked in by Fangren Yu <f37yu@…>, 3 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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