Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (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' into park_unpark

File:
1 edited

Legend:

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

    r3c64c668 r58fe85a  
    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;
     24
     25struct TranslationUnit;
     26
     27struct PureVisitor;
    2228
    2329namespace __pass {
     
    8288                };
    8389
    84                 std::stack< cleanup_t > cleanups;
     90                std::stack< cleanup_t, std::vector<cleanup_t> > cleanups;
    8591        };
    8692
     
    111117        /// "Short hand" to check if this is a valid previsit function
    112118        /// Mostly used to make the static_assert look (and print) prettier
    113         template<typename pass_t, typename node_t>
     119        template<typename core_t, typename node_t>
    114120        struct is_valid_previsit {
    115                 using ret_t = decltype( ((pass_t*)nullptr)->previsit( (const node_t *)nullptr ) );
     121                using ret_t = decltype( ((core_t*)nullptr)->previsit( (const node_t *)nullptr ) );
    116122
    117123                static constexpr bool value = std::is_void< ret_t >::value ||
     
    127133        template<>
    128134        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 );
     135                template<typename core_t, typename node_t>
     136                static inline void result( core_t & core, const node_t * & node ) {
     137                        core.previsit( node );
    132138                }
    133139        };
     
    135141        template<>
    136142        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 );
     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 );
    140146                        assertf(node, "Previsit must not return NULL");
    141147                }
     
    150156        template<>
    151157        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 );
     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 );
    155161                        return node;
    156162                }
     
    159165        template<>
    160166        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 );
     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 );
    164170                }
    165171        };
     
    180186        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    181187        // 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() ) {
     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() ) {
    184190                static_assert(
    185                         is_valid_previsit<pass_t, node_t>::value,
     191                        is_valid_previsit<core_t, node_t>::value,
    186192                        "Previsit may not change the type of the node. It must return its paremeter or void."
    187193                );
     
    189195                __assign<
    190196                        std::is_void<
    191                                 decltype( pass.previsit( node ) )
     197                                decltype( core.previsit( node ) )
    192198                        >::value
    193                 >::result( pass, node );
    194         }
    195 
    196         template<typename pass_t, typename node_t>
    197         static inline auto previsit( pass_t &, const node_t *, long ) {}
     199                >::result( core, node );
     200        }
     201
     202        template<typename core_t, typename node_t>
     203        static inline auto previsit( core_t &, const node_t *, long ) {}
    198204
    199205        // 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 ) )
     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 ) )
    203209        {
    204210                return __return<
    205211                        std::is_void<
    206                                 decltype( pass.postvisit( node ) )
     212                                decltype( core.postvisit( node ) )
    207213                        >::value
    208                 >::result( pass, node );
    209         }
    210 
    211         template<typename pass_t, typename node_t>
    212         static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; }
     214                >::result( core, node );
     215        }
     216
     217        template<typename core_t, typename node_t>
     218        static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }
    213219
    214220        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    225231        // The type is not strictly enforced but does match the accessory
    226232        #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; } \
     233        template< typename core_t > \
     234        static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \
    229235        \
    230         template< typename pass_t > \
    231         static inline default_type * name( pass_t &, long ) { return nullptr; }
     236        template< typename core_t > \
     237        static inline default_type * name( core_t &, long ) { return nullptr; }
    232238
    233239        // List of fields and their expected types
    234         FIELD_PTR( env, const ast::TypeSubstitution * )
     240        FIELD_PTR( typeSubs, const ast::TypeSubstitution * )
    235241        FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
    236242        FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
     
    239245        FIELD_PTR( visit_children, __pass::bool_ref )
    240246        FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    241         FIELD_PTR( visitor, ast::Pass<pass_t> * const )
     247        FIELD_PTR( visitor, ast::Pass<core_t> * const )
    242248
    243249        // Remove the macro to make sure we don't clash
    244250        #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        }
    245278
    246279        // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
     
    248281        // detect it using the same strategy
    249282        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
     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
    268301        // detect the presence of a member name `symtab` and call all the members appropriately
    269302        namespace symtab {
    270303                // 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 ) {}
     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 ) {}
    286319
    287320                // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    288321                // Create macro to condense these common patterns
    289322                #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 ); \
     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 ); \
    293326                } \
    294327                \
    295                 template<typename pass_t> \
    296                 static inline void func( pass_t &, long, type ) {}
     328                template<typename core_t> \
     329                static inline void func( core_t &, long, type ) {}
    297330
    298331                #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 ); \
     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 ); \
    302335                } \
    303336                        \
    304                 template<typename pass_t> \
    305                 static inline void func( pass_t &, long, type1, type2 ) {}
     337                template<typename core_t> \
     338                static inline void func( core_t &, long, type1, type2 ) {}
    306339
    307340                SYMTAB_FUNC1( addId     , const DeclWithType *  );
     
    311344                SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    312345                SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
    313                 SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
     346                SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Decl * );
    314347
    315348                // 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() ) {
     349                template<typename core_t>
     350                static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {
    318351                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    319352                        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() ) {
     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() ) {
    328361                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
    329362                        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 );
     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 );
    340373                        }
    341374                }
    342375
    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 );
     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 );
    350383                        }
    351384                }
    352385
    353                 template<typename pass_t>
    354                 static inline void addUnion( pass_t &, long, const std::string & ) {}
     386                template<typename core_t>
     387                static inline void addUnion( core_t &, long, const std::string & ) {}
    355388
    356389                #undef SYMTAB_FUNC1
    357390                #undef SYMTAB_FUNC2
    358         };
    359 };
    360 };
     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
Note: See TracChangeset for help on using the changeset viewer.