Changes in src/AST/Pass.hpp [3e5dd913:e67991f]
- File:
-
- 1 edited
-
src/AST/Pass.hpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.hpp
r3e5dd913 re67991f 8 8 // 9 9 // Author : Thierry Delisle 10 // Created On : Thu May 09 15: 37:05 201910 // Created On : Thu May 09 15::37::05 2019 11 11 // Last Modified By : 12 12 // Last Modified On : … … 46 46 // 47 47 // 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 70 64 //------------------------------------------------------------------------------------------------- 71 template< typename core_t >65 template< typename pass_t > 72 66 class Pass final : public ast::Visitor { 73 67 public: 74 using core_type = core_t;75 using type = Pass<core_t>;76 77 68 /// Forward any arguments to the pass constructor 78 69 /// Propagate 'this' if necessary 79 70 template< typename... Args > 80 71 Pass( Args &&... args) 81 : core( std::forward<Args>( args )... )72 : pass( std::forward<Args>( args )... ) 82 73 { 83 74 // 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); 85 77 if(visitor) { 86 *const_cast<t ype**>( visitor ) = this;78 *const_cast<this_t **>( visitor ) = this; 87 79 } 88 80 } … … 90 82 virtual ~Pass() = default; 91 83 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; 130 86 131 87 /// Visit function declarations … … 155 111 const ast::Stmt * visit( const ast::CatchStmt * ) override final; 156 112 const ast::Stmt * visit( const ast::FinallyStmt * ) override final; 157 const ast::Stmt * visit( const ast::SuspendStmt * ) override final;158 113 const ast::Stmt * visit( const ast::WaitForStmt * ) override final; 159 114 const ast::Decl * visit( const ast::WithStmt * ) override final; … … 223 178 const ast::TypeSubstitution * visit( const ast::TypeSubstitution * ) override final; 224 179 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 ); 232 182 private: 233 183 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; } 235 185 236 186 private: 237 187 const ast::Stmt * call_accept( const ast::Stmt * ); 238 188 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 *);243 189 244 190 template< typename node_t > … … 260 206 void maybe_accept(const node_t * &, child_t parent_t::* child); 261 207 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 265 208 private: 266 209 /// Internal RAII guard for symbol table features 267 210 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; 271 214 }; 272 215 273 216 /// Internal RAII guard for scope features 274 217 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; 287 221 }; 288 222 289 223 private: 290 224 bool inFunction = false; 291 bool atFunctionTop = false;292 225 }; 293 226 294 227 /// 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 ); 228 template<typename pass_t> 229 void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<pass_t> & visitor ); 300 230 301 231 //------------------------------------------------------------------------------------------------- … … 303 233 //------------------------------------------------------------------------------------------------- 304 234 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 309 236 struct WithConstTypeSubstitution { 310 const TypeSubstitution * typeSubs= nullptr;237 const TypeSubstitution * env = nullptr; 311 238 }; 312 239 … … 340 267 }; 341 268 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 ); 344 271 public: 345 272 … … 377 304 378 305 /// Used to get a pointer to the pass with its wrapped type 379 template<typename core_t>306 template<typename pass_t> 380 307 struct 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; 386 309 }; 387 310 … … 390 313 SymbolTable symtab; 391 314 }; 392 393 315 } 394 316 … … 398 320 extern struct PassVisitorStats { 399 321 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; 402 324 } pass_visitor_stats; 403 325 }
Note:
See TracChangeset
for help on using the changeset viewer.