Changeset 99fea48 for src/ControlStruct/ExceptTranslate.cc
- Timestamp:
- May 21, 2020, 5:06:35 PM (3 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:
- 0e4df2e, 7119daa
- Parents:
- 6f121b8 (diff), 66ba544 (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/ControlStruct/ExceptTranslate.cc
r6f121b8 r99fea48 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 27 11:58:00 202013 // Update Count : 1 312 // Last Modified On : Thr May 21 13:18:00 2020 13 // Update Count : 15 14 14 // 15 15 … … 64 64 } 65 65 66 class ExceptionMutatorCore : public WithGuards { 67 enum Context { NoHandler, TerHandler, ResHandler }; 68 69 // Also need to handle goto, break & continue. 70 // They need to be cut off in a ResHandler, until we enter another 71 // loop, switch or the goto stays within the function. 72 73 Context cur_context; 74 75 // The current (innermost) termination handler exception declaration. 76 ObjectDecl * handler_except_decl; 77 66 class ThrowMutatorCore : public WithGuards { 67 ObjectDecl * terminate_handler_except; 68 enum Context { NoHandler, TerHandler, ResHandler } cur_context; 69 70 // The helper functions for code/syntree generation. 71 Statement * create_either_throw( 72 ThrowStmt * throwStmt, const char * throwFunc ); 73 Statement * create_terminate_rethrow( ThrowStmt * throwStmt ); 74 Statement * create_resume_rethrow( ThrowStmt * throwStmt ); 75 76 public: 77 ThrowMutatorCore() : 78 terminate_handler_except( nullptr ), 79 cur_context( NoHandler ) 80 {} 81 82 void premutate( CatchStmt *catchStmt ); 83 Statement * postmutate( ThrowStmt *throwStmt ); 84 }; 85 86 // ThrowStmt Mutation Helpers 87 88 Statement * ThrowMutatorCore::create_either_throw( 89 ThrowStmt * throwStmt, const char * throwFunc ) { 90 // `throwFunc`( `throwStmt->get_name()` ); 91 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 92 call->get_args().push_back( throwStmt->get_expr() ); 93 throwStmt->set_expr( nullptr ); 94 delete throwStmt; 95 return new ExprStmt( call ); 96 } 97 98 Statement * ThrowMutatorCore::create_terminate_rethrow( 99 ThrowStmt *throwStmt ) { 100 // { `terminate_handler_except` = 0p; __rethrow_terminate(); } 101 assert( nullptr == throwStmt->get_expr() ); 102 assert( terminate_handler_except ); 103 104 CompoundStmt * result = new CompoundStmt(); 105 result->labels = throwStmt->labels; 106 result->push_back( new ExprStmt( UntypedExpr::createAssign( 107 nameOf( terminate_handler_except ), 108 new ConstantExpr( Constant::null( 109 //new PointerType( 110 // noQualifiers, 111 terminate_handler_except->get_type()->clone() 112 // ) 113 ) ) 114 ) ) ); 115 result->push_back( new ExprStmt( 116 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) ) 117 ) ); 118 delete throwStmt; 119 return result; 120 } 121 122 Statement * ThrowMutatorCore::create_resume_rethrow( 123 ThrowStmt *throwStmt ) { 124 // return false; 125 Statement * result = new ReturnStmt( 126 new ConstantExpr( Constant::from_bool( false ) ) 127 ); 128 result->labels = throwStmt->labels; 129 delete throwStmt; 130 return result; 131 } 132 133 // Visiting/Mutating Functions 134 135 void ThrowMutatorCore::premutate( CatchStmt *catchStmt ) { 136 // Validate the statement's form. 137 ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 138 // Also checking the type would be nice. 139 if ( decl ) { 140 // Pass. 141 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 142 SemanticError(catchStmt->location, "catch must have exception type"); 143 } else { 144 SemanticError(catchStmt->location, "catchResume must have exception type"); 145 } 146 147 // Track the handler context. 148 GuardValue( cur_context ); 149 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 150 cur_context = TerHandler; 151 152 GuardValue( terminate_handler_except ); 153 terminate_handler_except = decl; 154 } else { 155 cur_context = ResHandler; 156 } 157 } 158 159 Statement * ThrowMutatorCore::postmutate( ThrowStmt *throwStmt ) { 160 // Ignoring throwStmt->get_target() for now. 161 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 162 if ( throwStmt->get_expr() ) { 163 return create_either_throw( throwStmt, "$throw" ); 164 } else if ( TerHandler == cur_context ) { 165 return create_terminate_rethrow( throwStmt ); 166 } else { 167 abort("Invalid throw in %s at %i\n", 168 throwStmt->location.filename.c_str(), 169 throwStmt->location.first_line); 170 } 171 } else { 172 if ( throwStmt->get_expr() ) { 173 return create_either_throw( throwStmt, "$throwResume" ); 174 } else if ( ResHandler == cur_context ) { 175 return create_resume_rethrow( throwStmt ); 176 } else { 177 abort("Invalid throwResume in %s at %i\n", 178 throwStmt->location.filename.c_str(), 179 throwStmt->location.first_line); 180 } 181 } 182 } 183 184 class TryMutatorCore { 78 185 // The built in types used in translation. 79 186 StructDecl * except_decl; … … 82 189 83 190 // The many helper functions for code/syntree generation. 84 Statement * create_given_throw(85 const char * throwFunc, ThrowStmt * throwStmt );86 Statement * create_terminate_throw( ThrowStmt * throwStmt );87 Statement * create_terminate_rethrow( ThrowStmt * throwStmt );88 Statement * create_resume_throw( ThrowStmt * throwStmt );89 Statement * create_resume_rethrow( ThrowStmt * throwStmt );90 191 CompoundStmt * take_try_block( TryStmt * tryStmt ); 91 192 FunctionDecl * create_try_wrapper( CompoundStmt * body ); … … 121 222 122 223 public: 123 ExceptionMutatorCore() : 124 cur_context( NoHandler ), 125 handler_except_decl( nullptr ), 224 TryMutatorCore() : 126 225 except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ), 127 226 try_func_t( noQualifiers, false ), … … 132 231 {} 133 232 134 void premutate( CatchStmt *catchStmt );135 233 void premutate( StructDecl *structDecl ); 136 234 Statement * postmutate( ThrowStmt *throwStmt ); … … 138 236 }; 139 237 140 void ExceptionMutatorCore::init_func_types() {238 void TryMutatorCore::init_func_types() { 141 239 assert( except_decl ); 142 240 … … 196 294 } 197 295 198 // ThrowStmt Mutation Helpers199 200 Statement * ExceptionMutatorCore::create_given_throw(201 const char * throwFunc, ThrowStmt * throwStmt ) {202 // `throwFunc`( `throwStmt->get_name` );203 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );204 call->get_args().push_back( throwStmt->get_expr() );205 throwStmt->set_expr( nullptr );206 delete throwStmt;207 return new ExprStmt( call );208 }209 210 Statement * ExceptionMutatorCore::create_terminate_throw(211 ThrowStmt *throwStmt ) {212 // __throw_terminate( `throwStmt->get_name()` ); }213 return create_given_throw( "__cfaehm_throw_terminate", throwStmt );214 }215 216 Statement * ExceptionMutatorCore::create_terminate_rethrow(217 ThrowStmt *throwStmt ) {218 // { `handler_except_decl` = NULL; __rethrow_terminate(); }219 assert( nullptr == throwStmt->get_expr() );220 assert( handler_except_decl );221 222 CompoundStmt * result = new CompoundStmt();223 result->labels = throwStmt->labels;224 result->push_back( new ExprStmt( UntypedExpr::createAssign(225 nameOf( handler_except_decl ),226 new ConstantExpr( Constant::null(227 new PointerType(228 noQualifiers,229 handler_except_decl->get_type()->clone()230 )231 ) )232 ) ) );233 result->push_back( new ExprStmt(234 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )235 ) );236 delete throwStmt;237 return result;238 }239 240 Statement * ExceptionMutatorCore::create_resume_throw(241 ThrowStmt *throwStmt ) {242 // __throw_resume( `throwStmt->get_name` );243 return create_given_throw( "__cfaehm_throw_resume", throwStmt );244 }245 246 Statement * ExceptionMutatorCore::create_resume_rethrow(247 ThrowStmt *throwStmt ) {248 // return false;249 Statement * result = new ReturnStmt(250 new ConstantExpr( Constant::from_bool( false ) )251 );252 result->labels = throwStmt->labels;253 delete throwStmt;254 return result;255 }256 257 296 // TryStmt Mutation Helpers 258 297 259 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {298 CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) { 260 299 CompoundStmt * block = tryStmt->get_block(); 261 300 tryStmt->set_block( nullptr ); … … 263 302 } 264 303 265 FunctionDecl * ExceptionMutatorCore::create_try_wrapper(304 FunctionDecl * TryMutatorCore::create_try_wrapper( 266 305 CompoundStmt *body ) { 267 306 … … 270 309 } 271 310 272 FunctionDecl * ExceptionMutatorCore::create_terminate_catch(311 FunctionDecl * TryMutatorCore::create_terminate_catch( 273 312 CatchList &handlers ) { 274 313 std::list<CaseStmt *> handler_wrappers; … … 350 389 // Create a single check from a moddified handler. 351 390 // except_obj is referenced, modded_handler will be freed. 352 CompoundStmt * ExceptionMutatorCore::create_single_matcher(391 CompoundStmt * TryMutatorCore::create_single_matcher( 353 392 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 354 393 // { … … 388 427 } 389 428 390 FunctionDecl * ExceptionMutatorCore::create_terminate_match(429 FunctionDecl * TryMutatorCore::create_terminate_match( 391 430 CatchList &handlers ) { 392 431 // int match(exception * except) { … … 425 464 } 426 465 427 CompoundStmt * ExceptionMutatorCore::create_terminate_caller(466 CompoundStmt * TryMutatorCore::create_terminate_caller( 428 467 FunctionDecl * try_wrapper, 429 468 FunctionDecl * terminate_catch, … … 443 482 } 444 483 445 FunctionDecl * ExceptionMutatorCore::create_resume_handler(484 FunctionDecl * TryMutatorCore::create_resume_handler( 446 485 CatchList &handlers ) { 447 486 // bool handle(exception * except) { … … 480 519 } 481 520 482 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(521 CompoundStmt * TryMutatorCore::create_resume_wrapper( 483 522 Statement * wraps, 484 523 FunctionDecl * resume_handler ) { … … 524 563 } 525 564 526 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(565 FunctionDecl * TryMutatorCore::create_finally_wrapper( 527 566 TryStmt * tryStmt ) { 528 // void finally() { <finally code>}567 // void finally() { `finally->block` } 529 568 FinallyStmt * finally = tryStmt->get_finally(); 530 569 CompoundStmt * body = finally->get_block(); … … 537 576 } 538 577 539 ObjectDecl * ExceptionMutatorCore::create_finally_hook(578 ObjectDecl * TryMutatorCore::create_finally_hook( 540 579 FunctionDecl * finally_wrapper ) { 541 580 // struct __cfaehm_cleanup_hook __finally_hook 542 // __attribute__((cleanup( finally_wrapper)));581 // __attribute__((cleanup( `finally_wrapper` ))); 543 582 544 583 // Make Cleanup Attribute. … … 565 604 566 605 // Visiting/Mutating Functions 567 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 568 // Validate the Statement's form. 569 ObjectDecl * decl = 570 dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 571 if ( decl && true /* check decl->get_type() */ ) { 572 // Pass. 573 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 574 SemanticError(catchStmt->location, "catch must have exception type"); 575 } else { 576 SemanticError(catchStmt->location, "catchResume must have exception type"); 577 } 578 579 // Track the handler context. 580 GuardValue( cur_context ); 581 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 582 cur_context = TerHandler; 583 584 GuardValue( handler_except_decl ); 585 handler_except_decl = decl; 586 } else { 587 cur_context = ResHandler; 588 } 589 } 590 591 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 606 void TryMutatorCore::premutate( StructDecl *structDecl ) { 592 607 if ( !structDecl->has_body() ) { 593 608 // Skip children? … … 604 619 hook_decl = structDecl; 605 620 } 606 // Later we might get the exception type as well. 607 } 608 609 Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) { 610 assert( except_decl ); 611 612 // Ignoring throwStmt->get_target() for now. 613 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 614 if ( throwStmt->get_expr() ) { 615 return create_terminate_throw( throwStmt ); 616 } else if ( TerHandler == cur_context ) { 617 return create_terminate_rethrow( throwStmt ); 618 } else { 619 abort("Invalid throw in %s at %i\n", 620 throwStmt->location.filename.c_str(), 621 throwStmt->location.first_line); 622 } 623 } else { 624 if ( throwStmt->get_expr() ) { 625 return create_resume_throw( throwStmt ); 626 } else if ( ResHandler == cur_context ) { 627 return create_resume_rethrow( throwStmt ); 628 } else { 629 abort("Invalid throwResume in %s at %i\n", 630 throwStmt->location.filename.c_str(), 631 throwStmt->location.first_line); 632 } 633 } 634 } 635 636 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 621 } 622 623 Statement * TryMutatorCore::postmutate( ThrowStmt * ) { 624 // All throws should be removed by this point. 625 assert( false ); 626 } 627 628 Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) { 637 629 assert( except_decl ); 638 630 assert( node_decl ); … … 688 680 } 689 681 690 void translate EHM( std::list< Declaration *> & translationUnit ) {691 PassVisitor< ExceptionMutatorCore> translator;682 void translateThrows( std::list< Declaration *> & translationUnit ) { 683 PassVisitor<ThrowMutatorCore> translator; 692 684 mutateAll( translationUnit, translator ); 693 685 } 686 687 void translateTries( std::list< Declaration *> & translationUnit ) { 688 PassVisitor<TryMutatorCore> translator; 689 mutateAll( translationUnit, translator ); 690 } 694 691 }
Note: See TracChangeset
for help on using the changeset viewer.