Example #1
0
IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end)
: finallyBody(NULL)
{
    target = llvm::BasicBlock::Create(gIR->context(), "catch", gIR->topfunc(), end);
    gIR->scope() = IRScope(target,end);
    DtoDwarfBlockStart(catchstmt->loc);

    // assign storage to catch var
    if(catchstmt->var) {
        // use the same storage for all exceptions that are not accessed in
        // nested functions
    #if DMDV2
        if(!catchstmt->var->nestedrefs.dim) {
    #else
        if(!catchstmt->var->nestedref) {
    #endif
            assert(!catchstmt->var->ir.irLocal);
            catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
            LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage();
            catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
        }

        // this will alloca if we haven't already and take care of nested refs
        DtoDeclarationExp(catchstmt->var);

        // the exception will only be stored in catch_var. copy it over if necessary
        if(catchstmt->var->ir.irLocal->value != gIR->func()->gen->landingPadInfo.getExceptionStorage()) {
            LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type));
            DtoStore(exc, catchstmt->var->ir.irLocal->value);
        }
    }

    // emit handler, if there is one
    // handler is zero for instance for 'catch { debug foo(); }'
    if(catchstmt->handler)
        catchstmt->handler->toIR(gIR);

    if (!gIR->scopereturned())
        gIR->ir->CreateBr(end);

    assert(catchstmt->type);
    catchType = catchstmt->type->toBasetype()->isClassHandle();
    assert(catchType);
    catchType->codegen(Type::sir);
    DtoDwarfBlockEnd();
}

IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt)
: target(NULL), finallyBody(finallystmt), catchType(NULL)
{

}


void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end)
{
    unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end));
}
Example #2
0
void IRLandingPad::addFinally(Statement* finallystmt)
{
    unpushed_infos.push_front(IRLandingPadInfo(finallystmt));
}
Example #3
0
void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end)
{
    unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end));
}