summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-03-03 19:21:04 +0000
committerReid Kleckner <reid@kleckner.net>2015-03-03 19:21:04 +0000
commitfff8e7f6ba1e05d4c45df6923609a73e0300db1f (patch)
treeba080c0ecf6356ec5adc3c2f523421a7b4b553ab /clang/lib/CodeGen/MicrosoftCXXABI.cpp
parent5b240485b73db875dca0fd24e13c6485bbad3444 (diff)
downloadbcm5719-llvm-fff8e7f6ba1e05d4c45df6923609a73e0300db1f.tar.gz
bcm5719-llvm-fff8e7f6ba1e05d4c45df6923609a73e0300db1f.zip
Split catch IRgen into ItaniumCXXABI and MicrosoftCXXABI
Use llvm.eh.begincatch for Microsoft-style catches. This moves lots of CGException code into ItaniumCXXABI. Sorry for the blame pain. llvm-svn: 231105
Diffstat (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 4a07d406eb8..399a6e4d420 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -17,12 +17,15 @@
#include "CGCXXABI.h"
#include "CGVTables.h"
#include "CodeGenModule.h"
+#include "TargetInfo.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/StmtCXX.h"
#include "clang/AST/VTableBuilder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Intrinsics.h"
using namespace clang;
using namespace CodeGen;
@@ -72,6 +75,8 @@ public:
void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
+ void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
+
llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
const VPtrInfo *Info);
@@ -695,6 +700,42 @@ void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
CGF.EmitRuntimeCallOrInvoke(Fn, Args);
}
+namespace {
+struct CallEndCatchMSVC : EHScopeStack::Cleanup {
+ CallEndCatchMSVC() {}
+ void Emit(CodeGenFunction &CGF, Flags flags) override {
+ CGF.EmitNounwindRuntimeCall(
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_endcatch));
+ }
+};
+}
+
+void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
+ const CXXCatchStmt *S) {
+ // In the MS ABI, the runtime handles the copy, and the catch handler is
+ // responsible for destruction.
+ VarDecl *CatchParam = S->getExceptionDecl();
+ llvm::Value *Exn = CGF.getExceptionFromSlot();
+ llvm::Function *BeginCatch =
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_begincatch);
+
+ if (!CatchParam) {
+ llvm::Value *Args[2] = {Exn, llvm::Constant::getNullValue(CGF.Int8PtrTy)};
+ CGF.EmitNounwindRuntimeCall(BeginCatch, Args);
+ CGF.EHStack.pushCleanup<CallEndCatchMSVC>(NormalAndEHCleanup);
+ return;
+ }
+
+ CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
+ llvm::Value *ParamAddr =
+ CGF.Builder.CreateBitCast(var.getObjectAddress(CGF), CGF.Int8PtrTy);
+ llvm::Value *Args[2] = {Exn, ParamAddr};
+ CGF.EmitNounwindRuntimeCall(BeginCatch, Args);
+ // FIXME: Do we really need exceptional endcatch cleanups?
+ CGF.EHStack.pushCleanup<CallEndCatchMSVC>(NormalAndEHCleanup);
+ CGF.EmitAutoVarCleanups(var);
+}
+
std::pair<llvm::Value *, llvm::Value *>
MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, llvm::Value *Value,
QualType SrcRecordTy) {
OpenPOWER on IntegriCloud