Changeset 046a890 for src/ControlStruct
- Timestamp:
- May 19, 2020, 5:31:20 PM (5 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:
- 918b90c
- Parents:
- 7d6e01d
- Location:
- src/ControlStruct
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
r7d6e01d r046a890 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 : Tue May 19 16:46:00 2020 13 // Update Count : 14 14 14 // 15 15 … … 64 64 } 65 65 66 class ExceptionMutatorCore : public WithGuards { 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 : public WithGuards { 67 185 enum Context { NoHandler, TerHandler, ResHandler }; 68 186 … … 82 200 83 201 // 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 202 CompoundStmt * take_try_block( TryStmt * tryStmt ); 91 203 FunctionDecl * create_try_wrapper( CompoundStmt * body ); … … 121 233 122 234 public: 123 ExceptionMutatorCore() :235 TryMutatorCore() : 124 236 cur_context( NoHandler ), 125 237 handler_except_decl( nullptr ), … … 138 250 }; 139 251 140 void ExceptionMutatorCore::init_func_types() {252 void TryMutatorCore::init_func_types() { 141 253 assert( except_decl ); 142 254 … … 196 308 } 197 309 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 310 // TryStmt Mutation Helpers 258 311 259 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {312 CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) { 260 313 CompoundStmt * block = tryStmt->get_block(); 261 314 tryStmt->set_block( nullptr ); … … 263 316 } 264 317 265 FunctionDecl * ExceptionMutatorCore::create_try_wrapper(318 FunctionDecl * TryMutatorCore::create_try_wrapper( 266 319 CompoundStmt *body ) { 267 320 … … 270 323 } 271 324 272 FunctionDecl * ExceptionMutatorCore::create_terminate_catch(325 FunctionDecl * TryMutatorCore::create_terminate_catch( 273 326 CatchList &handlers ) { 274 327 std::list<CaseStmt *> handler_wrappers; … … 350 403 // Create a single check from a moddified handler. 351 404 // except_obj is referenced, modded_handler will be freed. 352 CompoundStmt * ExceptionMutatorCore::create_single_matcher(405 CompoundStmt * TryMutatorCore::create_single_matcher( 353 406 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 354 407 // { … … 388 441 } 389 442 390 FunctionDecl * ExceptionMutatorCore::create_terminate_match(443 FunctionDecl * TryMutatorCore::create_terminate_match( 391 444 CatchList &handlers ) { 392 445 // int match(exception * except) { … … 425 478 } 426 479 427 CompoundStmt * ExceptionMutatorCore::create_terminate_caller(480 CompoundStmt * TryMutatorCore::create_terminate_caller( 428 481 FunctionDecl * try_wrapper, 429 482 FunctionDecl * terminate_catch, … … 443 496 } 444 497 445 FunctionDecl * ExceptionMutatorCore::create_resume_handler(498 FunctionDecl * TryMutatorCore::create_resume_handler( 446 499 CatchList &handlers ) { 447 500 // bool handle(exception * except) { … … 480 533 } 481 534 482 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(535 CompoundStmt * TryMutatorCore::create_resume_wrapper( 483 536 Statement * wraps, 484 537 FunctionDecl * resume_handler ) { … … 524 577 } 525 578 526 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(579 FunctionDecl * TryMutatorCore::create_finally_wrapper( 527 580 TryStmt * tryStmt ) { 528 581 // void finally() { <finally code> } … … 537 590 } 538 591 539 ObjectDecl * ExceptionMutatorCore::create_finally_hook(592 ObjectDecl * TryMutatorCore::create_finally_hook( 540 593 FunctionDecl * finally_wrapper ) { 541 594 // struct __cfaehm_cleanup_hook __finally_hook 542 // __attribute__((cleanup( finally_wrapper)));595 // __attribute__((cleanup( `finally_wrapper` ))); 543 596 544 597 // Make Cleanup Attribute. … … 565 618 566 619 // Visiting/Mutating Functions 567 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {620 void TryMutatorCore::premutate( CatchStmt *catchStmt ) { 568 621 // Validate the Statement's form. 569 ObjectDecl * decl = 570 dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 622 ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 571 623 if ( decl && true /* check decl->get_type() */ ) { 572 624 // Pass. … … 589 641 } 590 642 591 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {643 void TryMutatorCore::premutate( StructDecl *structDecl ) { 592 644 if ( !structDecl->has_body() ) { 593 645 // Skip children? … … 604 656 hook_decl = structDecl; 605 657 } 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 ) { 658 } 659 660 Statement * TryMutatorCore::postmutate( ThrowStmt * ) { 661 // All throws should be removed by this point. 662 assert( false ); 663 } 664 665 Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) { 637 666 assert( except_decl ); 638 667 assert( node_decl ); … … 688 717 } 689 718 690 void translate EHM( std::list< Declaration *> & translationUnit ) {691 PassVisitor< ExceptionMutatorCore> translator;719 void translateThrows( std::list< Declaration *> & translationUnit ) { 720 PassVisitor<ThrowMutatorCore> translator; 692 721 mutateAll( translationUnit, translator ); 693 722 } 723 724 void translateTries( std::list< Declaration *> & translationUnit ) { 725 PassVisitor<TryMutatorCore> translator; 726 mutateAll( translationUnit, translator ); 727 } 694 728 } -
src/ControlStruct/ExceptTranslate.h
r7d6e01d r046a890 9 9 // Author : Andrew Beach 10 10 // Created On : Tus Jun 06 10:13:00 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:19:23 201713 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus May 19 11:47:00 2020 13 // Update Count : 5 14 14 // 15 15 … … 21 21 22 22 namespace ControlStruct { 23 void translateEHM( std::list< Declaration *> & translationUnit ); 24 // Converts exception handling structures into their underlying C code. Translation does use the exception 25 // handling header, make sure it is visible wherever translation occurs. 23 void translateThrows( std::list< Declaration *> & translationUnit ); 24 /* Replaces all throw & throwResume statements with function calls. 25 * These still need to be resolved, so call this before the reslover. 26 */ 27 28 void translateTries( std::list< Declaration *> & translationUnit ); 29 /* Replaces all try blocks (and their many clauses) with function definitions and calls. 30 * This uses the exception built-ins to produce typed output and should take place after 31 * the resolver. 32 */ 26 33 } 27 34
Note: See TracChangeset
for help on using the changeset viewer.