source: src/AST/Pass.impl.hpp@ 62d62db

ast-experimental
Last change on this file since 62d62db was 148f836e, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Cleaned up namespacing, indentation and whitespacing in Pass.impl.hpp.

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