Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    rac10576 rba912706  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 18 10:09:00 2017
    13 // Update Count     : 4
     12// Last Modified On : Thr Jun 22 15:57:00 2017
     13// Update Count     : 0
    1414//
    1515
    1616#include "ExceptTranslate.h"
    1717#include "Common/PassVisitor.h"
    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 {
     18
     19namespace ControlFlow {
    2520
    2621        // This (large) section could probably be moved out of the class
     
    2924        // Type(Qualifiers &, false, std::list<Attribute *> &)
    3025
    31         // void (*function)();
    32         static FunctionType try_func_t(Type::Qualifiers(), false);
     26        // void (*function)()
     27        static FunctionType void_func_t(Type::Qualifiers(), false);
    3328        // void (*function)(int, exception);
    3429        static FunctionType catch_func_t(Type::Qualifiers(), false);
     
    3732        // bool (*function)(exception);
    3833        static FunctionType handle_func_t(Type::Qualifiers(), false);
    39         // void (*function)(__attribute__((unused)) void *);
    40         static FunctionType finally_func_t(Type::Qualifiers(), false);
    4134
    4235        static void init_func_types() {
    43                 static bool init_complete = false;
     36                static init_complete = false;
    4437                if (init_complete) {
    4538                        return;
    4639                }
    4740                ObjectDecl index_obj(
    48                         "__handler_index",
     41                        "index_t",
    4942                        Type::StorageClasses(),
    5043                        LinkageSpec::Cforall,
    5144                        /*bitfieldWidth*/ NULL,
    52                         new BasicType( noQualifiers, BasicType::SignedInt ),
     45                        new BasicType(emptyQualifiers, BasicType::UnsignedInt),
    5346                        /*init*/ NULL
    54                         );
     47                );
    5548                ObjectDecl exception_obj(
    56                         "__exception_inst",
     49                        "exception_t",
    5750                        Type::StorageClasses(),
    5851                        LinkageSpec::Cforall,
    5952                        /*bitfieldWidth*/ NULL,
    60                         new PointerType(
    61                                 noQualifiers,
    62                                 new BasicType( noQualifiers, BasicType::SignedInt )
    63                                 ),
     53                        new BasicType(emptyQualifiers, BasicType::UnsignedInt),
    6454                        /*init*/ NULL
    65                         );
     55                );
    6656                ObjectDecl bool_obj(
    67                         "__ret_bool",
     57                        "bool_t",
    6858                        Type::StorageClasses(),
    6959                        LinkageSpec::Cforall,
    7060                        /*bitfieldWidth*/ NULL,
    71                         new BasicType(noQualifiers, BasicType::Bool),
     61                        new BasicType(emptyQualifiers, BasicType::Bool),
    7262                        /*init*/ NULL
    73                         );
    74                 ObjectDecl voidptr_obj(
    75                         "__hook",
    76                         Type::StorageClasses(),
    77                         LinkageSpec::Cforall,
    78                         NULL,
    79                         new PointerType(
    80                                 noQualifiers,
    81                                 new VoidType(
    82                                         noQualifiers
    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() );
     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());
    9671
    9772                init_complete = true;
     
    10378
    10479        void split( CatchList& allHandlers, CatchList& terHandlers,
    105                                 CatchList& resHandlers ) {
     80                    CatchList& resHandlers ) {
    10681                while ( !allHandlers.empty() ) {
    107                         CatchStmt * stmt = allHandlers.front();
     82                        Statement * stmt = allHandlers.front();
    10883                        allHandlers.pop_front();
    109                         if (CatchStmt::Terminate == stmt->get_kind()) {
     84                        if (CaseStmt::Terminate == stmt->get_kind()) {
    11085                                terHandlers.push_back(stmt);
    11186                        } else {
     
    11792        template<typename T>
    11893        void free_all( std::list<T *> &list ) {
    119                 typename std::list<T *>::iterator it;
     94                std::list<T *>::iterator it;
    12095                for ( it = list.begin() ; it != list.end() ; ++it ) {
    12196                        delete *it;
     
    125100
    126101        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    127                 block->push_back(new DeclStmt(noLabels, item));
    128         }
    129 
    130         Expression * nameOf( DeclarationWithType * decl ) {
    131                 return new VariableExpr( decl );
     102                block->push_back(new DeclStmt(no_labels, item));
     103        }
     104
     105        Expression * nameOf( FunctionDecl * function ) {
     106                return new VariableExpr( function );
    132107        }
    133108
    134109        // ThrowStmt Mutation Helpers
    135110
    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( noQualifiers, 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 ) );
     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 );
    152116                throwStmt->set_expr( nullptr );
    153117                delete throwStmt;
    154118                return result;
    155119        }
    156 
    157         Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    158                 // { int NAME = EXPR; __throw_terminate( &NAME ); }
    159                 return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    160         }
    161120        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
    162121                // __rethrow_terminate();
    163                 assert( nullptr == throwStmt->get_expr() );
    164122                Statement * result = new ExprStmt(
    165123                        throwStmt->get_labels(),
    166                         new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
     124                        new ApplicationExpr( /* ... */ );
    167125                        );
    168126                delete throwStmt;
     
    171129        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    172130                // __throw_resume( EXPR );
    173                 return create_given_throw( "__cfaehm__throw_resume", throwStmt );
     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;
    174137        }
    175138        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     
    177140                Statement * result = new ReturnStmt(
    178141                        throwStmt->get_labels(),
    179                         new ConstantExpr( Constant::from_bool( false ) )
     142                        new ConstantExpr(
     143                                Constant(
     144                                        new BasicType(
     145                                                Type::Qualifiers(),
     146                                                BasicType::Bool
     147                                                ),
     148                                        "0")
     149                                )
    180150                        );
    181151                delete throwStmt;
     
    190160                return block;
    191161        }
    192         FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
    193 
    194                 return new FunctionDecl( "try", Type::StorageClasses(),
    195                         LinkageSpec::Cforall, try_func_t.clone(), body );
     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);
    196168        }
    197169
    198170        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    199171                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();
    204172
    205173                // Index 1..{number of handlers}
     
    210178                        CatchStmt * handler = *it;
    211179
    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(
     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(
    224189                                noLabels,
    225190                                new ConstantExpr( Constant::from_int( index ) ),
    226                                 caseBody
    227                                 ) );
     191                                core
     192                                );
     193                        handler_wrappers.push_back(wrapper);
    228194                }
    229195                // 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                 }
    236196
    237197                SwitchStmt * handler_lookup = new SwitchStmt(
    238198                        noLabels,
    239                         nameOf( index_obj ),
    240                         stmt_handlers
     199                        /*parameter 0: index*/,
     200                        handler_wrappers,
     201                        false
    241202                        );
    242203                CompoundStmt * body = new CompoundStmt( noLabels );
     
    244205
    245206                return new FunctionDecl("catch", Type::StorageClasses(),
    246                         LinkageSpec::Cforall, func_type, body);
     207                        LinkageSpec::Cforall, catch_func_t, body);
    247208        }
    248209
    249210        // Create a single check from a moddified handler.
    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                 }
     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 ) );
    275218
    276219                if ( modded_handler->get_cond() ) {
    277                         cond = new LogicalExpr( cond, modded_handler->get_cond() );
     220                        cond = new LogicalExpr( cond, modded_handler->get_cond() )q
    278221                }
    279222                block->push_back( new IfStmt( noLabels,
    280                         cond, modded_handler->get_body(), nullptr ) );
     223                        cond, modded_handler->get_body() );
    281224
    282225                modded_handler->set_decl( nullptr );
     
    289232        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    290233                CompoundStmt * body = new CompoundStmt( noLabels );
    291 
    292                 FunctionType * func_type = match_func_t.clone();
    293                 DeclarationWithType * except_obj = func_type->get_parameters().back();
    294234
    295235                // Index 1..{number of handlers}
     
    300240                        CatchStmt * handler = *it;
    301241
    302                         // Body should have been taken by create_terminate_catch.
    303                         assert( nullptr == handler->get_body() );
    304 
    305                         // Create new body.
     242                        // body should have been taken by create_terminate_catch.
     243                        // assert( nullptr == handler->get_body() );
    306244                        handler->set_body( new ReturnStmt( noLabels,
    307245                                new ConstantExpr( Constant::from_int( index ) ) ) );
    308246
    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 ) ) ) );
     247                        body->push_back( create_single_matcher( handler ) );
     248                }
    316249
    317250                return new FunctionDecl("match", Type::StorageClasses(),
    318                         LinkageSpec::Cforall, func_type, body);
    319         }
    320 
    321         CompoundStmt * create_terminate_caller(
     251                        LinkageSpec::Cforall, match_func_t, body);
     252        }
     253
     254        Statement * create_terminate_caller(
    322255                        FunctionDecl * try_wrapper,
    323256                        FunctionDecl * terminate_catch,
    324257                        FunctionDecl * terminate_match) {
    325258
    326                 UntypedExpr * caller = new UntypedExpr( new NameExpr(
    327                         "__cfaehm__try_terminate" ) );
    328                 std::list<Expression *>& args = caller->get_args();
     259                ApplicationExpr * caller = new ApplicationExpr( /* ... */ );
     260                std::list<Expression *>& args = caller.get_args();
    329261                args.push_back( nameOf( try_wrapper ) );
    330262                args.push_back( nameOf( terminate_catch ) );
    331263                args.push_back( nameOf( terminate_match ) );
    332264
    333                 CompoundStmt * callStmt = new CompoundStmt( noLabels );
    334                 callStmt->push_back( new ExprStmt( noLabels, caller ) );
    335                 return callStmt;
     265                return new ExprStmt( noLabels, caller );
    336266        }
    337267
    338268        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    339                 CompoundStmt * body = new CompoundStmt( noLabels );
    340 
    341                 FunctionType * func_type = match_func_t.clone();
    342                 DeclarationWithType * except_obj = func_type->get_parameters().back();
     269                CompoundStmt * body = new CompountStmt( noLabels );
    343270
    344271                CatchList::iterator it;
     
    353280                                handling_code->push_back( handler->get_body() );
    354281                        }
    355                         handling_code->push_back( new ReturnStmt( noLabels,
    356                                 new ConstantExpr( Constant::from_bool( true ) ) ) );
     282                        handling_code->push_back( new ReturnStmt( noLabel,
     283                                new ConstantExpr( Constant::from_bool( false ) ) ) );
    357284                        handler->set_body( handling_code );
    358285
    359286                        // Create the handler.
    360                         body->push_back( create_single_matcher( except_obj, handler ) );
    361                         *it = nullptr;
    362                 }
    363 
    364                 body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
    365                         Constant::from_bool( false ) ) ) );
     287                        body->push_back( create_single_matcher( handler ) );
     288                }
    366289
    367290                return new FunctionDecl("handle", Type::StorageClasses(),
    368                         LinkageSpec::Cforall, func_type, body);
    369         }
    370 
    371         CompoundStmt * create_resume_wrapper(
    372                         StructDecl * node_decl,
     291                        LinkageSpec::Cforall, handle_func_t, body);
     292        }
     293
     294        Statement * create_resume_wrapper(
    373295                        Statement * wraps,
    374296                        FunctionDecl * resume_handler ) {
    375297                CompoundStmt * body = new CompoundStmt( noLabels );
    376298
    377                 // struct __try_resume_node __resume_node
    378                 //      __attribute__((cleanup( __cfaehm__try_resume_cleanup )));
    379                 // ** unwinding of the stack here could cause problems **
    380                 // ** however I don't think that can happen currently **
    381                 // __cfaehm__try_resume_setup( &__resume_node, resume_handler );
     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                }
    382311
    383312                std::list< Attribute * > attributes;
    384313                {
    385314                        std::list< Expression * > attr_params;
    386                         attr_params.push_back( new NameExpr(
    387                                 "__cfaehm__try_resume_cleanup" ) );
    388                         attributes.push_back( new Attribute( "cleanup", attr_params ) );
    389                 }
    390 
    391                 ObjectDecl * obj = new ObjectDecl(
    392                         "__resume_node",
     315                        attr_params.push_back( nameOf( /* ... deconstructor ... */ ) );
     316                        attrributes.push_back( new Attribute( "cleanup", attr_params ) );
     317                }
     318
     319                appendDeclStmt( body,
     320                /**/ ObjectDecl(
     321                        "resume_node",
    393322                        Type::StorageClasses(),
    394323                        LinkageSpec::Cforall,
    395324                        nullptr,
    396                         new StructInstType(
    397                                 Type::Qualifiers(),
    398                                 node_decl
    399                                 ),
    400                         nullptr,
     325                        /* Type* = resume_node */,
     326                        node_init,
    401327                        attributes
    402                         );
    403                 appendDeclStmt( body, obj );
    404 
    405                 UntypedExpr *setup = new UntypedExpr( new NameExpr(
    406                         "__cfaehm__try_resume_setup" ) );
    407                 setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) );
    408                 setup->get_args().push_back( nameOf( resume_handler ) );
    409 
    410                 body->push_back( new ExprStmt( noLabels, setup ) );
    411 
     328                        )
     329                );
    412330                body->push_back( wraps );
    413331                return body;
     
    415333
    416334        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    417                 FinallyStmt * finally = tryStmt->get_finally();
    418                 CompoundStmt * body = finally->get_block();
    419                 finally->set_block( nullptr );
    420                 delete finally;
     335                CompoundStmt * body = tryStmt->get_finally();
    421336                tryStmt->set_finally( nullptr );
    422337
    423338                return new FunctionDecl("finally", Type::StorageClasses(),
    424                         LinkageSpec::Cforall, finally_func_t.clone(), body);
    425         }
    426 
    427         ObjectDecl * create_finally_hook(
    428                         StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
    429                 // struct __cfaehm__cleanup_hook __finally_hook
    430                 //      __attribute__((cleanup( finally_wrapper )));
     339                        LinkageSpec::Cforall, void_func_t, body);
     340        }
     341
     342        ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
     343                // struct _cleanup_hook NAME __attribute__((cleanup( ... )));
    431344
    432345                // Make Cleanup Attribute.
     
    435348                        std::list< Expression * > attr_params;
    436349                        attr_params.push_back( nameOf( finally_wrapper ) );
    437                         attributes.push_back( new Attribute( "cleanup", attr_params ) );
    438                 }
    439 
    440                 return new ObjectDecl(
    441                         "__finally_hook",
     350                        attrributes.push_back( new Attribute( "cleanup", attr_params ) );
     351                }
     352
     353                return ObjectDecl( /* ... */
     354                        const std::string &name "finally_hook",
    442355                        Type::StorageClasses(),
    443356                        LinkageSpec::Cforall,
    444357                        nullptr,
    445                         new StructInstType(
    446                                 noQualifiers,
    447                                 hook_decl
    448                                 ),
     358                        /* ... Type * ... */,
    449359                        nullptr,
    450360                        attributes
     
    453363
    454364
    455         class ExceptionMutatorCore : public WithGuards {
     365        class ExceptionMutatorCore : public WithScoping {
    456366                enum Context { NoHandler, TerHandler, ResHandler };
    457367
     
    460370                // loop, switch or the goto stays within the function.
    461371
    462                 Context cur_context;
     372                Context curContext;
    463373
    464374                // We might not need this, but a unique base for each try block's
     
    467377                //unsigned int try_count = 0;
    468378
    469                 StructDecl *node_decl;
    470                 StructDecl *hook_decl;
    471379
    472380        public:
    473381                ExceptionMutatorCore() :
    474                         cur_context(NoHandler),
    475                         node_decl(nullptr), hook_decl(nullptr)
     382                        curContext(NoHandler)
    476383                {}
    477384
    478                 void premutate( CatchStmt *catchStmt );
    479                 void premutate( StructDecl *structDecl );
     385                void premutate( CatchStmt *tryStmt );
    480386                Statement * postmutate( ThrowStmt *throwStmt );
    481387                Statement * postmutate( TryStmt *tryStmt );
     
    487393                        if ( throwStmt->get_expr() ) {
    488394                                return create_terminate_throw( throwStmt );
    489                         } else if ( TerHandler == cur_context ) {
     395                        } else if ( TerHandler == curContext ) {
    490396                                return create_terminate_rethrow( throwStmt );
    491397                        } else {
    492398                                assertf(false, "Invalid throw in %s at %i\n",
    493                                         throwStmt->location.filename.c_str(),
     399                                        throwStmt->location.filename,
    494400                                        throwStmt->location.linenumber);
    495401                                return nullptr;
     
    498404                        if ( throwStmt->get_expr() ) {
    499405                                return create_resume_throw( throwStmt );
    500                         } else if ( ResHandler == cur_context ) {
     406                        } else if ( ResHandler == curContext ) {
    501407                                return create_resume_rethrow( throwStmt );
    502408                        } else {
    503409                                assertf(false, "Invalid throwResume in %s at %i\n",
    504                                         throwStmt->location.filename.c_str(),
     410                                        throwStmt->location.filename,
    505411                                        throwStmt->location.linenumber);
    506412                                return nullptr;
     
    510416
    511417        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
    512                 assert( node_decl );
    513                 assert( hook_decl );
    514 
    515418                // Generate a prefix for the function names?
    516419
    517                 CompoundStmt * block = new CompoundStmt( noLabels );
    518                 CompoundStmt * inner = take_try_block( tryStmt );
     420                CompoundStmt * block = new CompoundStmt();
     421                Statement * inner = take_try_block( tryStmt );
    519422
    520423                if ( tryStmt->get_finally() ) {
     
    524427                        appendDeclStmt( block, finally_block );
    525428                        // Create and add the finally cleanup hook.
    526                         appendDeclStmt( block,
    527                                 create_finally_hook( hook_decl, finally_block ) );
    528                 }
    529 
    530                 CatchList termination_handlers;
    531                 CatchList resumption_handlers;
    532                 split( tryStmt->get_catchers(),
    533                            termination_handlers, resumption_handlers );
    534 
    535                 if ( resumption_handlers.size() ) {
     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() ) {
    536438                        // Define the helper function.
    537439                        FunctionDecl * resume_handler =
     
    539441                        appendDeclStmt( block, resume_handler );
    540442                        // Prepare hooks
    541                         inner = create_resume_wrapper( node_decl, inner, resume_handler );
     443                        inner = create_resume_wrapper( inner, resume_handler );
    542444                }
    543445
     
    560462                block->push_back( inner );
    561463
    562                 //free_all( termination_handlers );
    563                 //free_all( resumption_handlers );
     464                free_all( termination_handlers );
     465                free_all( resumption_handlers );
    564466
    565467                return block;
     
    567469
    568470        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    569                 GuardValue( cur_context );
    570                 if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    571                         cur_context = TerHandler;
     471                GuardValue( curContext );
     472                if ( CatchStmt::Termination == catchStmt->get_kind() ) {
     473                        curContext = TerHandler;
    572474                } else {
    573                         cur_context = ResHandler;
    574                 }
    575         }
    576 
    577         void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
    578                 if ( !structDecl->has_body() ) {
    579                         // Skip children?
    580                         return;
    581                 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
    582                         assert( nullptr == node_decl );
    583                         node_decl = structDecl;
    584                 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
    585                         assert( nullptr == hook_decl );
    586                         hook_decl = structDecl;
    587                 }
    588                 // Later we might get the exception type as well.
    589         }
    590 
    591         void translateEHM( std::list< Declaration *> & translationUnit ) {
    592                 init_func_types();
    593 
     475                        curContext = ResHandler;
     476                }
     477        }
     478
     479    void translateEHM( std::list< Declaration *> & translationUnit ) {
    594480                PassVisitor<ExceptionMutatorCore> translator;
    595                 mutateAll( translationUnit, translator );
     481                for ( Declaration * decl : translationUnit ) {
     482                        decl->mutate( translator );
     483                }
    596484        }
    597485}
Note: See TracChangeset for help on using the changeset viewer.