Changeset 67fa9f9 for src/ControlStruct/ExceptTranslate.cc
- Timestamp:
- Jul 5, 2017, 10:50:22 AM (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:
- 0614d14
- Parents:
- 11dbfe1 (diff), 307a732 (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
r11dbfe1 r67fa9f9 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 22 15:57:00 201713 // Update Count : 012 // Last Modified On : Fri Jun 30 13:30:00 2017 13 // Update Count : 1 14 14 // 15 15 16 16 #include "ExceptTranslate.h" 17 17 #include "Common/PassVisitor.h" 18 19 namespace ControlFlow { 18 #include "SynTree/Statement.h" 19 #include "SynTree/Declaration.h" 20 #include "SynTree/Expression.h" 21 #include "SynTree/Type.h" 22 #include "SynTree/Attribute.h" 23 24 namespace ControlStruct { 20 25 21 26 // This (large) section could probably be moved out of the class … … 24 29 // Type(Qualifiers &, false, std::list<Attribute *> &) 25 30 26 // void (*function)() 27 static FunctionType void_func_t(Type::Qualifiers(), false);31 // void (*function)(); 32 static FunctionType try_func_t(Type::Qualifiers(), false); 28 33 // void (*function)(int, exception); 29 34 static FunctionType catch_func_t(Type::Qualifiers(), false); … … 32 37 // bool (*function)(exception); 33 38 static FunctionType handle_func_t(Type::Qualifiers(), false); 39 // void (*function)(__attribute__((unused)) void *); 40 static FunctionType finally_func_t(Type::Qualifiers(), false); 34 41 35 42 static void init_func_types() { 36 static init_complete = false;43 static bool init_complete = false; 37 44 if (init_complete) { 38 45 return; 39 46 } 40 47 ObjectDecl index_obj( 41 " index_t",48 "__handler_index", 42 49 Type::StorageClasses(), 43 50 LinkageSpec::Cforall, 44 51 /*bitfieldWidth*/ NULL, 45 new BasicType( emptyQualifiers, BasicType::UnsignedInt),52 new BasicType( emptyQualifiers, BasicType::SignedInt ), 46 53 /*init*/ NULL 47 );54 ); 48 55 ObjectDecl exception_obj( 49 " exception_t",56 "__exception_inst", 50 57 Type::StorageClasses(), 51 58 LinkageSpec::Cforall, 52 59 /*bitfieldWidth*/ NULL, 53 new BasicType(emptyQualifiers, BasicType::UnsignedInt), 60 new PointerType( 61 emptyQualifiers, 62 new BasicType( emptyQualifiers, BasicType::SignedInt ) 63 ), 54 64 /*init*/ NULL 55 );65 ); 56 66 ObjectDecl bool_obj( 57 " bool_t",67 "__ret_bool", 58 68 Type::StorageClasses(), 59 69 LinkageSpec::Cforall, … … 61 71 new BasicType(emptyQualifiers, BasicType::Bool), 62 72 /*init*/ NULL 63 ); 64 65 catch_func_t.get_parameters().push_back(index_obj.clone()); 66 catch_func_t.get_parameters().push_back(exception_obj.clone()); 67 match_func_t.get_returnVals().push_back(index_obj.clone()); 68 match_func_t.get_parameters().push_back(exception_obj.clone()); 69 handle_func_t.get_returnVals().push_back(bool_obj.clone()); 70 handle_func_t.get_parameters().push_back(exception_obj.clone()); 73 ); 74 ObjectDecl voidptr_obj( 75 "__hook", 76 Type::StorageClasses(), 77 LinkageSpec::Cforall, 78 NULL, 79 new PointerType( 80 emptyQualifiers, 81 new VoidType( 82 emptyQualifiers 83 ), 84 std::list<Attribute *>{new Attribute("unused")} 85 ), 86 NULL 87 ); 88 89 catch_func_t.get_parameters().push_back( index_obj.clone() ); 90 catch_func_t.get_parameters().push_back( exception_obj.clone() ); 91 match_func_t.get_returnVals().push_back( index_obj.clone() ); 92 match_func_t.get_parameters().push_back( exception_obj.clone() ); 93 handle_func_t.get_returnVals().push_back( bool_obj.clone() ); 94 handle_func_t.get_parameters().push_back( exception_obj.clone() ); 95 finally_func_t.get_parameters().push_back( voidptr_obj.clone() ); 71 96 72 97 init_complete = true; … … 78 103 79 104 void split( CatchList& allHandlers, CatchList& terHandlers, 80 105 CatchList& resHandlers ) { 81 106 while ( !allHandlers.empty() ) { 82 Statement * stmt = allHandlers.front();107 CatchStmt * stmt = allHandlers.front(); 83 108 allHandlers.pop_front(); 84 if (Ca seStmt::Terminate == stmt->get_kind()) {109 if (CatchStmt::Terminate == stmt->get_kind()) { 85 110 terHandlers.push_back(stmt); 86 111 } else { … … 92 117 template<typename T> 93 118 void free_all( std::list<T *> &list ) { 94 std::list<T *>::iterator it;119 typename std::list<T *>::iterator it; 95 120 for ( it = list.begin() ; it != list.end() ; ++it ) { 96 121 delete *it; … … 100 125 101 126 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 102 block->push_back(new DeclStmt(no _labels, item));103 } 104 105 Expression * nameOf( FunctionDecl * function) {106 return new VariableExpr( function);127 block->push_back(new DeclStmt(noLabels, item)); 128 } 129 130 Expression * nameOf( DeclarationWithType * decl ) { 131 return new VariableExpr( decl ); 107 132 } 108 133 109 134 // ThrowStmt Mutation Helpers 110 135 111 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 112 // __throw_terminate( EXPR ); 113 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 114 call->get_args.push_back( throwStmt->get_expr() ); 115 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 136 Statement * create_given_throw( 137 const char * throwFunc, ThrowStmt * throwStmt ) { 138 // { int NAME = EXPR; throwFunc( &NAME ); } 139 CompoundStmt * result = new CompoundStmt( noLabels ); 140 ObjectDecl * local = new ObjectDecl( 141 "__local_exception_copy", 142 Type::StorageClasses(), 143 LinkageSpec::Cforall, 144 NULL, 145 new BasicType( emptyQualifiers, BasicType::SignedInt ), 146 new SingleInit( throwStmt->get_expr() ) 147 ); 148 appendDeclStmt( result, local ); 149 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 150 call->get_args().push_back( new AddressExpr( nameOf( local ) ) ); 151 result->push_back( new ExprStmt( throwStmt->get_labels(), call ) ); 116 152 throwStmt->set_expr( nullptr ); 117 153 delete throwStmt; 118 154 return result; 119 155 } 156 157 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 158 // { int NAME = EXPR; __throw_terminate( &NAME ); } 159 return create_given_throw( "__cfaehm__throw_termination", throwStmt ); 160 } 120 161 Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) { 121 162 // __rethrow_terminate(); 163 assert( nullptr == throwStmt->get_expr() ); 122 164 Statement * result = new ExprStmt( 123 165 throwStmt->get_labels(), 124 new ApplicationExpr( /* ... */ );166 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) ) 125 167 ); 126 168 delete throwStmt; … … 129 171 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 130 172 // __throw_resume( EXPR ); 131 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 132 call->get_args.push_back( throwStmt->get_expr() ); 133 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 134 throwStmt->set_expr( nullptr ); 135 delete throwStmt; 136 return result; 173 return create_given_throw( "__cfaehm__throw_resumption", throwStmt ); 137 174 } 138 175 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { … … 140 177 Statement * result = new ReturnStmt( 141 178 throwStmt->get_labels(), 142 new ConstantExpr( 143 Constant( 144 new BasicType( 145 Type::Qualifiers(), 146 BasicType::Bool 147 ), 148 "0") 149 ) 179 new ConstantExpr( Constant::from_bool( false ) ) 150 180 ); 151 181 delete throwStmt; … … 160 190 return block; 161 191 } 162 FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) { 163 CompoundStmt * body = base_try->get_block(); 164 base_try->set_block(nullptr); 165 166 return new FunctionDecl("try", Type::StorageClasses(), 167 LinkageSpec::Cforall, void_func_t, body); 192 FunctionDecl * create_try_wrapper( CompoundStmt *body ) { 193 194 return new FunctionDecl( "try", Type::StorageClasses(), 195 LinkageSpec::Cforall, try_func_t.clone(), body ); 168 196 } 169 197 170 198 FunctionDecl * create_terminate_catch( CatchList &handlers ) { 171 199 std::list<CaseStmt *> handler_wrappers; 200 201 FunctionType *func_type = catch_func_t.clone(); 202 DeclarationWithType * index_obj = func_type->get_parameters().front(); 203 // DeclarationWithType * except_obj = func_type->get_parameters().back(); 172 204 173 205 // Index 1..{number of handlers} … … 178 210 CatchStmt * handler = *it; 179 211 180 std::list<Statement *> core; 181 if ( /*the exception is named*/ ) { 182 ObjectDecl * local_except = /* Dynamic case, same */; 183 core->push_back( new DeclStmt( noLabel, local_except ) ); 184 } 185 // Append the provided statement to the handler. 186 core->push_back( cur_handler->get_body() ); 187 // Append return onto the inner block? case stmt list? 188 CaseStmt * wrapper = new CaseStmt( 212 // INTEGERconstant Version 213 // case `index`: 214 // { 215 // `handler.body` 216 // } 217 // return; 218 std::list<Statement *> caseBody; 219 caseBody.push_back( handler->get_body() ); 220 handler->set_body( nullptr ); 221 caseBody.push_back( new ReturnStmt( noLabels, nullptr ) ); 222 223 handler_wrappers.push_back( new CaseStmt( 189 224 noLabels, 190 225 new ConstantExpr( Constant::from_int( index ) ), 191 core 192 ); 193 handler_wrappers.push_back(wrapper); 226 caseBody 227 ) ); 194 228 } 195 229 // TODO: Some sort of meaningful error on default perhaps? 230 231 std::list<Statement*> stmt_handlers; 232 while ( !handler_wrappers.empty() ) { 233 stmt_handlers.push_back( handler_wrappers.front() ); 234 handler_wrappers.pop_front(); 235 } 196 236 197 237 SwitchStmt * handler_lookup = new SwitchStmt( 198 238 noLabels, 199 /*parameter 0: index*/, 200 handler_wrappers, 201 false 239 nameOf( index_obj ), 240 stmt_handlers 202 241 ); 203 242 CompoundStmt * body = new CompoundStmt( noLabels ); … … 205 244 206 245 return new FunctionDecl("catch", Type::StorageClasses(), 207 LinkageSpec::Cforall, catch_func_t, body);246 LinkageSpec::Cforall, func_type, body); 208 247 } 209 248 210 249 // Create a single check from a moddified handler. 211 CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) { 212 CompoundStmt * block = new CompoundStmt( noLables ); 213 214 appendDeclStmt( block, modded_handler->get_decl() ); 215 216 // TODO: This is not the actual check. 217 LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) ); 250 // except_obj is referenced, modded_handler will be freed. 251 CompoundStmt *create_single_matcher( 252 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 253 CompoundStmt * block = new CompoundStmt( noLabels ); 254 255 // INTEGERconstant Version 256 assert( nullptr == modded_handler->get_decl() ); 257 ConstantExpr * number = 258 dynamic_cast<ConstantExpr*>( modded_handler->get_cond() ); 259 assert( number ); 260 modded_handler->set_cond( nullptr ); 261 262 Expression * cond; 263 { 264 std::list<Expression *> args; 265 args.push_back( number ); 266 267 std::list<Expression *> rhs_args; 268 rhs_args.push_back( nameOf( except_obj ) ); 269 Expression * rhs = new UntypedExpr( 270 new NameExpr( "*?" ), rhs_args ); 271 args.push_back( rhs ); 272 273 cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args ); 274 } 218 275 219 276 if ( modded_handler->get_cond() ) { 220 cond = new LogicalExpr( cond, modded_handler->get_cond() ) q277 cond = new LogicalExpr( cond, modded_handler->get_cond() ); 221 278 } 222 279 block->push_back( new IfStmt( noLabels, 223 cond, modded_handler->get_body() );280 cond, modded_handler->get_body(), nullptr ) ); 224 281 225 282 modded_handler->set_decl( nullptr ); … … 232 289 FunctionDecl * create_terminate_match( CatchList &handlers ) { 233 290 CompoundStmt * body = new CompoundStmt( noLabels ); 291 292 FunctionType * func_type = match_func_t.clone(); 293 DeclarationWithType * except_obj = func_type->get_parameters().back(); 234 294 235 295 // Index 1..{number of handlers} … … 240 300 CatchStmt * handler = *it; 241 301 242 // body should have been taken by create_terminate_catch. 243 // assert( nullptr == handler->get_body() ); 302 // Body should have been taken by create_terminate_catch. 303 assert( nullptr == handler->get_body() ); 304 305 // Create new body. 244 306 handler->set_body( new ReturnStmt( noLabels, 245 307 new ConstantExpr( Constant::from_int( index ) ) ) ); 246 308 247 body->push_back( create_single_matcher( handler ) ); 248 } 309 // Create the handler. 310 body->push_back( create_single_matcher( except_obj, handler ) ); 311 *it = nullptr; 312 } 313 314 body->push_back( new ReturnStmt( noLabels, new ConstantExpr( 315 Constant::from_int( 0 ) ) ) ); 249 316 250 317 return new FunctionDecl("match", Type::StorageClasses(), 251 LinkageSpec::Cforall, match_func_t, body);252 } 253 254 Statement * create_terminate_caller(318 LinkageSpec::Cforall, func_type, body); 319 } 320 321 CompoundStmt * create_terminate_caller( 255 322 FunctionDecl * try_wrapper, 256 323 FunctionDecl * terminate_catch, 257 324 FunctionDecl * terminate_match) { 258 325 259 ApplicationExpr * caller = new ApplicationExpr( /* ... */ ); 260 std::list<Expression *>& args = caller.get_args(); 326 UntypedExpr * caller = new UntypedExpr( new NameExpr( 327 "__cfaehm__try_terminate" ) ); 328 std::list<Expression *>& args = caller->get_args(); 261 329 args.push_back( nameOf( try_wrapper ) ); 262 330 args.push_back( nameOf( terminate_catch ) ); 263 331 args.push_back( nameOf( terminate_match ) ); 264 332 265 return new ExprStmt( noLabels, caller ); 333 CompoundStmt * callStmt = new CompoundStmt( noLabels ); 334 callStmt->push_back( new ExprStmt( noLabels, caller ) ); 335 return callStmt; 266 336 } 267 337 268 338 FunctionDecl * create_resume_handler( CatchList &handlers ) { 269 CompoundStmt * body = new CompountStmt( noLabels ); 339 CompoundStmt * body = new CompoundStmt( noLabels ); 340 341 FunctionType * func_type = match_func_t.clone(); 342 DeclarationWithType * except_obj = func_type->get_parameters().back(); 270 343 271 344 CatchList::iterator it; … … 280 353 handling_code->push_back( handler->get_body() ); 281 354 } 282 handling_code->push_back( new ReturnStmt( noLabel ,355 handling_code->push_back( new ReturnStmt( noLabels, 283 356 new ConstantExpr( Constant::from_bool( false ) ) ) ); 284 357 handler->set_body( handling_code ); 285 358 286 359 // Create the handler. 287 body->push_back( create_single_matcher( handler ) ); 360 body->push_back( create_single_matcher( except_obj, handler ) ); 361 *it = nullptr; 288 362 } 289 363 290 364 return new FunctionDecl("handle", Type::StorageClasses(), 291 LinkageSpec::Cforall, handle_func_t, body); 292 } 293 294 Statement * create_resume_wrapper( 365 LinkageSpec::Cforall, func_type, body); 366 } 367 368 CompoundStmt * create_resume_wrapper( 369 StructDecl * node_decl, 295 370 Statement * wraps, 296 371 FunctionDecl * resume_handler ) { 297 372 CompoundStmt * body = new CompoundStmt( noLabels ); 298 373 299 // struct node = {current top resume handler, call to resume_handler}; 300 // __attribute__((cleanup( ... ))); 301 // set top resume handler to node. 302 // The wrapped statement. 303 304 ListInit * node_init; 305 { 306 std::list<Initializer*> field_inits; 307 field_inits.push_back( new SingleInit( /* ... */ ) ); 308 field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) ); 309 node_init = new ListInit( field_inits ); 310 } 374 // struct __try_resume_node __resume_node 375 // __attribute__((cleanup( __cfaehm__try_resume_cleanup ))); 376 // ** unwinding of the stack here could cause problems ** 377 // ** however I don't think that can happen currently ** 378 // __cfaehm__try_resume_setup( &__resume_node, resume_handler ); 311 379 312 380 std::list< Attribute * > attributes; 313 381 { 314 382 std::list< Expression * > attr_params; 315 attr_params.push_back( n ameOf( /* ... deconstructor ... */ ) );316 attrributes.push_back( new Attribute( "cleanup", attr_params) );317 }318 319 appendDeclStmt( body, 320 /**/ObjectDecl(321 " resume_node",383 attr_params.push_back( new NameExpr( 384 "__cfaehm__try_resume_cleanup" ) ); 385 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 386 } 387 388 ObjectDecl * obj = new ObjectDecl( 389 "__resume_node", 322 390 Type::StorageClasses(), 323 391 LinkageSpec::Cforall, 324 392 nullptr, 325 /* Type* = resume_node */, 326 node_init, 393 new StructInstType( 394 Type::Qualifiers(), 395 node_decl 396 ), 397 nullptr, 327 398 attributes 328 ) 329 ); 399 ); 400 appendDeclStmt( body, obj ); 401 402 UntypedExpr *setup = new UntypedExpr( new NameExpr( 403 "__cfaehm__try_resume_setup" ) ); 404 setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) ); 405 setup->get_args().push_back( nameOf( resume_handler ) ); 406 407 body->push_back( new ExprStmt( noLabels, setup ) ); 408 330 409 body->push_back( wraps ); 331 410 return body; … … 333 412 334 413 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 335 CompoundStmt * body = tryStmt->get_finally(); 414 FinallyStmt * finally = tryStmt->get_finally(); 415 CompoundStmt * body = finally->get_block(); 416 finally->set_block( nullptr ); 417 delete finally; 336 418 tryStmt->set_finally( nullptr ); 337 419 338 420 return new FunctionDecl("finally", Type::StorageClasses(), 339 LinkageSpec::Cforall, void_func_t, body); 340 } 341 342 ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) { 343 // struct _cleanup_hook NAME __attribute__((cleanup( ... ))); 421 LinkageSpec::Cforall, finally_func_t.clone(), body); 422 } 423 424 ObjectDecl * create_finally_hook( 425 StructDecl * hook_decl, FunctionDecl * finally_wrapper ) { 426 // struct __cfaehm__cleanup_hook __finally_hook 427 // __attribute__((cleanup( finally_wrapper ))); 344 428 345 429 // Make Cleanup Attribute. … … 348 432 std::list< Expression * > attr_params; 349 433 attr_params.push_back( nameOf( finally_wrapper ) ); 350 attr ributes.push_back( new Attribute( "cleanup", attr_params ) );351 } 352 353 return ObjectDecl( /* ... */354 const std::string &name "finally_hook",434 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 435 } 436 437 return new ObjectDecl( 438 "__finally_hook", 355 439 Type::StorageClasses(), 356 440 LinkageSpec::Cforall, 357 441 nullptr, 358 /* ... Type * ... */, 442 new StructInstType( 443 emptyQualifiers, 444 hook_decl 445 ), 359 446 nullptr, 360 447 attributes … … 363 450 364 451 365 class ExceptionMutatorCore : public With Scoping{452 class ExceptionMutatorCore : public WithGuards { 366 453 enum Context { NoHandler, TerHandler, ResHandler }; 367 454 … … 370 457 // loop, switch or the goto stays within the function. 371 458 372 Context cur Context;459 Context cur_context; 373 460 374 461 // We might not need this, but a unique base for each try block's … … 377 464 //unsigned int try_count = 0; 378 465 466 StructDecl *node_decl; 467 StructDecl *hook_decl; 379 468 380 469 public: 381 470 ExceptionMutatorCore() : 382 curContext(NoHandler) 471 cur_context(NoHandler), 472 node_decl(nullptr), hook_decl(nullptr) 383 473 {} 384 474 385 void premutate( CatchStmt *tryStmt ); 475 void premutate( CatchStmt *catchStmt ); 476 void premutate( StructDecl *structDecl ); 386 477 Statement * postmutate( ThrowStmt *throwStmt ); 387 478 Statement * postmutate( TryStmt *tryStmt ); … … 393 484 if ( throwStmt->get_expr() ) { 394 485 return create_terminate_throw( throwStmt ); 395 } else if ( TerHandler == cur Context ) {486 } else if ( TerHandler == cur_context ) { 396 487 return create_terminate_rethrow( throwStmt ); 397 488 } else { 398 489 assertf(false, "Invalid throw in %s at %i\n", 399 throwStmt->location.filename ,490 throwStmt->location.filename.c_str(), 400 491 throwStmt->location.linenumber); 401 492 return nullptr; … … 404 495 if ( throwStmt->get_expr() ) { 405 496 return create_resume_throw( throwStmt ); 406 } else if ( ResHandler == cur Context ) {497 } else if ( ResHandler == cur_context ) { 407 498 return create_resume_rethrow( throwStmt ); 408 499 } else { 409 500 assertf(false, "Invalid throwResume in %s at %i\n", 410 throwStmt->location.filename ,501 throwStmt->location.filename.c_str(), 411 502 throwStmt->location.linenumber); 412 503 return nullptr; … … 416 507 417 508 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 509 assert( node_decl ); 510 assert( hook_decl ); 511 418 512 // Generate a prefix for the function names? 419 513 420 CompoundStmt * block = new CompoundStmt( );421 Statement * inner = take_try_block( tryStmt );514 CompoundStmt * block = new CompoundStmt( noLabels ); 515 CompoundStmt * inner = take_try_block( tryStmt ); 422 516 423 517 if ( tryStmt->get_finally() ) { … … 427 521 appendDeclStmt( block, finally_block ); 428 522 // Create and add the finally cleanup hook. 429 appendDeclStmt( block, create_finally_hook( finally_block ) ); 430 } 431 432 StatementList termination_handlers; 433 StatementList resumption_handlers; 434 split( tryStmt->get_handlers(), 435 termination_handlers, resumption_handlers ); 436 437 if ( resumeption_handlers.size() ) { 523 appendDeclStmt( block, 524 create_finally_hook( hook_decl, finally_block ) ); 525 } 526 527 CatchList termination_handlers; 528 CatchList resumption_handlers; 529 split( tryStmt->get_catchers(), 530 termination_handlers, resumption_handlers ); 531 532 if ( resumption_handlers.size() ) { 438 533 // Define the helper function. 439 534 FunctionDecl * resume_handler = … … 441 536 appendDeclStmt( block, resume_handler ); 442 537 // Prepare hooks 443 inner = create_resume_wrapper( inner, resume_handler );538 inner = create_resume_wrapper( node_decl, inner, resume_handler ); 444 539 } 445 540 … … 462 557 block->push_back( inner ); 463 558 464 free_all( termination_handlers );465 free_all( resumption_handlers );559 //free_all( termination_handlers ); 560 //free_all( resumption_handlers ); 466 561 467 562 return block; … … 469 564 470 565 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 471 GuardValue( cur Context );472 if ( CatchStmt::Terminat ion== catchStmt->get_kind() ) {473 cur Context = TerHandler;566 GuardValue( cur_context ); 567 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 568 cur_context = TerHandler; 474 569 } else { 475 curContext = ResHandler; 476 } 477 } 478 479 void translateEHM( std::list< Declaration *> & translationUnit ) { 570 cur_context = ResHandler; 571 } 572 } 573 574 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 575 if ( !structDecl->has_body() ) { 576 // Skip children? 577 return; 578 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) { 579 assert( nullptr == node_decl ); 580 node_decl = structDecl; 581 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) { 582 assert( nullptr == hook_decl ); 583 hook_decl = structDecl; 584 } 585 // Later we might get the exception type as well. 586 } 587 588 void translateEHM( std::list< Declaration *> & translationUnit ) { 589 init_func_types(); 590 480 591 PassVisitor<ExceptionMutatorCore> translator; 481 592 for ( Declaration * decl : translationUnit ) { 482 decl-> mutate( translator );593 decl->acceptMutator( translator ); 483 594 } 484 595 }
Note: See TracChangeset
for help on using the changeset viewer.