Ignore:
Timestamp:
Jul 5, 2017, 10:50:22 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 22 15:57:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jun 30 13:30:00 2017
     13// Update Count     : 1
    1414//
    1515
    1616#include "ExceptTranslate.h"
    1717#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
     24namespace ControlStruct {
    2025
    2126        // This (large) section could probably be moved out of the class
     
    2429        // Type(Qualifiers &, false, std::list<Attribute *> &)
    2530
    26         // void (*function)()
    27         static FunctionType void_func_t(Type::Qualifiers(), false);
     31        // void (*function)();
     32        static FunctionType try_func_t(Type::Qualifiers(), false);
    2833        // void (*function)(int, exception);
    2934        static FunctionType catch_func_t(Type::Qualifiers(), false);
     
    3237        // bool (*function)(exception);
    3338        static FunctionType handle_func_t(Type::Qualifiers(), false);
     39        // void (*function)(__attribute__((unused)) void *);
     40        static FunctionType finally_func_t(Type::Qualifiers(), false);
    3441
    3542        static void init_func_types() {
    36                 static init_complete = false;
     43                static bool init_complete = false;
    3744                if (init_complete) {
    3845                        return;
    3946                }
    4047                ObjectDecl index_obj(
    41                         "index_t",
     48                        "__handler_index",
    4249                        Type::StorageClasses(),
    4350                        LinkageSpec::Cforall,
    4451                        /*bitfieldWidth*/ NULL,
    45                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     52                        new BasicType( emptyQualifiers, BasicType::SignedInt ),
    4653                        /*init*/ NULL
    47                 );
     54                        );
    4855                ObjectDecl exception_obj(
    49                         "exception_t",
     56                        "__exception_inst",
    5057                        Type::StorageClasses(),
    5158                        LinkageSpec::Cforall,
    5259                        /*bitfieldWidth*/ NULL,
    53                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     60                        new PointerType(
     61                                emptyQualifiers,
     62                                new BasicType( emptyQualifiers, BasicType::SignedInt )
     63                                ),
    5464                        /*init*/ NULL
    55                 );
     65                        );
    5666                ObjectDecl bool_obj(
    57                         "bool_t",
     67                        "__ret_bool",
    5868                        Type::StorageClasses(),
    5969                        LinkageSpec::Cforall,
     
    6171                        new BasicType(emptyQualifiers, BasicType::Bool),
    6272                        /*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() );
    7196
    7297                init_complete = true;
     
    78103
    79104        void split( CatchList& allHandlers, CatchList& terHandlers,
    80                     CatchList& resHandlers ) {
     105                                CatchList& resHandlers ) {
    81106                while ( !allHandlers.empty() ) {
    82                         Statement * stmt = allHandlers.front();
     107                        CatchStmt * stmt = allHandlers.front();
    83108                        allHandlers.pop_front();
    84                         if (CaseStmt::Terminate == stmt->get_kind()) {
     109                        if (CatchStmt::Terminate == stmt->get_kind()) {
    85110                                terHandlers.push_back(stmt);
    86111                        } else {
     
    92117        template<typename T>
    93118        void free_all( std::list<T *> &list ) {
    94                 std::list<T *>::iterator it;
     119                typename std::list<T *>::iterator it;
    95120                for ( it = list.begin() ; it != list.end() ; ++it ) {
    96121                        delete *it;
     
    100125
    101126        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 );
    107132        }
    108133
    109134        // ThrowStmt Mutation Helpers
    110135
    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 ) );
    116152                throwStmt->set_expr( nullptr );
    117153                delete throwStmt;
    118154                return result;
    119155        }
     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        }
    120161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
    121162                // __rethrow_terminate();
     163                assert( nullptr == throwStmt->get_expr() );
    122164                Statement * result = new ExprStmt(
    123165                        throwStmt->get_labels(),
    124                         new ApplicationExpr( /* ... */ );
     166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) )
    125167                        );
    126168                delete throwStmt;
     
    129171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    130172                // __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 );
    137174        }
    138175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     
    140177                Statement * result = new ReturnStmt(
    141178                        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 ) )
    150180                        );
    151181                delete throwStmt;
     
    160190                return block;
    161191        }
    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 );
    168196        }
    169197
    170198        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    171199                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();
    172204
    173205                // Index 1..{number of handlers}
     
    178210                        CatchStmt * handler = *it;
    179211
    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(
    189224                                noLabels,
    190225                                new ConstantExpr( Constant::from_int( index ) ),
    191                                 core
    192                                 );
    193                         handler_wrappers.push_back(wrapper);
     226                                caseBody
     227                                ) );
    194228                }
    195229                // 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                }
    196236
    197237                SwitchStmt * handler_lookup = new SwitchStmt(
    198238                        noLabels,
    199                         /*parameter 0: index*/,
    200                         handler_wrappers,
    201                         false
     239                        nameOf( index_obj ),
     240                        stmt_handlers
    202241                        );
    203242                CompoundStmt * body = new CompoundStmt( noLabels );
     
    205244
    206245                return new FunctionDecl("catch", Type::StorageClasses(),
    207                         LinkageSpec::Cforall, catch_func_t, body);
     246                        LinkageSpec::Cforall, func_type, body);
    208247        }
    209248
    210249        // 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                }
    218275
    219276                if ( modded_handler->get_cond() ) {
    220                         cond = new LogicalExpr( cond, modded_handler->get_cond() )q
     277                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    221278                }
    222279                block->push_back( new IfStmt( noLabels,
    223                         cond, modded_handler->get_body() );
     280                        cond, modded_handler->get_body(), nullptr ) );
    224281
    225282                modded_handler->set_decl( nullptr );
     
    232289        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    233290                CompoundStmt * body = new CompoundStmt( noLabels );
     291
     292                FunctionType * func_type = match_func_t.clone();
     293                DeclarationWithType * except_obj = func_type->get_parameters().back();
    234294
    235295                // Index 1..{number of handlers}
     
    240300                        CatchStmt * handler = *it;
    241301
    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.
    244306                        handler->set_body( new ReturnStmt( noLabels,
    245307                                new ConstantExpr( Constant::from_int( index ) ) ) );
    246308
    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 ) ) ) );
    249316
    250317                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(
    255322                        FunctionDecl * try_wrapper,
    256323                        FunctionDecl * terminate_catch,
    257324                        FunctionDecl * terminate_match) {
    258325
    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();
    261329                args.push_back( nameOf( try_wrapper ) );
    262330                args.push_back( nameOf( terminate_catch ) );
    263331                args.push_back( nameOf( terminate_match ) );
    264332
    265                 return new ExprStmt( noLabels, caller );
     333                CompoundStmt * callStmt = new CompoundStmt( noLabels );
     334                callStmt->push_back( new ExprStmt( noLabels, caller ) );
     335                return callStmt;
    266336        }
    267337
    268338        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();
    270343
    271344                CatchList::iterator it;
     
    280353                                handling_code->push_back( handler->get_body() );
    281354                        }
    282                         handling_code->push_back( new ReturnStmt( noLabel,
     355                        handling_code->push_back( new ReturnStmt( noLabels,
    283356                                new ConstantExpr( Constant::from_bool( false ) ) ) );
    284357                        handler->set_body( handling_code );
    285358
    286359                        // Create the handler.
    287                         body->push_back( create_single_matcher( handler ) );
     360                        body->push_back( create_single_matcher( except_obj, handler ) );
     361                        *it = nullptr;
    288362                }
    289363
    290364                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,
    295370                        Statement * wraps,
    296371                        FunctionDecl * resume_handler ) {
    297372                CompoundStmt * body = new CompoundStmt( noLabels );
    298373
    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 );
    311379
    312380                std::list< Attribute * > attributes;
    313381                {
    314382                        std::list< Expression * > attr_params;
    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",
     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",
    322390                        Type::StorageClasses(),
    323391                        LinkageSpec::Cforall,
    324392                        nullptr,
    325                         /* Type* = resume_node */,
    326                         node_init,
     393                        new StructInstType(
     394                                Type::Qualifiers(),
     395                                node_decl
     396                                ),
     397                        nullptr,
    327398                        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
    330409                body->push_back( wraps );
    331410                return body;
     
    333412
    334413        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;
    336418                tryStmt->set_finally( nullptr );
    337419
    338420                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 )));
    344428
    345429                // Make Cleanup Attribute.
     
    348432                        std::list< Expression * > attr_params;
    349433                        attr_params.push_back( nameOf( finally_wrapper ) );
    350                         attrributes.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",
    355439                        Type::StorageClasses(),
    356440                        LinkageSpec::Cforall,
    357441                        nullptr,
    358                         /* ... Type * ... */,
     442                        new StructInstType(
     443                                emptyQualifiers,
     444                                hook_decl
     445                                ),
    359446                        nullptr,
    360447                        attributes
     
    363450
    364451
    365         class ExceptionMutatorCore : public WithScoping {
     452        class ExceptionMutatorCore : public WithGuards {
    366453                enum Context { NoHandler, TerHandler, ResHandler };
    367454
     
    370457                // loop, switch or the goto stays within the function.
    371458
    372                 Context curContext;
     459                Context cur_context;
    373460
    374461                // We might not need this, but a unique base for each try block's
     
    377464                //unsigned int try_count = 0;
    378465
     466                StructDecl *node_decl;
     467                StructDecl *hook_decl;
    379468
    380469        public:
    381470                ExceptionMutatorCore() :
    382                         curContext(NoHandler)
     471                        cur_context(NoHandler),
     472                        node_decl(nullptr), hook_decl(nullptr)
    383473                {}
    384474
    385                 void premutate( CatchStmt *tryStmt );
     475                void premutate( CatchStmt *catchStmt );
     476                void premutate( StructDecl *structDecl );
    386477                Statement * postmutate( ThrowStmt *throwStmt );
    387478                Statement * postmutate( TryStmt *tryStmt );
     
    393484                        if ( throwStmt->get_expr() ) {
    394485                                return create_terminate_throw( throwStmt );
    395                         } else if ( TerHandler == curContext ) {
     486                        } else if ( TerHandler == cur_context ) {
    396487                                return create_terminate_rethrow( throwStmt );
    397488                        } else {
    398489                                assertf(false, "Invalid throw in %s at %i\n",
    399                                         throwStmt->location.filename,
     490                                        throwStmt->location.filename.c_str(),
    400491                                        throwStmt->location.linenumber);
    401492                                return nullptr;
     
    404495                        if ( throwStmt->get_expr() ) {
    405496                                return create_resume_throw( throwStmt );
    406                         } else if ( ResHandler == curContext ) {
     497                        } else if ( ResHandler == cur_context ) {
    407498                                return create_resume_rethrow( throwStmt );
    408499                        } else {
    409500                                assertf(false, "Invalid throwResume in %s at %i\n",
    410                                         throwStmt->location.filename,
     501                                        throwStmt->location.filename.c_str(),
    411502                                        throwStmt->location.linenumber);
    412503                                return nullptr;
     
    416507
    417508        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
     509                assert( node_decl );
     510                assert( hook_decl );
     511
    418512                // Generate a prefix for the function names?
    419513
    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 );
    422516
    423517                if ( tryStmt->get_finally() ) {
     
    427521                        appendDeclStmt( block, finally_block );
    428522                        // 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() ) {
    438533                        // Define the helper function.
    439534                        FunctionDecl * resume_handler =
     
    441536                        appendDeclStmt( block, resume_handler );
    442537                        // Prepare hooks
    443                         inner = create_resume_wrapper( inner, resume_handler );
     538                        inner = create_resume_wrapper( node_decl, inner, resume_handler );
    444539                }
    445540
     
    462557                block->push_back( inner );
    463558
    464                 free_all( termination_handlers );
    465                 free_all( resumption_handlers );
     559                //free_all( termination_handlers );
     560                //free_all( resumption_handlers );
    466561
    467562                return block;
     
    469564
    470565        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    471                 GuardValue( curContext );
    472                 if ( CatchStmt::Termination == catchStmt->get_kind() ) {
    473                         curContext = TerHandler;
     566                GuardValue( cur_context );
     567                if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     568                        cur_context = TerHandler;
    474569                } 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
    480591                PassVisitor<ExceptionMutatorCore> translator;
    481592                for ( Declaration * decl : translationUnit ) {
    482                         decl->mutate( translator );
     593                        decl->acceptMutator( translator );
    483594                }
    484595        }
Note: See TracChangeset for help on using the changeset viewer.