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

Last change on this file since b723b63 was b6f2e7ab, checked in by Andrew Beach <ajbeach@…>, 13 months ago

Removed SizeofExpr::expr and AlignofExpr::expr, expressions that would be stored there are wrapped in TypeofType and stored in the type field. Some special cases to hide the typeof in code generation were added. In addition, initializer length is calculated in more cases so that the full type of more arrays is known sooner. Other than that, most of the code changes were just stripping out the conditional code and checks no longer needed. Some tests had to be updated, because the typeof is not hidden in dumps and the resolver replaces known typeof expressions with the type. The extension case caused some concern but it appears that just hides warnings in the expression which no longer exists.

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