Changes in src/AST/Pass.impl.hpp [6d51bd7:04124c4]
- File:
-
- 1 edited
-
src/AST/Pass.impl.hpp (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.impl.hpp
r6d51bd7 r04124c4 16 16 #pragma once 17 17 // IWYU pragma: private, include "AST/Pass.hpp" 18 19 #include <type_traits>20 #include <unordered_map>21 18 22 19 #define VISIT_START( node ) \ … … 29 26 __pass::previsit( pass, node, 0 ); 30 27 31 #define VISIT( code ...) \28 #define VISIT( code ) \ 32 29 /* if this node should visit its children */ \ 33 30 if ( __visit_children() ) { \ … … 38 35 #define VISIT_END( type, node ) \ 39 36 /* call the implementation of the postvisit of this pass */ \ 40 auto __return = __pass::postvisit ( pass, node, 0); \37 auto __return = __pass::postvisit< type * >( node ); \ 41 38 assertf(__return, "post visit should never return null"); \ 42 39 return __return; 43 40 44 41 #ifdef PEDANTIC_PASS_ASSERT 45 #define __pedantic_pass_assert (...) assert (__VA_ARGS__)46 #define __pedantic_pass_assertf(...) assertf(__VA _ARGS__)42 #define __pedantic_pass_assert (...) assert (__VAR_ARGS__) 43 #define __pedantic_pass_assertf(...) assertf(__VAR_ARGS__) 47 44 #else 48 #define __pedantic_pass_assert (...)45 #define __pedantic_pass_assert (...) 49 46 #define __pedantic_pass_assertf(...) 50 47 #endif … … 58 55 } 59 56 60 //------------------------------ 61 template<typename it_t, template <class...> class container_t> 62 static inline void take_all( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) { 57 template<typename it_t, template <class> class container_t> 58 static inline void take_all( it_t it, container_t<ast::ptr<ast::Declaration>> * decls, bool * mutated = nullptr ) { 63 59 if(empty(decls)) return; 64 60 65 std::transform(decls->begin(), decls->end(), it, []( const ast::Decl* decl) -> auto {61 std::transform(decls->begin(), decls->end(), it, [](Declaration * decl) -> auto { 66 62 return new DeclStmt( decl ); 67 63 }); … … 70 66 } 71 67 72 template<typename it_t, template <class ...> class container_t>73 static inline void take_all( it_t it, container_t<ast::ptr<ast::St mt>> * decls, bool * mutated = nullptr ) {68 template<typename it_t, template <class> class container_t> 69 static inline void take_all( it_t it, container_t<ast::ptr<ast::Statement>> * decls, bool * mutated = nullptr ) { 74 70 if(empty(decls)) return; 75 71 … … 79 75 } 80 76 81 //------------------------------82 /// Check if should be skipped, different for pointers and containers83 77 template<typename node_t> 84 bool skip( const ast::ptr<node_t> & val) { 85 return !val; 86 } 87 88 template< template <class...> class container_t, typename node_t > 89 bool skip( const container_t<ast::ptr< node_t >> & val ) { 90 return val.empty(); 91 } 92 93 //------------------------------ 94 /// Get the value to visit, different for pointers and containers 95 template<typename node_t> 96 auto get( const ast::ptr<node_t> & val, int ) -> decltype(val.get()) { 97 return val.get(); 98 } 99 100 template<typename node_t> 101 const node_t & get( const node_t & val, long) { 102 return val; 103 } 104 105 106 //------------------------------ 107 /// Check if value was mutated, different for pointers and containers 108 template<typename lhs_t, typename rhs_t> 109 bool differs( const lhs_t * old_val, const rhs_t * new_val ) { 78 bool differs( const node_t * old_val, const node_t * new_val ) { 110 79 return old_val != new_val; 111 80 } 112 81 113 template< template <class ...> class container_t, typename node_t >114 bool differs( const container_t<ast::ptr< node_t >> &, const container_t<ast::ptr< node_t >> & new_val ) {82 template< template <class> class container_t > 83 bool differs( const container_t<ast::ptr< ast::Statement >> &, const container_t<ast::ptr< ast::Statement >> & new_val ) { 115 84 return !new_val.empty(); 116 85 } 117 86 } 118 87 88 template<typename parent_t, typename child_t> 89 template< typename pass_t > 90 void Pass< pass_t >::maybe_accept( 91 const parent_t * & parent, 92 const typename parent_t::child_t * child 93 ) { 94 const auto & old_val = parent->*child; 95 if(!old_val) return; 96 97 auto new_val = call_accept(old_val); 98 99 if( __pass::differs(old_val, new_val) ) { 100 auto new_parent = mutate(parent); 101 new_parent->*child = new_val; 102 parent = new_parent; 103 } 104 } 105 119 106 template< typename pass_t > 120 107 template< typename node_t > 121 auto Pass< pass_t >::call_accept( const node_t * node ) -> decltype( node->accept(*this) ){108 auto Pass< pass_t >::call_accept( const node_t * node ) { 122 109 __pedantic_pass_assert( __visit_children() ); 123 110 __pedantic_pass_assert( expr ); 124 111 125 static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");126 static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR");127 128 112 return node->accept( *this ); 129 113 } 130 114 131 115 template< typename pass_t > 132 constast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {116 ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) { 133 117 __pedantic_pass_assert( __visit_children() ); 134 118 __pedantic_pass_assert( expr ); … … 143 127 144 128 template< typename pass_t > 145 const ast::Stmt * Pass< pass_t >::call_accept( const ast::Stmt * stmt ) {129 Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) { 146 130 __pedantic_pass_assert( __visit_children() ); 147 131 __pedantic_pass_assert( stmt ); … … 157 141 158 142 // These may be modified by subnode but most be restored once we exit this statemnet. 159 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::env( pass, 0) );160 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > >__old_decls_before( stmts_before );161 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > >__old_decls_after ( stmts_after );162 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > >__old_stmts_before( decls_before );163 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > >__old_stmts_after ( decls_after );143 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::env( pass, 0); ); 144 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before ); 145 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after ); 146 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before ); 147 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after ); 164 148 165 149 // Now is the time to actually visit the node 166 const ast::Stmt * nstmt = stmt->accept( *this );150 ast::Statement * nstmt = stmt->accept( *this ); 167 151 168 152 // If the pass doesn't want to add anything then we are done … … 177 161 178 162 // Create a new Compound Statement to hold the new decls/stmts 179 ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );163 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location ); 180 164 181 165 // Take all the declarations that go before … … 184 168 185 169 // Insert the original declaration 186 compound->kids. emplace_back( nstmt );170 compound->kids.push_back( nstmt ); 187 171 188 172 // Insert all the declarations that go before … … 194 178 195 179 template< typename pass_t > 196 template< template <class ...> class container_t >180 template< template <class> class container_t > 197 181 container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 198 182 __pedantic_pass_assert( __visit_children() ); … … 212 196 213 197 // These may be modified by subnode but most be restored once we exit this statemnet. 214 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > >__old_decls_before( stmts_before );215 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > >__old_decls_after ( stmts_after );216 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > >__old_stmts_before( decls_before );217 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > >__old_stmts_after ( decls_after );198 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before ); 199 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after ); 200 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before ); 201 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after ); 218 202 219 203 // update pass statitistics … … 227 211 try { 228 212 __pedantic_pass_assert( stmt ); 229 const ast::St mt * new_stmt = stmt->accept( *this);213 const ast::Statment * new_stmt = stmt->accept( visitor ); 230 214 assert( new_stmt ); 231 215 if(new_stmt != stmt ) mutated = true; … … 256 240 if ( !errors.isEmpty() ) { throw errors; } 257 241 258 return mutated ? new_kids : container_t< ptr<Stmt> >();259 } 260 261 template< typename pass_t > 262 template< template <class ...> class container_t, typename node_t >242 return mutated ? new_kids : {}; 243 } 244 245 template< typename pass_t > 246 template< template <class> class container_t, typename node_t > 263 247 container_t< ast::ptr<node_t> > Pass< pass_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 264 248 __pedantic_pass_assert( __visit_children() ); … … 275 259 try { 276 260 __pedantic_pass_assert( node ); 277 const node_t * new_ stmt= strict_dynamic_cast< const node_t * >( node->accept( *this ) );278 if(new_stmt != node) mutated = true;261 const node_t * new_node = strict_dynamic_cast< const node_t * >( node->accept( *this ) ); 262 if(new_stmt != stmt ) mutated = true; 279 263 280 264 new_kids.emplace_back( new_stmt ); … … 287 271 if ( ! errors.isEmpty() ) { throw errors; } 288 272 289 return mutated ? new_kids : container_t< ast::ptr<node_t> >(); 290 } 291 292 template< typename pass_t > 293 template<typename node_t, typename parent_t, typename child_t> 294 void Pass< pass_t >::maybe_accept( 295 const node_t * & parent, 296 child_t parent_t::*child 297 ) { 298 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deductiing member object" ); 299 300 if(__pass::skip(parent->*child)) return; 301 const auto & old_val = __pass::get(parent->*child, 0); 302 303 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR"); 304 305 auto new_val = call_accept( old_val ); 306 307 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); 308 309 if( __pass::differs(old_val, new_val) ) { 310 auto new_parent = mutate(parent); 311 new_parent->*child = new_val; 312 parent = new_parent; 313 } 314 } 315 273 return mutated ? new_kids : {}; 274 } 316 275 } 317 276 … … 325 284 326 285 template< typename pass_t > 327 inline void ast::accept _all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {286 inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) { 328 287 // We are going to aggregate errors for all these statements 329 288 SemanticErrorException errors; … … 333 292 334 293 // get the stmts/decls that will need to be spliced in 335 auto decls_before = __pass::declsToAddBefore( visitor.pass, 0);336 auto decls_after = __pass::declsToAddAfter ( visitor.pass, 0);294 auto decls_before = __pass::declsToAddBefore( pass, 0); 295 auto decls_after = __pass::declsToAddAfter ( pass, 0); 337 296 338 297 // update pass statitistics … … 384 343 // ObjectDecl 385 344 template< typename pass_t > 386 constast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {345 ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) { 387 346 VISIT_START( node ); 388 347 389 348 VISIT( 390 349 { 391 guard_indexerguard { *this };392 maybe_accept( node, &ast::ObjectDecl::type );393 } 394 maybe_accept( node, &ast::ObjectDecl::init );395 maybe_accept( node, &ast::ObjectDecl::bitfieldWidth );396 maybe_accept( node, &ast::ObjectDecl::attributes );350 indexer_guard guard { *this }; 351 maybe_accept( node, ObjectDecl::type ); 352 } 353 maybe_accept( node, ObjectDecl::init ); 354 maybe_accept( node, ObjectDecl::bitfieldWidth ); 355 maybe_accept( node, ObjectDecl::attributes ); 397 356 ) 398 357 399 __pass::indexer:: addId( pass, 0, node );358 __pass::indexer::AddId( pass, 0, node ); 400 359 401 360 VISIT_END( DeclWithType, node ); 402 }403 404 //--------------------------------------------------------------------------405 // SingleInit406 template< typename pass_t >407 const ast::Init * ast::Pass< pass_t >::visit( const ast::SingleInit * node ) {408 VISIT_START( node );409 410 VISIT(411 maybe_accept( node, &SingleInit::value );412 )413 414 VISIT_END( Init, node );415 }416 417 //--------------------------------------------------------------------------418 // ListInit419 template< typename pass_t >420 const ast::Init * ast::Pass< pass_t >::visit( const ast::ListInit * node ) {421 VISIT_START( node );422 423 VISIT(424 maybe_accept( node, &ListInit::designations );425 maybe_accept( node, &ListInit::initializers );426 )427 428 VISIT_END( Init, node );429 }430 431 //--------------------------------------------------------------------------432 // ConstructorInit433 template< typename pass_t >434 const ast::Init * ast::Pass< pass_t >::visit( const ast::ConstructorInit * node ) {435 VISIT_START( node );436 437 VISIT(438 maybe_accept( node, &ConstructorInit::ctor );439 maybe_accept( node, &ConstructorInit::dtor );440 maybe_accept( node, &ConstructorInit::init );441 )442 443 VISIT_END( Init, node );444 361 } 445 362 446 363 //-------------------------------------------------------------------------- 447 364 // Attribute 448 template< typename pass_t >449 const ast::Attribute * ast::Pass< pass_t>::visit( const ast::Attribute * node ) {450 VISIT_START( node);365 template< typename pass_type > 366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute * node ) { 367 VISIT_START(node); 451 368 452 369 VISIT( 453 maybe_accept( node, &Attribute::parameters );370 maybe_accept( node, ast::Attribute::parameters ); 454 371 ) 455 372 456 VISIT_END( Attribute *, node );373 VISIT_END(ast::Attribute *, node ); 457 374 } 458 375 459 376 //-------------------------------------------------------------------------- 460 377 // TypeSubstitution 461 template< typename pass_t > 462 const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) { 463 VISIT_START( node ); 464 465 VISIT( 466 { 467 bool mutated = false; 468 std::unordered_map< std::string, ast::ptr< ast::Type > > new_map; 469 for ( const auto & p : node->typeEnv ) { 470 guard_indexer guard { *this }; 471 auto new_node = p.second->accept( *this ); 472 if (new_node != p.second) mutated = false; 473 new_map.insert({ p.first, new_node }); 474 } 475 if (mutated) { 476 auto new_node = mutate( node ); 477 new_node->typeEnv.swap( new_map ); 478 node = new_node; 479 } 480 } 481 482 { 483 bool mutated = false; 484 std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map; 485 for ( const auto & p : node->varEnv ) { 486 guard_indexer guard { *this }; 487 auto new_node = p.second->accept( *this ); 488 if (new_node != p.second) mutated = false; 489 new_map.insert({ p.first, new_node }); 490 } 491 if (mutated) { 492 auto new_node = mutate( node ); 493 new_node->varEnv.swap( new_map ); 494 node = new_node; 495 } 496 } 497 ) 498 499 VISIT_END( TypeSubstitution, node ); 378 template< typename pass_type > 379 TypeSubstitution * PassVisitor< pass_type >::mutate( const TypeSubstitution * node ) { 380 MUTATE_START( node ); 381 382 #error this is broken 383 384 for ( auto & p : node->typeEnv ) { 385 indexerScopedMutate( p.second, *this ); 386 } 387 for ( auto & p : node->varEnv ) { 388 indexerScopedMutate( p.second, *this ); 389 } 390 391 MUTATE_END( TypeSubstitution, node ); 500 392 } 501 393
Note:
See TracChangeset
for help on using the changeset viewer.