Changes in src/AST/Pass.proto.hpp [3e5dd913:0e42794]
- File:
-
- 1 edited
-
src/AST/Pass.proto.hpp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.proto.hpp
r3e5dd913 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 25 struct TranslationUnit;26 27 struct PureVisitor;28 22 29 23 namespace __pass { … … 88 82 }; 89 83 90 std::stack< cleanup_t , std::vector<cleanup_t>> cleanups;84 std::stack< cleanup_t > cleanups; 91 85 }; 92 86 … … 117 111 /// "Short hand" to check if this is a valid previsit function 118 112 /// Mostly used to make the static_assert look (and print) prettier 119 template<typename core_t, typename node_t>113 template<typename pass_t, typename node_t> 120 114 struct is_valid_previsit { 121 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 ) ); 122 116 123 117 static constexpr bool value = std::is_void< ret_t >::value || … … 133 127 template<> 134 128 struct __assign<true> { 135 template<typename core_t, typename node_t>136 static inline void result( core_t & core, const node_t * & node ) {137 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 ); 138 132 } 139 133 }; … … 141 135 template<> 142 136 struct __assign<false> { 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 );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 ); 146 140 assertf(node, "Previsit must not return NULL"); 147 141 } … … 156 150 template<> 157 151 struct __return<true> { 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 );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 ); 161 155 return node; 162 156 } … … 165 159 template<> 166 160 struct __return<false> { 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 );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 ); 170 164 } 171 165 }; … … 186 180 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 187 181 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 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() ) {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() ) { 190 184 static_assert( 191 is_valid_previsit< core_t, node_t>::value,185 is_valid_previsit<pass_t, node_t>::value, 192 186 "Previsit may not change the type of the node. It must return its paremeter or void." 193 187 ); … … 195 189 __assign< 196 190 std::is_void< 197 decltype( core.previsit( node ) )191 decltype( pass.previsit( node ) ) 198 192 >::value 199 >::result( core, node );193 >::result( pass, node ); 200 194 } 201 195 202 template<typename core_t, typename node_t>203 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 ) {} 204 198 205 199 // PostVisit : never mutates the passed pointer but may return a different node 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 ) )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 ) ) 209 203 { 210 204 return __return< 211 205 std::is_void< 212 decltype( core.postvisit( node ) )206 decltype( pass.postvisit( node ) ) 213 207 >::value 214 >::result( core, node );208 >::result( pass, node ); 215 209 } 216 210 217 template<typename core_t, typename node_t>218 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; } 219 213 220 214 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 231 225 // The type is not strictly enforced but does match the accessory 232 226 #define FIELD_PTR( name, default_type ) \ 233 template< typename core_t > \234 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; } \ 235 229 \ 236 template< typename core_t > \237 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; } 238 232 239 233 // List of fields and their expected types 240 FIELD_PTR( typeSubs, const ast::TypeSubstitution * )234 FIELD_PTR( env, const ast::TypeSubstitution * ) 241 235 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 242 236 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) … … 245 239 FIELD_PTR( visit_children, __pass::bool_ref ) 246 240 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 247 FIELD_PTR( visitor, ast::Pass< core_t> * const )241 FIELD_PTR( visitor, ast::Pass<pass_t> * const ) 248 242 249 243 // Remove the macro to make sure we don't clash 250 244 #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 }278 245 279 246 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. … … 281 248 // detect it using the same strategy 282 249 namespace scope { 283 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 scope299 300 // 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 301 268 // detect the presence of a member name `symtab` and call all the members appropriately 302 269 namespace symtab { 303 270 // Some simple scoping rules 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 ) {}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 ) {} 319 286 320 287 // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments 321 288 // Create macro to condense these common patterns 322 289 #define SYMTAB_FUNC1( func, type ) \ 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 ); \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 ); \ 326 293 } \ 327 294 \ 328 template<typename core_t> \329 static inline void func( core_t &, long, type ) {}295 template<typename pass_t> \ 296 static inline void func( pass_t &, long, type ) {} 330 297 331 298 #define SYMTAB_FUNC2( func, type1, type2 ) \ 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 ); \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 ); \ 335 302 } \ 336 303 \ 337 template<typename core_t> \338 static inline void func( core_t &, long, type1, type2 ) {}304 template<typename pass_t> \ 305 static inline void func( pass_t &, long, type1, type2 ) {} 339 306 340 307 SYMTAB_FUNC1( addId , const DeclWithType * ); … … 344 311 SYMTAB_FUNC1( addUnion , const UnionDecl * ); 345 312 SYMTAB_FUNC1( addTrait , const TraitDecl * ); 346 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Decl* );313 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Node * ); 347 314 348 315 // A few extra functions have more complicated behaviour, they are hand written 349 template<typename core_t>350 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() ) { 351 318 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 352 319 fwd->params = decl->params; 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() ) {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() ) { 361 328 UnionDecl * fwd = new UnionDecl( decl->location, decl->name ); 362 329 fwd->params = decl->params; 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 );373 } 374 } 375 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 );383 } 384 } 385 386 template<typename core_t>387 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 & ) {} 388 355 389 356 #undef SYMTAB_FUNC1 390 357 #undef SYMTAB_FUNC2 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 358 }; 359 }; 360 };
Note:
See TracChangeset
for help on using the changeset viewer.