Changeset 58fe85a for src/AST/Pass.proto.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.proto.hpp
r3c64c668 r58fe85a 17 17 // IWYU pragma: private, include "Pass.hpp" 18 18 19 #include "Common/Stats/Heap.h" 20 19 21 namespace ast { 20 template<typename pass_type>22 template<typename core_t> 21 23 class Pass; 24 25 struct TranslationUnit; 26 27 struct PureVisitor; 22 28 23 29 namespace __pass { … … 82 88 }; 83 89 84 std::stack< cleanup_t > cleanups;90 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups; 85 91 }; 86 92 … … 111 117 /// "Short hand" to check if this is a valid previsit function 112 118 /// 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> 114 120 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 ) ); 116 122 117 123 static constexpr bool value = std::is_void< ret_t >::value || … … 127 133 template<> 128 134 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 ); 132 138 } 133 139 }; … … 135 141 template<> 136 142 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 ); 140 146 assertf(node, "Previsit must not return NULL"); 141 147 } … … 150 156 template<> 151 157 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 ); 155 161 return node; 156 162 } … … 159 165 template<> 160 166 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 ); 164 170 } 165 171 }; … … 180 186 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 181 187 // 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() ) { 184 190 static_assert( 185 is_valid_previsit< pass_t, node_t>::value,191 is_valid_previsit<core_t, node_t>::value, 186 192 "Previsit may not change the type of the node. It must return its paremeter or void." 187 193 ); … … 189 195 __assign< 190 196 std::is_void< 191 decltype( pass.previsit( node ) )197 decltype( core.previsit( node ) ) 192 198 >::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 ) {} 198 204 199 205 // 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 ) ) 203 209 { 204 210 return __return< 205 211 std::is_void< 206 decltype( pass.postvisit( node ) )212 decltype( core.postvisit( node ) ) 207 213 >::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; } 213 219 214 220 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 225 231 // The type is not strictly enforced but does match the accessory 226 232 #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; } \ 229 235 \ 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; } 232 238 233 239 // List of fields and their expected types 234 FIELD_PTR( env, const ast::TypeSubstitution * )240 FIELD_PTR( typeSubs, const ast::TypeSubstitution * ) 235 241 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 236 242 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) … … 239 245 FIELD_PTR( visit_children, __pass::bool_ref ) 240 246 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 ) 242 248 243 249 // Remove the macro to make sure we don't clash 244 250 #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 } 245 278 246 279 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. … … 248 281 // detect it using the same strategy 249 282 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 automatically283 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 268 301 // detect the presence of a member name `symtab` and call all the members appropriately 269 302 namespace symtab { 270 303 // 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 ) {} 286 319 287 320 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 288 321 // Create macro to condense these common patterns 289 322 #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 ); \ 293 326 } \ 294 327 \ 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 ) {} 297 330 298 331 #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 ); \ 302 335 } \ 303 336 \ 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 ) {} 306 339 307 340 SYMTAB_FUNC1( addId , const DeclWithType * ); … … 311 344 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 312 345 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 * ); 314 347 315 348 // 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() ) { 318 351 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 319 352 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() ) { 328 361 UnionDecl * fwd = new UnionDecl( decl->location, decl->name ); 329 362 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 ); 340 373 } 341 374 } 342 375 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 ); 350 383 } 351 384 } 352 385 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 & ) {} 355 388 356 389 #undef SYMTAB_FUNC1 357 390 #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.