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

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since c4072d8e was eb5962a, checked in by JiadaL <j82liang@…>, 3 years ago

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

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