Changes in src/AST/Pass.proto.hpp [7ff3e522:0e42794]
- File:
-
- 1 edited
-
src/AST/Pass.proto.hpp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.proto.hpp
r7ff3e522 r0e42794 17 17 // IWYU pragma: private, include "Pass.hpp" 18 18 19 #include "Common/Stats/Heap.h"20 21 19 namespace ast { 22 template<typename core_t>20 template<typename pass_type> 23 21 class Pass; 24 22 … … 84 82 }; 85 83 86 std::stack< cleanup_t , std::vector<cleanup_t>> cleanups;84 std::stack< cleanup_t > cleanups; 87 85 }; 88 86 … … 113 111 /// "Short hand" to check if this is a valid previsit function 114 112 /// Mostly used to make the static_assert look (and print) prettier 115 template<typename core_t, typename node_t>113 template<typename pass_t, typename node_t> 116 114 struct is_valid_previsit { 117 using ret_t = decltype( (( core_t*)nullptr)->previsit( (const node_t *)nullptr ) );115 using ret_t = decltype( ((pass_t*)nullptr)->previsit( (const node_t *)nullptr ) ); 118 116 119 117 static constexpr bool value = std::is_void< ret_t >::value || … … 129 127 template<> 130 128 struct __assign<true> { 131 template<typename core_t, typename node_t>132 static inline void result( core_t & core, const node_t * & node ) {133 core.previsit( node );129 template<typename pass_t, typename node_t> 130 static inline void result( pass_t & pass, const node_t * & node ) { 131 pass.previsit( node ); 134 132 } 135 133 }; … … 137 135 template<> 138 136 struct __assign<false> { 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 );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 ); 142 140 assertf(node, "Previsit must not return NULL"); 143 141 } … … 152 150 template<> 153 151 struct __return<true> { 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 );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 ); 157 155 return node; 158 156 } … … 161 159 template<> 162 160 struct __return<false> { 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 );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 ); 166 164 } 167 165 }; … … 182 180 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 183 181 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 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() ) {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() ) { 186 184 static_assert( 187 is_valid_previsit< core_t, node_t>::value,185 is_valid_previsit<pass_t, node_t>::value, 188 186 "Previsit may not change the type of the node. It must return its paremeter or void." 189 187 ); … … 191 189 __assign< 192 190 std::is_void< 193 decltype( core.previsit( node ) )191 decltype( pass.previsit( node ) ) 194 192 >::value 195 >::result( core, node );193 >::result( pass, node ); 196 194 } 197 195 198 template<typename core_t, typename node_t>199 static inline auto previsit( core_t &, const node_t *, long ) {}196 template<typename pass_t, typename node_t> 197 static inline auto previsit( pass_t &, const node_t *, long ) {} 200 198 201 199 // PostVisit : never mutates the passed pointer but may return a different node 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 ) )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 ) ) 205 203 { 206 204 return __return< 207 205 std::is_void< 208 decltype( core.postvisit( node ) )206 decltype( pass.postvisit( node ) ) 209 207 >::value 210 >::result( core, node );208 >::result( pass, node ); 211 209 } 212 210 213 template<typename core_t, typename node_t>214 static inline const node_t * postvisit( core_t &, const node_t * node, long ) { return node; }211 template<typename pass_t, typename node_t> 212 static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; } 215 213 216 214 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 227 225 // The type is not strictly enforced but does match the accessory 228 226 #define FIELD_PTR( name, default_type ) \ 229 template< typename core_t > \230 static inline auto name( core_t & core, int ) -> decltype( &core.name ) { return &core.name; } \227 template< typename pass_t > \ 228 static inline auto name( pass_t & pass, int ) -> decltype( &pass.name ) { return &pass.name; } \ 231 229 \ 232 template< typename core_t > \233 static inline default_type * name( core_t &, long ) { return nullptr; }230 template< typename pass_t > \ 231 static inline default_type * name( pass_t &, long ) { return nullptr; } 234 232 235 233 // List of fields and their expected types … … 241 239 FIELD_PTR( visit_children, __pass::bool_ref ) 242 240 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 243 FIELD_PTR( visitor, ast::Pass< core_t> * const )241 FIELD_PTR( visitor, ast::Pass<pass_t> * const ) 244 242 245 243 // Remove the macro to make sure we don't clash 246 244 #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) {}263 245 264 246 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. … … 266 248 // detect it using the same strategy 267 249 namespace scope { 268 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 scope284 285 // Certain passes desire an up to date symbol table automatically250 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 automatically 286 268 // detect the presence of a member name `symtab` and call all the members appropriately 287 269 namespace symtab { 288 270 // Some simple scoping rules 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 ) {}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 286 305 287 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 306 288 // Create macro to condense these common patterns 307 289 #define SYMTAB_FUNC1( func, type ) \ 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 ); \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 ); \ 311 293 } \ 312 294 \ 313 template<typename core_t> \314 static inline void func( core_t &, long, type ) {}295 template<typename pass_t> \ 296 static inline void func( pass_t &, long, type ) {} 315 297 316 298 #define SYMTAB_FUNC2( func, type1, type2 ) \ 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 ); \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 ); \ 320 302 } \ 321 303 \ 322 template<typename core_t> \323 static inline void func( core_t &, long, type1, type2 ) {}304 template<typename pass_t> \ 305 static inline void func( pass_t &, long, type1, type2 ) {} 324 306 325 307 SYMTAB_FUNC1( addId , const DeclWithType * ); … … 329 311 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 330 312 SYMTAB_FUNC1( addTrait , const TraitDecl * ); 331 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Decl* );313 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Node * ); 332 314 333 315 // A few extra functions have more complicated behaviour, they are hand written 334 template<typename core_t>335 static inline auto addStructFwd( core_t & core, int, const ast::StructDecl * decl ) -> decltype( core.symtab.addStruct( decl ), void() ) {316 template<typename pass_t> 317 static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.symtab.addStruct( decl ), void() ) { 336 318 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 337 319 fwd->params = decl->params; 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() ) {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() ) { 346 328 UnionDecl * fwd = new UnionDecl( decl->location, decl->name ); 347 329 fwd->params = decl->params; 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 );358 } 359 } 360 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 );368 } 369 } 370 371 template<typename core_t>372 static inline void addUnion( core_t &, long, const std::string & ) {}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 ); 340 } 341 } 342 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 ); 350 } 351 } 352 353 template<typename pass_t> 354 static inline void addUnion( pass_t &, long, const std::string & ) {} 373 355 374 356 #undef SYMTAB_FUNC1 375 357 #undef SYMTAB_FUNC2 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 358 }; 359 }; 360 };
Note:
See TracChangeset
for help on using the changeset viewer.