summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerdim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/CodeGen/CGException.cpp
parentc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (diff)
downloadFreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.zip
FreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.tar.gz
Vendor import of clang trunk r135360:
http://llvm.org/svn/llvm-project/cfe/trunk@135360
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r--lib/CodeGen/CGException.cpp212
1 files changed, 106 insertions, 106 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index e8ad6da..418bea6 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -29,10 +29,9 @@ using namespace CodeGen;
static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
// void *__cxa_allocate_exception(size_t thrown_size);
- const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
+ llvm::Type *ArgTys[] = { CGF.SizeTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getInt8PtrTy(CGF.getLLVMContext()),
- SizeTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.Int8PtrTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
}
@@ -40,10 +39,9 @@ static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
static llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) {
// void __cxa_free_exception(void *thrown_exception);
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+ llvm::Type *ArgTys[] = { CGF.Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
}
@@ -52,11 +50,9 @@ static llvm::Constant *getThrowFn(CodeGenFunction &CGF) {
// void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
// void (*dest) (void *));
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
- const llvm::Type *Args[3] = { Int8PtrTy, Int8PtrTy, Int8PtrTy };
+ llvm::Type *Args[3] = { CGF.Int8PtrTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- Args, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, Args, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
}
@@ -65,8 +61,7 @@ static llvm::Constant *getReThrowFn(CodeGenFunction &CGF) {
// void __cxa_rethrow();
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
}
@@ -74,9 +69,9 @@ static llvm::Constant *getReThrowFn(CodeGenFunction &CGF) {
static llvm::Constant *getGetExceptionPtrFn(CodeGenFunction &CGF) {
// void *__cxa_get_exception_ptr(void*);
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+ llvm::Type *ArgTys[] = { CGF.Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(Int8PtrTy, Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.Int8PtrTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");
}
@@ -84,9 +79,9 @@ static llvm::Constant *getGetExceptionPtrFn(CodeGenFunction &CGF) {
static llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) {
// void *__cxa_begin_catch(void*);
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+ llvm::Type *ArgTys[] = { CGF.Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(Int8PtrTy, Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.Int8PtrTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
}
@@ -95,8 +90,7 @@ static llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) {
// void __cxa_end_catch();
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
}
@@ -104,17 +98,17 @@ static llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) {
static llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) {
// void __cxa_call_unexepcted(void *thrown_exception);
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+ llvm::Type *ArgTys[] = { CGF.Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
}
llvm::Constant *CodeGenFunction::getUnwindResumeFn() {
+ llvm::Type *ArgTys[] = { Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(VoidTy, ArgTys, /*IsVarArgs=*/false);
if (CGM.getLangOptions().SjLjExceptions)
return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
@@ -122,8 +116,9 @@ llvm::Constant *CodeGenFunction::getUnwindResumeFn() {
}
llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
+ llvm::Type *ArgTys[] = { Int8PtrTy };
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
+ llvm::FunctionType::get(VoidTy, ArgTys, /*IsVarArgs=*/false);
if (CGM.getLangOptions().SjLjExceptions)
return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
@@ -134,20 +129,26 @@ static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
// void __terminate();
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
- /*IsVarArgs=*/false);
+ llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false);
- return CGF.CGM.CreateRuntimeFunction(FTy,
- CGF.CGM.getLangOptions().CPlusPlus ? "_ZSt9terminatev" : "abort");
+ llvm::StringRef name;
+
+ // In C++, use std::terminate().
+ if (CGF.getLangOptions().CPlusPlus)
+ name = "_ZSt9terminatev"; // FIXME: mangling!
+ else if (CGF.getLangOptions().ObjC1 &&
+ CGF.CGM.getCodeGenOpts().ObjCRuntimeHasTerminate)
+ name = "objc_terminate";
+ else
+ name = "abort";
+ return CGF.CGM.CreateRuntimeFunction(FTy, name);
}
static llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF,
llvm::StringRef Name) {
- const llvm::Type *Int8PtrTy =
- llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
- const llvm::Type *VoidTy = llvm::Type::getVoidTy(CGF.getLLVMContext());
- const llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, Int8PtrTy,
- /*IsVarArgs=*/false);
+ llvm::Type *ArgTys[] = { CGF.Int8PtrTy };
+ const llvm::FunctionType *FTy =
+ llvm::FunctionType::get(CGF.VoidTy, ArgTys, /*IsVarArgs=*/false);
return CGF.CGM.CreateRuntimeFunction(FTy, Name);
}
@@ -322,9 +323,10 @@ static llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
namespace {
/// A cleanup to free the exception object if its initialization
/// throws.
- struct FreeException {
- static void Emit(CodeGenFunction &CGF, bool forEH,
- llvm::Value *exn) {
+ struct FreeException : EHScopeStack::Cleanup {
+ llvm::Value *exn;
+ FreeException(llvm::Value *exn) : exn(exn) {}
+ void Emit(CodeGenFunction &CGF, Flags flags) {
CGF.Builder.CreateCall(getFreeExceptionFn(CGF), exn)
->setDoesNotThrow();
}
@@ -354,7 +356,8 @@ static void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *e,
// evaluated but before the exception is caught. But the best way
// to handle that is to teach EmitAggExpr to do the final copy
// differently if it can't be elided.
- CGF.EmitAnyExprToMem(e, typedAddr, /*Volatile*/ false, /*IsInit*/ true);
+ CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
+ /*IsInit*/ true);
// Deactivate the cleanup block.
CGF.DeactivateCleanupBlock(cleanup);
@@ -407,7 +410,6 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
// Now throw the exception.
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
/*ForEH=*/true);
@@ -786,7 +788,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
// Tell the backend how to generate the landing pad.
llvm::CallInst *Selection =
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- EHSelector.begin(), EHSelector.end(), "eh.selector");
+ EHSelector, "eh.selector");
Selection->setDoesNotThrow();
// Save the selector value in mandatory-cleanup mode.
@@ -920,13 +922,13 @@ namespace {
CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
bool MightThrow;
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ void Emit(CodeGenFunction &CGF, Flags flags) {
if (!MightThrow) {
CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow();
return;
}
- CGF.EmitCallOrInvoke(getEndCatchFn(CGF), 0, 0);
+ CGF.EmitCallOrInvoke(getEndCatchFn(CGF));
}
};
}
@@ -1084,7 +1086,8 @@ static void InitCatchParam(CodeGenFunction &CGF,
CGF.EHStack.pushTerminate();
// Perform the copy construction.
- CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, false, false));
+ CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, Qualifiers(),
+ false));
// Leave the terminate scope.
CGF.EHStack.popTerminate();
@@ -1137,8 +1140,8 @@ static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {
namespace {
struct CallRethrow : EHScopeStack::Cleanup {
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
- CGF.EmitCallOrInvoke(getReThrowFn(CGF), 0, 0);
+ void Emit(CodeGenFunction &CGF, Flags flags) {
+ CGF.EmitCallOrInvoke(getReThrowFn(CGF));
}
};
}
@@ -1209,7 +1212,7 @@ namespace {
CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
: ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ void Emit(CodeGenFunction &CGF, Flags flags) {
llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
llvm::BasicBlock *CleanupContBB =
CGF.createBasicBlock("finally.cleanup.cont");
@@ -1218,7 +1221,7 @@ namespace {
CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch");
CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
CGF.EmitBlock(EndCatchBB);
- CGF.EmitCallOrInvoke(EndCatchFn, 0, 0); // catch-all, so might throw
+ CGF.EmitCallOrInvoke(EndCatchFn); // catch-all, so might throw
CGF.EmitBlock(CleanupContBB);
}
};
@@ -1236,7 +1239,7 @@ namespace {
: Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ void Emit(CodeGenFunction &CGF, Flags flags) {
// Enter a cleanup to call the end-catch function if one was provided.
if (EndCatchFn)
CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
@@ -1263,10 +1266,9 @@ namespace {
CGF.EmitBlock(RethrowBB);
if (SavedExnVar) {
- llvm::Value *Args[] = { CGF.Builder.CreateLoad(SavedExnVar) };
- CGF.EmitCallOrInvoke(RethrowFn, Args, Args+1);
+ CGF.EmitCallOrInvoke(RethrowFn, CGF.Builder.CreateLoad(SavedExnVar));
} else {
- CGF.EmitCallOrInvoke(RethrowFn, 0, 0);
+ CGF.EmitCallOrInvoke(RethrowFn);
}
CGF.Builder.CreateUnreachable();
@@ -1296,14 +1298,16 @@ namespace {
/// Enters a finally block for an implementation using zero-cost
/// exceptions. This is mostly general, but hard-codes some
/// language/ABI-specific behavior in the catch-all sections.
-CodeGenFunction::FinallyInfo
-CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
- llvm::Constant *BeginCatchFn,
- llvm::Constant *EndCatchFn,
- llvm::Constant *RethrowFn) {
- assert((BeginCatchFn != 0) == (EndCatchFn != 0) &&
+void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
+ const Stmt *body,
+ llvm::Constant *beginCatchFn,
+ llvm::Constant *endCatchFn,
+ llvm::Constant *rethrowFn) {
+ assert((beginCatchFn != 0) == (endCatchFn != 0) &&
"begin/end catch functions not paired");
- assert(RethrowFn && "rethrow function is required");
+ assert(rethrowFn && "rethrow function is required");
+
+ BeginCatchFn = beginCatchFn;
// The rethrow function has one of the following two types:
// void (*)()
@@ -1311,13 +1315,12 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
// In the latter case we need to pass it the exception object.
// But we can't use the exception slot because the @finally might
// have a landing pad (which would overwrite the exception slot).
- const llvm::FunctionType *RethrowFnTy =
+ const llvm::FunctionType *rethrowFnTy =
cast<llvm::FunctionType>(
- cast<llvm::PointerType>(RethrowFn->getType())
- ->getElementType());
- llvm::Value *SavedExnVar = 0;
- if (RethrowFnTy->getNumParams())
- SavedExnVar = CreateTempAlloca(Builder.getInt8PtrTy(), "finally.exn");
+ cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
+ SavedExnVar = 0;
+ if (rethrowFnTy->getNumParams())
+ SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
// A finally block is a statement which must be executed on any edge
// out of a given scope. Unlike a cleanup, the finally block may
@@ -1331,67 +1334,64 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
// The finally block itself is generated in the context of a cleanup
// which conditionally leaves the catch-all.
- FinallyInfo Info;
-
// Jump destination for performing the finally block on an exception
// edge. We'll never actually reach this block, so unreachable is
// fine.
- JumpDest RethrowDest = getJumpDestInCurrentScope(getUnreachableBlock());
+ RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
// Whether the finally block is being executed for EH purposes.
- llvm::AllocaInst *ForEHVar = CreateTempAlloca(Builder.getInt1Ty(),
- "finally.for-eh");
- InitTempAlloca(ForEHVar, llvm::ConstantInt::getFalse(getLLVMContext()));
+ ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
+ CGF.Builder.CreateStore(CGF.Builder.getFalse(), ForEHVar);
// Enter a normal cleanup which will perform the @finally block.
- EHStack.pushCleanup<PerformFinally>(NormalCleanup, Body,
- ForEHVar, EndCatchFn,
- RethrowFn, SavedExnVar);
+ CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
+ ForEHVar, endCatchFn,
+ rethrowFn, SavedExnVar);
// Enter a catch-all scope.
- llvm::BasicBlock *CatchAllBB = createBasicBlock("finally.catchall");
- CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
- Builder.SetInsertPoint(CatchAllBB);
-
- // If there's a begin-catch function, call it.
- if (BeginCatchFn) {
- Builder.CreateCall(BeginCatchFn, Builder.CreateLoad(getExceptionSlot()))
- ->setDoesNotThrow();
- }
-
- // If we need to remember the exception pointer to rethrow later, do so.
- if (SavedExnVar) {
- llvm::Value *SavedExn = Builder.CreateLoad(getExceptionSlot());
- Builder.CreateStore(SavedExn, SavedExnVar);
- }
+ llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
+ EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
+ catchScope->setCatchAllHandler(0, catchBB);
+}
- // Tell the finally block that we're in EH.
- Builder.CreateStore(llvm::ConstantInt::getTrue(getLLVMContext()), ForEHVar);
+void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
+ // Leave the finally catch-all.
+ EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
+ llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
+ CGF.EHStack.popCatch();
- // Thread a jump through the finally cleanup.
- EmitBranchThroughCleanup(RethrowDest);
+ // If there are any references to the catch-all block, emit it.
+ if (catchBB->use_empty()) {
+ delete catchBB;
+ } else {
+ CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
+ CGF.EmitBlock(catchBB);
- Builder.restoreIP(SavedIP);
+ llvm::Value *exn = 0;
- EHCatchScope *CatchScope = EHStack.pushCatch(1);
- CatchScope->setCatchAllHandler(0, CatchAllBB);
+ // If there's a begin-catch function, call it.
+ if (BeginCatchFn) {
+ exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
+ CGF.Builder.CreateCall(BeginCatchFn, exn)->setDoesNotThrow();
+ }
- return Info;
-}
+ // If we need to remember the exception pointer to rethrow later, do so.
+ if (SavedExnVar) {
+ if (!exn) exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
+ CGF.Builder.CreateStore(exn, SavedExnVar);
+ }
-void CodeGenFunction::ExitFinallyBlock(FinallyInfo &Info) {
- // Leave the finally catch-all.
- EHCatchScope &Catch = cast<EHCatchScope>(*EHStack.begin());
- llvm::BasicBlock *CatchAllBB = Catch.getHandler(0).Block;
- EHStack.popCatch();
+ // Tell the cleanups in the finally block that we're do this for EH.
+ CGF.Builder.CreateStore(CGF.Builder.getTrue(), ForEHVar);
- // And leave the normal cleanup.
- PopCleanupBlock();
+ // Thread a jump through the finally cleanup.
+ CGF.EmitBranchThroughCleanup(RethrowDest);
- CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
- EmitBlock(CatchAllBB, true);
+ CGF.Builder.restoreIP(savedIP);
+ }
- Builder.restoreIP(SavedIP);
+ // Finally, leave the @finally cleanup.
+ CGF.PopCleanupBlock();
}
llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
@@ -1416,7 +1416,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
llvm::Value *Args[3] = { Exn, getOpaquePersonalityFn(CGM, Personality),
getCatchAllValue(*this) };
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- Args, Args+3, "eh.selector")
+ Args, "eh.selector")
->setDoesNotThrow();
llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
OpenPOWER on IntegriCloud