summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r--clang/lib/CodeGen/CGException.cpp113
1 files changed, 54 insertions, 59 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index e7119149557..14a89cff3f9 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -306,12 +306,6 @@ static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
}
-/// Returns the value to inject into a selector to indicate the
-/// presence of a cleanup.
-static llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
- return llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
-}
-
namespace {
/// A cleanup to free the exception object if its initialization
/// throws.
@@ -733,17 +727,19 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
llvm::BasicBlock *lpad = createBasicBlock("lpad");
EmitBlock(lpad);
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
+ getOpaquePersonalityFn(CGM, personality), 0);
+
+ llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
+ Builder.CreateStore(LPadExn, getExceptionSlot());
+ llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
+ Builder.CreateStore(LPadSel, getEHSelectorSlot());
+
// Save the exception pointer. It's safe to use a single exception
// pointer per function because EH cleanups can never have nested
// try/catches.
- llvm::CallInst *exn =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
- exn->setDoesNotThrow();
-
- // Build the selector arguments.
- SmallVector<llvm::Value*, 8> selector;
- selector.push_back(exn);
- selector.push_back(getOpaquePersonalityFn(CGM, personality));
+ // Build the landingpad instruction.
// Accumulate all the handlers in scope.
bool hasCatchAll = false;
@@ -764,7 +760,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
assert(!hasCatchAll && "EH filter reached after catch-all");
- // Filter scopes get added to the selector in weird ways.
+ // Filter scopes get added to the landingpad in weird ways.
EHFilterScope &filter = cast<EHFilterScope>(*I);
hasFilter = true;
@@ -800,54 +796,52 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
}
// Check whether we already have a handler for this type.
- if (catchTypes.insert(handler.Type)) {
- // If not, add it directly to the selector.
- selector.push_back(handler.Type);
- }
+ if (catchTypes.insert(handler.Type))
+ // If not, add it directly to the landingpad.
+ LPadInst->addClause(handler.Type);
}
}
done:
- // If we have a catch-all, add null to the selector.
+ // If we have a catch-all, add null to the landingpad.
assert(!(hasCatchAll && hasFilter));
if (hasCatchAll) {
- selector.push_back(getCatchAllValue(*this));
+ LPadInst->addClause(getCatchAllValue(*this));
// If we have an EH filter, we need to add those handlers in the
- // right place in the selector, which is to say, at the end.
+ // right place in the landingpad, which is to say, at the end.
} else if (hasFilter) {
// Create a filter expression: an integer constant saying how many
// filters there are (+1 to avoid ambiguity with 0 for cleanup),
// followed by the filter types. The personality routine only
// lands here if the filter doesn't match.
- selector.push_back(Builder.getInt32(filterTypes.size() + 1));
- selector.append(filterTypes.begin(), filterTypes.end());
+ llvm::SmallVector<llvm::Constant*, 8> Filters;
+ llvm::ArrayType *AType =
+ llvm::ArrayType::get(!filterTypes.empty() ?
+ filterTypes[0]->getType() : Int8PtrTy,
+ filterTypes.size());
+
+ for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
+ Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
+ llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
+ LPadInst->addClause(FilterArray);
// Also check whether we need a cleanup.
- if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup)
- selector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
- ? getCatchAllValue(*this)
- : getCleanupValue(*this));
+ if (hasCleanup)
+ LPadInst->setCleanup(true);
// Otherwise, signal that we at least have cleanups.
} else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {
- selector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
- ? getCatchAllValue(*this)
- : getCleanupValue(*this));
+ if (CleanupHackLevel == CHL_MandatoryCatchall)
+ LPadInst->addClause(getCatchAllValue(*this));
+ else
+ LPadInst->setCleanup(true);
}
- assert(selector.size() >= 3 && "selector call has only two arguments!");
+ assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
+ "landingpad instruction has no clauses!");
// Tell the backend how to generate the landing pad.
- llvm::CallInst *selectorCall =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- selector, "eh.selector");
- selectorCall->setDoesNotThrow();
-
- // Save the selector and exception pointer.
- Builder.CreateStore(exn, getExceptionSlot());
- Builder.CreateStore(selectorCall, getEHSelectorSlot());
-
Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
// Restore the old IR generation state.
@@ -1462,19 +1456,11 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
Builder.SetInsertPoint(TerminateLandingPad);
// Tell the backend that this is a landing pad.
- llvm::CallInst *Exn =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
- Exn->setDoesNotThrow();
-
const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
-
- // Tell the backend what the exception table should be:
- // nothing but a catch-all.
- llvm::Value *Args[3] = { Exn, getOpaquePersonalityFn(CGM, Personality),
- getCatchAllValue(*this) };
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- Args, "eh.selector")
- ->setDoesNotThrow();
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
+ getOpaquePersonalityFn(CGM, Personality), 0);
+ LPadInst->addClause(getCatchAllValue(*this));
llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
TerminateCall->setDoesNotReturn();
@@ -1538,12 +1524,21 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock() {
->setDoesNotReturn();
break;
case CHL_MandatoryCleanup: {
- // In mandatory-cleanup mode, we should use llvm.eh.resume.
- llvm::Value *Selector = getSelectorFromSlot();
- Builder.CreateCall2(CGM.getIntrinsic(llvm::Intrinsic::eh_resume),
- Exn, Selector)
- ->setDoesNotReturn();
- break;
+ // In mandatory-cleanup mode, we should use 'resume'.
+
+ // Recreate the landingpad's return value for the 'resume' instruction.
+ llvm::Value *Exn = getExceptionFromSlot();
+ llvm::Value *Sel = getSelectorFromSlot();
+
+ llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
+ Sel->getType(), NULL);
+ llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
+ LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
+ LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
+
+ Builder.CreateResume(LPadVal);
+ Builder.restoreIP(SavedIP);
+ return EHResumeBlock;
}
case CHL_Ideal:
// In an idealized mode where we don't have to worry about the
OpenPOWER on IntegriCloud