Ignore:
Timestamp:
Aug 14, 2020, 11:40:04 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
5715d43, fa5e0112
Parents:
309d814 (diff), badd22f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r309d814 r4c925cd  
    1717// IWYU pragma: private, include "Pass.hpp"
    1818
     19#include "Common/Stats/Heap.h"
     20
    1921namespace ast {
    20 template<typename pass_type>
     22template<typename core_t>
    2123class Pass;
    2224
     
    8284                };
    8385
    84                 std::stack< cleanup_t > cleanups;
     86                std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
    8587        };
    8688
     
    111113        /// "Short hand" to check if this is a valid previsit function
    112114        /// Mostly used to make the static_assert look (and print) prettier
    113         template<typename pass_t, typename node_t>
     115        template<typename core_t, typename node_t>
    114116        struct is_valid_previsit {
    115                 using ret_t = decltype( ((pass_t*)nullptr)->previsit( (const node_t *)nullptr ) );
     117                using ret_t = decltype( ((core_t*)nullptr)->previsit( (const node_t *)nullptr ) );
    116118
    117119                static constexpr bool value = std::is_void< ret_t >::value ||
     
    127129        template<>
    128130        struct __assign<true> {
    129                 template<typename pass_t, typename node_t>
    130                 static inline void result( pass_t & pass, const node_t * & node ) {
    131                         pass.previsit( node );
     131                template<typename core_t, typename node_t>
     132                static inline void result( core_t & core, const node_t * & node ) {
     133                        core.previsit( node );
    132134                }
    133135        };
     
    135137        template<>
    136138        struct __assign<false> {
    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 );
     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 );
    140142                        assertf(node, "Previsit must not return NULL");
    141143                }
     
    150152        template<>
    151153        struct __return<true> {
    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 );
     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 );
    155157                        return node;
    156158                }
     
    159161        template<>
    160162        struct __return<false> {
    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 );
     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 );
    164166                }
    165167        };
     
    180182        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    181183        // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call
    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() ) {
     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() ) {
    184186                static_assert(
    185                         is_valid_previsit<pass_t, node_t>::value,
     187                        is_valid_previsit<core_t, node_t>::value,
    186188                        "Previsit may not change the type of the node. It must return its paremeter or void."
    187189                );
     
    189191                __assign<
    190192                        std::is_void<
    191                                 decltype( pass.previsit( node ) )
     193                                decltype( core.previsit( node ) )
    192194                        >::value
    193                 >::result( pass, node );
     195                >::result( core, node );
    194196        }
    195197
    196         template<typename pass_t, typename node_t>
    197         static inline auto previsit( pass_t &, const node_t *, long ) {}
     198        template<typename core_t, typename node_t>
     199        static inline auto previsit( core_t &, const node_t *, long ) {}
    198200
    199201        // PostVisit : never mutates the passed pointer but may return a different node
    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 ) )
     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 ) )
    203205        {
    204206                return __return<
    205207                        std::is_void<
    206                                 decltype( pass.postvisit( node ) )
     208                                decltype( core.postvisit( node ) )
    207209                        >::value
    208                 >::result( pass, node );
     210                >::result( core, node );
    209211        }
    210212
    211         template<typename pass_t, typename node_t>
    212         static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; }
     213        template<typename core_t, typename node_t>
     214        static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }
    213215
    214216        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    225227        // The type is not strictly enforced but does match the accessory
    226228        #define FIELD_PTR( name, default_type ) \
    227         template< typename pass_t > \
    228         static inline auto name( pass_t & pass, int ) -> decltype( &pass.name ) { return &pass.name; } \
     229        template< typename core_t > \
     230        static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \
    229231        \
    230         template< typename pass_t > \
    231         static inline default_type * name( pass_t &, long ) { return nullptr; }
     232        template< typename core_t > \
     233        static inline default_type * name( core_t &, long ) { return nullptr; }
    232234
    233235        // List of fields and their expected types
     
    239241        FIELD_PTR( visit_children, __pass::bool_ref )
    240242        FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    241         FIELD_PTR( visitor, ast::Pass<pass_t> * const )
     243        FIELD_PTR( visitor, ast::Pass<core_t> * const )
    242244
    243245        // Remove the macro to make sure we don't clash
    244246        #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) {}
    245263
    246264        // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
     
    248266        // detect it using the same strategy
    249267        namespace scope {
    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
     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
    268286        // detect the presence of a member name `symtab` and call all the members appropriately
    269287        namespace symtab {
    270288                // Some simple scoping rules
    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 ) {}
     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 ) {}
    286304
    287305                // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    288306                // Create macro to condense these common patterns
    289307                #define SYMTAB_FUNC1( func, type ) \
    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 ); \
     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 ); \
    293311                } \
    294312                \
    295                 template<typename pass_t> \
    296                 static inline void func( pass_t &, long, type ) {}
     313                template<typename core_t> \
     314                static inline void func( core_t &, long, type ) {}
    297315
    298316                #define SYMTAB_FUNC2( func, type1, type2 ) \
    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 ); \
     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 ); \
    302320                } \
    303321                        \
    304                 template<typename pass_t> \
    305                 static inline void func( pass_t &, long, type1, type2 ) {}
     322                template<typename core_t> \
     323                static inline void func( core_t &, long, type1, type2 ) {}
    306324
    307325                SYMTAB_FUNC1( addId     , const DeclWithType *  );
     
    311329                SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    312330                SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
    313                 SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
     331                SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
    314332
    315333                // A few extra functions have more complicated behaviour, they are hand written
    316                 template<typename pass_t>
    317                 static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.symtab.addStruct( decl ), void() ) {
     334                template<typename core_t>
     335                static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {
    318336                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    319337                        fwd->params = decl->params;
    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() ) {
     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() ) {
    328346                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
    329347                        fwd->params = decl->params;
    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 );
     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 );
    340358                        }
    341359                }
    342360
    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 );
     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 );
    350368                        }
    351369                }
    352370
    353                 template<typename pass_t>
    354                 static inline void addUnion( pass_t &, long, const std::string & ) {}
     371                template<typename core_t>
     372                static inline void addUnion( core_t &, long, const std::string & ) {}
    355373
    356374                #undef SYMTAB_FUNC1
    357375                #undef SYMTAB_FUNC2
    358         };
    359 };
    360 };
     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
Note: See TracChangeset for help on using the changeset viewer.