Changeset 4c925cd for src/AST/Pass.proto.hpp
- Timestamp:
- Aug 14, 2020, 11:40:04 AM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 5715d43, fa5e0112
- Parents:
- 309d814 (diff), badd22f (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
r309d814 r4c925cd 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; 22 24 … … 82 84 }; 83 85 84 std::stack< cleanup_t > cleanups;86 std::stack< cleanup_t, std::vector<cleanup_t> > cleanups; 85 87 }; 86 88 … … 111 113 /// "Short hand" to check if this is a valid previsit function 112 114 /// Mostly used to make the static_assert look (and print) prettier 113 template<typename pass_t, typename node_t>115 template<typename core_t, typename node_t> 114 116 struct is_valid_previsit { 115 using ret_t = decltype( (( pass_t*)nullptr)->previsit( (const node_t *)nullptr ) );117 using ret_t = decltype( ((core_t*)nullptr)->previsit( (const node_t *)nullptr ) ); 116 118 117 119 static constexpr bool value = std::is_void< ret_t >::value || … … 127 129 template<> 128 130 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 );131 template<typename core_t, typename node_t> 132 static inline void result( core_t & core, const node_t * & node ) { 133 core.previsit( node ); 132 134 } 133 135 }; … … 135 137 template<> 136 138 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 );139 template<typename core_t, typename node_t> 140 static inline void result( core_t & core, const node_t * & node ) { 141 node = core.previsit( node ); 140 142 assertf(node, "Previsit must not return NULL"); 141 143 } … … 150 152 template<> 151 153 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 );154 template<typename core_t, typename node_t> 155 static inline const node_t * result( core_t & core, const node_t * & node ) { 156 core.postvisit( node ); 155 157 return node; 156 158 } … … 159 161 template<> 160 162 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 );163 template<typename core_t, typename node_t> 164 static inline auto result( core_t & core, const node_t * & node ) { 165 return core.postvisit( node ); 164 166 } 165 167 }; … … 180 182 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 181 183 // 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() ) {184 template<typename core_t, typename node_t> 185 static inline auto previsit( core_t & core, const node_t * & node, int ) -> decltype( core.previsit( node ), void() ) { 184 186 static_assert( 185 is_valid_previsit< pass_t, node_t>::value,187 is_valid_previsit<core_t, node_t>::value, 186 188 "Previsit may not change the type of the node. It must return its paremeter or void." 187 189 ); … … 189 191 __assign< 190 192 std::is_void< 191 decltype( pass.previsit( node ) )193 decltype( core.previsit( node ) ) 192 194 >::value 193 >::result( pass, node );195 >::result( core, node ); 194 196 } 195 197 196 template<typename pass_t, typename node_t>197 static inline auto previsit( pass_t &, const node_t *, long ) {}198 template<typename core_t, typename node_t> 199 static inline auto previsit( core_t &, const node_t *, long ) {} 198 200 199 201 // 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 ) )202 template<typename core_t, typename node_t> 203 static inline auto postvisit( core_t & core, const node_t * node, int ) -> 204 decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 203 205 { 204 206 return __return< 205 207 std::is_void< 206 decltype( pass.postvisit( node ) )208 decltype( core.postvisit( node ) ) 207 209 >::value 208 >::result( pass, node );210 >::result( core, node ); 209 211 } 210 212 211 template<typename pass_t, typename node_t>212 static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; }213 template<typename core_t, typename node_t> 214 static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; } 213 215 214 216 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 225 227 // The type is not strictly enforced but does match the accessory 226 228 #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; } \229 template< typename core_t > \ 230 static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \ 229 231 \ 230 template< typename pass_t > \231 static inline default_type * name( pass_t &, long ) { return nullptr; }232 template< typename core_t > \ 233 static inline default_type * name( core_t &, long ) { return nullptr; } 232 234 233 235 // List of fields and their expected types … … 239 241 FIELD_PTR( visit_children, __pass::bool_ref ) 240 242 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 241 FIELD_PTR( visitor, ast::Pass< pass_t> * const )243 FIELD_PTR( visitor, ast::Pass<core_t> * const ) 242 244 243 245 // Remove the macro to make sure we don't clash 244 246 #undef FIELD_PTR 247 248 template< typename core_t > 249 static inline auto beginTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 250 // Stats::Heap::stacktrace_push(core_t::traceId); 251 } 252 253 template< typename core_t > 254 static inline auto endTrace(core_t &, int) -> decltype( core_t::traceId, void() ) { 255 // Stats::Heap::stacktrace_pop(); 256 } 257 258 template< typename core_t > 259 static void beginTrace(core_t &, long) {} 260 261 template< typename core_t > 262 static void endTrace(core_t &, long) {} 245 263 246 264 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. … … 248 266 // detect it using the same strategy 249 267 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 automatically268 template<typename core_t> 269 static inline auto enter( core_t & core, int ) -> decltype( core.beginScope(), void() ) { 270 core.beginScope(); 271 } 272 273 template<typename core_t> 274 static inline void enter( core_t &, long ) {} 275 276 template<typename core_t> 277 static inline auto leave( core_t & core, int ) -> decltype( core.endScope(), void() ) { 278 core.endScope(); 279 } 280 281 template<typename core_t> 282 static inline void leave( core_t &, long ) {} 283 } // namespace scope 284 285 // Certain passes desire an up to date symbol table automatically 268 286 // detect the presence of a member name `symtab` and call all the members appropriately 269 287 namespace symtab { 270 288 // 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 ) {}289 template<typename core_t> 290 static inline auto enter( core_t & core, int ) -> decltype( core.symtab, void() ) { 291 core.symtab.enterScope(); 292 } 293 294 template<typename core_t> 295 static inline auto enter( core_t &, long ) {} 296 297 template<typename core_t> 298 static inline auto leave( core_t & core, int ) -> decltype( core.symtab, void() ) { 299 core.symtab.leaveScope(); 300 } 301 302 template<typename core_t> 303 static inline auto leave( core_t &, long ) {} 286 304 287 305 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 288 306 // Create macro to condense these common patterns 289 307 #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 ); \308 template<typename core_t> \ 309 static inline auto func( core_t & core, int, type arg ) -> decltype( core.symtab.func( arg ), void() ) {\ 310 core.symtab.func( arg ); \ 293 311 } \ 294 312 \ 295 template<typename pass_t> \296 static inline void func( pass_t &, long, type ) {}313 template<typename core_t> \ 314 static inline void func( core_t &, long, type ) {} 297 315 298 316 #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 ); \317 template<typename core_t> \ 318 static inline auto func( core_t & core, int, type1 arg1, type2 arg2 ) -> decltype( core.symtab.func( arg1, arg2 ), void () ) {\ 319 core.symtab.func( arg1, arg2 ); \ 302 320 } \ 303 321 \ 304 template<typename pass_t> \305 static inline void func( pass_t &, long, type1, type2 ) {}322 template<typename core_t> \ 323 static inline void func( core_t &, long, type1, type2 ) {} 306 324 307 325 SYMTAB_FUNC1( addId , const DeclWithType * ); … … 311 329 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 312 330 SYMTAB_FUNC1( addTrait , const TraitDecl * ); 313 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Node* );331 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Decl * ); 314 332 315 333 // 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() ) {334 template<typename core_t> 335 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) { 318 336 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 319 337 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() ) {338 core.symtab.addStruct( fwd ); 339 } 340 341 template<typename core_t> 342 static inline void addStructFwd( core_t &, long, const ast::StructDecl * ) {} 343 344 template<typename core_t> 345 static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) { 328 346 UnionDecl * fwd = new UnionDecl( decl->location, decl->name ); 329 347 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 );348 core.symtab.addUnion( fwd ); 349 } 350 351 template<typename core_t> 352 static inline void addUnionFwd( core_t &, long, const ast::UnionDecl * ) {} 353 354 template<typename core_t> 355 static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) { 356 if ( ! core.symtab.lookupStruct( str ) ) { 357 core.symtab.addStruct( str ); 340 358 } 341 359 } 342 360 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 );361 template<typename core_t> 362 static inline void addStruct( core_t &, long, const std::string & ) {} 363 364 template<typename core_t> 365 static inline auto addUnion( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addUnion( str ), void() ) { 366 if ( ! core.symtab.lookupUnion( str ) ) { 367 core.symtab.addUnion( str ); 350 368 } 351 369 } 352 370 353 template<typename pass_t>354 static inline void addUnion( pass_t &, long, const std::string & ) {}371 template<typename core_t> 372 static inline void addUnion( core_t &, long, const std::string & ) {} 355 373 356 374 #undef SYMTAB_FUNC1 357 375 #undef SYMTAB_FUNC2 358 }; 359 }; 360 }; 376 } // namespace symtab 377 378 // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType. 379 // Detect the presence of a member name `subs` and call all members appropriately 380 namespace forall { 381 // Some simple scoping rules 382 template<typename core_t> 383 static inline auto enter( core_t & core, int, const ast::ParameterizedType * type ) 384 -> decltype( core.subs, void() ) { 385 if ( ! type->forall.empty() ) core.subs.beginScope(); 386 } 387 388 template<typename core_t> 389 static inline auto enter( core_t &, long, const ast::ParameterizedType * ) {} 390 391 template<typename core_t> 392 static inline auto leave( core_t & core, int, const ast::ParameterizedType * type ) 393 -> decltype( core.subs, void() ) { 394 if ( ! type->forall.empty() ) { core.subs.endScope(); } 395 } 396 397 template<typename core_t> 398 static inline auto leave( core_t &, long, const ast::ParameterizedType * ) {} 399 400 // Get the substitution table, if present 401 template<typename core_t> 402 static inline auto subs( core_t & core, int ) -> decltype( &core.subs ) { 403 return &core.subs; 404 } 405 406 template<typename core_t> 407 static inline ast::ForallSubstitutionTable * subs( core_t &, long ) { return nullptr; } 408 409 // Replaces a TypeInstType's base TypeDecl according to the table 410 template<typename core_t> 411 static inline auto replace( core_t & core, int, const ast::TypeInstType *& inst ) 412 -> decltype( core.subs, void() ) { 413 inst = ast::mutate_field( 414 inst, &ast::TypeInstType::base, core.subs.replace( inst->base ) ); 415 } 416 417 template<typename core_t> 418 static inline auto replace( core_t &, long, const ast::TypeInstType *& ) {} 419 420 } // namespace forall 421 } // namespace __pass 422 } // namespace ast
Note: See TracChangeset
for help on using the changeset viewer.