Changeset 296b2be
- Timestamp:
- Jun 1, 2017, 1:35:58 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 5013c62
- Parents:
- ab904dc
- Location:
- src/Common
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/PassVisitor.h
rab904dc r296b2be 1 1 #pragma once 2 3 #include <stack> 2 4 3 5 #include "SynTree/Mutator.h" … … 11 13 #include "SynTree/Constant.h" 12 14 13 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 14 // Deep magic (a.k.a template meta programming) to make the templated visitor work 15 // Basically the goal is to make 2 previsit_impl 16 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 17 // 'pass.previsit( node )' that compiles will be used for that node for that type 18 // This requires that this option only compile for passes that actually define an appropriate visit. 19 // SFINAE will make sure the compilation errors in this function don't halt the build. 20 // See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE 21 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing. 22 // This is needed only to eliminate the need for passes to specify any kind of handlers. 23 // The second implementation only works because it has a lower priority. This is due to the bogus last parameter. 24 // The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0 25 // the first implementation takes priority in regards to overloading. 26 // Mutator functions work along the same principal 27 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 28 // Visit 29 template<typename pass_type, typename node_type> 30 static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) { 31 pass.previsit( node ); 32 } 33 34 template<typename pass_type, typename node_type> 35 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {} 36 37 38 template<typename pass_type, typename node_type> 39 static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) { 40 pass.postvisit( node ); 41 } 42 43 template<typename pass_type, typename node_type> 44 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {} 45 46 // Mutate 47 template<typename pass_type, typename node_type> 48 static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.premutate( node ), void() ) { 49 return pass.premutate( node ); 50 } 51 52 template<typename pass_type, typename node_type> 53 static inline void premutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {} 54 55 56 template<typename return_type, typename pass_type, typename node_type> 57 static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postmutate( node ) ) { 58 return pass.postmutate( node ); 59 } 60 61 template<typename return_type, typename pass_type, typename node_type> 62 static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; } 15 #include "PassVisitor.proto.h" 63 16 64 17 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 256 209 257 210 private: 258 template<typename node_type> 259 auto call_previsit ( node_type * node ) 260 -> decltype( previsit_impl ( pass, node, 0 ), void() ) 261 { 262 previsit_impl ( pass, node, 0 ); 263 } 264 265 template<typename node_type> 266 auto call_postvisit( node_type * node ) 267 -> decltype( postvisit_impl( pass, node, 0 ), void() ) 268 { 269 postvisit_impl( pass, node, 0 ); 270 } 271 272 template<typename node_type> 273 auto call_premutate ( node_type * node ) 274 -> decltype( premutate_impl( pass, node, 0 ), void() ) 275 { 276 premutate_impl( pass, node, 0 ); 277 } 278 279 template<typename return_type, typename node_type> 280 auto call_postmutate ( node_type * node ) 281 -> decltype( postmutate_impl<return_type>( pass, node, 0 ) ) 282 { 283 return postmutate_impl<return_type>( pass, node, 0 ); 284 } 211 template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); } 212 template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); } 213 214 template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); } 215 template<typename return_type, typename node_type> return_type call_postmutate ( node_type * node ) { return postmutate_impl<return_type>( pass, node, 0 ); } 216 217 void call_beginScope() { begin_scope_impl( pass, 0 ); } 218 void call_endScope () { end_scope_impl ( pass, 0 ); } 219 220 void mutateStatementList( std::list< Statement* > &statements ); 221 Statement * mutateStatement( Statement * stmt ); 222 Expression * mutateExpression( Expression * expr ); 223 224 private: 225 TypeSubstitution * env; 226 227 std::list< Statement* > stmtsToAdd; 228 std::list< Statement* > stmtsToAddAfter; 285 229 }; 286 230 -
src/Common/PassVisitor.impl.h
rab904dc r296b2be 1 1 #pragma once 2 3 #define MUTATE_START( node ) \ 4 call_premutate( node ); \ 5 6 7 #define MUTATE_END( type, node ) \ 8 return call_postmutate< type * >( node ); \ 9 2 10 3 11 #define VISIT_BODY( node ) \ … … 6 14 call_postvisit( node ); \ 7 15 8 #define MUTATE_BODY( type, node ) \ 9 call_premutate( node ); \ 10 Mutator::mutate( node ); \ 11 auto ret = call_postmutate< type * >( node ); \ 12 return ret; \ 13 14 15 16 17 #define MUTATE_BODY( type, node ) \ 18 MUTATE_START( node ); \ 19 Mutator::mutate( node ); \ 20 MUTATE_END( type, node ); \ 21 22 template< typename pass_type > 23 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 24 SemanticError errors; 25 26 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { 27 if ( ! stmtsToAddAfter.empty() ) { 28 statements.splice( i, stmtsToAddAfter ); 29 } // if 30 try { 31 *i = (*i)->acceptMutator( *this ); 32 } catch ( SemanticError &e ) { 33 errors.append( e ); 34 } // try 35 if ( ! stmtsToAdd.empty() ) { 36 statements.splice( i, stmtsToAdd ); 37 } // if 38 } // for 39 if ( ! stmtsToAddAfter.empty() ) { 40 statements.splice( statements.end(), stmtsToAddAfter ); 41 } // if 42 if ( ! errors.isEmpty() ) { 43 throw errors; 44 } 45 } 46 47 template< typename pass_type > 48 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 49 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 50 ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd ); 51 ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter ); 52 ValueGuard< TypeSubstitution * > oldEnv( env ); 53 stmtsToAdd.clear(); 54 stmtsToAddAfter.clear(); 55 56 Statement *newStmt = maybeMutate( stmt, *this ); 57 if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) { 58 CompoundStmt *compound = new CompoundStmt( noLabels ); 59 compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd ); 60 compound->get_kids().push_back( newStmt ); 61 compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter ); 62 // doEndScope(); 63 return compound; 64 } else { 65 return newStmt; 66 } 67 } 68 69 template< typename pass_type > 70 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 71 if( !expr ) return nullptr; 72 73 if ( expr->get_env() ) { 74 env = expr->get_env(); 75 } 76 // xxx - should env be cloned (or moved) onto the result of the mutate? 77 return expr->acceptMutator( *this ); 78 } 79 80 81 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 16 82 17 83 template< typename pass_type > … … 66 132 67 133 template< typename pass_type > 134 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { 135 MUTATE_START( node ); 136 call_beginScope(); 137 138 mutateStatementList( node->get_kids() ); 139 140 call_endScope(); 141 MUTATE_END( CompoundStmt, node ); 142 } 143 144 template< typename pass_type > 68 145 void PassVisitor< pass_type >::visit( ExprStmt * node ) { 69 146 VISIT_BODY( node ); … … 71 148 72 149 template< typename pass_type > 150 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) { 151 MUTATE_START( node ); 152 153 node->set_expr( mutateExpression( node->get_expr() ) ); 154 155 MUTATE_END( Statement, node ); 156 } 157 158 template< typename pass_type > 73 159 void PassVisitor< pass_type >::visit( AsmStmt * node ) { 74 160 VISIT_BODY( node ); … … 81 167 82 168 template< typename pass_type > 169 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 170 MUTATE_START( node ); 171 172 node->set_condition( mutateExpression( node->get_condition() ) ); 173 node->set_thenPart ( mutateStatement ( node->get_thenPart() ) ); 174 node->set_elsePart ( mutateStatement ( node->get_elsePart() ) ); 175 176 MUTATE_END( Statement, node ); 177 } 178 179 template< typename pass_type > 83 180 void PassVisitor< pass_type >::visit( WhileStmt * node ) { 84 181 VISIT_BODY( node ); … … 86 183 87 184 template< typename pass_type > 185 Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) { 186 MUTATE_START( node ); 187 188 node->set_condition( mutateExpression( node->get_condition() ) ); 189 node->set_body( mutateStatement( node->get_body() ) ); 190 191 MUTATE_END( Statement, node ); 192 } 193 194 195 template< typename pass_type > 88 196 void PassVisitor< pass_type >::visit( ForStmt * node ) { 89 197 VISIT_BODY( node ); … … 91 199 92 200 template< typename pass_type > 201 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { 202 MUTATE_START( node ); 203 204 mutateAll( node->get_initialization(), *this ); 205 node->set_condition( mutateExpression( node->get_condition() ) ); 206 node->set_increment( mutateExpression( node->get_increment() ) ); 207 node->set_body( mutateStatement( node->get_body() ) ); 208 209 MUTATE_END( Statement, node ); 210 } 211 212 template< typename pass_type > 93 213 void PassVisitor< pass_type >::visit( SwitchStmt * node ) { 94 214 VISIT_BODY( node ); … … 96 216 97 217 template< typename pass_type > 218 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { 219 MUTATE_START( node ); 220 221 node->set_condition( mutateExpression( node->get_condition() ) ); 222 mutateStatementList( node->get_statements() ); 223 224 MUTATE_END( Statement, node ); 225 } 226 227 template< typename pass_type > 98 228 void PassVisitor< pass_type >::visit( CaseStmt * node ) { 99 229 VISIT_BODY( node ); … … 101 231 102 232 template< typename pass_type > 233 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { 234 MUTATE_START( node ); 235 236 node->set_condition( mutateExpression( node->get_condition() ) ); 237 mutateStatementList( node->get_statements() ); 238 239 MUTATE_END( Statement, node ); 240 } 241 242 template< typename pass_type > 103 243 void PassVisitor< pass_type >::visit( BranchStmt * node ) { 104 244 VISIT_BODY( node ); … … 111 251 112 252 template< typename pass_type > 253 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { 254 MUTATE_START( node ); 255 256 node->set_expr( mutateExpression( node->get_expr() ) ); 257 258 MUTATE_END( Statement, node ); 259 } 260 261 template< typename pass_type > 113 262 void PassVisitor< pass_type >::visit( TryStmt * node ) { 114 263 VISIT_BODY( node ); … … 116 265 117 266 template< typename pass_type > 267 Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) { 268 MUTATE_START( node ); 269 270 node->set_block( maybeMutate( node->get_block(), *this ) ); 271 mutateAll( node->get_catchers(), *this ); 272 273 MUTATE_END( Statement, node ); 274 } 275 276 template< typename pass_type > 118 277 void PassVisitor< pass_type >::visit( CatchStmt * node ) { 119 278 VISIT_BODY( node ); … … 121 280 122 281 template< typename pass_type > 282 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { 283 MUTATE_START( node ); 284 285 node->set_body( mutateStatement( node->get_body() ) ); 286 node->set_decl( maybeMutate( node->get_decl(), *this ) ); 287 288 MUTATE_END( Statement, node ); 289 } 290 291 template< typename pass_type > 123 292 void PassVisitor< pass_type >::visit( FinallyStmt * node ) { 124 293 VISIT_BODY( node ); … … 151 320 152 321 template< typename pass_type > 322 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 323 MUTATE_START( node ); 324 325 for ( auto& expr : node->get_args() ) { 326 expr = mutateExpression( expr ); 327 } 328 329 MUTATE_END( Expression, node ); 330 } 331 332 template< typename pass_type > 153 333 void PassVisitor< pass_type >::visit( NameExpr * node ) { 154 334 VISIT_BODY( node ); … … 301 481 302 482 template< typename pass_type > 483 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 484 MUTATE_START( node ); 485 486 // don't want statements from outer CompoundStmts to be added to this StmtExpr 487 ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd ); 488 ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter ); 489 ValueGuard< TypeSubstitution * > oldEnv( env ); 490 491 // xxx - not sure if this is needed, along with appropriate reset, but I don't think so... 492 // ValueGuard< TyVarMap > oldScopeTyVars( scopeTyVars ); 493 494 stmtsToAdd.clear(); 495 stmtsToAddAfter.clear(); 496 // scopeTyVars.clear(); 497 498 Mutator::mutate( node ); 499 500 MUTATE_END( Expression, node ); 501 } 502 503 template< typename pass_type > 303 504 void PassVisitor< pass_type >::visit( UniqueExpr * node ) { 304 505 VISIT_BODY( node ); … … 388 589 void PassVisitor< pass_type >::visit( SingleInit * node ) { 389 590 VISIT_BODY( node ); 591 } 592 593 template< typename pass_type > 594 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { 595 MUTATE_START( node ); 596 597 node->set_value( mutateExpression( node->get_value() ) ); 598 599 MUTATE_END( Initializer, node ); 390 600 } 391 601 … … 458 668 459 669 template< typename pass_type > 460 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {461 MUTATE_BODY( CompoundStmt, node );462 }463 464 template< typename pass_type >465 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {466 MUTATE_BODY( Statement, node );467 }468 469 template< typename pass_type >470 670 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 471 671 MUTATE_BODY( Statement, node ); … … 473 673 474 674 template< typename pass_type > 475 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {476 MUTATE_BODY( Statement, node );477 }478 479 template< typename pass_type >480 Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {481 MUTATE_BODY( Statement, node );482 }483 484 template< typename pass_type >485 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {486 MUTATE_BODY( Statement, node );487 }488 489 template< typename pass_type >490 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {491 MUTATE_BODY( Statement, node );492 }493 494 template< typename pass_type >495 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {496 MUTATE_BODY( Statement, node );497 }498 499 template< typename pass_type >500 675 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 501 676 MUTATE_BODY( Statement, node ); … … 503 678 504 679 template< typename pass_type > 505 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {506 MUTATE_BODY( Statement, node );507 }508 509 template< typename pass_type >510 Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {511 MUTATE_BODY( Statement, node );512 }513 514 template< typename pass_type >515 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {516 MUTATE_BODY( Statement, node );517 }518 519 template< typename pass_type >520 680 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { 521 681 MUTATE_BODY( Statement, node ); … … 543 703 544 704 template< typename pass_type > 545 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {546 MUTATE_BODY( Expression, node );547 }548 549 template< typename pass_type >550 705 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) { 551 706 MUTATE_BODY( Expression, node ); … … 693 848 694 849 template< typename pass_type > 695 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {696 MUTATE_BODY( Expression, node );697 }698 699 template< typename pass_type >700 850 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { 701 851 MUTATE_BODY( Expression, node ); … … 780 930 Type * PassVisitor< pass_type >::mutate( OneType * node ) { 781 931 MUTATE_BODY( Type, node ); 782 }783 784 template< typename pass_type >785 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {786 MUTATE_BODY( Initializer, node );787 932 } 788 933
Note: See TracChangeset
for help on using the changeset viewer.