Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    r307a732 rba912706  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jun 30 13:30:00 2017
    13 // Update Count     : 1
     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( emptyQualifiers, 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                                 emptyQualifiers,
    62                                 new BasicType( emptyQualifiers, 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,
     
    7161                        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                                 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() );
     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( 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 ) );
     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_termination", 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_termination" ) )
     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_resumption", 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,
     282                        handling_code->push_back( new ReturnStmt( noLabel,
    356283                                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;
     287                        body->push_back( create_single_matcher( handler ) );
    362288                }
    363289
    364290                return new FunctionDecl("handle", Type::StorageClasses(),
    365                         LinkageSpec::Cforall, func_type, body);
    366         }
    367 
    368         CompoundStmt * create_resume_wrapper(
    369                         StructDecl * node_decl,
     291                        LinkageSpec::Cforall, handle_func_t, body);
     292        }
     293
     294        Statement * create_resume_wrapper(
    370295                        Statement * wraps,
    371296                        FunctionDecl * resume_handler ) {
    372297                CompoundStmt * body = new CompoundStmt( noLabels );
    373298
    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 );
     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                }
    379311
    380312                std::list< Attribute * > attributes;
    381313                {
    382314                        std::list< Expression * > attr_params;
    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",
     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",
    390322                        Type::StorageClasses(),
    391323                        LinkageSpec::Cforall,
    392324                        nullptr,
    393                         new StructInstType(
    394                                 Type::Qualifiers(),
    395                                 node_decl
    396                                 ),
    397                         nullptr,
     325                        /* Type* = resume_node */,
     326                        node_init,
    398327                        attributes
    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 
     328                        )
     329                );
    409330                body->push_back( wraps );
    410331                return body;
     
    412333
    413334        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    414                 FinallyStmt * finally = tryStmt->get_finally();
    415                 CompoundStmt * body = finally->get_block();
    416                 finally->set_block( nullptr );
    417                 delete finally;
     335                CompoundStmt * body = tryStmt->get_finally();
    418336                tryStmt->set_finally( nullptr );
    419337
    420338                return new FunctionDecl("finally", Type::StorageClasses(),
    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 )));
     339                        LinkageSpec::Cforall, void_func_t, body);
     340        }
     341
     342        ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
     343                // struct _cleanup_hook NAME __attribute__((cleanup( ... )));
    428344
    429345                // Make Cleanup Attribute.
     
    432348                        std::list< Expression * > attr_params;
    433349                        attr_params.push_back( nameOf( finally_wrapper ) );
    434                         attributes.push_back( new Attribute( "cleanup", attr_params ) );
    435                 }
    436 
    437                 return new ObjectDecl(
    438                         "__finally_hook",
     350                        attrributes.push_back( new Attribute( "cleanup", attr_params ) );
     351                }
     352
     353                return ObjectDecl( /* ... */
     354                        const std::string &name "finally_hook",
    439355                        Type::StorageClasses(),
    440356                        LinkageSpec::Cforall,
    441357                        nullptr,
    442                         new StructInstType(
    443                                 emptyQualifiers,
    444                                 hook_decl
    445                                 ),
     358                        /* ... Type * ... */,
    446359                        nullptr,
    447360                        attributes
     
    450363
    451364
    452         class ExceptionMutatorCore : public WithGuards {
     365        class ExceptionMutatorCore : public WithScoping {
    453366                enum Context { NoHandler, TerHandler, ResHandler };
    454367
     
    457370                // loop, switch or the goto stays within the function.
    458371
    459                 Context cur_context;
     372                Context curContext;
    460373
    461374                // We might not need this, but a unique base for each try block's
     
    464377                //unsigned int try_count = 0;
    465378
    466                 StructDecl *node_decl;
    467                 StructDecl *hook_decl;
    468379
    469380        public:
    470381                ExceptionMutatorCore() :
    471                         cur_context(NoHandler),
    472                         node_decl(nullptr), hook_decl(nullptr)
     382                        curContext(NoHandler)
    473383                {}
    474384
    475                 void premutate( CatchStmt *catchStmt );
    476                 void premutate( StructDecl *structDecl );
     385                void premutate( CatchStmt *tryStmt );
    477386                Statement * postmutate( ThrowStmt *throwStmt );
    478387                Statement * postmutate( TryStmt *tryStmt );
     
    484393                        if ( throwStmt->get_expr() ) {
    485394                                return create_terminate_throw( throwStmt );
    486                         } else if ( TerHandler == cur_context ) {
     395                        } else if ( TerHandler == curContext ) {
    487396                                return create_terminate_rethrow( throwStmt );
    488397                        } else {
    489398                                assertf(false, "Invalid throw in %s at %i\n",
    490                                         throwStmt->location.filename.c_str(),
     399                                        throwStmt->location.filename,
    491400                                        throwStmt->location.linenumber);
    492401                                return nullptr;
     
    495404                        if ( throwStmt->get_expr() ) {
    496405                                return create_resume_throw( throwStmt );
    497                         } else if ( ResHandler == cur_context ) {
     406                        } else if ( ResHandler == curContext ) {
    498407                                return create_resume_rethrow( throwStmt );
    499408                        } else {
    500409                                assertf(false, "Invalid throwResume in %s at %i\n",
    501                                         throwStmt->location.filename.c_str(),
     410                                        throwStmt->location.filename,
    502411                                        throwStmt->location.linenumber);
    503412                                return nullptr;
     
    507416
    508417        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
    509                 assert( node_decl );
    510                 assert( hook_decl );
    511 
    512418                // Generate a prefix for the function names?
    513419
    514                 CompoundStmt * block = new CompoundStmt( noLabels );
    515                 CompoundStmt * inner = take_try_block( tryStmt );
     420                CompoundStmt * block = new CompoundStmt();
     421                Statement * inner = take_try_block( tryStmt );
    516422
    517423                if ( tryStmt->get_finally() ) {
     
    521427                        appendDeclStmt( block, finally_block );
    522428                        // Create and add the finally cleanup hook.
    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() ) {
     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() ) {
    533438                        // Define the helper function.
    534439                        FunctionDecl * resume_handler =
     
    536441                        appendDeclStmt( block, resume_handler );
    537442                        // Prepare hooks
    538                         inner = create_resume_wrapper( node_decl, inner, resume_handler );
     443                        inner = create_resume_wrapper( inner, resume_handler );
    539444                }
    540445
     
    557462                block->push_back( inner );
    558463
    559                 //free_all( termination_handlers );
    560                 //free_all( resumption_handlers );
     464                free_all( termination_handlers );
     465                free_all( resumption_handlers );
    561466
    562467                return block;
     
    564469
    565470        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    566                 GuardValue( cur_context );
    567                 if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    568                         cur_context = TerHandler;
     471                GuardValue( curContext );
     472                if ( CatchStmt::Termination == catchStmt->get_kind() ) {
     473                        curContext = TerHandler;
    569474                } else {
    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 
     475                        curContext = ResHandler;
     476                }
     477        }
     478
     479    void translateEHM( std::list< Declaration *> & translationUnit ) {
    591480                PassVisitor<ExceptionMutatorCore> translator;
    592481                for ( Declaration * decl : translationUnit ) {
    593                         decl->acceptMutator( translator );
     482                        decl->mutate( translator );
    594483                }
    595484        }
Note: See TracChangeset for help on using the changeset viewer.