Ignore:
File:
1 edited

Legend:

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

    r7a36848 r5bf685f  
    154154                bool is_old;
    155155
    156                 explicit delta(const Stmt * s) : new_val(s), old_idx(-1), is_old(false) {}
    157                 explicit delta(ssize_t i) : new_val(nullptr), old_idx(i), is_old(true) {}
     156                delta(const Stmt * s, ssize_t i, bool old) :
     157                        new_val(s), old_idx(i), is_old(old) {}
    158158        };
    159159
     
    188188                std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ),
    189189                        [](ast::ptr<ast::Stmt>& stmt) -> delta {
    190                                 return delta( stmt.release() );
     190                                return delta( stmt.release(), -1, false );
    191191                        });
    192192                stmts->clear();
     
    201201                        [](ast::ptr<ast::Decl>& decl) -> delta {
    202202                                ast::Decl const * d = decl.release();
    203                                 return delta( new DeclStmt( d->location, d ) );
     203                                return delta( new DeclStmt( d->location, d ), -1, false );
    204204                        });
    205205                decls->clear();
     
    226226                // Now the original containers should still have the unchanged values
    227227                // but also contain the new values.
     228        }
     229};
     230
     231/// Used by previsit implementation
     232/// We need to reassign the result to 'node', unless the function
     233/// returns void, then we just leave 'node' unchanged
     234template<bool is_void>
     235struct __assign;
     236
     237template<>
     238struct __assign<true> {
     239        template<typename core_t, typename node_t>
     240        static inline void result( core_t & core, const node_t * & node ) {
     241                core.previsit( node );
     242        }
     243};
     244
     245template<>
     246struct __assign<false> {
     247        template<typename core_t, typename node_t>
     248        static inline void result( core_t & core, const node_t * & node ) {
     249                node = core.previsit( node );
     250                assertf(node, "Previsit must not return NULL");
     251        }
     252};
     253
     254/// Used by postvisit implementation
     255/// We need to return the result unless the function
     256/// returns void, then we just return the original node
     257template<bool is_void>
     258struct __return;
     259
     260template<>
     261struct __return<true> {
     262        template<typename core_t, typename node_t>
     263        static inline const node_t * result( core_t & core, const node_t * & node ) {
     264                core.postvisit( node );
     265                return node;
     266        }
     267};
     268
     269template<>
     270struct __return<false> {
     271        template<typename core_t, typename node_t>
     272        static inline auto result( core_t & core, const node_t * & node ) {
     273                return core.postvisit( node );
    228274        }
    229275};
     
    251297        );
    252298
    253         // We need to reassign the result to 'node', unless the function
    254         // returns void, then we just leave 'node' unchanged
    255         if constexpr ( std::is_void_v<decltype( core.previsit( node ) )> ) {
    256                 core.previsit( node );
    257         } else {
    258                 node = core.previsit( node );
    259                 assertf( node, "Previsit must not return nullptr." );
    260         }
     299        __assign<
     300                std::is_void<
     301                        decltype( core.previsit( node ) )
     302                >::value
     303        >::result( core, node );
    261304}
    262305
     
    269312        decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
    270313{
    271         // We need to return the result unless the function
    272         // returns void, then we just return the original node
    273         if constexpr ( std::is_void_v<decltype( core.postvisit( node ) )> ) {
    274                 core.postvisit( node );
    275                 return node;
    276         } else {
    277                 return core.postvisit( node );
    278         }
     314        return __return<
     315                std::is_void<
     316                        decltype( core.postvisit( node ) )
     317                >::value
     318        >::result( core, node );
    279319}
    280320
     
    310350FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    311351FIELD_PTR( visitor, ast::Pass<core_t> * const )
    312 FIELD_PTR( translationUnit, const TranslationUnit * )
    313352
    314353// Remove the macro to make sure we don't clash
     
    507546} // namespace forall
    508547
     548// For passes that need access to the global context. Searches `translationUnit`
     549namespace translation_unit {
     550        template<typename core_t>
     551        static inline auto get_cptr( core_t & core, int )
     552                        -> decltype( &core.translationUnit ) {
     553                return &core.translationUnit;
     554        }
     555
     556        template<typename core_t>
     557        static inline const TranslationUnit ** get_cptr( core_t &, long ) {
     558                return nullptr;
     559        }
     560}
     561
    509562// For passes, usually utility passes, that have a result.
    510563namespace result {
Note: See TracChangeset for help on using the changeset viewer.