Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.impl.hpp

    r665f432 r3e5dd913  
    2020#include <unordered_map>
    2121
     22#include "AST/TranslationUnit.hpp"
    2223#include "AST/TypeSubstitution.hpp"
    2324
     
    2526        using namespace ast; \
    2627        /* back-up the visit children */ \
    27         __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(pass, 0) ); \
     28        __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \
    2829        /* setup the scope for passes that want to run code at exit */ \
    29         __attribute__((unused)) ast::__pass::guard_value          guard2( ast::__pass::at_cleanup    (pass, 0) ); \
     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 ); \
    3033        /* call the implementation of the previsit of this pass */ \
    31         __pass::previsit( pass, node, 0 );
     34        __pass::previsit( core, node, 0 );
    3235
    3336#define VISIT( code... ) \
     
    4043#define VISIT_END( type, node ) \
    4144        /* call the implementation of the postvisit of this pass */ \
    42         auto __return = __pass::postvisit( pass, node, 0 ); \
     45        auto __return = __pass::postvisit( core, node, 0 ); \
    4346        assertf(__return, "post visit should never return null"); \
     47        /* end tracing memory allocation if requested by this pass */ \
     48        __pass::endTrace( core, 0 ); \
    4449        return __return;
    4550
     
    5358
    5459namespace ast {
     60        template<typename node_t>
     61        node_t * shallowCopy( const node_t * node );
     62
    5563        namespace __pass {
    5664                // Check if this is either a null pointer or a pointer to an empty container
     
    6068                }
    6169
     70                template< typename core_t, typename node_t >
     71                static inline node_t* mutate(const node_t *node) {
     72                        return std::is_base_of<PureVisitor, core_t>::value ? ::ast::shallowCopy(node) : ::ast::mutate(node);
     73                }
     74
    6275                //------------------------------
    6376                template<typename it_t, template <class...> class container_t>
     
    119132        }
    120133
    121         template< typename pass_t >
     134        template< typename core_t >
    122135        template< typename node_t >
    123         auto ast::Pass< pass_t >::call_accept( const node_t * node )
     136        auto ast::Pass< core_t >::call_accept( const node_t * node )
    124137                -> typename std::enable_if<
    125138                                !std::is_base_of<ast::Expr, node_t>::value &&
     
    127140                        , decltype( node->accept(*this) )
    128141                >::type
    129 
    130142        {
    131143                __pedantic_pass_assert( __visit_children() );
    132                 __pedantic_pass_assert( expr );
     144                __pedantic_pass_assert( node );
    133145
    134146                static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
     
    138150        }
    139151
    140         template< typename pass_t >
    141         const ast::Expr * ast::Pass< pass_t >::call_accept( const ast::Expr * expr ) {
     152        template< typename core_t >
     153        const ast::Expr * ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
    142154                __pedantic_pass_assert( __visit_children() );
    143155                __pedantic_pass_assert( expr );
    144156
    145                 const ast::TypeSubstitution ** env_ptr = __pass::env( pass, 0);
    146                 if ( env_ptr && expr->env ) {
    147                         *env_ptr = expr->env;
     157                const ast::TypeSubstitution ** typeSubs_ptr = __pass::typeSubs( core, 0 );
     158                if ( typeSubs_ptr && expr->env ) {
     159                        *typeSubs_ptr = expr->env;
    148160                }
    149161
     
    151163        }
    152164
    153         template< typename pass_t >
    154         const ast::Stmt * ast::Pass< pass_t >::call_accept( const ast::Stmt * stmt ) {
     165        template< typename core_t >
     166        const ast::Stmt * ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
    155167                __pedantic_pass_assert( __visit_children() );
    156168                __pedantic_pass_assert( stmt );
    157169
     170                return stmt->accept( *this );
     171        }
     172
     173        template< typename core_t >
     174        const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     175                __pedantic_pass_assert( __visit_children() );
     176                __pedantic_pass_assert( stmt );
     177
    158178                // add a few useful symbols to the scope
    159179                using __pass::empty;
    160180
    161181                // get the stmts/decls that will need to be spliced in
    162                 auto stmts_before = __pass::stmtsToAddBefore( pass, 0);
    163                 auto stmts_after  = __pass::stmtsToAddAfter ( pass, 0);
    164                 auto decls_before = __pass::declsToAddBefore( pass, 0);
    165                 auto decls_after  = __pass::declsToAddAfter ( pass, 0);
     182                auto stmts_before = __pass::stmtsToAddBefore( core, 0);
     183                auto stmts_after  = __pass::stmtsToAddAfter ( core, 0);
     184                auto decls_before = __pass::declsToAddBefore( core, 0);
     185                auto decls_after  = __pass::declsToAddAfter ( core, 0);
    166186
    167187                // These may be modified by subnode but most be restored once we exit this statemnet.
    168                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0) );
     188                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::typeSubs( core, 0 ) );
    169189                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
    170190                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
     
    202222        }
    203223
    204         template< typename pass_t >
     224        template< typename core_t >
    205225        template< template <class...> class container_t >
    206         container_t< ptr<Stmt> > ast::Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
     226        container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    207227                __pedantic_pass_assert( __visit_children() );
    208228                if( statements.empty() ) return {};
     
    215235
    216236                // get the stmts/decls that will need to be spliced in
    217                 auto stmts_before = __pass::stmtsToAddBefore( pass, 0);
    218                 auto stmts_after  = __pass::stmtsToAddAfter ( pass, 0);
    219                 auto decls_before = __pass::declsToAddBefore( pass, 0);
    220                 auto decls_after  = __pass::declsToAddAfter ( pass, 0);
     237                auto stmts_before = __pass::stmtsToAddBefore( core, 0);
     238                auto stmts_after  = __pass::stmtsToAddAfter ( core, 0);
     239                auto decls_before = __pass::declsToAddBefore( core, 0);
     240                auto decls_after  = __pass::declsToAddAfter ( core, 0);
    221241
    222242                // These may be modified by subnode but most be restored once we exit this statemnet.
     
    268288        }
    269289
    270         template< typename pass_t >
     290        template< typename core_t >
    271291        template< template <class...> class container_t, typename node_t >
    272         container_t< ast::ptr<node_t> > ast::Pass< pass_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
     292        container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    273293                __pedantic_pass_assert( __visit_children() );
    274294                if( container.empty() ) return {};
     
    299319        }
    300320
    301         template< typename pass_t >
     321        template< typename core_t >
    302322        template<typename node_t, typename parent_t, typename child_t>
    303         void ast::Pass< pass_t >::maybe_accept(
     323        void ast::Pass< core_t >::maybe_accept(
    304324                const node_t * & parent,
    305325                child_t parent_t::*child
     
    317337
    318338                if( __pass::differs(old_val, new_val) ) {
    319                         auto new_parent = mutate(parent);
     339                        auto new_parent = __pass::mutate<core_t>(parent);
     340                        new_parent->*child = new_val;
     341                        parent = new_parent;
     342                }
     343        }
     344
     345        template< typename core_t >
     346        template<typename node_t, typename parent_t, typename child_t>
     347        void ast::Pass< core_t >::maybe_accept_as_compound(
     348                const node_t * & parent,
     349                child_t parent_t::*child
     350        ) {
     351                static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );
     352
     353                if(__pass::skip(parent->*child)) return;
     354                const auto & old_val = __pass::get(parent->*child, 0);
     355
     356                static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
     357
     358                auto new_val = call_accept_as_compound( old_val );
     359
     360                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     361
     362                if( __pass::differs(old_val, new_val) ) {
     363                        auto new_parent = __pass::mutate<core_t>(parent);
    320364                        new_parent->*child = new_val;
    321365                        parent = new_parent;
     
    333377//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    334378
    335 template< typename pass_t >
    336 inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
     379template< typename core_t >
     380inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< core_t > & visitor ) {
    337381        // We are going to aggregate errors for all these statements
    338382        SemanticErrorException errors;
     
    342386
    343387        // get the stmts/decls that will need to be spliced in
    344         auto decls_before = __pass::declsToAddBefore( visitor.pass, 0);
    345         auto decls_after  = __pass::declsToAddAfter ( visitor.pass, 0);
     388        auto decls_before = __pass::declsToAddBefore( visitor.core, 0);
     389        auto decls_after  = __pass::declsToAddAfter ( visitor.core, 0);
    346390
    347391        // update pass statitistics
     
    363407                }
    364408                catch( SemanticErrorException &e ) {
    365                         errors.append( e );
     409                        if (__pass::on_error (visitor.core, *i, 0))
     410                                errors.append( e );
    366411                }
    367412
     
    371416        pass_visitor_stats.depth--;
    372417        if ( !errors.isEmpty() ) { throw errors; }
     418}
     419
     420template< typename core_t >
     421inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) {
     422        return ast::accept_all( unit.decls, visitor );
    373423}
    374424
     
    392442//--------------------------------------------------------------------------
    393443// ObjectDecl
    394 template< typename pass_t >
    395 const ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
     444template< typename core_t >
     445const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::ObjectDecl * node ) {
    396446        VISIT_START( node );
    397447
     
    406456        )
    407457
    408         __pass::symtab::addId( pass, 0, node );
     458        __pass::symtab::addId( core, 0, node );
    409459
    410460        VISIT_END( DeclWithType, node );
     
    413463//--------------------------------------------------------------------------
    414464// FunctionDecl
    415 template< typename pass_t >
    416 const ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::FunctionDecl * node ) {
    417         VISIT_START( node );
    418 
    419         __pass::symtab::addId( pass, 0, node );
     465template< typename core_t >
     466const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::FunctionDecl * node ) {
     467        VISIT_START( node );
     468
     469        __pass::symtab::addId( core, 0, node );
    420470
    421471        VISIT(maybe_accept( node, &FunctionDecl::withExprs );)
     
    425475                // shadow with exprs and not the other way around.
    426476                guard_symtab guard { *this };
    427                 __pass::symtab::addWith( pass, 0, node->withExprs, node );
     477                __pass::symtab::addWith( core, 0, node->withExprs, node );
    428478                {
    429479                        guard_symtab guard { *this };
    430480                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    431                         static ast::ObjectDecl func(
    432                                 node->location, "__func__",
    433                                 new ast::ArrayType(
    434                                         new ast::BasicType( ast::BasicType::Char, ast::CV::Qualifiers( ast::CV::Const ) ),
     481                        static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{
     482                                CodeLocation{}, "__func__",
     483                                new ast::ArrayType{
     484                                        new ast::BasicType{ ast::BasicType::Char, ast::CV::Const },
    435485                                        nullptr, VariableLen, DynamicDim
    436                                 )
    437                         );
    438                         __pass::symtab::addId( pass, 0, &func );
     486                                }
     487                        } };
     488                        __pass::symtab::addId( core, 0, func );
    439489                        VISIT(
    440                                 maybe_accept( node, &FunctionDecl::type );
    441                                 // function body needs to have the same scope as parameters - CompoundStmt will not enter
    442                                 // a new scope if inFunction is true
     490                                // parameter declarations
     491                                maybe_accept( node, &FunctionDecl::params );
     492                                maybe_accept( node, &FunctionDecl::returns );
     493                                // type params and assertions
     494                                maybe_accept( node, &FunctionDecl::type_params );
     495                                maybe_accept( node, &FunctionDecl::assertions );
     496                                // First remember that we are now within a function.
    443497                                ValueGuard< bool > oldInFunction( inFunction );
    444498                                inFunction = true;
     499                                // The function body needs to have the same scope as parameters.
     500                                // A CompoundStmt will not enter a new scope if atFunctionTop is true.
     501                                ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
     502                                atFunctionTop = true;
    445503                                maybe_accept( node, &FunctionDecl::stmts );
    446504                                maybe_accept( node, &FunctionDecl::attributes );
     
    454512//--------------------------------------------------------------------------
    455513// StructDecl
    456 template< typename pass_t >
    457 const ast::Decl * ast::Pass< pass_t >::visit( const ast::StructDecl * node ) {
     514template< typename core_t >
     515const ast::Decl * ast::Pass< core_t >::visit( const ast::StructDecl * node ) {
    458516        VISIT_START( node );
    459517
    460518        // make up a forward declaration and add it before processing the members
    461519        // needs to be on the heap because addStruct saves the pointer
    462         __pass::symtab::addStructFwd( pass, 0, node );
     520        __pass::symtab::addStructFwd( core, 0, node );
    463521
    464522        VISIT({
     
    469527
    470528        // this addition replaces the forward declaration
    471         __pass::symtab::addStruct( pass, 0, node );
     529        __pass::symtab::addStruct( core, 0, node );
    472530
    473531        VISIT_END( Decl, node );
     
    476534//--------------------------------------------------------------------------
    477535// UnionDecl
    478 template< typename pass_t >
    479 const ast::Decl * ast::Pass< pass_t >::visit( const ast::UnionDecl * node ) {
     536template< typename core_t >
     537const ast::Decl * ast::Pass< core_t >::visit( const ast::UnionDecl * node ) {
    480538        VISIT_START( node );
    481539
    482540        // make up a forward declaration and add it before processing the members
    483         __pass::symtab::addUnionFwd( pass, 0, node );
     541        __pass::symtab::addUnionFwd( core, 0, node );
    484542
    485543        VISIT({
     
    489547        })
    490548
    491         __pass::symtab::addUnion( pass, 0, node );
     549        __pass::symtab::addUnion( core, 0, node );
    492550
    493551        VISIT_END( Decl, node );
     
    496554//--------------------------------------------------------------------------
    497555// EnumDecl
    498 template< typename pass_t >
    499 const ast::Decl * ast::Pass< pass_t >::visit( const ast::EnumDecl * node ) {
    500         VISIT_START( node );
    501 
    502         __pass::symtab::addEnum( pass, 0, node );
     556template< typename core_t >
     557const ast::Decl * ast::Pass< core_t >::visit( const ast::EnumDecl * node ) {
     558        VISIT_START( node );
     559
     560        __pass::symtab::addEnum( core, 0, node );
    503561
    504562        VISIT(
     
    513571//--------------------------------------------------------------------------
    514572// TraitDecl
    515 template< typename pass_t >
    516 const ast::Decl * ast::Pass< pass_t >::visit( const ast::TraitDecl * node ) {
     573template< typename core_t >
     574const ast::Decl * ast::Pass< core_t >::visit( const ast::TraitDecl * node ) {
    517575        VISIT_START( node );
    518576
     
    523581        })
    524582
    525         __pass::symtab::addTrait( pass, 0, node );
     583        __pass::symtab::addTrait( core, 0, node );
    526584
    527585        VISIT_END( Decl, node );
     
    530588//--------------------------------------------------------------------------
    531589// TypeDecl
    532 template< typename pass_t >
    533 const ast::Decl * ast::Pass< pass_t >::visit( const ast::TypeDecl * node ) {
     590template< typename core_t >
     591const ast::Decl * ast::Pass< core_t >::visit( const ast::TypeDecl * node ) {
    534592        VISIT_START( node );
    535593
    536594        VISIT({
    537595                guard_symtab guard { *this };
    538                 maybe_accept( node, &TypeDecl::params );
    539596                maybe_accept( node, &TypeDecl::base   );
    540597        })
     
    543600        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    544601        // and may depend on the type itself
    545         __pass::symtab::addType( pass, 0, node );
     602        __pass::symtab::addType( core, 0, node );
    546603
    547604        VISIT(
     
    559616//--------------------------------------------------------------------------
    560617// TypedefDecl
    561 template< typename pass_t >
    562 const ast::Decl * ast::Pass< pass_t >::visit( const ast::TypedefDecl * node ) {
     618template< typename core_t >
     619const ast::Decl * ast::Pass< core_t >::visit( const ast::TypedefDecl * node ) {
    563620        VISIT_START( node );
    564621
    565622        VISIT({
    566623                guard_symtab guard { *this };
    567                 maybe_accept( node, &TypedefDecl::params );
    568624                maybe_accept( node, &TypedefDecl::base   );
    569625        })
    570626
    571         __pass::symtab::addType( pass, 0, node );
     627        __pass::symtab::addType( core, 0, node );
    572628
    573629        VISIT( maybe_accept( node, &TypedefDecl::assertions ); )
     
    578634//--------------------------------------------------------------------------
    579635// AsmDecl
    580 template< typename pass_t >
    581 const ast::AsmDecl * ast::Pass< pass_t >::visit( const ast::AsmDecl * node ) {
     636template< typename core_t >
     637const ast::AsmDecl * ast::Pass< core_t >::visit( const ast::AsmDecl * node ) {
    582638        VISIT_START( node );
    583639
     
    591647//--------------------------------------------------------------------------
    592648// StaticAssertDecl
    593 template< typename pass_t >
    594 const ast::StaticAssertDecl * ast::Pass< pass_t >::visit( const ast::StaticAssertDecl * node ) {
     649template< typename core_t >
     650const ast::StaticAssertDecl * ast::Pass< core_t >::visit( const ast::StaticAssertDecl * node ) {
    595651        VISIT_START( node );
    596652
     
    605661//--------------------------------------------------------------------------
    606662// CompoundStmt
    607 template< typename pass_t >
    608 const ast::CompoundStmt * ast::Pass< pass_t >::visit( const ast::CompoundStmt * node ) {
    609         VISIT_START( node );
    610         VISIT({
    611                 // do not enter a new scope if inFunction is true - needs to check old state before the assignment
    612                 auto guard1 = makeFuncGuard( [this, inFunction = this->inFunction]() {
    613                         if ( ! inFunction ) __pass::symtab::enter(pass, 0);
    614                 }, [this, inFunction = this->inFunction]() {
    615                         if ( ! inFunction ) __pass::symtab::leave(pass, 0);
     663template< typename core_t >
     664const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
     665        VISIT_START( node );
     666        VISIT(
     667                // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
     668                auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
     669                        if ( enterScope ) {
     670                                __pass::symtab::enter(core, 0);
     671                                __pass::scope::enter(core, 0);
     672                        }
     673                }, [this, leaveScope = !this->atFunctionTop]() {
     674                        if ( leaveScope ) {
     675                                __pass::symtab::leave(core, 0);
     676                                __pass::scope::leave(core, 0);
     677                        }
    616678                });
    617                 ValueGuard< bool > guard2( inFunction );
     679                ValueGuard< bool > guard2( atFunctionTop );
     680                atFunctionTop = false;
    618681                guard_scope guard3 { *this };
    619                 inFunction = false;
    620682                maybe_accept( node, &CompoundStmt::kids );
    621         })
     683        )
    622684        VISIT_END( CompoundStmt, node );
    623685}
     
    625687//--------------------------------------------------------------------------
    626688// ExprStmt
    627 template< typename pass_t >
    628 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ExprStmt * node ) {
     689template< typename core_t >
     690const ast::Stmt * ast::Pass< core_t >::visit( const ast::ExprStmt * node ) {
    629691        VISIT_START( node );
    630692
     
    638700//--------------------------------------------------------------------------
    639701// AsmStmt
    640 template< typename pass_t >
    641 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::AsmStmt * node ) {
     702template< typename core_t >
     703const ast::Stmt * ast::Pass< core_t >::visit( const ast::AsmStmt * node ) {
    642704        VISIT_START( node )
    643705
     
    654716//--------------------------------------------------------------------------
    655717// DirectiveStmt
    656 template< typename pass_t >
    657 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::DirectiveStmt * node ) {
     718template< typename core_t >
     719const ast::Stmt * ast::Pass< core_t >::visit( const ast::DirectiveStmt * node ) {
    658720        VISIT_START( node )
    659721
     
    663725//--------------------------------------------------------------------------
    664726// IfStmt
    665 template< typename pass_t >
    666 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::IfStmt * node ) {
     727template< typename core_t >
     728const ast::Stmt * ast::Pass< core_t >::visit( const ast::IfStmt * node ) {
    667729        VISIT_START( node );
    668730
     
    672734                maybe_accept( node, &IfStmt::inits    );
    673735                maybe_accept( node, &IfStmt::cond     );
    674                 maybe_accept( node, &IfStmt::thenPart );
    675                 maybe_accept( node, &IfStmt::elsePart );
     736                maybe_accept_as_compound( node, &IfStmt::thenPart );
     737                maybe_accept_as_compound( node, &IfStmt::elsePart );
    676738        })
    677739
     
    681743//--------------------------------------------------------------------------
    682744// WhileStmt
    683 template< typename pass_t >
    684 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WhileStmt * node ) {
     745template< typename core_t >
     746const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileStmt * node ) {
    685747        VISIT_START( node );
    686748
     
    690752                maybe_accept( node, &WhileStmt::inits );
    691753                maybe_accept( node, &WhileStmt::cond  );
    692                 maybe_accept( node, &WhileStmt::body  );
     754                maybe_accept_as_compound( node, &WhileStmt::body  );
    693755        })
    694756
     
    698760//--------------------------------------------------------------------------
    699761// ForStmt
    700 template< typename pass_t >
    701 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ForStmt * node ) {
     762template< typename core_t >
     763const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForStmt * node ) {
    702764        VISIT_START( node );
    703765
     
    705767                // for statements introduce a level of scope (for the initialization)
    706768                guard_symtab guard { *this };
     769                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
    707770                maybe_accept( node, &ForStmt::inits );
    708771                maybe_accept( node, &ForStmt::cond  );
    709772                maybe_accept( node, &ForStmt::inc   );
    710                 maybe_accept( node, &ForStmt::body  );
     773                maybe_accept_as_compound( node, &ForStmt::body  );
    711774        })
    712775
     
    716779//--------------------------------------------------------------------------
    717780// SwitchStmt
    718 template< typename pass_t >
    719 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::SwitchStmt * node ) {
     781template< typename core_t >
     782const ast::Stmt * ast::Pass< core_t >::visit( const ast::SwitchStmt * node ) {
    720783        VISIT_START( node );
    721784
     
    730793//--------------------------------------------------------------------------
    731794// CaseStmt
    732 template< typename pass_t >
    733 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::CaseStmt * node ) {
     795template< typename core_t >
     796const ast::Stmt * ast::Pass< core_t >::visit( const ast::CaseStmt * node ) {
    734797        VISIT_START( node );
    735798
     
    744807//--------------------------------------------------------------------------
    745808// BranchStmt
    746 template< typename pass_t >
    747 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::BranchStmt * node ) {
     809template< typename core_t >
     810const ast::Stmt * ast::Pass< core_t >::visit( const ast::BranchStmt * node ) {
    748811        VISIT_START( node );
    749812        VISIT_END( Stmt, node );
     
    752815//--------------------------------------------------------------------------
    753816// ReturnStmt
    754 template< typename pass_t >
    755 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ReturnStmt * node ) {
     817template< typename core_t >
     818const ast::Stmt * ast::Pass< core_t >::visit( const ast::ReturnStmt * node ) {
    756819        VISIT_START( node );
    757820
     
    765828//--------------------------------------------------------------------------
    766829// ThrowStmt
    767 template< typename pass_t >
    768 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ThrowStmt * node ) {
     830template< typename core_t >
     831const ast::Stmt * ast::Pass< core_t >::visit( const ast::ThrowStmt * node ) {
    769832        VISIT_START( node );
    770833
     
    779842//--------------------------------------------------------------------------
    780843// TryStmt
    781 template< typename pass_t >
    782 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::TryStmt * node ) {
     844template< typename core_t >
     845const ast::Stmt * ast::Pass< core_t >::visit( const ast::TryStmt * node ) {
    783846        VISIT_START( node );
    784847
     
    794857//--------------------------------------------------------------------------
    795858// CatchStmt
    796 template< typename pass_t >
    797 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::CatchStmt * node ) {
     859template< typename core_t >
     860const ast::Stmt * ast::Pass< core_t >::visit( const ast::CatchStmt * node ) {
    798861        VISIT_START( node );
    799862
     
    803866                maybe_accept( node, &CatchStmt::decl );
    804867                maybe_accept( node, &CatchStmt::cond );
    805                 maybe_accept( node, &CatchStmt::body );
     868                maybe_accept_as_compound( node, &CatchStmt::body );
    806869        })
    807870
     
    811874//--------------------------------------------------------------------------
    812875// FinallyStmt
    813 template< typename pass_t >
    814 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::FinallyStmt * node ) {
     876template< typename core_t >
     877const ast::Stmt * ast::Pass< core_t >::visit( const ast::FinallyStmt * node ) {
    815878        VISIT_START( node );
    816879
     
    823886
    824887//--------------------------------------------------------------------------
     888// FinallyStmt
     889template< typename core_t >
     890const ast::Stmt * ast::Pass< core_t >::visit( const ast::SuspendStmt * node ) {
     891        VISIT_START( node );
     892
     893        VISIT(
     894                maybe_accept( node, &SuspendStmt::then   );
     895        )
     896
     897        VISIT_END( Stmt, node );
     898}
     899
     900//--------------------------------------------------------------------------
    825901// WaitForStmt
    826 template< typename pass_t >
    827 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WaitForStmt * node ) {
     902template< typename core_t >
     903const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitForStmt * node ) {
    828904        VISIT_START( node );
    829905                // for( auto & clause : node->clauses ) {
     
    862938
    863939                if(mutated) {
    864                         auto n = mutate(node);
     940                        auto n = __pass::mutate<core_t>(node);
    865941                        n->clauses = std::move( new_clauses );
    866942                        node = n;
     
    872948                        auto nval = call_accept( node->field ); \
    873949                        if(nval != node->field ) { \
    874                                 auto nparent = mutate(node); \
     950                                auto nparent = __pass::mutate<core_t>(node); \
    875951                                nparent->field = nval; \
    876952                                node = nparent; \
     
    893969//--------------------------------------------------------------------------
    894970// WithStmt
    895 template< typename pass_t >
    896 const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
     971template< typename core_t >
     972const ast::Decl * ast::Pass< core_t >::visit( const ast::WithStmt * node ) {
    897973        VISIT_START( node );
    898974
     
    902978                        // catch statements introduce a level of scope (for the caught exception)
    903979                        guard_symtab guard { *this };
    904                         __pass::symtab::addWith( pass, 0, node->exprs, node );
     980                        __pass::symtab::addWith( core, 0, node->exprs, node );
    905981                        maybe_accept( node, &WithStmt::stmt );
    906982                }
     
    911987//--------------------------------------------------------------------------
    912988// NullStmt
    913 template< typename pass_t >
    914 const ast::NullStmt * ast::Pass< pass_t >::visit( const ast::NullStmt * node ) {
     989template< typename core_t >
     990const ast::NullStmt * ast::Pass< core_t >::visit( const ast::NullStmt * node ) {
    915991        VISIT_START( node );
    916992        VISIT_END( NullStmt, node );
     
    919995//--------------------------------------------------------------------------
    920996// DeclStmt
    921 template< typename pass_t >
    922 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::DeclStmt * node ) {
     997template< typename core_t >
     998const ast::Stmt * ast::Pass< core_t >::visit( const ast::DeclStmt * node ) {
    923999        VISIT_START( node );
    9241000
     
    9321008//--------------------------------------------------------------------------
    9331009// ImplicitCtorDtorStmt
    934 template< typename pass_t >
    935 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
     1010template< typename core_t >
     1011const ast::Stmt * ast::Pass< core_t >::visit( const ast::ImplicitCtorDtorStmt * node ) {
    9361012        VISIT_START( node );
    9371013
    9381014        // For now this isn't visited, it is unclear if this causes problem
    9391015        // if all tests are known to pass, remove this code
    940         // VISIT(
    941         //      maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
    942         // )
     1016        VISIT(
     1017                maybe_accept( node, &ImplicitCtorDtorStmt::callStmt );
     1018        )
    9431019
    9441020        VISIT_END( Stmt, node );
     
    9471023//--------------------------------------------------------------------------
    9481024// ApplicationExpr
    949 template< typename pass_t >
    950 const ast::Expr * ast::Pass< pass_t >::visit( const ast::ApplicationExpr * node ) {
     1025template< typename core_t >
     1026const ast::Expr * ast::Pass< core_t >::visit( const ast::ApplicationExpr * node ) {
    9511027        VISIT_START( node );
    9521028
     
    9651041//--------------------------------------------------------------------------
    9661042// UntypedExpr
    967 template< typename pass_t >
    968 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedExpr * node ) {
     1043template< typename core_t >
     1044const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedExpr * node ) {
    9691045        VISIT_START( node );
    9701046
     
    9831059//--------------------------------------------------------------------------
    9841060// NameExpr
    985 template< typename pass_t >
    986 const ast::Expr * ast::Pass< pass_t >::visit( const ast::NameExpr * node ) {
     1061template< typename core_t >
     1062const ast::Expr * ast::Pass< core_t >::visit( const ast::NameExpr * node ) {
    9871063        VISIT_START( node );
    9881064
     
    9971073//--------------------------------------------------------------------------
    9981074// CastExpr
    999 template< typename pass_t >
    1000 const ast::Expr * ast::Pass< pass_t >::visit( const ast::CastExpr * node ) {
     1075template< typename core_t >
     1076const ast::Expr * ast::Pass< core_t >::visit( const ast::CastExpr * node ) {
    10011077        VISIT_START( node );
    10021078
     
    10131089//--------------------------------------------------------------------------
    10141090// KeywordCastExpr
    1015 template< typename pass_t >
    1016 const ast::Expr * ast::Pass< pass_t >::visit( const ast::KeywordCastExpr * node ) {
     1091template< typename core_t >
     1092const ast::Expr * ast::Pass< core_t >::visit( const ast::KeywordCastExpr * node ) {
    10171093        VISIT_START( node );
    10181094
     
    10291105//--------------------------------------------------------------------------
    10301106// VirtualCastExpr
    1031 template< typename pass_t >
    1032 const ast::Expr * ast::Pass< pass_t >::visit( const ast::VirtualCastExpr * node ) {
     1107template< typename core_t >
     1108const ast::Expr * ast::Pass< core_t >::visit( const ast::VirtualCastExpr * node ) {
    10331109        VISIT_START( node );
    10341110
     
    10451121//--------------------------------------------------------------------------
    10461122// AddressExpr
    1047 template< typename pass_t >
    1048 const ast::Expr * ast::Pass< pass_t >::visit( const ast::AddressExpr * node ) {
     1123template< typename core_t >
     1124const ast::Expr * ast::Pass< core_t >::visit( const ast::AddressExpr * node ) {
    10491125        VISIT_START( node );
    10501126
     
    10611137//--------------------------------------------------------------------------
    10621138// LabelAddressExpr
    1063 template< typename pass_t >
    1064 const ast::Expr * ast::Pass< pass_t >::visit( const ast::LabelAddressExpr * node ) {
     1139template< typename core_t >
     1140const ast::Expr * ast::Pass< core_t >::visit( const ast::LabelAddressExpr * node ) {
    10651141        VISIT_START( node );
    10661142
     
    10751151//--------------------------------------------------------------------------
    10761152// UntypedMemberExpr
    1077 template< typename pass_t >
    1078 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedMemberExpr * node ) {
     1153template< typename core_t >
     1154const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedMemberExpr * node ) {
    10791155        VISIT_START( node );
    10801156
     
    10921168//--------------------------------------------------------------------------
    10931169// MemberExpr
    1094 template< typename pass_t >
    1095 const ast::Expr * ast::Pass< pass_t >::visit( const ast::MemberExpr * node ) {
     1170template< typename core_t >
     1171const ast::Expr * ast::Pass< core_t >::visit( const ast::MemberExpr * node ) {
    10961172        VISIT_START( node );
    10971173
     
    11081184//--------------------------------------------------------------------------
    11091185// VariableExpr
    1110 template< typename pass_t >
    1111 const ast::Expr * ast::Pass< pass_t >::visit( const ast::VariableExpr * node ) {
     1186template< typename core_t >
     1187const ast::Expr * ast::Pass< core_t >::visit( const ast::VariableExpr * node ) {
    11121188        VISIT_START( node );
    11131189
     
    11221198//--------------------------------------------------------------------------
    11231199// ConstantExpr
    1124 template< typename pass_t >
    1125 const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConstantExpr * node ) {
     1200template< typename core_t >
     1201const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstantExpr * node ) {
    11261202        VISIT_START( node );
    11271203
     
    11361212//--------------------------------------------------------------------------
    11371213// SizeofExpr
    1138 template< typename pass_t >
    1139 const ast::Expr * ast::Pass< pass_t >::visit( const ast::SizeofExpr * node ) {
     1214template< typename core_t >
     1215const ast::Expr * ast::Pass< core_t >::visit( const ast::SizeofExpr * node ) {
    11401216        VISIT_START( node );
    11411217
     
    11561232//--------------------------------------------------------------------------
    11571233// AlignofExpr
    1158 template< typename pass_t >
    1159 const ast::Expr * ast::Pass< pass_t >::visit( const ast::AlignofExpr * node ) {
     1234template< typename core_t >
     1235const ast::Expr * ast::Pass< core_t >::visit( const ast::AlignofExpr * node ) {
    11601236        VISIT_START( node );
    11611237
     
    11761252//--------------------------------------------------------------------------
    11771253// UntypedOffsetofExpr
    1178 template< typename pass_t >
    1179 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedOffsetofExpr * node ) {
     1254template< typename core_t >
     1255const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedOffsetofExpr * node ) {
    11801256        VISIT_START( node );
    11811257
     
    11921268//--------------------------------------------------------------------------
    11931269// OffsetofExpr
    1194 template< typename pass_t >
    1195 const ast::Expr * ast::Pass< pass_t >::visit( const ast::OffsetofExpr * node ) {
     1270template< typename core_t >
     1271const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetofExpr * node ) {
    11961272        VISIT_START( node );
    11971273
     
    12081284//--------------------------------------------------------------------------
    12091285// OffsetPackExpr
    1210 template< typename pass_t >
    1211 const ast::Expr * ast::Pass< pass_t >::visit( const ast::OffsetPackExpr * node ) {
     1286template< typename core_t >
     1287const ast::Expr * ast::Pass< core_t >::visit( const ast::OffsetPackExpr * node ) {
    12121288        VISIT_START( node );
    12131289
     
    12241300//--------------------------------------------------------------------------
    12251301// LogicalExpr
    1226 template< typename pass_t >
    1227 const ast::Expr * ast::Pass< pass_t >::visit( const ast::LogicalExpr * node ) {
     1302template< typename core_t >
     1303const ast::Expr * ast::Pass< core_t >::visit( const ast::LogicalExpr * node ) {
    12281304        VISIT_START( node );
    12291305
     
    12411317//--------------------------------------------------------------------------
    12421318// ConditionalExpr
    1243 template< typename pass_t >
    1244 const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConditionalExpr * node ) {
     1319template< typename core_t >
     1320const ast::Expr * ast::Pass< core_t >::visit( const ast::ConditionalExpr * node ) {
    12451321        VISIT_START( node );
    12461322
     
    12591335//--------------------------------------------------------------------------
    12601336// CommaExpr
    1261 template< typename pass_t >
    1262 const ast::Expr * ast::Pass< pass_t >::visit( const ast::CommaExpr * node ) {
     1337template< typename core_t >
     1338const ast::Expr * ast::Pass< core_t >::visit( const ast::CommaExpr * node ) {
    12631339        VISIT_START( node );
    12641340
     
    12761352//--------------------------------------------------------------------------
    12771353// TypeExpr
    1278 template< typename pass_t >
    1279 const ast::Expr * ast::Pass< pass_t >::visit( const ast::TypeExpr * node ) {
     1354template< typename core_t >
     1355const ast::Expr * ast::Pass< core_t >::visit( const ast::TypeExpr * node ) {
    12801356        VISIT_START( node );
    12811357
     
    12921368//--------------------------------------------------------------------------
    12931369// AsmExpr
    1294 template< typename pass_t >
    1295 const ast::Expr * ast::Pass< pass_t >::visit( const ast::AsmExpr * node ) {
     1370template< typename core_t >
     1371const ast::Expr * ast::Pass< core_t >::visit( const ast::AsmExpr * node ) {
    12961372        VISIT_START( node );
    12971373
     
    13091385//--------------------------------------------------------------------------
    13101386// ImplicitCopyCtorExpr
    1311 template< typename pass_t >
    1312 const ast::Expr * ast::Pass< pass_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
     1387template< typename core_t >
     1388const ast::Expr * ast::Pass< core_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
    13131389        VISIT_START( node );
    13141390
     
    13251401//--------------------------------------------------------------------------
    13261402// ConstructorExpr
    1327 template< typename pass_t >
    1328 const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConstructorExpr * node ) {
     1403template< typename core_t >
     1404const ast::Expr * ast::Pass< core_t >::visit( const ast::ConstructorExpr * node ) {
    13291405        VISIT_START( node );
    13301406
     
    13411417//--------------------------------------------------------------------------
    13421418// CompoundLiteralExpr
    1343 template< typename pass_t >
    1344 const ast::Expr * ast::Pass< pass_t >::visit( const ast::CompoundLiteralExpr * node ) {
     1419template< typename core_t >
     1420const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * node ) {
    13451421        VISIT_START( node );
    13461422
     
    13571433//--------------------------------------------------------------------------
    13581434// RangeExpr
    1359 template< typename pass_t >
    1360 const ast::Expr * ast::Pass< pass_t >::visit( const ast::RangeExpr * node ) {
     1435template< typename core_t >
     1436const ast::Expr * ast::Pass< core_t >::visit( const ast::RangeExpr * node ) {
    13611437        VISIT_START( node );
    13621438
     
    13741450//--------------------------------------------------------------------------
    13751451// UntypedTupleExpr
    1376 template< typename pass_t >
    1377 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedTupleExpr * node ) {
     1452template< typename core_t >
     1453const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedTupleExpr * node ) {
    13781454        VISIT_START( node );
    13791455
     
    13901466//--------------------------------------------------------------------------
    13911467// TupleExpr
    1392 template< typename pass_t >
    1393 const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleExpr * node ) {
     1468template< typename core_t >
     1469const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleExpr * node ) {
    13941470        VISIT_START( node );
    13951471
     
    14061482//--------------------------------------------------------------------------
    14071483// TupleIndexExpr
    1408 template< typename pass_t >
    1409 const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleIndexExpr * node ) {
     1484template< typename core_t >
     1485const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleIndexExpr * node ) {
    14101486        VISIT_START( node );
    14111487
     
    14221498//--------------------------------------------------------------------------
    14231499// TupleAssignExpr
    1424 template< typename pass_t >
    1425 const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleAssignExpr * node ) {
     1500template< typename core_t >
     1501const ast::Expr * ast::Pass< core_t >::visit( const ast::TupleAssignExpr * node ) {
    14261502        VISIT_START( node );
    14271503
     
    14381514//--------------------------------------------------------------------------
    14391515// StmtExpr
    1440 template< typename pass_t >
    1441 const ast::Expr * ast::Pass< pass_t >::visit( const ast::StmtExpr * node ) {
     1516template< typename core_t >
     1517const ast::Expr * ast::Pass< core_t >::visit( const ast::StmtExpr * node ) {
    14421518        VISIT_START( node );
    14431519
    14441520        VISIT(// don't want statements from outer CompoundStmts to be added to this StmtExpr
    14451521                // get the stmts that will need to be spliced in
    1446                 auto stmts_before = __pass::stmtsToAddBefore( pass, 0);
    1447                 auto stmts_after  = __pass::stmtsToAddAfter ( pass, 0);
     1522                auto stmts_before = __pass::stmtsToAddBefore( core, 0);
     1523                auto stmts_after  = __pass::stmtsToAddAfter ( core, 0);
    14481524
    14491525                // These may be modified by subnode but most be restored once we exit this statemnet.
    1450                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::env( pass, 0) );
     1526                ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
    14511527                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
    14521528                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
     
    14661542//--------------------------------------------------------------------------
    14671543// UniqueExpr
    1468 template< typename pass_t >
    1469 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UniqueExpr * node ) {
     1544template< typename core_t >
     1545const ast::Expr * ast::Pass< core_t >::visit( const ast::UniqueExpr * node ) {
    14701546        VISIT_START( node );
    14711547
     
    14821558//--------------------------------------------------------------------------
    14831559// UntypedInitExpr
    1484 template< typename pass_t >
    1485 const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedInitExpr * node ) {
     1560template< typename core_t >
     1561const ast::Expr * ast::Pass< core_t >::visit( const ast::UntypedInitExpr * node ) {
    14861562        VISIT_START( node );
    14871563
     
    14991575//--------------------------------------------------------------------------
    15001576// InitExpr
    1501 template< typename pass_t >
    1502 const ast::Expr * ast::Pass< pass_t >::visit( const ast::InitExpr * node ) {
     1577template< typename core_t >
     1578const ast::Expr * ast::Pass< core_t >::visit( const ast::InitExpr * node ) {
    15031579        VISIT_START( node );
    15041580
     
    15161592//--------------------------------------------------------------------------
    15171593// DeletedExpr
    1518 template< typename pass_t >
    1519 const ast::Expr * ast::Pass< pass_t >::visit( const ast::DeletedExpr * node ) {
     1594template< typename core_t >
     1595const ast::Expr * ast::Pass< core_t >::visit( const ast::DeletedExpr * node ) {
    15201596        VISIT_START( node );
    15211597
     
    15331609//--------------------------------------------------------------------------
    15341610// DefaultArgExpr
    1535 template< typename pass_t >
    1536 const ast::Expr * ast::Pass< pass_t >::visit( const ast::DefaultArgExpr * node ) {
     1611template< typename core_t >
     1612const ast::Expr * ast::Pass< core_t >::visit( const ast::DefaultArgExpr * node ) {
    15371613        VISIT_START( node );
    15381614
     
    15491625//--------------------------------------------------------------------------
    15501626// GenericExpr
    1551 template< typename pass_t >
    1552 const ast::Expr * ast::Pass< pass_t >::visit( const ast::GenericExpr * node ) {
     1627template< typename core_t >
     1628const ast::Expr * ast::Pass< core_t >::visit( const ast::GenericExpr * node ) {
    15531629        VISIT_START( node );
    15541630
     
    15781654
    15791655                if(mutated) {
    1580                         auto n = mutate(node);
     1656                        auto n = __pass::mutate<core_t>(node);
    15811657                        n->associations = std::move( new_kids );
    15821658                        node = n;
     
    15891665//--------------------------------------------------------------------------
    15901666// VoidType
    1591 template< typename pass_t >
    1592 const ast::Type * ast::Pass< pass_t >::visit( const ast::VoidType * node ) {
     1667template< typename core_t >
     1668const ast::Type * ast::Pass< core_t >::visit( const ast::VoidType * node ) {
    15931669        VISIT_START( node );
    15941670
     
    15981674//--------------------------------------------------------------------------
    15991675// BasicType
    1600 template< typename pass_t >
    1601 const ast::Type * ast::Pass< pass_t >::visit( const ast::BasicType * node ) {
     1676template< typename core_t >
     1677const ast::Type * ast::Pass< core_t >::visit( const ast::BasicType * node ) {
    16021678        VISIT_START( node );
    16031679
     
    16071683//--------------------------------------------------------------------------
    16081684// PointerType
    1609 template< typename pass_t >
    1610 const ast::Type * ast::Pass< pass_t >::visit( const ast::PointerType * node ) {
     1685template< typename core_t >
     1686const ast::Type * ast::Pass< core_t >::visit( const ast::PointerType * node ) {
    16111687        VISIT_START( node );
    16121688
     
    16211697//--------------------------------------------------------------------------
    16221698// ArrayType
    1623 template< typename pass_t >
    1624 const ast::Type * ast::Pass< pass_t >::visit( const ast::ArrayType * node ) {
     1699template< typename core_t >
     1700const ast::Type * ast::Pass< core_t >::visit( const ast::ArrayType * node ) {
    16251701        VISIT_START( node );
    16261702
     
    16351711//--------------------------------------------------------------------------
    16361712// ReferenceType
    1637 template< typename pass_t >
    1638 const ast::Type * ast::Pass< pass_t >::visit( const ast::ReferenceType * node ) {
     1713template< typename core_t >
     1714const ast::Type * ast::Pass< core_t >::visit( const ast::ReferenceType * node ) {
    16391715        VISIT_START( node );
    16401716
     
    16481724//--------------------------------------------------------------------------
    16491725// QualifiedType
    1650 template< typename pass_t >
    1651 const ast::Type * ast::Pass< pass_t >::visit( const ast::QualifiedType * node ) {
     1726template< typename core_t >
     1727const ast::Type * ast::Pass< core_t >::visit( const ast::QualifiedType * node ) {
    16521728        VISIT_START( node );
    16531729
     
    16621738//--------------------------------------------------------------------------
    16631739// FunctionType
    1664 template< typename pass_t >
    1665 const ast::Type * ast::Pass< pass_t >::visit( const ast::FunctionType * node ) {
    1666         VISIT_START( node );
    1667 
    1668         VISIT(
    1669                 maybe_accept( node, &FunctionType::forall  );
     1740template< typename core_t >
     1741const ast::Type * ast::Pass< core_t >::visit( const ast::FunctionType * node ) {
     1742        VISIT_START( node );
     1743
     1744        VISIT({
     1745                // guard_forall_subs forall_guard { *this, node };
     1746                // mutate_forall( node );
     1747                maybe_accept( node, &FunctionType::assertions );
    16701748                maybe_accept( node, &FunctionType::returns );
    16711749                maybe_accept( node, &FunctionType::params  );
    1672         )
     1750        })
    16731751
    16741752        VISIT_END( Type, node );
     
    16771755//--------------------------------------------------------------------------
    16781756// StructInstType
    1679 template< typename pass_t >
    1680 const ast::Type * ast::Pass< pass_t >::visit( const ast::StructInstType * node ) {
    1681         VISIT_START( node );
    1682 
    1683         __pass::symtab::addStruct( pass, 0, node->name );
     1757template< typename core_t >
     1758const ast::Type * ast::Pass< core_t >::visit( const ast::StructInstType * node ) {
     1759        VISIT_START( node );
     1760
     1761        __pass::symtab::addStruct( core, 0, node->name );
    16841762
    16851763        VISIT({
    16861764                guard_symtab guard { *this };
    1687                 maybe_accept( node, &StructInstType::forall );
    16881765                maybe_accept( node, &StructInstType::params );
    16891766        })
     
    16941771//--------------------------------------------------------------------------
    16951772// UnionInstType
    1696 template< typename pass_t >
    1697 const ast::Type * ast::Pass< pass_t >::visit( const ast::UnionInstType * node ) {
    1698         VISIT_START( node );
    1699 
    1700         __pass::symtab::addStruct( pass, 0, node->name );
    1701 
    1702         {
     1773template< typename core_t >
     1774const ast::Type * ast::Pass< core_t >::visit( const ast::UnionInstType * node ) {
     1775        VISIT_START( node );
     1776
     1777        __pass::symtab::addUnion( core, 0, node->name );
     1778
     1779        VISIT({
    17031780                guard_symtab guard { *this };
    1704                 maybe_accept( node, &UnionInstType::forall );
    17051781                maybe_accept( node, &UnionInstType::params );
    1706         }
     1782        })
    17071783
    17081784        VISIT_END( Type, node );
     
    17111787//--------------------------------------------------------------------------
    17121788// EnumInstType
    1713 template< typename pass_t >
    1714 const ast::Type * ast::Pass< pass_t >::visit( const ast::EnumInstType * node ) {
    1715         VISIT_START( node );
    1716 
    1717         VISIT(
    1718                 maybe_accept( node, &EnumInstType::forall );
     1789template< typename core_t >
     1790const ast::Type * ast::Pass< core_t >::visit( const ast::EnumInstType * node ) {
     1791        VISIT_START( node );
     1792
     1793        VISIT({
    17191794                maybe_accept( node, &EnumInstType::params );
    1720         )
     1795        })
    17211796
    17221797        VISIT_END( Type, node );
     
    17251800//--------------------------------------------------------------------------
    17261801// TraitInstType
    1727 template< typename pass_t >
    1728 const ast::Type * ast::Pass< pass_t >::visit( const ast::TraitInstType * node ) {
    1729         VISIT_START( node );
    1730 
    1731         VISIT(
    1732                 maybe_accept( node, &TraitInstType::forall );
     1802template< typename core_t >
     1803const ast::Type * ast::Pass< core_t >::visit( const ast::TraitInstType * node ) {
     1804        VISIT_START( node );
     1805
     1806        VISIT({
    17331807                maybe_accept( node, &TraitInstType::params );
    1734         )
     1808        })
    17351809
    17361810        VISIT_END( Type, node );
     
    17391813//--------------------------------------------------------------------------
    17401814// TypeInstType
    1741 template< typename pass_t >
    1742 const ast::Type * ast::Pass< pass_t >::visit( const ast::TypeInstType * node ) {
    1743         VISIT_START( node );
    1744 
    1745         VISIT(
    1746                 maybe_accept( node, &TypeInstType::forall );
    1747                 maybe_accept( node, &TypeInstType::params );
     1815template< typename core_t >
     1816const ast::Type * ast::Pass< core_t >::visit( const ast::TypeInstType * node ) {
     1817        VISIT_START( node );
     1818
     1819        VISIT(
     1820                {
     1821                        maybe_accept( node, &TypeInstType::params );
     1822                }
     1823                // ensure that base re-bound if doing substitution
     1824                __pass::forall::replace( core, 0, node );
    17481825        )
    17491826
     
    17531830//--------------------------------------------------------------------------
    17541831// TupleType
    1755 template< typename pass_t >
    1756 const ast::Type * ast::Pass< pass_t >::visit( const ast::TupleType * node ) {
     1832template< typename core_t >
     1833const ast::Type * ast::Pass< core_t >::visit( const ast::TupleType * node ) {
    17571834        VISIT_START( node );
    17581835
     
    17671844//--------------------------------------------------------------------------
    17681845// TypeofType
    1769 template< typename pass_t >
    1770 const ast::Type * ast::Pass< pass_t >::visit( const ast::TypeofType * node ) {
     1846template< typename core_t >
     1847const ast::Type * ast::Pass< core_t >::visit( const ast::TypeofType * node ) {
    17711848        VISIT_START( node );
    17721849
     
    17801857//--------------------------------------------------------------------------
    17811858// VarArgsType
    1782 template< typename pass_t >
    1783 const ast::Type * ast::Pass< pass_t >::visit( const ast::VarArgsType * node ) {
     1859template< typename core_t >
     1860const ast::Type * ast::Pass< core_t >::visit( const ast::VarArgsType * node ) {
    17841861        VISIT_START( node );
    17851862
     
    17891866//--------------------------------------------------------------------------
    17901867// ZeroType
    1791 template< typename pass_t >
    1792 const ast::Type * ast::Pass< pass_t >::visit( const ast::ZeroType * node ) {
     1868template< typename core_t >
     1869const ast::Type * ast::Pass< core_t >::visit( const ast::ZeroType * node ) {
    17931870        VISIT_START( node );
    17941871
     
    17981875//--------------------------------------------------------------------------
    17991876// OneType
    1800 template< typename pass_t >
    1801 const ast::Type * ast::Pass< pass_t >::visit( const ast::OneType * node ) {
     1877template< typename core_t >
     1878const ast::Type * ast::Pass< core_t >::visit( const ast::OneType * node ) {
    18021879        VISIT_START( node );
    18031880
     
    18071884//--------------------------------------------------------------------------
    18081885// GlobalScopeType
    1809 template< typename pass_t >
    1810 const ast::Type * ast::Pass< pass_t >::visit( const ast::GlobalScopeType * node ) {
     1886template< typename core_t >
     1887const ast::Type * ast::Pass< core_t >::visit( const ast::GlobalScopeType * node ) {
    18111888        VISIT_START( node );
    18121889
     
    18171894//--------------------------------------------------------------------------
    18181895// Designation
    1819 template< typename pass_t >
    1820 const ast::Designation * ast::Pass< pass_t >::visit( const ast::Designation * node ) {
     1896template< typename core_t >
     1897const ast::Designation * ast::Pass< core_t >::visit( const ast::Designation * node ) {
    18211898        VISIT_START( node );
    18221899
     
    18281905//--------------------------------------------------------------------------
    18291906// SingleInit
    1830 template< typename pass_t >
    1831 const ast::Init * ast::Pass< pass_t >::visit( const ast::SingleInit * node ) {
     1907template< typename core_t >
     1908const ast::Init * ast::Pass< core_t >::visit( const ast::SingleInit * node ) {
    18321909        VISIT_START( node );
    18331910
     
    18411918//--------------------------------------------------------------------------
    18421919// ListInit
    1843 template< typename pass_t >
    1844 const ast::Init * ast::Pass< pass_t >::visit( const ast::ListInit * node ) {
     1920template< typename core_t >
     1921const ast::Init * ast::Pass< core_t >::visit( const ast::ListInit * node ) {
    18451922        VISIT_START( node );
    18461923
     
    18551932//--------------------------------------------------------------------------
    18561933// ConstructorInit
    1857 template< typename pass_t >
    1858 const ast::Init * ast::Pass< pass_t >::visit( const ast::ConstructorInit * node ) {
     1934template< typename core_t >
     1935const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node ) {
    18591936        VISIT_START( node );
    18601937
     
    18701947//--------------------------------------------------------------------------
    18711948// Attribute
    1872 template< typename pass_t >
    1873 const ast::Attribute * ast::Pass< pass_t >::visit( const ast::Attribute * node  )  {
     1949template< typename core_t >
     1950const ast::Attribute * ast::Pass< core_t >::visit( const ast::Attribute * node  )  {
    18741951        VISIT_START( node );
    18751952
     
    18831960//--------------------------------------------------------------------------
    18841961// TypeSubstitution
    1885 template< typename pass_t >
    1886 const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
     1962template< typename core_t >
     1963const ast::TypeSubstitution * ast::Pass< core_t >::visit( const ast::TypeSubstitution * node ) {
    18871964        VISIT_START( node );
    18881965
     
    18901967                {
    18911968                        bool mutated = false;
    1892                         std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
     1969                        std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map;
    18931970                        for ( const auto & p : node->typeEnv ) {
    18941971                                guard_symtab guard { *this };
    18951972                                auto new_node = p.second->accept( *this );
    1896                                 if (new_node != p.second) mutated = false;
     1973                                if (new_node != p.second) mutated = true;
    18971974                                new_map.insert({ p.first, new_node });
    18981975                        }
    18991976                        if (mutated) {
    1900                                 auto new_node = mutate( node );
     1977                                auto new_node = __pass::mutate<core_t>( node );
    19011978                                new_node->typeEnv.swap( new_map );
    19021979                                node = new_node;
    19031980                        }
    19041981                }
    1905 
    1906                 {
    1907                         bool mutated = false;
    1908                         std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
    1909                         for ( const auto & p : node->varEnv ) {
    1910                                 guard_symtab guard { *this };
    1911                                 auto new_node = p.second->accept( *this );
    1912                                 if (new_node != p.second) mutated = false;
    1913                                 new_map.insert({ p.first, new_node });
    1914                         }
    1915                         if (mutated) {
    1916                                 auto new_node = mutate( node );
    1917                                 new_node->varEnv.swap( new_map );
    1918                                 node = new_node;
    1919                         }
    1920                 }
    19211982        )
    19221983
Note: See TracChangeset for help on using the changeset viewer.