Changeset 58fe85a for src/AST/Pass.hpp


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.hpp

    r3c64c668 r58fe85a  
    88//
    99// Author           : Thierry Delisle
    10 // Created On       : Thu May 09 15::37::05 2019
     10// Created On       : Thu May 09 15:37:05 2019
    1111// Last Modified By :
    1212// Last Modified On :
     
    4646//
    4747// Several additional features are available through inheritance
    48 // | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the
    49 //                          current expression
    50 // | WithStmtsToAdd       - provides the ability to insert statements before or after the current
    51 //                          statement by adding new statements into stmtsToAddBefore or
    52 //                          stmtsToAddAfter respectively.
    53 // | WithDeclsToAdd       - provides the ability to insert declarations before or after the current
    54 //                          declarations by adding new DeclStmt into declsToAddBefore or
    55 //                          declsToAddAfter respectively.
    56 // | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children
    57 //                          to false in pre{visit,visit} to skip visiting children
    58 // | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save,
    59 //                          call GuardValue with the variable to save, the variable will
    60 //                          automatically be restored to its previous value after the corresponding
    61 //                          postvisit/postmutate teminates.
    62 // | WithVisitorRef       - provides an pointer to the templated visitor wrapper
    63 // | WithSymbolTable      - provides symbol table functionality
     48// | PureVisitor           - makes the visitor pure, it never modifies nodes in place and always
     49//                           clones nodes it needs to make changes to
     50// | WithConstTypeSubstitution - provides polymorphic const TypeSubstitution * typeSubs for the
     51//                           current expression
     52// | WithStmtsToAdd        - provides the ability to insert statements before or after the current
     53//                           statement by adding new statements into stmtsToAddBefore or
     54//                           stmtsToAddAfter respectively.
     55// | WithDeclsToAdd        - provides the ability to insert declarations before or after the
     56//                           current declarations by adding new DeclStmt into declsToAddBefore or
     57//                           declsToAddAfter respectively.
     58// | WithShortCircuiting   - provides the ability to skip visiting child nodes; set visit_children
     59//                           to false in pre{visit,visit} to skip visiting children
     60// | WithGuards            - provides the ability to save/restore data like a LIFO stack; to save,
     61//                           call GuardValue with the variable to save, the variable will
     62//                           automatically be restored to its previous value after the
     63//                           corresponding postvisit/postmutate teminates.
     64// | WithVisitorRef        - provides an pointer to the templated visitor wrapper
     65// | WithSymbolTable       - provides symbol table functionality
     66//
     67// Other Special Members:
     68// | result                - Either a method that takes no parameters or a field. If a method (or
     69//                           callable field) get_result calls it, otherwise the value is returned.
    6470//-------------------------------------------------------------------------------------------------
    65 template< typename pass_t >
     71template< typename core_t >
    6672class Pass final : public ast::Visitor {
    6773public:
     74        using core_type = core_t;
     75        using type = Pass<core_t>;
     76
    6877        /// Forward any arguments to the pass constructor
    6978        /// Propagate 'this' if necessary
    7079        template< typename... Args >
    7180        Pass( Args &&... args)
    72                 : pass( std::forward<Args>( args )... )
     81                : core( std::forward<Args>( args )... )
    7382        {
    7483                // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor
    75                 typedef Pass<pass_t> this_t;
    76                 this_t * const * visitor = __pass::visitor(pass, 0);
     84                type * const * visitor = __pass::visitor(core, 0);
    7785                if(visitor) {
    78                         *const_cast<this_t **>( visitor ) = this;
     86                        *const_cast<type **>( visitor ) = this;
    7987                }
    8088        }
     
    8290        virtual ~Pass() = default;
    8391
    84         /// Storage for the actual pass
    85         pass_t pass;
     92        /// Storage for the actual pass.
     93        core_t core;
     94
     95        /// If the core defines a result, call it if possible, otherwise return it.
     96        inline auto get_result() -> decltype( __pass::get_result( core, '0' ) ) {
     97                return __pass::get_result( core, '0' );
     98        }
     99
     100        /// Construct and run a pass on a translation unit.
     101        template< typename... Args >
     102        static void run( TranslationUnit & decls, Args &&... args ) {
     103                Pass<core_t> visitor( std::forward<Args>( args )... );
     104                accept_all( decls, visitor );
     105        }
     106
     107        /// Contruct and run a pass on a pointer to extract a value.
     108        template< typename node_type, typename... Args >
     109        static auto read( node_type const * node, Args&&... args ) {
     110                Pass<core_t> visitor( std::forward<Args>( args )... );
     111                node_type const * temp = node->accept( visitor );
     112                assert( temp == node );
     113                return visitor.get_result();
     114        }
     115
     116        // Versions of the above for older compilers.
     117        template< typename... Args >
     118        static void run( TranslationUnit & decls ) {
     119                Pass<core_t> visitor;
     120                accept_all( decls, visitor );
     121        }
     122
     123        template< typename node_type, typename... Args >
     124        static auto read( node_type const * node ) {
     125                Pass<core_t> visitor;
     126                node_type const * temp = node->accept( visitor );
     127                assert( temp == node );
     128                return visitor.get_result();
     129        }
    86130
    87131        /// Visit function declarations
     
    111155        const ast::Stmt *             visit( const ast::CatchStmt            * ) override final;
    112156        const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
     157        const ast::Stmt *             visit( const ast::SuspendStmt          * ) override final;
    113158        const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
    114159        const ast::Decl *             visit( const ast::WithStmt             * ) override final;
     
    178223        const ast::TypeSubstitution * visit( const ast::TypeSubstitution     * ) override final;
    179224
    180         template<typename pass_type>
    181         friend void accept_all( std::list< ptr<Decl> > & decls, Pass<pass_type>& visitor );
     225        template<typename core_type>
     226        friend void accept_all( std::list< ptr<Decl> > & decls, Pass<core_type>& visitor );
     227
     228        bool isInFunction() const {
     229                return inFunction;
     230        }
     231
    182232private:
    183233
    184         bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(pass, 0); return ptr ? *ptr : true; }
     234        bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(core, 0); return ptr ? *ptr : true; }
    185235
    186236private:
    187237        const ast::Stmt * call_accept( const ast::Stmt * );
    188238        const ast::Expr * call_accept( const ast::Expr * );
     239
     240        // requests WithStmtsToAdd directly add to this statement, as if it is a compound.
     241
     242        const ast::Stmt * call_accept_as_compound(const ast::Stmt *);
    189243
    190244        template< typename node_t >
     
    206260        void maybe_accept(const node_t * &, child_t parent_t::* child);
    207261
     262        template<typename node_t, typename parent_t, typename child_t>
     263        void maybe_accept_as_compound(const node_t * &, child_t parent_t::* child);
     264
    208265private:
    209266        /// Internal RAII guard for symbol table features
    210267        struct guard_symtab {
    211                 guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass, 0); }
    212                 ~guard_symtab()                                   { __pass::symtab::leave(pass, 0); }
    213                 Pass<pass_t> & pass;
     268                guard_symtab( Pass<core_t> & pass ): pass( pass ) { __pass::symtab::enter(pass.core, 0); }
     269                ~guard_symtab()                                   { __pass::symtab::leave(pass.core, 0); }
     270                Pass<core_t> & pass;
    214271        };
    215272
    216273        /// Internal RAII guard for scope features
    217274        struct guard_scope {
    218                 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass, 0); }
    219                 ~guard_scope()                                   { __pass::scope::leave(pass, 0); }
    220                 Pass<pass_t> & pass;
     275                guard_scope( Pass<core_t> & pass ): pass( pass ) { __pass::scope::enter(pass.core, 0); }
     276                ~guard_scope()                                   { __pass::scope::leave(pass.core, 0); }
     277                Pass<core_t> & pass;
     278        };
     279
     280        /// Internal RAII guard for forall substitutions
     281        struct guard_forall_subs {
     282                guard_forall_subs( Pass<core_t> & pass, const FunctionType * type )
     283                : pass( pass ), type( type ) { __pass::forall::enter(pass.core, 0, type ); }
     284                ~guard_forall_subs()         { __pass::forall::leave(pass.core, 0, type ); }
     285                Pass<core_t> & pass;
     286                const FunctionType * type;
    221287        };
    222288
    223289private:
    224290        bool inFunction = false;
     291        bool atFunctionTop = false;
    225292};
    226293
    227294/// Apply a pass to an entire translation unit
    228 template<typename pass_t>
    229 void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<pass_t> & visitor );
     295template<typename core_t>
     296void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<core_t> & visitor );
     297
     298template<typename core_t>
     299void accept_all( ast::TranslationUnit &, ast::Pass<core_t> & visitor );
    230300
    231301//-------------------------------------------------------------------------------------------------
     
    233303//-------------------------------------------------------------------------------------------------
    234304
    235 /// Keep track of the polymorphic const TypeSubstitution * env for the current expression
     305/// If used the visitor will always clone nodes.
     306struct PureVisitor {};
     307
     308/// Keep track of the polymorphic const TypeSubstitution * typeSubs for the current expression.
    236309struct WithConstTypeSubstitution {
    237         const TypeSubstitution * env = nullptr;
     310        const TypeSubstitution * typeSubs = nullptr;
    238311};
    239312
     
    267340        };
    268341
    269         template< typename pass_t>
    270         friend auto __pass::at_cleanup( pass_t & pass, int ) -> decltype( &pass.at_cleanup );
     342        template< typename core_t>
     343        friend auto __pass::at_cleanup( core_t & core, int ) -> decltype( &core.at_cleanup );
    271344public:
    272345
     
    304377
    305378/// Used to get a pointer to the pass with its wrapped type
    306 template<typename pass_t>
     379template<typename core_t>
    307380struct WithVisitorRef {
    308         Pass<pass_t> * const visitor = nullptr;
     381        Pass<core_t> * const visitor = nullptr;
     382
     383        bool isInFunction() const {
     384                return visitor->isInFunction();
     385        }
    309386};
    310387
     
    313390        SymbolTable symtab;
    314391};
     392
    315393}
    316394
     
    320398extern struct PassVisitorStats {
    321399        size_t depth = 0;
    322         Stats::Counters::MaxCounter<double> * max = nullptr;
    323         Stats::Counters::AverageCounter<double> * avg = nullptr;
     400        Stats::Counters::MaxCounter<double> * max;
     401        Stats::Counters::AverageCounter<double> * avg;
    324402} pass_visitor_stats;
    325403}
Note: See TracChangeset for help on using the changeset viewer.