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