Ignore:
File:
1 edited

Legend:

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

    r6d51bd7 r04124c4  
    1616#pragma once
    1717// IWYU pragma: private, include "AST/Pass.hpp"
    18 
    19 #include <type_traits>
    20 #include <unordered_map>
    2118
    2219#define VISIT_START( node ) \
     
    2926        __pass::previsit( pass, node, 0 );
    3027
    31 #define VISIT( code... ) \
     28#define VISIT( code ) \
    3229        /* if this node should visit its children */ \
    3330        if ( __visit_children() ) { \
     
    3835#define VISIT_END( type, node ) \
    3936        /* call the implementation of the postvisit of this pass */ \
    40         auto __return = __pass::postvisit( pass, node, 0 ); \
     37        auto __return = __pass::postvisit< type * >( node ); \
    4138        assertf(__return, "post visit should never return null"); \
    4239        return __return;
    4340
    4441#ifdef PEDANTIC_PASS_ASSERT
    45 #define __pedantic_pass_assert(...) assert (__VA_ARGS__)
    46 #define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
     42#define __pedantic_pass_assert (...) assert (__VAR_ARGS__)
     43#define __pedantic_pass_assertf(...) assertf(__VAR_ARGS__)
    4744#else
    48 #define __pedantic_pass_assert(...)
     45#define __pedantic_pass_assert (...)
    4946#define __pedantic_pass_assertf(...)
    5047#endif
     
    5855                }
    5956
    60                 //------------------------------
    61                 template<typename it_t, template <class...> class container_t>
    62                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) {
     57                template<typename it_t, template <class> class container_t>
     58                static inline void take_all( it_t it, container_t<ast::ptr<ast::Declaration>> * decls, bool * mutated = nullptr ) {
    6359                        if(empty(decls)) return;
    6460
    65                         std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
     61                        std::transform(decls->begin(), decls->end(), it, [](Declaration * decl) -> auto {
    6662                                        return new DeclStmt( decl );
    6763                                });
     
    7066                }
    7167
    72                 template<typename it_t, template <class...> class container_t>
    73                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) {
     68                template<typename it_t, template <class> class container_t>
     69                static inline void take_all( it_t it, container_t<ast::ptr<ast::Statement>> * decls, bool * mutated = nullptr ) {
    7470                        if(empty(decls)) return;
    7571
     
    7975                }
    8076
    81                 //------------------------------
    82                 /// Check if should be skipped, different for pointers and containers
    8377                template<typename node_t>
    84                 bool skip( const ast::ptr<node_t> & val) {
    85                         return !val;
    86                 }
    87 
    88                 template< template <class...> class container_t, typename node_t >
    89                 bool skip( const container_t<ast::ptr< node_t >> & val ) {
    90                         return val.empty();
    91                 }
    92 
    93                 //------------------------------
    94                 /// Get the value to visit, different for pointers and containers
    95                 template<typename node_t>
    96                 auto get( const ast::ptr<node_t> & val, int ) -> decltype(val.get()) {
    97                         return val.get();
    98                 }
    99 
    100                 template<typename node_t>
    101                 const node_t & get( const node_t & val, long) {
    102                         return val;
    103                 }
    104 
    105 
    106                 //------------------------------
    107                 /// Check if value was mutated, different for pointers and containers
    108                 template<typename lhs_t, typename rhs_t>
    109                 bool differs( const lhs_t * old_val, const rhs_t * new_val ) {
     78                bool differs( const node_t * old_val, const node_t * new_val ) {
    11079                        return old_val != new_val;
    11180                }
    11281
    113                 template< template <class...> class container_t, typename node_t >
    114                 bool differs( const container_t<ast::ptr< node_t >> &, const container_t<ast::ptr< node_t >> & new_val ) {
     82                template< template <class> class container_t >
     83                bool differs( const container_t<ast::ptr< ast::Statement >> &, const container_t<ast::ptr< ast::Statement >> & new_val ) {
    11584                        return !new_val.empty();
    11685                }
    11786        }
    11887
     88        template<typename parent_t, typename child_t>
     89        template< typename pass_t >
     90        void Pass< pass_t >::maybe_accept(
     91                const parent_t * & parent,
     92                const typename parent_t::child_t * child
     93        ) {
     94                const auto & old_val = parent->*child;
     95                if(!old_val) return;
     96
     97                auto new_val = call_accept(old_val);
     98
     99                if( __pass::differs(old_val, new_val) ) {
     100                        auto new_parent = mutate(parent);
     101                        new_parent->*child = new_val;
     102                        parent = new_parent;
     103                }
     104        }
     105
    119106        template< typename pass_t >
    120107        template< typename node_t >
    121         auto Pass< pass_t >::call_accept( const node_t * node ) -> decltype( node->accept(*this) ) {
     108        auto Pass< pass_t >::call_accept( const node_t * node ) {
    122109                __pedantic_pass_assert( __visit_children() );
    123110                __pedantic_pass_assert( expr );
    124111
    125                 static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
    126                 static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR");
    127 
    128112                return node->accept( *this );
    129113        }
    130114
    131115        template< typename pass_t >
    132         const ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
     116        ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
    133117                __pedantic_pass_assert( __visit_children() );
    134118                __pedantic_pass_assert( expr );
     
    143127
    144128        template< typename pass_t >
    145         const ast::Stmt * Pass< pass_t >::call_accept( const ast::Stmt * stmt ) {
     129        Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) {
    146130                __pedantic_pass_assert( __visit_children() );
    147131                __pedantic_pass_assert( stmt );
     
    157141
    158142                // These may be modified by subnode but most be restored once we exit this statemnet.
    159                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0) );
    160                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
    161                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
    162                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
    163                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
     143                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0); );
     144                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
     145                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
     146                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
     147                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
    164148
    165149                // Now is the time to actually visit the node
    166                 const ast::Stmt * nstmt = stmt->accept( *this );
     150                ast::Statement * nstmt = stmt->accept( *this );
    167151
    168152                // If the pass doesn't want to add anything then we are done
     
    177161
    178162                // Create a new Compound Statement to hold the new decls/stmts
    179                 ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
     163                ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );
    180164
    181165                // Take all the declarations that go before
     
    184168
    185169                // Insert the original declaration
    186                 compound->kids.emplace_back( nstmt );
     170                compound->kids.push_back( nstmt );
    187171
    188172                // Insert all the declarations that go before
     
    194178
    195179        template< typename pass_t >
    196         template< template <class...> class container_t >
     180        template< template <class> class container_t >
    197181        container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    198182                __pedantic_pass_assert( __visit_children() );
     
    212196
    213197                // These may be modified by subnode but most be restored once we exit this statemnet.
    214                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
    215                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
    216                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
    217                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
     198                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
     199                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
     200                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
     201                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
    218202
    219203                // update pass statitistics
     
    227211                        try {
    228212                                __pedantic_pass_assert( stmt );
    229                                 const ast::Stmt * new_stmt = stmt->accept( *this );
     213                                const ast::Statment * new_stmt = stmt->accept( visitor );
    230214                                assert( new_stmt );
    231215                                if(new_stmt != stmt ) mutated = true;
     
    256240                if ( !errors.isEmpty() ) { throw errors; }
    257241
    258                 return mutated ? new_kids : container_t< ptr<Stmt> >();
    259         }
    260 
    261         template< typename pass_t >
    262         template< template <class...> class container_t, typename node_t >
     242                return mutated ? new_kids : {};
     243        }
     244
     245        template< typename pass_t >
     246        template< template <class> class container_t, typename node_t >
    263247        container_t< ast::ptr<node_t> > Pass< pass_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    264248                __pedantic_pass_assert( __visit_children() );
     
    275259                        try {
    276260                                __pedantic_pass_assert( node );
    277                                 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
    278                                 if(new_stmt != node ) mutated = true;
     261                                const node_t * new_node = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
     262                                if(new_stmt != stmt ) mutated = true;
    279263
    280264                                new_kids.emplace_back( new_stmt );
     
    287271                if ( ! errors.isEmpty() ) { throw errors; }
    288272
    289                 return mutated ? new_kids : container_t< ast::ptr<node_t> >();
    290         }
    291 
    292         template< typename pass_t >
    293         template<typename node_t, typename parent_t, typename child_t>
    294         void Pass< pass_t >::maybe_accept(
    295                 const node_t * & parent,
    296                 child_t parent_t::*child
    297         ) {
    298                 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deductiing member object" );
    299 
    300                 if(__pass::skip(parent->*child)) return;
    301                 const auto & old_val = __pass::get(parent->*child, 0);
    302 
    303                 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
    304 
    305                 auto new_val = call_accept( old_val );
    306 
    307                 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
    308 
    309                 if( __pass::differs(old_val, new_val) ) {
    310                         auto new_parent = mutate(parent);
    311                         new_parent->*child = new_val;
    312                         parent = new_parent;
    313                 }
    314         }
    315 
     273                return mutated ? new_kids : {};
     274        }
    316275}
    317276
     
    325284
    326285template< typename pass_t >
    327 inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
     286inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
    328287        // We are going to aggregate errors for all these statements
    329288        SemanticErrorException errors;
     
    333292
    334293        // get the stmts/decls that will need to be spliced in
    335         auto decls_before = __pass::declsToAddBefore( visitor.pass, 0);
    336         auto decls_after  = __pass::declsToAddAfter ( visitor.pass, 0);
     294        auto decls_before = __pass::declsToAddBefore( pass, 0);
     295        auto decls_after  = __pass::declsToAddAfter ( pass, 0);
    337296
    338297        // update pass statitistics
     
    384343// ObjectDecl
    385344template< typename pass_t >
    386 const ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
     345ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
    387346        VISIT_START( node );
    388347
    389348        VISIT(
    390349                {
    391                         guard_indexer guard { *this };
    392                         maybe_accept( node, &ast::ObjectDecl::type );
    393                 }
    394                 maybe_accept( node, &ast::ObjectDecl::init          );
    395                 maybe_accept( node, &ast::ObjectDecl::bitfieldWidth );
    396                 maybe_accept( node, &ast::ObjectDecl::attributes    );
     350                        indexer_guard guard { *this };
     351                        maybe_accept( node, ObjectDecl::type );
     352                }
     353                maybe_accept( node, ObjectDecl::init          );
     354                maybe_accept( node, ObjectDecl::bitfieldWidth );
     355                maybe_accept( node, ObjectDecl::attributes    );
    397356        )
    398357
    399         __pass::indexer::addId( pass, 0, node );
     358        __pass::indexer::AddId( pass, 0, node );
    400359
    401360        VISIT_END( DeclWithType, node );
    402 }
    403 
    404 //--------------------------------------------------------------------------
    405 // SingleInit
    406 template< typename pass_t >
    407 const ast::Init * ast::Pass< pass_t >::visit( const ast::SingleInit * node ) {
    408         VISIT_START( node );
    409 
    410         VISIT(
    411                 maybe_accept( node, &SingleInit::value );
    412         )
    413 
    414         VISIT_END( Init, node );
    415 }
    416 
    417 //--------------------------------------------------------------------------
    418 // ListInit
    419 template< typename pass_t >
    420 const ast::Init * ast::Pass< pass_t >::visit( const ast::ListInit * node ) {
    421         VISIT_START( node );
    422 
    423         VISIT(
    424                 maybe_accept( node, &ListInit::designations );
    425                 maybe_accept( node, &ListInit::initializers );
    426         )
    427 
    428         VISIT_END( Init, node );
    429 }
    430 
    431 //--------------------------------------------------------------------------
    432 // ConstructorInit
    433 template< typename pass_t >
    434 const ast::Init * ast::Pass< pass_t >::visit( const ast::ConstructorInit * node ) {
    435         VISIT_START( node );
    436 
    437         VISIT(
    438                 maybe_accept( node, &ConstructorInit::ctor );
    439                 maybe_accept( node, &ConstructorInit::dtor );
    440                 maybe_accept( node, &ConstructorInit::init );
    441         )
    442 
    443         VISIT_END( Init, node );
    444361}
    445362
    446363//--------------------------------------------------------------------------
    447364// Attribute
    448 template< typename pass_t >
    449 const ast::Attribute * ast::Pass< pass_t >::visit( const ast::Attribute * node  )  {
    450         VISIT_START( node );
     365template< typename pass_type >
     366ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute * node  )  {
     367        VISIT_START(node);
    451368
    452369        VISIT(
    453                 maybe_accept( node, &Attribute::parameters );
     370                maybe_accept( node, ast::Attribute::parameters );
    454371        )
    455372
    456         VISIT_END( Attribute *, node );
     373        VISIT_END(ast::Attribute *, node );
    457374}
    458375
    459376//--------------------------------------------------------------------------
    460377// TypeSubstitution
    461 template< typename pass_t >
    462 const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
    463         VISIT_START( node );
    464 
    465         VISIT(
    466                 {
    467                         bool mutated = false;
    468                         std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
    469                         for ( const auto & p : node->typeEnv ) {
    470                                 guard_indexer guard { *this };
    471                                 auto new_node = p.second->accept( *this );
    472                                 if (new_node != p.second) mutated = false;
    473                                 new_map.insert({ p.first, new_node });
    474                         }
    475                         if (mutated) {
    476                                 auto new_node = mutate( node );
    477                                 new_node->typeEnv.swap( new_map );
    478                                 node = new_node;
    479                         }
    480                 }
    481 
    482                 {
    483                         bool mutated = false;
    484                         std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
    485                         for ( const auto & p : node->varEnv ) {
    486                                 guard_indexer guard { *this };
    487                                 auto new_node = p.second->accept( *this );
    488                                 if (new_node != p.second) mutated = false;
    489                                 new_map.insert({ p.first, new_node });
    490                         }
    491                         if (mutated) {
    492                                 auto new_node = mutate( node );
    493                                 new_node->varEnv.swap( new_map );
    494                                 node = new_node;
    495                         }
    496                 }
    497         )
    498 
    499         VISIT_END( TypeSubstitution, node );
     378template< typename pass_type >
     379TypeSubstitution * PassVisitor< pass_type >::mutate( const TypeSubstitution * node ) {
     380        MUTATE_START( node );
     381
     382        #error this is broken
     383
     384        for ( auto & p : node->typeEnv ) {
     385                indexerScopedMutate( p.second, *this );
     386        }
     387        for ( auto & p : node->varEnv ) {
     388                indexerScopedMutate( p.second, *this );
     389        }
     390
     391        MUTATE_END( TypeSubstitution, node );
    500392}
    501393
Note: See TracChangeset for help on using the changeset viewer.