Changeset 5f3ba11


Ignore:
Timestamp:
Feb 4, 2022, 10:08:15 PM (5 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
enum, forall-pointer-decay, master
Children:
b56ad5e
Parents:
451d958
Message:

TranslateTries? pass

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.h

    r451d958 r5f3ba11  
    3131
    3232        void translateTries( std::list< Declaration *> & translationUnit );
     33        void translateTries( ast::TranslationUnit & transUnit );
    3334        /* Replaces all try blocks (and their many clauses) with function definitions and calls.
    3435         * This uses the exception built-ins to produce typed output and should take place after
  • src/ControlStruct/ExceptTranslateNew.cpp

    r451d958 r5f3ba11  
    2020#include "AST/Stmt.hpp"
    2121#include "AST/TranslationUnit.hpp"
     22#include "AST/DeclReplacer.hpp"
    2223
    2324namespace ControlStruct {
    2425
    2526namespace {
     27
     28        typedef std::list<ast::CatchStmt*> CatchList;
     29
     30        void split( CatchList& allHandlers, CatchList& terHandlers,
     31                                CatchList& resHandlers ) {
     32                while ( !allHandlers.empty() ) {
     33                        ast::CatchStmt * stmt = allHandlers.front();
     34                        allHandlers.pop_front();
     35                        if (stmt->kind == ast::ExceptionKind::Terminate) {
     36                                terHandlers.push_back(stmt);
     37                        } else {
     38                                resHandlers.push_back(stmt);
     39                        }
     40                }
     41        }
     42
     43        void appendDeclStmt( ast::CompoundStmt * block, ast::DeclWithType * item ) {
     44                block->push_back(new ast::DeclStmt(block->location, item));
     45        }
    2646
    2747class TranslateThrowsCore : public ast::WithGuards {
     
    128148}
    129149
     150
     151class TryMutatorCore {
     152        // The built in types used in translation.
     153        const ast::StructDecl * except_decl;
     154        const ast::StructDecl * node_decl;
     155        const ast::StructDecl * hook_decl;
     156
     157        // The many helper functions for code/syntree generation.
     158        ast::CompoundStmt * take_try_block( ast::TryStmt * tryStmt );
     159        ast::FunctionDecl * create_try_wrapper( const ast::CompoundStmt * body );
     160        ast::FunctionDecl * create_terminate_catch( CatchList &handlers );
     161        ast::CompoundStmt * create_single_matcher(
     162                const ast::DeclWithType * except_obj, ast::CatchStmt * modded_handler );
     163        ast::FunctionDecl * create_terminate_match( CatchList &handlers );
     164        ast::CompoundStmt * create_terminate_caller( CodeLocation loc, ast::FunctionDecl * try_wrapper,
     165                ast::FunctionDecl * terminate_catch, ast::FunctionDecl * terminate_match );
     166        ast::FunctionDecl * create_resume_handler( CatchList &handlers );
     167        ast::CompoundStmt * create_resume_wrapper(
     168                const ast::Stmt * wraps, const ast::FunctionDecl * resume_handler );
     169        ast::FunctionDecl * create_finally_wrapper( ast::TryStmt * tryStmt );
     170        ast::ObjectDecl * create_finally_hook( ast::FunctionDecl * finally_wrapper );
     171        ast::Stmt * create_resume_rethrow( const ast::ThrowStmt * throwStmt );
     172
     173        // Types used in translation, make sure to use clone.
     174        // void (*function)();
     175        ast::FunctionDecl * try_func_t;
     176        // void (*function)(int, exception);
     177        ast::FunctionDecl * catch_func_t;
     178        // int (*function)(exception);
     179        ast::FunctionDecl * match_func_t;
     180        // bool (*function)(exception);
     181        ast::FunctionDecl * handle_func_t;
     182        // void (*function)(__attribute__((unused)) void *);
     183        ast::FunctionDecl * finally_func_t;
     184
     185        ast::StructInstType * create_except_type() {
     186                assert( except_decl );
     187                return new ast::StructInstType( except_decl );
     188        }
     189        void init_func_types();
     190
     191public:
     192        TryMutatorCore() :
     193                except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr )
     194        {}
     195
     196        void previsit( const ast::StructDecl *structDecl );
     197        ast::Stmt * postvisit( const ast::TryStmt *tryStmt );
     198        ast::Stmt * postvisit( const ast::ThrowStmt *throwStmt );
     199};
     200
     201void TryMutatorCore::init_func_types() {
     202        assert( except_decl );
     203
     204        ast::ObjectDecl index_obj(
     205                {},
     206                "__handler_index",
     207                new ast::BasicType(ast::BasicType::SignedInt)
     208                );
     209        ast::ObjectDecl exception_obj(
     210                {},
     211                "__exception_inst",
     212                new ast::PointerType(
     213                        new ast::StructInstType( except_decl )
     214                        ),
     215                NULL
     216                );
     217        ast::ObjectDecl bool_obj(
     218                {},
     219                "__ret_bool",
     220                new ast::BasicType( ast::BasicType::Bool ),
     221                nullptr, //init
     222                ast::Storage::Classes{},
     223                ast::Linkage::Cforall,
     224                nullptr, //width
     225                std::vector<ast::ptr<ast::Attribute>>{ new ast::Attribute( "unused" ) }
     226                );
     227        ast::ObjectDecl voidptr_obj(
     228                {},
     229                "__hook",
     230                new ast::PointerType(
     231                        new ast::VoidType()
     232                ),
     233                nullptr, //init
     234                ast::Storage::Classes{},
     235                ast::Linkage::Cforall,
     236                nullptr, //width
     237                std::vector<ast::ptr<ast::Attribute>>{ new ast::Attribute( "unused" ) }
     238                );
     239
     240        ast::ObjectDecl unused_index_obj(
     241                {},
     242                "__handler_index",
     243                new ast::BasicType(ast::BasicType::SignedInt),
     244                nullptr,
     245                ast::Storage::Classes{},
     246                ast::Linkage::Cforall,
     247                nullptr, //width
     248                std::vector<ast::ptr<ast::Attribute>>{ new ast::Attribute( "unused" ) }
     249        );
     250        //unused_index_obj->attributes.push_back( new Attribute( "unused" ) );
     251
     252        try_func_t = new ast::FunctionDecl(
     253                {},
     254                "try",
     255                {}, //forall
     256                {}, //no param
     257                {}, //no return
     258                nullptr,
     259                ast::Storage::Classes{},
     260                ast::Linkage::Cforall
     261        );
     262
     263        catch_func_t = new ast::FunctionDecl(
     264                {},
     265                "catch",
     266                {}, //forall
     267                {ast::deepCopy(&index_obj), ast::deepCopy(&exception_obj)},//param
     268                {}, //return void
     269                nullptr,
     270                ast::Storage::Classes{},
     271                ast::Linkage::Cforall
     272        );
     273
     274        match_func_t = new ast::FunctionDecl(
     275                {},
     276                "match",
     277                {}, //forall
     278                {ast::deepCopy(&exception_obj)},
     279                {ast::deepCopy(&unused_index_obj)},
     280                nullptr,
     281                ast::Storage::Classes{},
     282                ast::Linkage::Cforall
     283        );
     284
     285        handle_func_t = new ast::FunctionDecl(
     286                {},
     287                "handle",
     288                {}, //forall
     289                {ast::deepCopy(&exception_obj)},
     290                {ast::deepCopy(&bool_obj)},
     291                nullptr,
     292                ast::Storage::Classes{},
     293                ast::Linkage::Cforall
     294        );
     295
     296        finally_func_t = new ast::FunctionDecl(
     297                {},
     298                "finally",
     299                {}, //forall
     300                {ast::deepCopy(&voidptr_obj)},
     301                {}, //return void
     302                nullptr,
     303                ast::Storage::Classes{},
     304                ast::Linkage::Cforall
     305        );
     306
     307        //catch_func_t.get_parameters().push_back( index_obj.clone() );
     308        //catch_func_t.get_parameters().push_back( exception_obj.clone() );
     309        //match_func_t.get_returnVals().push_back( unused_index_obj );
     310        //match_func_t.get_parameters().push_back( exception_obj.clone() );
     311        //handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     312        //handle_func_t.get_parameters().push_back( exception_obj.clone() );
     313        //finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
     314}
     315
     316// TryStmt Mutation Helpers
     317
     318/*
     319ast::CompoundStmt * TryMutatorCore::take_try_block( ast::TryStmt *tryStmt ) {
     320        ast::CompoundStmt * block = tryStmt->body;
     321        tryStmt->body = nullptr;
     322        return block;
     323}
     324*/
     325
     326ast::FunctionDecl * TryMutatorCore::create_try_wrapper(
     327                const ast::CompoundStmt *body ) {
     328
     329        ast::FunctionDecl * ret = ast::deepCopy(try_func_t);
     330        ret->stmts = body;
     331        return ret;
     332}
     333
     334ast::FunctionDecl * TryMutatorCore::create_terminate_catch(
     335                CatchList &handlers ) {
     336        std::vector<ast::ptr<ast::Stmt>> handler_wrappers;
     337
     338        assert (!handlers.empty());
     339        const CodeLocation loc = handlers.front()->location;
     340
     341        ast::FunctionDecl * func_t = ast::deepCopy(catch_func_t);
     342        const ast::DeclWithType * index_obj = func_t->params.front();
     343        const ast::DeclWithType * except_obj = func_t->params.back();
     344
     345        // Index 1..{number of handlers}
     346        int index = 0;
     347        CatchList::iterator it = handlers.begin();
     348        for ( ; it != handlers.end() ; ++it ) {
     349                ++index;
     350                ast::CatchStmt * handler = *it;
     351                const CodeLocation loc = handler->location;
     352
     353                // case `index`:
     354                // {
     355                //     `handler.decl` = { (virtual `decl.type`)`except` };
     356                //     `handler.body`;
     357                // }
     358                // return;
     359                ast::CompoundStmt * block = new ast::CompoundStmt(loc);
     360
     361                // Just copy the exception value. (Post Validation)
     362                const ast::ObjectDecl * handler_decl =
     363                        handler->decl.strict_as<ast::ObjectDecl>();
     364                ast::ObjectDecl * local_except = ast::deepCopy(handler_decl);
     365                ast::VirtualCastExpr * vcex = new ast::VirtualCastExpr(loc,
     366                        new ast::VariableExpr( loc, except_obj ),
     367                        local_except->get_type()
     368                        );
     369                vcex->location = handler->location;
     370                local_except->init = new ast::ListInit(loc, { new ast::SingleInit( loc, vcex ) });
     371                block->push_back( new ast::DeclStmt( loc, local_except ) );
     372
     373                // Add the cleanup attribute.
     374                local_except->attributes.push_back( new ast::Attribute(
     375                        "cleanup",
     376                        { new ast::NameExpr( loc, "__cfaehm_cleanup_terminate" ) }
     377                        ) );
     378
     379                ast::DeclReplacer::DeclMap mapping;
     380                mapping[handler_decl] = local_except;
     381                const ast::Stmt * mutBody = strict_dynamic_cast<const ast::Stmt *>(
     382                        ast::DeclReplacer::replace(handler->body, mapping));
     383
     384
     385                block->push_back( mutBody );
     386                // handler->body = nullptr;
     387
     388                handler_wrappers.push_back( new ast::CaseStmt(loc,
     389                        ast::ConstantExpr::from_int(loc, index) ,
     390                        { block, new ast::ReturnStmt( loc, nullptr ) }
     391                        ));
     392        }
     393        // TODO: Some sort of meaningful error on default perhaps?
     394
     395        /*
     396        std::list<Statement*> stmt_handlers;
     397        while ( !handler_wrappers.empty() ) {
     398                stmt_handlers.push_back( handler_wrappers.front() );
     399                handler_wrappers.pop_front();
     400        }
     401        */
     402
     403        ast::SwitchStmt * handler_lookup = new ast::SwitchStmt(loc,
     404                new ast::VariableExpr( loc, index_obj ),
     405                std::move(handler_wrappers)
     406                );
     407        ast::CompoundStmt * body = new ast::CompoundStmt(loc,
     408                {handler_lookup});
     409
     410        func_t->stmts = body;
     411        return func_t;
     412}
     413
     414// Create a single check from a moddified handler.
     415// except_obj is referenced, modded_handler will be freed.
     416ast::CompoundStmt * TryMutatorCore::create_single_matcher(
     417                const ast::DeclWithType * except_obj, ast::CatchStmt * modded_handler ) {
     418        // {
     419        //     `modded_handler.decl`
     420        //     if ( `decl.name = (virtual `decl.type`)`except`
     421        //             [&& `modded_handler.cond`] ) {
     422        //         `modded_handler.body`
     423        //     }
     424        // }
     425
     426        const CodeLocation loc = modded_handler->location;
     427        ast::CompoundStmt * block = new ast::CompoundStmt(loc);
     428
     429        // Local Declaration
     430        const ast::ObjectDecl * local_except =
     431                modded_handler->decl.strict_as<ast::ObjectDecl>();
     432        block->push_back( new ast::DeclStmt( loc,  local_except ) );
     433
     434        // Check for type match.
     435        ast::VirtualCastExpr * vcex = new ast::VirtualCastExpr(loc,
     436                new ast::VariableExpr(loc, except_obj ),
     437                local_except->get_type()
     438                );
     439        ast::Expr * cond = ast::UntypedExpr::createAssign(loc,
     440                new ast::VariableExpr(loc, local_except ), vcex );
     441
     442        // Add the check on the conditional if it is provided.
     443        if ( modded_handler->cond ) {
     444                cond = new ast::LogicalExpr( loc, cond, modded_handler->cond, ast::LogicalFlag::AndExpr );
     445        }
     446        // Construct the match condition.
     447        block->push_back( new ast::IfStmt(loc,
     448                cond, modded_handler->body, nullptr ) );
     449
     450        // xxx - how does this work in new ast
     451        //modded_handler->set_decl( nullptr );
     452        //modded_handler->set_cond( nullptr );
     453        //modded_handler->set_body( nullptr );
     454        //delete modded_handler;
     455        return block;
     456}
     457
     458ast::FunctionDecl * TryMutatorCore::create_terminate_match(
     459                CatchList &handlers ) {
     460        // int match(exception * except) {
     461        //     HANDLER WRAPPERS { return `index`; }
     462        // }
     463
     464        assert (!handlers.empty());
     465        const CodeLocation loc = handlers.front()->location;
     466
     467        ast::CompoundStmt * body = new ast::CompoundStmt(loc);
     468
     469        ast::FunctionDecl * func_t = ast::deepCopy(match_func_t);
     470        const ast::DeclWithType * except_obj = func_t->params.back();
     471
     472        // Index 1..{number of handlers}
     473        int index = 0;
     474        CatchList::iterator it;
     475        for ( it = handlers.begin() ; it != handlers.end() ; ++it ) {
     476                ++index;
     477                ast::CatchStmt * handler = *it;
     478
     479                // Body should have been taken by create_terminate_catch.
     480                // xxx - just ignore it?
     481                // assert( nullptr == handler->get_body() );
     482
     483                // Create new body.
     484                handler->body = new ast::ReturnStmt( handler->location,
     485                        ast::ConstantExpr::from_int( handler->location, index ) );
     486
     487                // Create the handler.
     488                body->push_back( create_single_matcher( except_obj, handler ) );
     489                *it = nullptr;
     490        }
     491
     492        body->push_back( new ast::ReturnStmt(loc,
     493                ast::ConstantExpr::from_int( loc, 0 ) ));
     494
     495        func_t->stmts = body;
     496
     497        return func_t;
     498}
     499
     500ast::CompoundStmt * TryMutatorCore::create_terminate_caller(
     501                CodeLocation loc,
     502                ast::FunctionDecl * try_wrapper,
     503                ast::FunctionDecl * terminate_catch,
     504                ast::FunctionDecl * terminate_match ) {
     505        // { __cfaehm_try_terminate(`try`, `catch`, `match`); }
     506
     507        ast::UntypedExpr * caller = new ast::UntypedExpr(loc, new ast::NameExpr(loc,
     508                "__cfaehm_try_terminate" ) );
     509        caller->args.push_back( new ast::VariableExpr(loc, try_wrapper ) );
     510        caller->args.push_back( new ast::VariableExpr(loc, terminate_catch ) );
     511        caller->args.push_back( new ast::VariableExpr(loc, terminate_match ) );
     512
     513        ast::CompoundStmt * callStmt = new ast::CompoundStmt(loc);
     514        callStmt->push_back( new ast::ExprStmt( loc, caller ) );
     515        return callStmt;
     516}
     517
     518ast::FunctionDecl * TryMutatorCore::create_resume_handler(
     519                CatchList &handlers ) {
     520        // bool handle(exception * except) {
     521        //     HANDLER WRAPPERS { `hander->body`; return true; }
     522        // }
     523        assert (!handlers.empty());
     524        const CodeLocation loc = handlers.front()->location;
     525        ast::CompoundStmt * body = new ast::CompoundStmt(loc);
     526
     527        ast::FunctionDecl * func_t = ast::deepCopy(handle_func_t);
     528        const ast::DeclWithType * except_obj = func_t->params.back();
     529
     530        CatchList::iterator it;
     531        for ( it = handlers.begin() ; it != handlers.end() ; ++it ) {
     532                ast::CatchStmt * handler = *it;
     533                const CodeLocation loc = handler->location;
     534                // Modifiy body.
     535                ast::CompoundStmt * handling_code;
     536                if (handler->body.as<ast::CompoundStmt>()) {
     537                        handling_code =
     538                        strict_dynamic_cast<ast::CompoundStmt*>( handler->body.get_and_mutate() );
     539                } else {
     540                        handling_code = new ast::CompoundStmt(loc);
     541                        handling_code->push_back( handler->body );
     542                }
     543                handling_code->push_back( new ast::ReturnStmt(loc,
     544                        ast::ConstantExpr::from_bool(loc, true ) ) );
     545                handler->body = handling_code;
     546
     547                // Create the handler.
     548                body->push_back( create_single_matcher( except_obj, handler ) );
     549                *it = nullptr;
     550        }
     551
     552        body->push_back( new ast::ReturnStmt(loc,
     553                ast::ConstantExpr::from_bool(loc, false ) ) );
     554        func_t->stmts = body;
     555
     556        return func_t;
     557}
     558
     559ast::CompoundStmt * TryMutatorCore::create_resume_wrapper(
     560                const ast::Stmt * wraps,
     561                const ast::FunctionDecl * resume_handler ) {
     562        const CodeLocation loc = wraps->location;
     563        ast::CompoundStmt * body = new ast::CompoundStmt(loc);
     564
     565        // struct __try_resume_node __resume_node
     566        //      __attribute__((cleanup( __cfaehm_try_resume_cleanup )));
     567        // ** unwinding of the stack here could cause problems **
     568        // ** however I don't think that can happen currently **
     569        // __cfaehm_try_resume_setup( &__resume_node, resume_handler );
     570
     571        ast::ObjectDecl * obj = new ast::ObjectDecl(
     572                loc,
     573                "__resume_node",
     574                new ast::StructInstType(
     575                        node_decl
     576                        ),
     577                nullptr,
     578                ast::Storage::Classes{},
     579                ast::Linkage::Cforall,
     580                nullptr,
     581                {new ast::Attribute("cleanup", {new ast::NameExpr(loc, "__cfaehm_try_resume_cleanup")})}
     582                );
     583        appendDeclStmt( body, obj );
     584
     585        ast::UntypedExpr *setup = new ast::UntypedExpr(loc, new ast::NameExpr(loc,
     586                "__cfaehm_try_resume_setup" ) );
     587        setup->args.push_back( new ast::AddressExpr( loc, new ast::VariableExpr(loc, obj ) ) );
     588        setup->args.push_back( new ast::VariableExpr( loc, resume_handler ) );
     589
     590        body->push_back( new ast::ExprStmt(loc, setup ) );
     591
     592        body->push_back( wraps );
     593        return body;
     594}
     595
     596ast::FunctionDecl * TryMutatorCore::create_finally_wrapper(
     597                ast::TryStmt * tryStmt ) {
     598        // void finally() { `finally->block` }
     599        const ast::FinallyStmt * finally = tryStmt->finally;
     600        const ast::CompoundStmt * body = finally->body;
     601
     602        ast::FunctionDecl * func_t = ast::deepCopy(finally_func_t);
     603        func_t->stmts = body;
     604
     605        // finally->set_block( nullptr );
     606        // delete finally;
     607        tryStmt->finally = nullptr;
     608
     609
     610        return func_t;
     611}
     612
     613ast::ObjectDecl * TryMutatorCore::create_finally_hook(
     614                ast::FunctionDecl * finally_wrapper ) {
     615        // struct __cfaehm_cleanup_hook __finally_hook
     616        //      __attribute__((cleanup( `finally_wrapper` )));
     617
     618        const CodeLocation loc = finally_wrapper->location;
     619        // Make Cleanup Attribute.
     620        /*
     621        std::list< ast::Attribute * > attributes;
     622        {
     623                std::list<  > attr_params;
     624                attr_params.push_back( nameOf( finally_wrapper ) );
     625                attributes.push_back( new Attribute( "cleanup", attr_params ) );
     626        }
     627        */
     628
     629        return new ast::ObjectDecl(
     630                loc,
     631                "__finally_hook",
     632                new ast::StructInstType(
     633                        hook_decl
     634                        ),
     635                nullptr,
     636                ast::Storage::Classes{},
     637                ast::Linkage::Cforall,
     638                nullptr,
     639                {new ast::Attribute("cleanup", {new ast::VariableExpr{loc, finally_wrapper}})}
     640                );
     641}
     642
     643ast::Stmt * TryMutatorCore::create_resume_rethrow( const ast::ThrowStmt *throwStmt ) {
     644        // return false;
     645        const CodeLocation loc = throwStmt->location;
     646        ast::Stmt * result = new ast::ReturnStmt(loc,
     647                ast::ConstantExpr::from_bool( loc, false )
     648                );
     649        result->labels = throwStmt->labels;
     650        // delete throwStmt; done by postvisit
     651        return result;
     652}
     653
     654// Visiting/Mutating Functions
     655void TryMutatorCore::previsit( const ast::StructDecl *structDecl ) {
     656        if ( !structDecl->body ) {
     657                // Skip children?
     658                return;
     659        } else if ( structDecl->name == "__cfaehm_base_exception_t" ) {
     660                assert( nullptr == except_decl );
     661                except_decl = structDecl;
     662                init_func_types();
     663        } else if ( structDecl->name == "__cfaehm_try_resume_node" ) {
     664                assert( nullptr == node_decl );
     665                node_decl = structDecl;
     666        } else if ( structDecl->name == "__cfaehm_cleanup_hook" ) {
     667                assert( nullptr == hook_decl );
     668                hook_decl = structDecl;
     669        }
     670}
     671
     672ast::Stmt * TryMutatorCore::postvisit( const ast::TryStmt *tryStmt ) {
     673        assert( except_decl );
     674        assert( node_decl );
     675        assert( hook_decl );
     676
     677        const CodeLocation loc = tryStmt->location;
     678        ast::TryStmt * mutStmt = mutate(tryStmt);
     679        // Generate a prefix for the function names?
     680
     681        ast::CompoundStmt * block = new ast::CompoundStmt( loc );
     682        // ast::CompoundStmt * inner = take_try_block( mutStmt );
     683        // this is never mutated so let node deletion do its job?
     684        const ast::CompoundStmt * inner = mutStmt->body;
     685
     686        if ( mutStmt->finally ) {
     687                // Define the helper function.
     688                ast::FunctionDecl * finally_block =
     689                        create_finally_wrapper( mutStmt );
     690                appendDeclStmt( block, finally_block );
     691                // Create and add the finally cleanup hook.
     692                appendDeclStmt( block, create_finally_hook( finally_block ) );
     693        }
     694
     695        CatchList termination_handlers;
     696        CatchList resumption_handlers;
     697
     698        for (auto & handler: mutStmt->handlers) {
     699                // xxx - should always be unique? mutate as safe const-cast
     700                assert(handler->unique());
     701                if (handler->kind == ast::ExceptionKind::Resume) {
     702                        resumption_handlers.push_back(handler.get_and_mutate());
     703                }
     704                else {
     705                        termination_handlers.push_back(handler.get_and_mutate());
     706                }
     707        }
     708        // split( mutStmt->handlers,
     709        //              termination_handlers, resumption_handlers );
     710
     711        if ( resumption_handlers.size() ) {
     712                // Define the helper function.
     713                ast::FunctionDecl * resume_handler =
     714                        create_resume_handler( resumption_handlers );
     715                appendDeclStmt( block, resume_handler );
     716                // Prepare hooks
     717                inner = create_resume_wrapper( inner, resume_handler );
     718        }
     719
     720        if ( termination_handlers.size() ) {
     721                // Define the three helper functions.
     722                ast::FunctionDecl * try_wrapper = create_try_wrapper( inner );
     723                appendDeclStmt( block, try_wrapper );
     724                ast::FunctionDecl * terminate_catch =
     725                        create_terminate_catch( termination_handlers );
     726                appendDeclStmt( block, terminate_catch );
     727                ast::FunctionDecl * terminate_match =
     728                        create_terminate_match( termination_handlers );
     729                appendDeclStmt( block, terminate_match );
     730                // Build the call to the try wrapper.
     731                inner = create_terminate_caller(inner->location,
     732                        try_wrapper, terminate_catch, terminate_match );
     733        }
     734
     735        // Embed the try block.
     736        block->push_back( inner );
     737
     738        return block;
     739}
     740
     741ast::Stmt * TryMutatorCore::postvisit( const ast::ThrowStmt *throwStmt ) {
     742        // Only valid `throwResume;` statements should remain. (2/3 checks)
     743        assert( ast::ExceptionKind::Resume == throwStmt->kind && ! throwStmt->expr );
     744        return create_resume_rethrow( throwStmt );
     745}
     746
    130747} // namespace
    131748
    132749void translateThrows( ast::TranslationUnit & transUnit ) {
    133750        ast::Pass<TranslateThrowsCore>::run( transUnit );
     751}
     752
     753void translateTries( ast::TranslationUnit & transUnit ) {
     754        ast::Pass<TryMutatorCore>::run(transUnit);
    134755}
    135756
  • src/main.cc

    r451d958 r5f3ba11  
    404404                        // Currently not working due to unresolved issues with UniqueExpr
    405405                        PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( transUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
     406
     407                        PASS( "Translate Tries" , ControlStruct::translateTries( transUnit ) );
     408
    406409                        translationUnit = convert( move( transUnit ) );
    407410                } else {
     
    469472
    470473                        PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
     474
     475                        PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );
    471476                }
    472477
    473                 PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );
     478               
    474479
    475480                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
Note: See TracChangeset for help on using the changeset viewer.