Ignore:
Timestamp:
Aug 11, 2017, 10:33:37 AM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
54cd58b0
Parents:
3d4b23fa (diff), 59a75cb (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:/u/cforall/software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    r3d4b23fa r0720e049  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 12 15:07:00 2017
    13 // Update Count     : 3
     12// Last Modified On : Tus Aug  8 16:54:00 2017
     13// Update Count     : 7
    1414//
    1515
     
    2121#include "SynTree/Type.h"
    2222#include "SynTree/Attribute.h"
     23#include "SynTree/VarExprReplacer.h"
    2324
    2425namespace ControlStruct {
    25 
    26         // This (large) section could probably be moved out of the class
    27         // and be static helpers instead.
    28 
    29         // Type(Qualifiers &, false, std::list<Attribute *> &)
    30 
    31         // void (*function)();
    32         static FunctionType try_func_t(Type::Qualifiers(), false);
    33         // void (*function)(int, exception);
    34         static FunctionType catch_func_t(Type::Qualifiers(), false);
    35         // int (*function)(exception);
    36         static FunctionType match_func_t(Type::Qualifiers(), false);
    37         // bool (*function)(exception);
    38         static FunctionType handle_func_t(Type::Qualifiers(), false);
    39         // void (*function)(__attribute__((unused)) void *);
    40         static FunctionType finally_func_t(Type::Qualifiers(), false);
    41 
    42         static void init_func_types() {
    43                 static bool init_complete = false;
    44                 if (init_complete) {
    45                         return;
    46                 }
    47                 ObjectDecl index_obj(
    48                         "__handler_index",
    49                         Type::StorageClasses(),
    50                         LinkageSpec::Cforall,
    51                         /*bitfieldWidth*/ NULL,
    52                         new BasicType( emptyQualifiers, BasicType::SignedInt ),
    53                         /*init*/ NULL
    54                         );
    55                 ObjectDecl exception_obj(
    56                         "__exception_inst",
    57                         Type::StorageClasses(),
    58                         LinkageSpec::Cforall,
    59                         /*bitfieldWidth*/ NULL,
    60                         new PointerType(
    61                                 emptyQualifiers,
    62                                 new BasicType( emptyQualifiers, BasicType::SignedInt )
    63                                 ),
    64                         /*init*/ NULL
    65                         );
    66                 ObjectDecl bool_obj(
    67                         "__ret_bool",
    68                         Type::StorageClasses(),
    69                         LinkageSpec::Cforall,
    70                         /*bitfieldWidth*/ NULL,
    71                         new BasicType(emptyQualifiers, BasicType::Bool),
    72                         /*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() );
    96 
    97                 init_complete = true;
    98         }
    9926
    10027        // Buricratic Helpers (Not having to do with the paritular operation.)
     
    11542        }
    11643
    117         template<typename T>
    118         void free_all( std::list<T *> &list ) {
    119                 typename std::list<T *>::iterator it;
    120                 for ( it = list.begin() ; it != list.end() ; ++it ) {
    121                         delete *it;
    122                 }
    123                 list.clear();
    124         }
    125 
    12644        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    12745                block->push_back(new DeclStmt(noLabels, item));
     
    13250        }
    13351
    134         // ThrowStmt Mutation Helpers
    135 
    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",
     52        class ExceptionMutatorCore : public WithGuards {
     53                enum Context { NoHandler, TerHandler, ResHandler };
     54
     55                // Also need to handle goto, break & continue.
     56                // They need to be cut off in a ResHandler, until we enter another
     57                // loop, switch or the goto stays within the function.
     58
     59                Context cur_context;
     60
     61                // The current (innermost) termination handler exception declaration.
     62                ObjectDecl * handler_except_decl;
     63
     64                // The built in types used in translation.
     65                StructDecl * except_decl;
     66                StructDecl * node_decl;
     67                StructDecl * hook_decl;
     68
     69                // The many helper functions for code/syntree generation.
     70                Statement * create_given_throw(
     71                        const char * throwFunc, ThrowStmt * throwStmt );
     72                Statement * create_terminate_throw( ThrowStmt * throwStmt );
     73                Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
     74                Statement * create_resume_throw( ThrowStmt * throwStmt );
     75                Statement * create_resume_rethrow( ThrowStmt * throwStmt );
     76                CompoundStmt * take_try_block( TryStmt * tryStmt );
     77                FunctionDecl * create_try_wrapper( CompoundStmt * body );
     78                FunctionDecl * create_terminate_catch( CatchList &handlers );
     79                CompoundStmt * create_single_matcher(
     80                        DeclarationWithType * except_obj, CatchStmt * modded_handler );
     81                FunctionDecl * create_terminate_match( CatchList &handlers );
     82                CompoundStmt * create_terminate_caller( FunctionDecl * try_wrapper,
     83                        FunctionDecl * terminate_catch, FunctionDecl * terminate_match );
     84                FunctionDecl * create_resume_handler( CatchList &handlers );
     85                CompoundStmt * create_resume_wrapper(
     86                        Statement * wraps, FunctionDecl * resume_handler );
     87                FunctionDecl * create_finally_wrapper( TryStmt * tryStmt );
     88                ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper );
     89
     90                // Types used in translation, make sure to use clone.
     91                // void (*function)();
     92                FunctionType try_func_t;
     93                // void (*function)(int, exception);
     94                FunctionType catch_func_t;
     95                // int (*function)(exception);
     96                FunctionType match_func_t;
     97                // bool (*function)(exception);
     98                FunctionType handle_func_t;
     99                // void (*function)(__attribute__((unused)) void *);
     100                FunctionType finally_func_t;
     101
     102                StructInstType * create_except_type() {
     103                        assert( except_decl );
     104                        return new StructInstType( noQualifiers, except_decl );
     105                }
     106                void init_func_types();
     107
     108        public:
     109                ExceptionMutatorCore() :
     110                        cur_context( NoHandler ),
     111                        handler_except_decl( nullptr ),
     112                        except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ),
     113                        try_func_t( noQualifiers, false ),
     114                        catch_func_t( noQualifiers, false ),
     115                        match_func_t( noQualifiers, false ),
     116                        handle_func_t( noQualifiers, false ),
     117                        finally_func_t( noQualifiers, false )
     118                {}
     119
     120                void premutate( CatchStmt *catchStmt );
     121                void premutate( StructDecl *structDecl );
     122                Statement * postmutate( ThrowStmt *throwStmt );
     123                Statement * postmutate( TryStmt *tryStmt );
     124        };
     125
     126        void ExceptionMutatorCore::init_func_types() {
     127                assert( except_decl );
     128
     129                ObjectDecl index_obj(
     130                        "__handler_index",
     131                        Type::StorageClasses(),
     132                        LinkageSpec::Cforall,
     133                        /*bitfieldWidth*/ NULL,
     134                        new BasicType( noQualifiers, BasicType::SignedInt ),
     135                        /*init*/ NULL
     136                        );
     137                ObjectDecl exception_obj(
     138                        "__exception_inst",
     139                        Type::StorageClasses(),
     140                        LinkageSpec::Cforall,
     141                        /*bitfieldWidth*/ NULL,
     142                        new PointerType(
     143                                noQualifiers,
     144                                new StructInstType( noQualifiers, except_decl )
     145                                ),
     146                        /*init*/ NULL
     147                        );
     148                ObjectDecl bool_obj(
     149                        "__ret_bool",
     150                        Type::StorageClasses(),
     151                        LinkageSpec::Cforall,
     152                        /*bitfieldWidth*/ NULL,
     153                        new BasicType( noQualifiers, BasicType::Bool ),
     154                        /*init*/ NULL
     155                        );
     156                ObjectDecl voidptr_obj(
     157                        "__hook",
    142158                        Type::StorageClasses(),
    143159                        LinkageSpec::Cforall,
    144160                        NULL,
    145                         new BasicType( emptyQualifiers, BasicType::SignedInt ),
    146                         new SingleInit( throwStmt->get_expr() )
    147                         );
    148                 appendDeclStmt( result, local );
     161                        new PointerType(
     162                                noQualifiers,
     163                                new VoidType(
     164                                        noQualifiers
     165                                        ),
     166                                std::list<Attribute *>{ new Attribute( "unused" ) }
     167                                ),
     168                        NULL
     169                        );
     170
     171                catch_func_t.get_parameters().push_back( index_obj.clone() );
     172                catch_func_t.get_parameters().push_back( exception_obj.clone() );
     173                match_func_t.get_returnVals().push_back( index_obj.clone() );
     174                match_func_t.get_parameters().push_back( exception_obj.clone() );
     175                handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     176                handle_func_t.get_parameters().push_back( exception_obj.clone() );
     177                finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
     178        }
     179
     180        // ThrowStmt Mutation Helpers
     181
     182        Statement * ExceptionMutatorCore::create_given_throw(
     183                        const char * throwFunc, ThrowStmt * throwStmt ) {
     184                // `throwFunc`( `throwStmt->get_name` );
    149185                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 ) );
     186                call->get_args().push_back( throwStmt->get_expr() );
    152187                throwStmt->set_expr( nullptr );
    153188                delete throwStmt;
    154                 return result;
    155         }
    156 
    157         Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    158                 // { int NAME = EXPR; __throw_terminate( &NAME ); }
     189                return new ExprStmt( noLabels, call );
     190        }
     191
     192        Statement * ExceptionMutatorCore::create_terminate_throw(
     193                        ThrowStmt *throwStmt ) {
     194                // __throw_terminate( `throwStmt->get_name()` ); }
    159195                return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    160196        }
    161         Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
    162                 // __rethrow_terminate();
     197
     198        Statement * ExceptionMutatorCore::create_terminate_rethrow(
     199                        ThrowStmt *throwStmt ) {
     200                // { `handler_except_decl` = NULL; __rethrow_terminate(); }
    163201                assert( nullptr == throwStmt->get_expr() );
    164                 Statement * result = new ExprStmt(
    165                         throwStmt->get_labels(),
     202                assert( handler_except_decl );
     203
     204                CompoundStmt * result = new CompoundStmt( throwStmt->get_labels() );
     205                result->push_back( new ExprStmt( noLabels, UntypedExpr::createAssign(
     206                        nameOf( handler_except_decl ),
     207                        new ConstantExpr( Constant::null(
     208                                new PointerType(
     209                                        noQualifiers,
     210                                        handler_except_decl->get_type()->clone()
     211                                        )
     212                                ) )
     213                        ) ) );
     214                result->push_back( new ExprStmt(
     215                        noLabels,
    166216                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
    167                         );
     217                        ) );
    168218                delete throwStmt;
    169219                return result;
    170220        }
    171         Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    172                 // __throw_resume( EXPR );
     221
     222        Statement * ExceptionMutatorCore::create_resume_throw(
     223                        ThrowStmt *throwStmt ) {
     224                // __throw_resume( `throwStmt->get_name` );
    173225                return create_given_throw( "__cfaehm__throw_resume", throwStmt );
    174226        }
    175         Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     227
     228        Statement * ExceptionMutatorCore::create_resume_rethrow(
     229                        ThrowStmt *throwStmt ) {
    176230                // return false;
    177231                Statement * result = new ReturnStmt(
     
    185239        // TryStmt Mutation Helpers
    186240
    187         CompoundStmt * take_try_block( TryStmt *tryStmt ) {
     241        CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
    188242                CompoundStmt * block = tryStmt->get_block();
    189243                tryStmt->set_block( nullptr );
    190244                return block;
    191245        }
    192         FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
     246
     247        FunctionDecl * ExceptionMutatorCore::create_try_wrapper(
     248                        CompoundStmt *body ) {
    193249
    194250                return new FunctionDecl( "try", Type::StorageClasses(),
     
    196252        }
    197253
    198         FunctionDecl * create_terminate_catch( CatchList &handlers ) {
     254        FunctionDecl * ExceptionMutatorCore::create_terminate_catch(
     255                        CatchList &handlers ) {
    199256                std::list<CaseStmt *> handler_wrappers;
    200257
    201258                FunctionType *func_type = catch_func_t.clone();
    202259                DeclarationWithType * index_obj = func_type->get_parameters().front();
    203         //      DeclarationWithType * except_obj = func_type->get_parameters().back();
     260                DeclarationWithType * except_obj = func_type->get_parameters().back();
    204261
    205262                // Index 1..{number of handlers}
     
    210267                        CatchStmt * handler = *it;
    211268
    212                         // INTEGERconstant Version
    213269                        // case `index`:
    214270                        // {
    215                         //     `handler.body`
     271                        //     `handler.decl` = { (virtual `decl.type`)`except` };
     272                        //     `handler.body`;
    216273                        // }
    217274                        // return;
    218                         std::list<Statement *> caseBody;
    219                         caseBody.push_back( handler->get_body() );
     275                        CompoundStmt * block = new CompoundStmt( noLabels );
     276
     277                        // Just copy the exception value. (Post Validation)
     278                        ObjectDecl * handler_decl =
     279                                static_cast<ObjectDecl *>( handler->get_decl() );
     280                        ObjectDecl * local_except = handler_decl->clone();
     281                        local_except->set_init(
     282                                new ListInit({ new SingleInit(
     283                                        new VirtualCastExpr( nameOf( except_obj ),
     284                                                local_except->get_type()
     285                                                )
     286                                        ) })
     287                                );
     288                        block->push_back( new DeclStmt( noLabels, local_except ) );
     289
     290                        // Add the cleanup attribute.
     291                        local_except->get_attributes().push_back( new Attribute(
     292                                "cleanup",
     293                                { new NameExpr( "__cfaehm__cleanup_terminate" ) }
     294                                ) );
     295
     296                        // Update variables in the body to point to this local copy.
     297                        {
     298                                VarExprReplacer::DeclMap mapping;
     299                                mapping[ handler_decl ] = local_except;
     300                                VarExprReplacer mapper( mapping );
     301                                handler->get_body()->accept( mapper );
     302                        }
     303
     304                        block->push_back( handler->get_body() );
    220305                        handler->set_body( nullptr );
    221                         caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
    222 
     306
     307                        std::list<Statement *> caseBody
     308                                        { block, new ReturnStmt( noLabels, nullptr ) };
    223309                        handler_wrappers.push_back( new CaseStmt(
    224310                                noLabels,
     
    249335        // Create a single check from a moddified handler.
    250336        // except_obj is referenced, modded_handler will be freed.
    251         CompoundStmt *create_single_matcher(
     337        CompoundStmt * ExceptionMutatorCore::create_single_matcher(
    252338                        DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
     339                // {
     340                //     `modded_handler.decl`
     341                //     if ( `decl.name = (virtual `decl.type`)`except`
     342                //             [&& `modded_handler.cond`] ) {
     343                //         `modded_handler.body`
     344                //     }
     345                // }
     346
    253347                CompoundStmt * block = new CompoundStmt( noLabels );
    254348
    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                 }
    275 
     349                // Local Declaration
     350                ObjectDecl * local_except =
     351                        dynamic_cast<ObjectDecl *>( modded_handler->get_decl() );
     352                assert( local_except );
     353                block->push_back( new DeclStmt( noLabels, local_except ) );
     354
     355                // Check for type match.
     356                Expression * cond = UntypedExpr::createAssign( nameOf( local_except ),
     357                        new VirtualCastExpr( nameOf( except_obj ),
     358                                local_except->get_type()->clone() ) );
     359
     360                // Add the check on the conditional if it is provided.
    276361                if ( modded_handler->get_cond() ) {
    277362                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    278363                }
     364                // Construct the match condition.
    279365                block->push_back( new IfStmt( noLabels,
    280366                        cond, modded_handler->get_body(), nullptr ) );
     
    287373        }
    288374
    289         FunctionDecl * create_terminate_match( CatchList &handlers ) {
     375        FunctionDecl * ExceptionMutatorCore::create_terminate_match(
     376                        CatchList &handlers ) {
     377                // int match(exception * except) {
     378                //     HANDLER WRAPPERS { return `index`; }
     379                // }
     380
    290381                CompoundStmt * body = new CompoundStmt( noLabels );
    291382
     
    319410        }
    320411
    321         CompoundStmt * create_terminate_caller(
     412        CompoundStmt * ExceptionMutatorCore::create_terminate_caller(
    322413                        FunctionDecl * try_wrapper,
    323414                        FunctionDecl * terminate_catch,
    324                         FunctionDecl * terminate_match) {
     415                        FunctionDecl * terminate_match ) {
     416                // { __cfaehm__try_terminate(`try`, `catch`, `match`); }
    325417
    326418                UntypedExpr * caller = new UntypedExpr( new NameExpr(
     
    336428        }
    337429
    338         FunctionDecl * create_resume_handler( CatchList &handlers ) {
     430        FunctionDecl * ExceptionMutatorCore::create_resume_handler(
     431                        CatchList &handlers ) {
     432                // bool handle(exception * except) {
     433                //     HANDLER WRAPPERS { `hander->body`; return true; }
     434                // }
    339435                CompoundStmt * body = new CompoundStmt( noLabels );
    340436
     
    369465        }
    370466
    371         CompoundStmt * create_resume_wrapper(
    372                         StructDecl * node_decl,
     467        CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(
    373468                        Statement * wraps,
    374469                        FunctionDecl * resume_handler ) {
     
    414509        }
    415510
    416         FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
     511        FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(
     512                        TryStmt * tryStmt ) {
     513                // void finally() { <finally code> }
    417514                FinallyStmt * finally = tryStmt->get_finally();
    418515                CompoundStmt * body = finally->get_block();
     
    425522        }
    426523
    427         ObjectDecl * create_finally_hook(
    428                         StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
     524        ObjectDecl * ExceptionMutatorCore::create_finally_hook(
     525                        FunctionDecl * finally_wrapper ) {
    429526                // struct __cfaehm__cleanup_hook __finally_hook
    430527                //      __attribute__((cleanup( finally_wrapper )));
     
    444541                        nullptr,
    445542                        new StructInstType(
    446                                 emptyQualifiers,
     543                                noQualifiers,
    447544                                hook_decl
    448545                                ),
     
    452549        }
    453550
    454 
    455         class ExceptionMutatorCore : public WithGuards {
    456                 enum Context { NoHandler, TerHandler, ResHandler };
    457 
    458                 // Also need to handle goto, break & continue.
    459                 // They need to be cut off in a ResHandler, until we enter another
    460                 // loop, switch or the goto stays within the function.
    461 
    462                 Context cur_context;
    463 
    464                 // We might not need this, but a unique base for each try block's
    465                 // generated functions might be nice.
    466                 //std::string curFunctionName;
    467                 //unsigned int try_count = 0;
    468 
    469                 StructDecl *node_decl;
    470                 StructDecl *hook_decl;
    471 
    472         public:
    473                 ExceptionMutatorCore() :
    474                         cur_context(NoHandler),
    475                         node_decl(nullptr), hook_decl(nullptr)
    476                 {}
    477 
    478                 void premutate( CatchStmt *catchStmt );
    479                 void premutate( StructDecl *structDecl );
    480                 Statement * postmutate( ThrowStmt *throwStmt );
    481                 Statement * postmutate( TryStmt *tryStmt );
    482         };
     551        // Visiting/Mutating Functions
     552        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
     553                // Validate the Statement's form.
     554                ObjectDecl * decl =
     555                        dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
     556                if ( decl && true /* check decl->get_type() */ ) {
     557                        // Pass.
     558                } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     559                        throw SemanticError("catch must have exception type");
     560                } else {
     561                        throw SemanticError("catchResume must have exception type");
     562                }
     563
     564                // Track the handler context.
     565                GuardValue( cur_context );
     566                if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     567                        cur_context = TerHandler;
     568
     569                        GuardValue( handler_except_decl );
     570                        handler_except_decl = decl;
     571                } else {
     572                        cur_context = ResHandler;
     573                }
     574        }
     575
     576        void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
     577                if ( !structDecl->has_body() ) {
     578                        // Skip children?
     579                        return;
     580                } else if ( structDecl->get_name() == "__cfaehm__base_exception_t" ) {
     581                        assert( nullptr == except_decl );
     582                        except_decl = structDecl;
     583                        init_func_types();
     584                } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
     585                        assert( nullptr == node_decl );
     586                        node_decl = structDecl;
     587                } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
     588                        assert( nullptr == hook_decl );
     589                        hook_decl = structDecl;
     590                }
     591                // Later we might get the exception type as well.
     592        }
    483593
    484594        Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
     595                assert( except_decl );
     596
    485597                // Ignoring throwStmt->get_target() for now.
    486598                if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
     
    510622
    511623        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
     624                assert( except_decl );
    512625                assert( node_decl );
    513626                assert( hook_decl );
     
    524637                        appendDeclStmt( block, finally_block );
    525638                        // Create and add the finally cleanup hook.
    526                         appendDeclStmt( block,
    527                                 create_finally_hook( hook_decl, finally_block ) );
     639                        appendDeclStmt( block, create_finally_hook( finally_block ) );
    528640                }
    529641
     
    539651                        appendDeclStmt( block, resume_handler );
    540652                        // Prepare hooks
    541                         inner = create_resume_wrapper( node_decl, inner, resume_handler );
     653                        inner = create_resume_wrapper( inner, resume_handler );
    542654                }
    543655
     
    560672                block->push_back( inner );
    561673
    562                 //free_all( termination_handlers );
    563                 //free_all( resumption_handlers );
    564 
    565674                return block;
    566675        }
    567676
    568         void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    569                 GuardValue( cur_context );
    570                 if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    571                         cur_context = TerHandler;
    572                 } 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 
    591677        void translateEHM( std::list< Declaration *> & translationUnit ) {
    592                 init_func_types();
    593 
    594678                PassVisitor<ExceptionMutatorCore> translator;
    595679                mutateAll( translationUnit, translator );
Note: See TracChangeset for help on using the changeset viewer.