diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-03-03 19:21:04 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-03-03 19:21:04 +0000 |
commit | fff8e7f6ba1e05d4c45df6923609a73e0300db1f (patch) | |
tree | ba080c0ecf6356ec5adc3c2f523421a7b4b553ab /clang/lib/CodeGen/MicrosoftCXXABI.cpp | |
parent | 5b240485b73db875dca0fd24e13c6485bbad3444 (diff) | |
download | bcm5719-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.cpp | 41 |
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) { |