Ignore:
File:
1 edited

Legend:

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

    r7ff3e522 r0e42794  
    1717// IWYU pragma: private, include "Pass.hpp"
    1818
    19 #include "Common/Stats/Heap.h"
    20 
    2119namespace ast {
    22 template<typename core_t>
     20template<typename pass_type>
    2321class Pass;
    2422
     
    8482                };
    8583
    86                 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
     84                std::stack< cleanup_t > cleanups;
    8785        };
    8886
     
    113111        /// "Short hand" to check if this is a valid previsit function
    114112        /// Mostly used to make the static_assert look (and print) prettier
    115         template<typename core_t, typename node_t>
     113        template<typename pass_t, typename node_t>
    116114        struct is_valid_previsit {
    117                 using ret_t = decltype( ((core_t*)nullptr)->previsit( (const node_t *)nullptr ) );
     115                using ret_t = decltype( ((pass_t*)nullptr)->previsit( (const node_t *)nullptr ) );
    118116
    119117                static constexpr bool value = std::is_void< ret_t >::value ||
     
    129127        template<>
    130128        struct __assign<true> {
    131                 template<typename core_t, typename node_t>
    132                 static inline void result( core_t & core, const node_t * & node ) {
    133                         core.previsit( node );
     129                template<typename pass_t, typename node_t>
     130                static inline void result( pass_t & pass, const node_t * & node ) {
     131                        pass.previsit( node );
    134132                }
    135133        };
     
    137135        template<>
    138136        struct __assign<false> {
    139                 template<typename core_t, typename node_t>
    140                 static inline void result( core_t & core, const node_t * & node ) {
    141                         node = core.previsit( node );
     137                template<typename pass_t, typename node_t>
     138                static inline void result( pass_t & pass, const node_t * & node ) {
     139                        node = pass.previsit( node );
    142140                        assertf(node, "Previsit must not return NULL");
    143141                }
     
    152150        template<>
    153151        struct __return<true> {
    154                 template<typename core_t, typename node_t>
    155                 static inline const node_t * result( core_t & core, const node_t * & node ) {
    156                         core.postvisit( node );
     152                template<typename pass_t, typename node_t>
     153                static inline const node_t * result( pass_t & pass, const node_t * & node ) {
     154                        pass.postvisit( node );
    157155                        return node;
    158156                }
     
    161159        template<>
    162160        struct __return<false> {
    163                 template<typename core_t, typename node_t>
    164                 static inline auto result( core_t & core, const node_t * & node ) {
    165                         return core.postvisit( node );
     161                template<typename pass_t, typename node_t>
     162                static inline auto result( pass_t & pass, const node_t * & node ) {
     163                        return pass.postvisit( node );
    166164                }
    167165        };
     
    182180        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    183181        // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call
    184         template<typename core_t, typename node_t>
    185         static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) {
     182        template<typename pass_t, typename node_t>
     183        static inline auto previsit( pass_t & pass, const node_t * & node, int ) -> decltype( pass.previsit( node ), void() ) {
    186184                static_assert(
    187                         is_valid_previsit<core_t, node_t>::value,
     185                        is_valid_previsit<pass_t, node_t>::value,
    188186                        "Previsit may not change the type of the node. It must return its paremeter or void."
    189187                );
     
    191189                __assign<
    192190                        std::is_void<
    193                                 decltype( core.previsit( node ) )
     191                                decltype( pass.previsit( node ) )
    194192                        >::value
    195                 >::result( core, node );
     193                >::result( pass, node );
    196194        }
    197195
    198         template<typename core_t, typename node_t>
    199         static inline auto previsit( core_t &, const node_t *, long ) {}
     196        template<typename pass_t, typename node_t>
     197        static inline auto previsit( pass_t &, const node_t *, long ) {}
    200198
    201199        // PostVisit : never mutates the passed pointer but may return a different node
    202         template<typename core_t, typename node_t>
    203         static inline auto postvisit( core_t & core, const node_t * node, int ) ->
    204                 decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
     200        template<typename pass_t, typename node_t>
     201        static inline auto postvisit( pass_t & pass, const node_t * node, int ) ->
     202                decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
    205203        {
    206204                return __return<
    207205                        std::is_void<
    208                                 decltype( core.postvisit( node ) )
     206                                decltype( pass.postvisit( node ) )
    209207                        >::value
    210                 >::result( core, node );
     208                >::result( pass, node );
    211209        }
    212210
    213         template<typename core_t, typename node_t>
    214         static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }
     211        template<typename pass_t, typename node_t>
     212        static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; }
    215213
    216214        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    227225        // The type is not strictly enforced but does match the accessory
    228226        #define FIELD_PTR( name, default_type ) \
    229         template< typename core_t > \
    230         static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \
     227        template< typename pass_t > \
     228        static inline auto name( pass_t & pass, int ) -> decltype( &pass.name ) { return &pass.name; } \
    231229        \
    232         template< typename core_t > \
    233         static inline default_type * name( core_t &, long ) { return nullptr; }
     230        template< typename pass_t > \
     231        static inline default_type * name( pass_t &, long ) { return nullptr; }
    234232
    235233        // List of fields and their expected types
     
    241239        FIELD_PTR( visit_children, __pass::bool_ref )
    242240        FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    243         FIELD_PTR( visitor, ast::Pass<core_t> * const )
     241        FIELD_PTR( visitor, ast::Pass<pass_t> * const )
    244242
    245243        // Remove the macro to make sure we don't clash
    246244        #undef FIELD_PTR
    247 
    248         template< typename core_t >
    249         static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    250                 // Stats::Heap::stacktrace_push(core_t::traceId);
    251         }
    252 
    253         template< typename core_t >
    254         static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    255                 // Stats::Heap::stacktrace_pop();
    256         }
    257 
    258         template< typename core_t >
    259         static void beginTrace(core_t &, long) {}
    260 
    261         template< typename core_t >
    262         static void endTrace(core_t &, long) {}
    263245
    264246        // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
     
    266248        // detect it using the same strategy
    267249        namespace scope {
    268                 template<typename core_t>
    269                 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) {
    270                         core.beginScope();
    271                 }
    272 
    273                 template<typename core_t>
    274                 static inline void enter( core_t &, long ) {}
    275 
    276                 template<typename core_t>
    277                 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) {
    278                         core.endScope();
    279                 }
    280 
    281                 template<typename core_t>
    282                 static inline void leave( core_t &, long ) {}
    283         } // namespace scope
    284 
    285         // Certain passes desire an up to date symbol table automatically
     250                template<typename pass_t>
     251                static inline auto enter( pass_t & pass, int ) -> decltype( pass.beginScope(), void() ) {
     252                        pass.beginScope();
     253                }
     254
     255                template<typename pass_t>
     256                static inline void enter( pass_t &, long ) {}
     257
     258                template<typename pass_t>
     259                static inline auto leave( pass_t & pass, int ) -> decltype( pass.endScope(), void() ) {
     260                        pass.endScope();
     261                }
     262
     263                template<typename pass_t>
     264                static inline void leave( pass_t &, long ) {}
     265        };
     266
     267        // Finally certain pass desire an up to date symbol table automatically
    286268        // detect the presence of a member name `symtab` and call all the members appropriately
    287269        namespace symtab {
    288270                // Some simple scoping rules
    289                 template<typename core_t>
    290                 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) {
    291                         core.symtab.enterScope();
    292                 }
    293 
    294                 template<typename core_t>
    295                 static inline auto enter( core_t &, long ) {}
    296 
    297                 template<typename core_t>
    298                 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) {
    299                         core.symtab.leaveScope();
    300                 }
    301 
    302                 template<typename core_t>
    303                 static inline auto leave( core_t &, long ) {}
     271                template<typename pass_t>
     272                static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab.enterScope(), void() ) {
     273                        pass.symtab.enterScope();
     274                }
     275
     276                template<typename pass_t>
     277                static inline auto enter( pass_t &, long ) {}
     278
     279                template<typename pass_t>
     280                static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab.leaveScope(), void() ) {
     281                        pass.symtab.leaveScope();
     282                }
     283
     284                template<typename pass_t>
     285                static inline auto leave( pass_t &, long ) {}
    304286
    305287                // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    306288                // Create macro to condense these common patterns
    307289                #define SYMTAB_FUNC1( func, type ) \
    308                 template<typename core_t> \
    309                 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\
    310                         core.symtab.func( arg ); \
     290                template<typename pass_t> \
     291                static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.symtab.func( arg ), void() ) {\
     292                        pass.symtab.func( arg ); \
    311293                } \
    312294                \
    313                 template<typename core_t> \
    314                 static inline void func( core_t &, long, type ) {}
     295                template<typename pass_t> \
     296                static inline void func( pass_t &, long, type ) {}
    315297
    316298                #define SYMTAB_FUNC2( func, type1, type2 ) \
    317                 template<typename core_t> \
    318                 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\
    319                         core.symtab.func( arg1, arg2 ); \
     299                template<typename pass_t> \
     300                static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.symtab.func( arg1, arg2 ), void () ) {\
     301                        pass.symtab.func( arg1, arg2 ); \
    320302                } \
    321303                        \
    322                 template<typename core_t> \
    323                 static inline void func( core_t &, long, type1, type2 ) {}
     304                template<typename pass_t> \
     305                static inline void func( pass_t &, long, type1, type2 ) {}
    324306
    325307                SYMTAB_FUNC1( addId     , const DeclWithType *  );
     
    329311                SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    330312                SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
    331                 SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
     313                SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
    332314
    333315                // A few extra functions have more complicated behaviour, they are hand written
    334                 template<typename core_t>
    335                 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {
     316                template<typename pass_t>
     317                static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.symtab.addStruct( decl ), void() ) {
    336318                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    337319                        fwd->params = decl->params;
    338                         core.symtab.addStruct( fwd );
    339                 }
    340 
    341                 template<typename core_t>
    342                 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {}
    343 
    344                 template<typename core_t>
    345                 static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) {
     320                        pass.symtab.addStruct( fwd );
     321                }
     322
     323                template<typename pass_t>
     324                static inline void addStructFwd( pass_t &, long, const ast::StructDecl * ) {}
     325
     326                template<typename pass_t>
     327                static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass.symtab.addUnion( decl ), void() ) {
    346328                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
    347329                        fwd->params = decl->params;
    348                         core.symtab.addUnion( fwd );
    349                 }
    350 
    351                 template<typename core_t>
    352                 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {}
    353 
    354                 template<typename core_t>
    355                 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
    356                         if ( ! core.symtab.lookupStruct( str ) ) {
    357                                 core.symtab.addStruct( str );
    358                         }
    359                 }
    360 
    361                 template<typename core_t>
    362                 static inline void addStruct( core_t &, long, const std::string & ) {}
    363 
    364                 template<typename core_t>
    365                 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) {
    366                         if ( ! core.symtab.lookupUnion( str ) ) {
    367                                 core.symtab.addUnion( str );
    368                         }
    369                 }
    370 
    371                 template<typename core_t>
    372                 static inline void addUnion( core_t &, long, const std::string & ) {}
     330                        pass.symtab.addUnion( fwd );
     331                }
     332
     333                template<typename pass_t>
     334                static inline void addUnionFwd( pass_t &, long, const ast::UnionDecl * ) {}
     335
     336                template<typename pass_t>
     337                static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.symtab.addStruct( str ), void() ) {
     338                        if ( ! pass.symtab.lookupStruct( str ) ) {
     339                                pass.symtab.addStruct( str );
     340                        }
     341                }
     342
     343                template<typename pass_t>
     344                static inline void addStruct( pass_t &, long, const std::string & ) {}
     345
     346                template<typename pass_t>
     347                static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.symtab.addUnion( str ), void() ) {
     348                        if ( ! pass.symtab.lookupUnion( str ) ) {
     349                                pass.symtab.addUnion( str );
     350                        }
     351                }
     352
     353                template<typename pass_t>
     354                static inline void addUnion( pass_t &, long, const std::string & ) {}
    373355
    374356                #undef SYMTAB_FUNC1
    375357                #undef SYMTAB_FUNC2
    376         } // namespace symtab
    377 
    378         // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType.
    379         // Detect the presence of a member name `subs` and call all members appropriately
    380         namespace forall {
    381                 // Some simple scoping rules
    382                 template<typename core_t>
    383                 static inline auto enter( core_t & core, int, const ast::ParameterizedType * type )
    384                 -> decltype( core.subs, void() ) {
    385                         if ( ! type->forall.empty() ) core.subs.beginScope();
    386                 }
    387 
    388                 template<typename core_t>
    389                 static inline auto enter( core_t &, long, const ast::ParameterizedType * ) {}
    390 
    391                 template<typename core_t>
    392                 static inline auto leave( core_t & core, int, const ast::ParameterizedType * type )
    393                 -> decltype( core.subs, void() ) {
    394                         if ( ! type->forall.empty() ) { core.subs.endScope(); }
    395                 }
    396 
    397                 template<typename core_t>
    398                 static inline auto leave( core_t &, long, const ast::ParameterizedType * ) {}
    399 
    400                 // Get the substitution table, if present
    401                 template<typename core_t>
    402                 static inline auto subs( core_t & core, int ) -> decltype( &core.subs ) {
    403                         return &core.subs;
    404                 }
    405 
    406                 template<typename core_t>
    407                 static inline ast::ForallSubstitutionTable * subs( core_t &, long ) { return nullptr; }
    408 
    409                 // Replaces a TypeInstType's base TypeDecl according to the table
    410                 template<typename core_t>
    411                 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst )
    412                 -> decltype( core.subs, void() ) {
    413                         inst = ast::mutate_field(
    414                                 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) );
    415                 }
    416 
    417                 template<typename core_t>
    418                 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {}
    419 
    420         } // namespace forall
    421 } // namespace __pass
    422 } // namespace ast
     358        };
     359};
     360};
Note: See TracChangeset for help on using the changeset viewer.