Ignore:
File:
1 edited

Legend:

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

    r3e5dd913 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;
    24 
    25 struct TranslationUnit;
    26 
    27 struct PureVisitor;
    2822
    2923namespace __pass {
     
    8882                };
    8983
    90                 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
     84                std::stack< cleanup_t > cleanups;
    9185        };
    9286
     
    117111        /// "Short hand" to check if this is a valid previsit function
    118112        /// Mostly used to make the static_assert look (and print) prettier
    119         template<typename core_t, typename node_t>
     113        template<typename pass_t, typename node_t>
    120114        struct is_valid_previsit {
    121                 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 ) );
    122116
    123117                static constexpr bool value = std::is_void< ret_t >::value ||
     
    133127        template<>
    134128        struct __assign<true> {
    135                 template<typename core_t, typename node_t>
    136                 static inline void result( core_t & core, const node_t * & node ) {
    137                         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 );
    138132                }
    139133        };
     
    141135        template<>
    142136        struct __assign<false> {
    143                 template<typename core_t, typename node_t>
    144                 static inline void result( core_t & core, const node_t * & node ) {
    145                         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 );
    146140                        assertf(node, "Previsit must not return NULL");
    147141                }
     
    156150        template<>
    157151        struct __return<true> {
    158                 template<typename core_t, typename node_t>
    159                 static inline const node_t * result( core_t & core, const node_t * & node ) {
    160                         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 );
    161155                        return node;
    162156                }
     
    165159        template<>
    166160        struct __return<false> {
    167                 template<typename core_t, typename node_t>
    168                 static inline auto result( core_t & core, const node_t * & node ) {
    169                         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 );
    170164                }
    171165        };
     
    186180        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    187181        // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call
    188         template<typename core_t, typename node_t>
    189         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() ) {
    190184                static_assert(
    191                         is_valid_previsit<core_t, node_t>::value,
     185                        is_valid_previsit<pass_t, node_t>::value,
    192186                        "Previsit may not change the type of the node. It must return its paremeter or void."
    193187                );
     
    195189                __assign<
    196190                        std::is_void<
    197                                 decltype( core.previsit( node ) )
     191                                decltype( pass.previsit( node ) )
    198192                        >::value
    199                 >::result( core, node );
     193                >::result( pass, node );
    200194        }
    201195
    202         template<typename core_t, typename node_t>
    203         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 ) {}
    204198
    205199        // PostVisit : never mutates the passed pointer but may return a different node
    206         template<typename core_t, typename node_t>
    207         static inline auto postvisit( core_t & core, const node_t * node, int ) ->
    208                 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 ) )
    209203        {
    210204                return __return<
    211205                        std::is_void<
    212                                 decltype( core.postvisit( node ) )
     206                                decltype( pass.postvisit( node ) )
    213207                        >::value
    214                 >::result( core, node );
     208                >::result( pass, node );
    215209        }
    216210
    217         template<typename core_t, typename node_t>
    218         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; }
    219213
    220214        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    231225        // The type is not strictly enforced but does match the accessory
    232226        #define FIELD_PTR( name, default_type ) \
    233         template< typename core_t > \
    234         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; } \
    235229        \
    236         template< typename core_t > \
    237         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; }
    238232
    239233        // List of fields and their expected types
    240         FIELD_PTR( typeSubs, const ast::TypeSubstitution * )
     234        FIELD_PTR( env, const ast::TypeSubstitution * )
    241235        FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
    242236        FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
     
    245239        FIELD_PTR( visit_children, __pass::bool_ref )
    246240        FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    247         FIELD_PTR( visitor, ast::Pass<core_t> * const )
     241        FIELD_PTR( visitor, ast::Pass<pass_t> * const )
    248242
    249243        // Remove the macro to make sure we don't clash
    250244        #undef FIELD_PTR
    251 
    252         template< typename core_t >
    253         static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    254                 // Stats::Heap::stacktrace_push(core_t::traceId);
    255         }
    256 
    257         template< typename core_t >
    258         static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) {
    259                 // Stats::Heap::stacktrace_pop();
    260         }
    261 
    262         template< typename core_t >
    263         static void beginTrace(core_t &, long) {}
    264 
    265         template< typename core_t >
    266         static void endTrace(core_t &, long) {}
    267 
    268         // Allows visitor to handle an error on top-level declarations, and possibly suppress the error.
    269         // If onError() returns false, the error will be ignored. By default, it returns true.
    270 
    271         template< typename core_t >
    272         static bool on_error (core_t &, ptr<Decl> &, long) { return true; }
    273 
    274         template< typename core_t >
    275         static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) {
    276                 return core.on_error(decl);
    277         }
    278245
    279246        // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
     
    281248        // detect it using the same strategy
    282249        namespace scope {
    283                 template<typename core_t>
    284                 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) {
    285                         core.beginScope();
    286                 }
    287 
    288                 template<typename core_t>
    289                 static inline void enter( core_t &, long ) {}
    290 
    291                 template<typename core_t>
    292                 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) {
    293                         core.endScope();
    294                 }
    295 
    296                 template<typename core_t>
    297                 static inline void leave( core_t &, long ) {}
    298         } // namespace scope
    299 
    300         // 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
    301268        // detect the presence of a member name `symtab` and call all the members appropriately
    302269        namespace symtab {
    303270                // Some simple scoping rules
    304                 template<typename core_t>
    305                 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) {
    306                         core.symtab.enterScope();
    307                 }
    308 
    309                 template<typename core_t>
    310                 static inline auto enter( core_t &, long ) {}
    311 
    312                 template<typename core_t>
    313                 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) {
    314                         core.symtab.leaveScope();
    315                 }
    316 
    317                 template<typename core_t>
    318                 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 ) {}
    319286
    320287                // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    321288                // Create macro to condense these common patterns
    322289                #define SYMTAB_FUNC1( func, type ) \
    323                 template<typename core_t> \
    324                 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\
    325                         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 ); \
    326293                } \
    327294                \
    328                 template<typename core_t> \
    329                 static inline void func( core_t &, long, type ) {}
     295                template<typename pass_t> \
     296                static inline void func( pass_t &, long, type ) {}
    330297
    331298                #define SYMTAB_FUNC2( func, type1, type2 ) \
    332                 template<typename core_t> \
    333                 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\
    334                         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 ); \
    335302                } \
    336303                        \
    337                 template<typename core_t> \
    338                 static inline void func( core_t &, long, type1, type2 ) {}
     304                template<typename pass_t> \
     305                static inline void func( pass_t &, long, type1, type2 ) {}
    339306
    340307                SYMTAB_FUNC1( addId     , const DeclWithType *  );
     
    344311                SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    345312                SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
    346                 SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
     313                SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
    347314
    348315                // A few extra functions have more complicated behaviour, they are hand written
    349                 template<typename core_t>
    350                 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() ) {
    351318                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    352319                        fwd->params = decl->params;
    353                         core.symtab.addStruct( fwd );
    354                 }
    355 
    356                 template<typename core_t>
    357                 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {}
    358 
    359                 template<typename core_t>
    360                 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() ) {
    361328                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
    362329                        fwd->params = decl->params;
    363                         core.symtab.addUnion( fwd );
    364                 }
    365 
    366                 template<typename core_t>
    367                 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {}
    368 
    369                 template<typename core_t>
    370                 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
    371                         if ( ! core.symtab.lookupStruct( str ) ) {
    372                                 core.symtab.addStruct( str );
    373                         }
    374                 }
    375 
    376                 template<typename core_t>
    377                 static inline void addStruct( core_t &, long, const std::string & ) {}
    378 
    379                 template<typename core_t>
    380                 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) {
    381                         if ( ! core.symtab.lookupUnion( str ) ) {
    382                                 core.symtab.addUnion( str );
    383                         }
    384                 }
    385 
    386                 template<typename core_t>
    387                 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 & ) {}
    388355
    389356                #undef SYMTAB_FUNC1
    390357                #undef SYMTAB_FUNC2
    391         } // namespace symtab
    392 
    393         // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType.
    394         // Detect the presence of a member name `subs` and call all members appropriately
    395         namespace forall {
    396                 // Some simple scoping rules
    397                 template<typename core_t>
    398                 static inline auto enter( core_t & core, int, const ast::FunctionType * type )
    399                 -> decltype( core.subs, void() ) {
    400                         if ( ! type->forall.empty() ) core.subs.beginScope();
    401                 }
    402 
    403                 template<typename core_t>
    404                 static inline auto enter( core_t &, long, const ast::FunctionType * ) {}
    405 
    406                 template<typename core_t>
    407                 static inline auto leave( core_t & core, int, const ast::FunctionType * type )
    408                 -> decltype( core.subs, void() ) {
    409                         if ( ! type->forall.empty() ) { core.subs.endScope(); }
    410                 }
    411 
    412                 template<typename core_t>
    413                 static inline auto leave( core_t &, long, const ast::FunctionType * ) {}
    414 
    415                 // Replaces a TypeInstType's base TypeDecl according to the table
    416                 template<typename core_t>
    417                 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst )
    418                 -> decltype( core.subs, void() ) {
    419                         inst = ast::mutate_field(
    420                                 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) );
    421                 }
    422 
    423                 template<typename core_t>
    424                 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {}
    425 
    426         } // namespace forall
    427 
    428         template<typename core_t>
    429         static inline auto get_result( core_t & core, char ) -> decltype( core.result() ) {
    430                 return core.result();
    431         }
    432 
    433         template<typename core_t>
    434         static inline auto get_result( core_t & core, int ) -> decltype( core.result ) {
    435                 return core.result;
    436         }
    437 
    438         template<typename core_t>
    439         static inline void get_result( core_t &, long ) {}
    440 } // namespace __pass
    441 } // namespace ast
     358        };
     359};
     360};
Note: See TracChangeset for help on using the changeset viewer.