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)); }
void IRLandingPad::addFinally(Statement* finallystmt) { unpushed_infos.push_front(IRLandingPadInfo(finallystmt)); }
void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end) { unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end)); }