Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.hpp

    r3e5dd913 re67991f  
    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 // | 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.
     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
    7064//-------------------------------------------------------------------------------------------------
    71 template< typename core_t >
     65template< typename pass_t >
    7266class Pass final : public ast::Visitor {
    7367public:
    74         using core_type = core_t;
    75         using type = Pass<core_t>;
    76 
    7768        /// Forward any arguments to the pass constructor
    7869        /// Propagate 'this' if necessary
    7970        template< typename... Args >
    8071        Pass( Args &&... args)
    81                 : core( std::forward<Args>( args )... )
     72                : pass( std::forward<Args>( args )... )
    8273        {
    8374                // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor
    84                 type * const * visitor = __pass::visitor(core, 0);
     75                typedef Pass<pass_t> this_t;
     76                this_t * const * visitor = __pass::visitor(pass, 0);
    8577                if(visitor) {
    86                         *const_cast<type **>( visitor ) = this;
     78                        *const_cast<this_t **>( visitor ) = this;
    8779                }
    8880        }
     
    9082        virtual ~Pass() = default;
    9183
    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         }
     84        /// Storage for the actual pass
     85        pass_t pass;
    13086
    13187        /// Visit function declarations
     
    155111        const ast::Stmt *             visit( const ast::CatchStmt            * ) override final;
    156112        const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
    157         const ast::Stmt *             visit( const ast::SuspendStmt          * ) override final;
    158113        const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
    159114        const ast::Decl *             visit( const ast::WithStmt             * ) override final;
     
    223178        const ast::TypeSubstitution * visit( const ast::TypeSubstitution     * ) override final;
    224179
    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 
     180        template<typename pass_type>
     181        friend void accept_all( std::list< ptr<Decl> > & decls, Pass<pass_type>& visitor );
    232182private:
    233183
    234         bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(core, 0); return ptr ? *ptr : true; }
     184        bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(pass, 0); return ptr ? *ptr : true; }
    235185
    236186private:
    237187        const ast::Stmt * call_accept( const ast::Stmt * );
    238188        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 *);
    243189
    244190        template< typename node_t >
     
    260206        void maybe_accept(const node_t * &, child_t parent_t::* child);
    261207
    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 
    265208private:
    266209        /// Internal RAII guard for symbol table features
    267210        struct guard_symtab {
    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;
     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;
    271214        };
    272215
    273216        /// Internal RAII guard for scope features
    274217        struct guard_scope {
    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;
     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;
    287221        };
    288222
    289223private:
    290224        bool inFunction = false;
    291         bool atFunctionTop = false;
    292225};
    293226
    294227/// Apply a pass to an entire translation unit
    295 template<typename core_t>
    296 void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<core_t> & visitor );
    297 
    298 template<typename core_t>
    299 void accept_all( ast::TranslationUnit &, ast::Pass<core_t> & visitor );
     228template<typename pass_t>
     229void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<pass_t> & visitor );
    300230
    301231//-------------------------------------------------------------------------------------------------
     
    303233//-------------------------------------------------------------------------------------------------
    304234
    305 /// If used the visitor will always clone nodes.
    306 struct PureVisitor {};
    307 
    308 /// Keep track of the polymorphic const TypeSubstitution * typeSubs for the current expression.
     235/// Keep track of the polymorphic const TypeSubstitution * env for the current expression
    309236struct WithConstTypeSubstitution {
    310         const TypeSubstitution * typeSubs = nullptr;
     237        const TypeSubstitution * env = nullptr;
    311238};
    312239
     
    340267        };
    341268
    342         template< typename core_t>
    343         friend auto __pass::at_cleanup( core_t & core, int ) -> decltype( &core.at_cleanup );
     269        template< typename pass_t>
     270        friend auto __pass::at_cleanup( pass_t & pass, int ) -> decltype( &pass.at_cleanup );
    344271public:
    345272
     
    377304
    378305/// Used to get a pointer to the pass with its wrapped type
    379 template<typename core_t>
     306template<typename pass_t>
    380307struct WithVisitorRef {
    381         Pass<core_t> * const visitor = nullptr;
    382 
    383         bool isInFunction() const {
    384                 return visitor->isInFunction();
    385         }
     308        Pass<pass_t> * const visitor = nullptr;
    386309};
    387310
     
    390313        SymbolTable symtab;
    391314};
    392 
    393315}
    394316
     
    398320extern struct PassVisitorStats {
    399321        size_t depth = 0;
    400         Stats::Counters::MaxCounter<double> * max;
    401         Stats::Counters::AverageCounter<double> * avg;
     322        Stats::Counters::MaxCounter<double> * max = nullptr;
     323        Stats::Counters::AverageCounter<double> * avg = nullptr;
    402324} pass_visitor_stats;
    403325}
Note: See TracChangeset for help on using the changeset viewer.