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

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since fde0a58 was 3b0bc16, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

change class name WhileStmt to WhileDoStmt, add else clause to WhileDoStmt and ForStmt, change names thenPart/ElsePart to then/else_

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