CGException.cpp revision da549e8995c447542d5631b8b67fcc3a9582797a
1756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===// 2756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 3756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// The LLVM Compiler Infrastructure 4756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 5756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This file is distributed under the University of Illinois Open Source 6756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// License. See LICENSE.TXT for details. 7756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 8756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===// 9756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 10756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This contains code dealing with C++ exception related code generation. 11756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 12756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===// 13756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson 142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "clang/AST/StmtCXX.h" 152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "llvm/Intrinsics.h" 17b25938303de0976b9f189363d43033e5788e3d36John McCall#include "llvm/IntrinsicInst.h" 18f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall#include "llvm/Support/CallSite.h" 192bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 205a180397870944548aaadeaebf58e415885b9489John McCall#include "CGObjCRuntime.h" 21756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson#include "CodeGenFunction.h" 22f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall#include "CGException.h" 2336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CGCleanup.h" 24204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall#include "TargetInfo.h" 25f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 26756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace clang; 27756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace CodeGen; 28756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson 29d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) { 30d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // void *__cxa_allocate_exception(size_t thrown_size); 318755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 33da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.Int8PtrTy, CGF.SizeTy, /*IsVarArgs=*/false); 348755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 35d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception"); 36d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson} 37d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 3899533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) { 3999533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_free_exception(void *thrown_exception); 408755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 412acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 42da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, /*IsVarArgs=*/false); 438755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 4499533834ba8f3658559f334e68a518ebb6388ceaMike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception"); 4599533834ba8f3658559f334e68a518ebb6388ceaMike Stump} 4699533834ba8f3658559f334e68a518ebb6388ceaMike Stump 47d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getThrowFn(CodeGenFunction &CGF) { 488755ec336108839b9621c3b18f0e175f8a3b671cMike Stump // void __cxa_throw(void *thrown_exception, std::type_info *tinfo, 4999533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void (*dest) (void *)); 50d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 5161c1601e2a8534c09cb7032f791f918158abaa27John McCall llvm::Type *Args[3] = { CGF.Int8PtrTy, CGF.Int8PtrTy, CGF.Int8PtrTy }; 522acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 5361c1601e2a8534c09cb7032f791f918158abaa27John McCall llvm::FunctionType::get(CGF.VoidTy, Args, /*IsVarArgs=*/false); 548755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 55d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw"); 56d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson} 57d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 58b4eea691866a3fa75722da9eba735c44f140398aMike Stumpstatic llvm::Constant *getReThrowFn(CodeGenFunction &CGF) { 5999533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_rethrow(); 60b4eea691866a3fa75722da9eba735c44f140398aMike Stump 612acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 6261c1601e2a8534c09cb7032f791f918158abaa27John McCall llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false); 638755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 64b4eea691866a3fa75722da9eba735c44f140398aMike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow"); 65b4eea691866a3fa75722da9eba735c44f140398aMike Stump} 66b4eea691866a3fa75722da9eba735c44f140398aMike Stump 67f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getGetExceptionPtrFn(CodeGenFunction &CGF) { 68f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // void *__cxa_get_exception_ptr(void*); 69f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 71da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, /*IsVarArgs=*/false); 72f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 73f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr"); 74f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 75f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 762bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) { 77f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // void *__cxa_begin_catch(void*); 782bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 792acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 80da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, /*IsVarArgs=*/false); 818755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 822bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); 832bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 842bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 852bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) { 8699533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_end_catch(); 872bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 882acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 8961c1601e2a8534c09cb7032f791f918158abaa27John McCall llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false); 908755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 912bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch"); 922bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 932bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 94cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpstatic llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) { 95cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // void __cxa_call_unexepcted(void *thrown_exception); 96cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 972acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 98da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, /*IsVarArgs=*/false); 998755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 100cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected"); 101cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 102cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 10393c332a8ba2c193c435b293966d343dab15f555bJohn McCallllvm::Constant *CodeGenFunction::getUnwindResumeFn() { 1042acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 105da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false); 10693c332a8ba2c193c435b293966d343dab15f555bJohn McCall 10793c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (CGM.getLangOptions().SjLjExceptions) 10893c332a8ba2c193c435b293966d343dab15f555bJohn McCall return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume"); 10993c332a8ba2c193c435b293966d343dab15f555bJohn McCall return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume"); 11093c332a8ba2c193c435b293966d343dab15f555bJohn McCall} 11193c332a8ba2c193c435b293966d343dab15f555bJohn McCall 11286a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregorllvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() { 1132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 114da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false); 1158755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 11686a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor if (CGM.getLangOptions().SjLjExceptions) 117a5f2de2e49e25ece82dd9fd63d8f390a7cda6417John McCall return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow"); 11886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow"); 1190f590be3808365e851352543faa6acbece50b686Mike Stump} 1200f590be3808365e851352543faa6acbece50b686Mike Stump 12199533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getTerminateFn(CodeGenFunction &CGF) { 12299533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __terminate(); 12399533834ba8f3658559f334e68a518ebb6388ceaMike Stump 1242acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 12561c1601e2a8534c09cb7032f791f918158abaa27John McCall llvm::FunctionType::get(CGF.VoidTy, /*IsVarArgs=*/false); 1268755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 1275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef name; 128256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall 129256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall // In C++, use std::terminate(). 130256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall if (CGF.getLangOptions().CPlusPlus) 131256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall name = "_ZSt9terminatev"; // FIXME: mangling! 132256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall else if (CGF.getLangOptions().ObjC1 && 133256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall CGF.CGM.getCodeGenOpts().ObjCRuntimeHasTerminate) 134256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall name = "objc_terminate"; 135256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall else 136256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall name = "abort"; 137256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall return CGF.CGM.CreateRuntimeFunction(FTy, name); 13879a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall} 13979a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall 1408262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallstatic llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF, 1415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name) { 1422acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 143da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, /*IsVarArgs=*/false); 1448262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 1458262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return CGF.CGM.CreateRuntimeFunction(FTy, Name); 146f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1488262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality EHPersonality::GNU_C("__gcc_personality_v0"); 14944680786286f4f651603c6811f8412a3ee7fe975John McCallconst EHPersonality EHPersonality::GNU_C_SJLJ("__gcc_personality_sj0"); 1508262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality EHPersonality::NeXT_ObjC("__objc_personality_v0"); 1518262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality EHPersonality::GNU_CPlusPlus("__gxx_personality_v0"); 1528262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ("__gxx_personality_sj0"); 1538262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality EHPersonality::GNU_ObjC("__gnu_objc_personality_v0", 1548262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall "objc_exception_throw"); 15580558d2db10a96eada4d8fb79949b3263b44652bDavid Chisnallconst EHPersonality EHPersonality::GNU_ObjCXX("__gnustep_objcxx_personality_v0"); 1568262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 1578262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallstatic const EHPersonality &getCPersonality(const LangOptions &L) { 15844680786286f4f651603c6811f8412a3ee7fe975John McCall if (L.SjLjExceptions) 15944680786286f4f651603c6811f8412a3ee7fe975John McCall return EHPersonality::GNU_C_SJLJ; 1608262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return EHPersonality::GNU_C; 1618262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall} 1628262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 1638262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallstatic const EHPersonality &getObjCPersonality(const LangOptions &L) { 1648262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.NeXTRuntime) { 1658262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.ObjCNonFragileABI) return EHPersonality::NeXT_ObjC; 1668262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall else return getCPersonality(L); 167f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 1688262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return EHPersonality::GNU_ObjC; 169f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1728262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallstatic const EHPersonality &getCXXPersonality(const LangOptions &L) { 1738262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.SjLjExceptions) 1748262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return EHPersonality::GNU_CPlusPlus_SJLJ; 175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall else 1768262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return EHPersonality::GNU_CPlusPlus; 177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 179f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Determines the personality function to use when both C++ 180f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// and Objective-C exceptions are being caught. 1818262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallstatic const EHPersonality &getObjCXXPersonality(const LangOptions &L) { 182f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The ObjC personality defers to the C++ personality for non-ObjC 183f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // handlers. Unlike the C++ case, we use the same personality 184f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // function on targets using (backend-driven) SJLJ EH. 1858262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.NeXTRuntime) { 1868262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.ObjCNonFragileABI) 1878262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return EHPersonality::NeXT_ObjC; 188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 189f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // In the fragile ABI, just use C++ exception handling and hope 190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // they're not doing crazy exception mixing. 1918019c45024be3026f854e3d22bfd89842be82266Daniel Dunbar else 1928262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return getCXXPersonality(L); 193dcf22ad88fdb6c4dd74f9065262cde8bac4f807bChandler Carruth } 19479a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall 1958262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall // The GNU runtime's personality function inherently doesn't support 1968262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall // mixed EH. Use the C++ personality just to avoid returning null. 19780558d2db10a96eada4d8fb79949b3263b44652bDavid Chisnall return EHPersonality::GNU_ObjCXX; 198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 2008262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCallconst EHPersonality &EHPersonality::get(const LangOptions &L) { 2018262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall if (L.CPlusPlus && L.ObjC1) 2028262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return getObjCXXPersonality(L); 2038262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall else if (L.CPlusPlus) 2048262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return getCXXPersonality(L); 2058262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall else if (L.ObjC1) 2068262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return getObjCPersonality(L); 207f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall else 2088262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall return getCPersonality(L); 2098262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall} 2108262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 211b25938303de0976b9f189363d43033e5788e3d36John McCallstatic llvm::Constant *getPersonalityFn(CodeGenModule &CGM, 2128262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall const EHPersonality &Personality) { 2138262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall llvm::Constant *Fn = 214b25938303de0976b9f189363d43033e5788e3d36John McCall CGM.CreateRuntimeFunction(llvm::FunctionType::get( 215b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::Type::getInt32Ty(CGM.getLLVMContext()), 216b25938303de0976b9f189363d43033e5788e3d36John McCall true), 217b25938303de0976b9f189363d43033e5788e3d36John McCall Personality.getPersonalityFnName()); 218b25938303de0976b9f189363d43033e5788e3d36John McCall return Fn; 219b25938303de0976b9f189363d43033e5788e3d36John McCall} 220b25938303de0976b9f189363d43033e5788e3d36John McCall 221b25938303de0976b9f189363d43033e5788e3d36John McCallstatic llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM, 222b25938303de0976b9f189363d43033e5788e3d36John McCall const EHPersonality &Personality) { 223b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::Constant *Fn = getPersonalityFn(CGM, Personality); 224d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy); 225b25938303de0976b9f189363d43033e5788e3d36John McCall} 226b25938303de0976b9f189363d43033e5788e3d36John McCall 227b25938303de0976b9f189363d43033e5788e3d36John McCall/// Check whether a personality function could reasonably be swapped 228b25938303de0976b9f189363d43033e5788e3d36John McCall/// for a C++ personality function. 229b25938303de0976b9f189363d43033e5788e3d36John McCallstatic bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) { 230b25938303de0976b9f189363d43033e5788e3d36John McCall for (llvm::Constant::use_iterator 231b25938303de0976b9f189363d43033e5788e3d36John McCall I = Fn->use_begin(), E = Fn->use_end(); I != E; ++I) { 232b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::User *User = *I; 233b25938303de0976b9f189363d43033e5788e3d36John McCall 234b25938303de0976b9f189363d43033e5788e3d36John McCall // Conditionally white-list bitcasts. 235b25938303de0976b9f189363d43033e5788e3d36John McCall if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(User)) { 236b25938303de0976b9f189363d43033e5788e3d36John McCall if (CE->getOpcode() != llvm::Instruction::BitCast) return false; 237b25938303de0976b9f189363d43033e5788e3d36John McCall if (!PersonalityHasOnlyCXXUses(CE)) 238b25938303de0976b9f189363d43033e5788e3d36John McCall return false; 239b25938303de0976b9f189363d43033e5788e3d36John McCall continue; 240b25938303de0976b9f189363d43033e5788e3d36John McCall } 241b25938303de0976b9f189363d43033e5788e3d36John McCall 242b25938303de0976b9f189363d43033e5788e3d36John McCall // Otherwise, it has to be a selector call. 243b25938303de0976b9f189363d43033e5788e3d36John McCall if (!isa<llvm::EHSelectorInst>(User)) return false; 244b25938303de0976b9f189363d43033e5788e3d36John McCall 245b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::EHSelectorInst *Selector = cast<llvm::EHSelectorInst>(User); 246b25938303de0976b9f189363d43033e5788e3d36John McCall for (unsigned I = 2, E = Selector->getNumArgOperands(); I != E; ++I) { 247b25938303de0976b9f189363d43033e5788e3d36John McCall // Look for something that would've been returned by the ObjC 248b25938303de0976b9f189363d43033e5788e3d36John McCall // runtime's GetEHType() method. 249b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::GlobalVariable *GV 250b25938303de0976b9f189363d43033e5788e3d36John McCall = dyn_cast<llvm::GlobalVariable>(Selector->getArgOperand(I)); 251b25938303de0976b9f189363d43033e5788e3d36John McCall if (!GV) continue; 252b25938303de0976b9f189363d43033e5788e3d36John McCall 253b25938303de0976b9f189363d43033e5788e3d36John McCall // ObjC EH selector entries are always global variables with 254b25938303de0976b9f189363d43033e5788e3d36John McCall // names starting like this. 255b25938303de0976b9f189363d43033e5788e3d36John McCall if (GV->getName().startswith("OBJC_EHTYPE")) 256b25938303de0976b9f189363d43033e5788e3d36John McCall return false; 257b25938303de0976b9f189363d43033e5788e3d36John McCall } 258b25938303de0976b9f189363d43033e5788e3d36John McCall } 259b25938303de0976b9f189363d43033e5788e3d36John McCall 260b25938303de0976b9f189363d43033e5788e3d36John McCall return true; 261b25938303de0976b9f189363d43033e5788e3d36John McCall} 262b25938303de0976b9f189363d43033e5788e3d36John McCall 263b25938303de0976b9f189363d43033e5788e3d36John McCall/// Try to use the C++ personality function in ObjC++. Not doing this 264b25938303de0976b9f189363d43033e5788e3d36John McCall/// can cause some incompatibilities with gcc, which is more 265b25938303de0976b9f189363d43033e5788e3d36John McCall/// aggressive about only using the ObjC++ personality in a function 266b25938303de0976b9f189363d43033e5788e3d36John McCall/// when it really needs it. 267b25938303de0976b9f189363d43033e5788e3d36John McCallvoid CodeGenModule::SimplifyPersonality() { 268b25938303de0976b9f189363d43033e5788e3d36John McCall // For now, this is really a Darwin-specific operation. 269eab80782f645489db299db24aa7a5886b37185b0Daniel Dunbar if (!Context.Target.getTriple().isOSDarwin()) 270b25938303de0976b9f189363d43033e5788e3d36John McCall return; 271b25938303de0976b9f189363d43033e5788e3d36John McCall 272b25938303de0976b9f189363d43033e5788e3d36John McCall // If we're not in ObjC++ -fexceptions, there's nothing to do. 273b25938303de0976b9f189363d43033e5788e3d36John McCall if (!Features.CPlusPlus || !Features.ObjC1 || !Features.Exceptions) 274b25938303de0976b9f189363d43033e5788e3d36John McCall return; 275b25938303de0976b9f189363d43033e5788e3d36John McCall 276b25938303de0976b9f189363d43033e5788e3d36John McCall const EHPersonality &ObjCXX = EHPersonality::get(Features); 277b25938303de0976b9f189363d43033e5788e3d36John McCall const EHPersonality &CXX = getCXXPersonality(Features); 278b25938303de0976b9f189363d43033e5788e3d36John McCall if (&ObjCXX == &CXX || 279b25938303de0976b9f189363d43033e5788e3d36John McCall ObjCXX.getPersonalityFnName() == CXX.getPersonalityFnName()) 280b25938303de0976b9f189363d43033e5788e3d36John McCall return; 281b25938303de0976b9f189363d43033e5788e3d36John McCall 282b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::Function *Fn = 283b25938303de0976b9f189363d43033e5788e3d36John McCall getModule().getFunction(ObjCXX.getPersonalityFnName()); 284b25938303de0976b9f189363d43033e5788e3d36John McCall 285b25938303de0976b9f189363d43033e5788e3d36John McCall // Nothing to do if it's unused. 286b25938303de0976b9f189363d43033e5788e3d36John McCall if (!Fn || Fn->use_empty()) return; 287b25938303de0976b9f189363d43033e5788e3d36John McCall 288b25938303de0976b9f189363d43033e5788e3d36John McCall // Can't do the optimization if it has non-C++ uses. 289b25938303de0976b9f189363d43033e5788e3d36John McCall if (!PersonalityHasOnlyCXXUses(Fn)) return; 290b25938303de0976b9f189363d43033e5788e3d36John McCall 291b25938303de0976b9f189363d43033e5788e3d36John McCall // Create the C++ personality function and kill off the old 292b25938303de0976b9f189363d43033e5788e3d36John McCall // function. 293b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::Constant *CXXFn = getPersonalityFn(*this, CXX); 294b25938303de0976b9f189363d43033e5788e3d36John McCall 295b25938303de0976b9f189363d43033e5788e3d36John McCall // This can happen if the user is screwing with us. 296b25938303de0976b9f189363d43033e5788e3d36John McCall if (Fn->getType() != CXXFn->getType()) return; 297b25938303de0976b9f189363d43033e5788e3d36John McCall 298b25938303de0976b9f189363d43033e5788e3d36John McCall Fn->replaceAllUsesWith(CXXFn); 299b25938303de0976b9f189363d43033e5788e3d36John McCall Fn->eraseFromParent(); 300f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 301f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 302f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the 303f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a catch-all. 304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) { 305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Possibly we should use @llvm.eh.catch.all.value here. 306d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return llvm::ConstantPointerNull::get(CGF.Int8PtrTy); 307f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 308f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the 310f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a cleanup. 311f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCleanupValue(CodeGenFunction &CGF) { 312f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); 31399533834ba8f3658559f334e68a518ebb6388ceaMike Stump} 31499533834ba8f3658559f334e68a518ebb6388ceaMike Stump 31509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCallnamespace { 31609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall /// A cleanup to free the exception object if its initialization 31709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall /// throws. 318c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall struct FreeException : EHScopeStack::Cleanup { 319c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall llvm::Value *exn; 320c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall FreeException(llvm::Value *exn) : exn(exn) {} 321ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 3223ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall CGF.Builder.CreateCall(getFreeExceptionFn(CGF), exn) 32309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall ->setDoesNotThrow(); 32409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall } 32509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall }; 32609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall} 32709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall 328ac418162692a951ca3796d6830496a85a2d12493John McCall// Emits an exception expression into the given location. This 329ac418162692a951ca3796d6830496a85a2d12493John McCall// differs from EmitAnyExprToMem only in that, if a final copy-ctor 330ac418162692a951ca3796d6830496a85a2d12493John McCall// call is required, an exception within that copy ctor causes 331ac418162692a951ca3796d6830496a85a2d12493John McCall// std::terminate to be invoked. 3323ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCallstatic void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *e, 3333ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall llvm::Value *addr) { 334f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Make sure the exception object is cleaned up if there's an 335f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // exception during initialization. 3363ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall CGF.pushFullExprCleanup<FreeException>(EHCleanup, addr); 3373ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall EHScopeStack::stable_iterator cleanup = CGF.EHStack.stable_begin(); 338ac418162692a951ca3796d6830496a85a2d12493John McCall 339ac418162692a951ca3796d6830496a85a2d12493John McCall // __cxa_allocate_exception returns a void*; we need to cast this 340ac418162692a951ca3796d6830496a85a2d12493John McCall // to the appropriate type for the object. 3412acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ty = CGF.ConvertTypeForMem(e->getType())->getPointerTo(); 3423ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall llvm::Value *typedAddr = CGF.Builder.CreateBitCast(addr, ty); 343ac418162692a951ca3796d6830496a85a2d12493John McCall 344ac418162692a951ca3796d6830496a85a2d12493John McCall // FIXME: this isn't quite right! If there's a final unelided call 345ac418162692a951ca3796d6830496a85a2d12493John McCall // to a copy constructor, then according to [except.terminate]p1 we 346ac418162692a951ca3796d6830496a85a2d12493John McCall // must call std::terminate() if that constructor throws, because 347ac418162692a951ca3796d6830496a85a2d12493John McCall // technically that copy occurs after the exception expression is 348ac418162692a951ca3796d6830496a85a2d12493John McCall // evaluated but before the exception is caught. But the best way 349ac418162692a951ca3796d6830496a85a2d12493John McCall // to handle that is to teach EmitAggExpr to do the final copy 350ac418162692a951ca3796d6830496a85a2d12493John McCall // differently if it can't be elided. 351f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(), 352f85e193739c953358c865005855253af4f68a497John McCall /*IsInit*/ true); 353ac418162692a951ca3796d6830496a85a2d12493John McCall 3543ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall // Deactivate the cleanup block. 3553ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall CGF.DeactivateCleanupBlock(cleanup); 356f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 357f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 358f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::Value *CodeGenFunction::getExceptionSlot() { 35993c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (!ExceptionSlot) 36093c332a8ba2c193c435b293966d343dab15f555bJohn McCall ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot"); 361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return ExceptionSlot; 3620f590be3808365e851352543faa6acbece50b686Mike Stump} 3630f590be3808365e851352543faa6acbece50b686Mike Stump 36493c332a8ba2c193c435b293966d343dab15f555bJohn McCallllvm::Value *CodeGenFunction::getEHSelectorSlot() { 36593c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (!EHSelectorSlot) 36693c332a8ba2c193c435b293966d343dab15f555bJohn McCall EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot"); 36793c332a8ba2c193c435b293966d343dab15f555bJohn McCall return EHSelectorSlot; 36893c332a8ba2c193c435b293966d343dab15f555bJohn McCall} 36993c332a8ba2c193c435b293966d343dab15f555bJohn McCall 370756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { 371d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson if (!E->getSubExpr()) { 3721eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor if (getInvokeDest()) { 373f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateInvoke(getReThrowFn(*this), 374f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall getUnreachableBlock(), 375f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall getInvokeDest()) 3761eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor ->setDoesNotReturn(); 377f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 3781eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn(); 379f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateUnreachable(); 380f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 3811eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor 382cd5b22e12b6513163dd131589746c194090f14e6John McCall // throw is an expression, and the expression emitters expect us 383cd5b22e12b6513163dd131589746c194090f14e6John McCall // to leave ourselves at a valid insertion point. 384cd5b22e12b6513163dd131589746c194090f14e6John McCall EmitBlock(createBasicBlock("throw.cont")); 385cd5b22e12b6513163dd131589746c194090f14e6John McCall 386d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return; 387d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson } 3888755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 389d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson QualType ThrowType = E->getSubExpr()->getType(); 3908755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 391d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now allocate the exception object. 3922acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 3933d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity(); 3948755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 395d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this); 396f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *ExceptionPtr = 3978755ec336108839b9621c3b18f0e175f8a3b671cMike Stump Builder.CreateCall(AllocExceptionFn, 398d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::ConstantInt::get(SizeTy, TypeSize), 399d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson "exception"); 400f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ExceptionPtr->setDoesNotThrow(); 4018370c58b9295b32bee50443fe3ac43a47a2047e8Anders Carlsson 402ac418162692a951ca3796d6830496a85a2d12493John McCall EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr); 4038755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 404d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now throw the exception. 40582a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, 40682a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson /*ForEH=*/true); 407ac418162692a951ca3796d6830496a85a2d12493John McCall 408ac418162692a951ca3796d6830496a85a2d12493John McCall // The address of the destructor. If the exception type has a 409ac418162692a951ca3796d6830496a85a2d12493John McCall // trivial destructor (or isn't a record), we just pass null. 410ac418162692a951ca3796d6830496a85a2d12493John McCall llvm::Constant *Dtor = 0; 411ac418162692a951ca3796d6830496a85a2d12493John McCall if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) { 412ac418162692a951ca3796d6830496a85a2d12493John McCall CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl()); 413ac418162692a951ca3796d6830496a85a2d12493John McCall if (!Record->hasTrivialDestructor()) { 4141d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor CXXDestructorDecl *DtorD = Record->getDestructor(); 415ac418162692a951ca3796d6830496a85a2d12493John McCall Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete); 416ac418162692a951ca3796d6830496a85a2d12493John McCall Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy); 417ac418162692a951ca3796d6830496a85a2d12493John McCall } 418ac418162692a951ca3796d6830496a85a2d12493John McCall } 419ac418162692a951ca3796d6830496a85a2d12493John McCall if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy); 4208755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 4210a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (getInvokeDest()) { 4228755ec336108839b9621c3b18f0e175f8a3b671cMike Stump llvm::InvokeInst *ThrowCall = 423f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateInvoke3(getThrowFn(*this), 424f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall getUnreachableBlock(), getInvokeDest(), 4250a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ExceptionPtr, TypeInfo, Dtor); 4260a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 4270a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } else { 4288755ec336108839b9621c3b18f0e175f8a3b671cMike Stump llvm::CallInst *ThrowCall = 4290a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor); 4300a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 431f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateUnreachable(); 4320a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } 4338755ec336108839b9621c3b18f0e175f8a3b671cMike Stump 434cd5b22e12b6513163dd131589746c194090f14e6John McCall // throw is an expression, and the expression emitters expect us 435cd5b22e12b6513163dd131589746c194090f14e6John McCall // to leave ourselves at a valid insertion point. 436cd5b22e12b6513163dd131589746c194090f14e6John McCall EmitBlock(createBasicBlock("throw.cont")); 437756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson} 4382bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 439cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) { 44015348aeb81285c75b2e92b5bf8d2db3445d147c2Anders Carlsson if (!CGM.getLangOptions().CXXExceptions) 441a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson return; 442a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson 443cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 444cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 445cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 446cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 447cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 448cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 449cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 450a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl ExceptionSpecificationType EST = Proto->getExceptionSpecType(); 451a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl if (isNoexceptExceptionSpec(EST)) { 452a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) { 453a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl // noexcept functions are simple terminate scopes. 454a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl EHStack.pushTerminate(); 455a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } 456a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { 457a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl unsigned NumExceptions = Proto->getNumExceptions(); 458a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl EHFilterScope *Filter = EHStack.pushFilter(NumExceptions); 459a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl 460a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl for (unsigned I = 0; I != NumExceptions; ++I) { 461a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl QualType Ty = Proto->getExceptionType(I); 462a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType(); 463a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, 464a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl /*ForEH=*/true); 465a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl Filter->setFilter(I, EHType); 466a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } 467cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 468cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 469cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 470cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) { 47115348aeb81285c75b2e92b5bf8d2db3445d147c2Anders Carlsson if (!CGM.getLangOptions().CXXExceptions) 472a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson return; 473a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson 474cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 475cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 476cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 477cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 478cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 479cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 480cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 481a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl ExceptionSpecificationType EST = Proto->getExceptionSpecType(); 482a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl if (isNoexceptExceptionSpec(EST)) { 483a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) { 484a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl EHStack.popTerminate(); 485a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } 486a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { 487a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl EHStack.popFilter(); 488a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl } 489cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 490cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 4912bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { 49259a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(S); 4939fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(S.getTryBlock()); 49459a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(S); 4959fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 4969fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 49759a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { 498f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall unsigned NumHandlers = S.getNumHandlers(); 499f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers); 500f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 501f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0; I != NumHandlers; ++I) { 502f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXCatchStmt *C = S.getHandler(I); 503f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 504f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *Handler = createBasicBlock("catch"); 505f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (C->getExceptionDecl()) { 506f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // FIXME: Dropping the reference type on the type into makes it 507f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // impossible to correctly implement catch-by-reference 508f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // semantics for pointers. Unfortunately, this is what all 509f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // existing compilers do, and it's not clear that the standard 510f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // personality routine is capable of doing this right. See C++ DR 388: 511f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388 512f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall QualType CaughtType = C->getCaughtType(); 513f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType(); 5145a180397870944548aaadeaebf58e415885b9489John McCall 5155a180397870944548aaadeaebf58e415885b9489John McCall llvm::Value *TypeInfo = 0; 5165a180397870944548aaadeaebf58e415885b9489John McCall if (CaughtType->isObjCObjectPointerType()) 517cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType); 5185a180397870944548aaadeaebf58e415885b9489John McCall else 51982a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true); 520f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchScope->setHandler(I, TypeInfo, Handler); 521f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 522f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // No exception decl indicates '...', a catch-all. 523f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchScope->setCatchAllHandler(I, Handler); 524f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 525f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 526f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 527f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 528f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Check whether this is a non-EH scope, i.e. a scope which doesn't 529f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// affect exception handling. Currently, the only non-EH scopes are 530f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// normal-only cleanup scopes. 531f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic bool isNonEHScope(const EHScope &S) { 532da65ea86482bc116906edfb9ba1d7124f76cc867John McCall switch (S.getKind()) { 5331f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall case EHScope::Cleanup: 5341f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall return !cast<EHCleanupScope>(S).isEHCleanup(); 535da65ea86482bc116906edfb9ba1d7124f76cc867John McCall case EHScope::Filter: 536da65ea86482bc116906edfb9ba1d7124f76cc867John McCall case EHScope::Catch: 537da65ea86482bc116906edfb9ba1d7124f76cc867John McCall case EHScope::Terminate: 538da65ea86482bc116906edfb9ba1d7124f76cc867John McCall return false; 539da65ea86482bc116906edfb9ba1d7124f76cc867John McCall } 540da65ea86482bc116906edfb9ba1d7124f76cc867John McCall 541da65ea86482bc116906edfb9ba1d7124f76cc867John McCall // Suppress warning. 542da65ea86482bc116906edfb9ba1d7124f76cc867John McCall return false; 543f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 5449fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 545f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() { 546f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(EHStack.requiresLandingPad()); 547f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(!EHStack.empty()); 5489fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 5497a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson if (!CGM.getLangOptions().Exceptions) 550da65ea86482bc116906edfb9ba1d7124f76cc867John McCall return 0; 551da65ea86482bc116906edfb9ba1d7124f76cc867John McCall 552f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Check the innermost scope for a cached landing pad. If this is 553f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad. 554f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad(); 555f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (LP) return LP; 556f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 557f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Build the landing pad for this scope. 558f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall LP = EmitLandingPad(); 559f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(LP); 560f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 561f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Cache the landing pad on the innermost scope. If this is a 562f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // non-EH scope, cache the landing pad on the enclosing scope, too. 563f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) { 564f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ir->setCachedLandingPad(LP); 565f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!isNonEHScope(*ir)) break; 566f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 568f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return LP; 5699fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 5709fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 57193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// This code contains a hack to work around a design flaw in 57293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// LLVM's EH IR which breaks semantics after inlining. This same 57393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// hack is implemented in llvm-gcc. 57493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// 57593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// The LLVM EH abstraction is basically a thin veneer over the 57693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// traditional GCC zero-cost design: for each range of instructions 57793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// in the function, there is (at most) one "landing pad" with an 57893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// associated chain of EH actions. A language-specific personality 57993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// function interprets this chain of actions and (1) decides whether 58093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// or not to resume execution at the landing pad and (2) if so, 58193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// provides an integer indicating why it's stopping. In LLVM IR, 58293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the association of a landing pad with a range of instructions is 58393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// achieved via an invoke instruction, the chain of actions becomes 58493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the arguments to the @llvm.eh.selector call, and the selector 58593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// call returns the integer indicator. Other than the required 58693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// presence of two intrinsic function calls in the landing pad, 58793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the IR exactly describes the layout of the output code. 58893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// 58993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// A principal advantage of this design is that it is completely 59093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// language-agnostic; in theory, the LLVM optimizers can treat 59193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// landing pads neutrally, and targets need only know how to lower 59293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the intrinsics to have a functioning exceptions system (assuming 59393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// that platform exceptions follow something approximately like the 59493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// GCC design). Unfortunately, landing pads cannot be combined in a 59593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// language-agnostic way: given selectors A and B, there is no way 59693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// to make a single landing pad which faithfully represents the 59793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// semantics of propagating an exception first through A, then 59893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// through B, without knowing how the personality will interpret the 59993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// (lowered form of the) selectors. This means that inlining has no 60093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// choice but to crudely chain invokes (i.e., to ignore invokes in 60193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the inlined function, but to turn all unwindable calls into 60293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// invokes), which is only semantically valid if every unwind stops 60393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// at every landing pad. 60493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// 60593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// Therefore, the invoke-inline hack is to guarantee that every 60693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// landing pad has a catch-all. 60793c332a8ba2c193c435b293966d343dab15f555bJohn McCallenum CleanupHackLevel_t { 60893c332a8ba2c193c435b293966d343dab15f555bJohn McCall /// A level of hack that requires that all landing pads have 60993c332a8ba2c193c435b293966d343dab15f555bJohn McCall /// catch-alls. 61093c332a8ba2c193c435b293966d343dab15f555bJohn McCall CHL_MandatoryCatchall, 61193c332a8ba2c193c435b293966d343dab15f555bJohn McCall 61293c332a8ba2c193c435b293966d343dab15f555bJohn McCall /// A level of hack that requires that all landing pads handle 61393c332a8ba2c193c435b293966d343dab15f555bJohn McCall /// cleanups. 61493c332a8ba2c193c435b293966d343dab15f555bJohn McCall CHL_MandatoryCleanup, 61593c332a8ba2c193c435b293966d343dab15f555bJohn McCall 61693c332a8ba2c193c435b293966d343dab15f555bJohn McCall /// No hacks at all; ideal IR generation. 61793c332a8ba2c193c435b293966d343dab15f555bJohn McCall CHL_Ideal 61893c332a8ba2c193c435b293966d343dab15f555bJohn McCall}; 61993c332a8ba2c193c435b293966d343dab15f555bJohn McCallconst CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup; 62093c332a8ba2c193c435b293966d343dab15f555bJohn McCall 621f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::EmitLandingPad() { 622f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(EHStack.requiresLandingPad()); 623f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 624f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (EHScopeStack::iterator ir = EHStack.begin(); ; ) { 625f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(ir != EHStack.end() && 626f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall "stack requiring landing pad is nothing but non-EH scopes?"); 627f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 628f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If this is a terminate scope, just use the singleton terminate 629f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // landing pad. 630f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (isa<EHTerminateScope>(*ir)) 631f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return getTerminateLandingPad(); 632f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 633f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If this isn't an EH scope, iterate; otherwise break out. 634f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!isNonEHScope(*ir)) break; 635f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ++ir; 636f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 637f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We haven't checked this scope for a cached landing pad yet. 638f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (llvm::BasicBlock *LP = ir->getCachedLandingPad()) 639f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return LP; 640f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 641f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 642f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Save the current IR generation state. 643f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); 644f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 645d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall const EHPersonality &Personality = EHPersonality::get(getLangOptions()); 6468262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 647f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create and configure the landing pad. 648f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LP = createBasicBlock("lpad"); 649f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(LP); 650f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 651f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Save the exception pointer. It's safe to use a single exception 652f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // pointer per function because EH cleanups can never have nested 653f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // try/catches. 654f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Exn = 655f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn"); 656f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Exn->setDoesNotThrow(); 657f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateStore(Exn, getExceptionSlot()); 658f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 659f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Build the selector arguments. 6605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Value*, 8> EHSelector; 661f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHSelector.push_back(Exn); 662b25938303de0976b9f189363d43033e5788e3d36John McCall EHSelector.push_back(getOpaquePersonalityFn(CGM, Personality)); 663f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 664f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Accumulate all the handlers in scope. 665ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::DenseMap<llvm::Value*, UnwindDest> EHHandlers; 666ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall UnwindDest CatchAll; 667f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall bool HasEHCleanup = false; 668f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall bool HasEHFilter = false; 6695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Value*, 8> EHFilters; 670f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); 671f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall I != E; ++I) { 672f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 673f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall switch (I->getKind()) { 6741f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall case EHScope::Cleanup: 675da65ea86482bc116906edfb9ba1d7124f76cc867John McCall if (!HasEHCleanup) 6761f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall HasEHCleanup = cast<EHCleanupScope>(*I).isEHCleanup(); 677da65ea86482bc116906edfb9ba1d7124f76cc867John McCall // We otherwise don't care about cleanups. 678da65ea86482bc116906edfb9ba1d7124f76cc867John McCall continue; 679da65ea86482bc116906edfb9ba1d7124f76cc867John McCall 680f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall case EHScope::Filter: { 681f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(I.next() == EHStack.end() && "EH filter is not end of EH stack"); 682ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(!CatchAll.isValid() && "EH filter reached after catch-all"); 683f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 684fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // Filter scopes get added to the selector in weird ways. 685f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHFilterScope &Filter = cast<EHFilterScope>(*I); 686f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall HasEHFilter = true; 687f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 688f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Add all the filter values which we aren't already explicitly 689f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // catching. 690f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0, E = Filter.getNumFilters(); I != E; ++I) { 691f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *FV = Filter.getFilter(I); 692f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!EHHandlers.count(FV)) 693f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHFilters.push_back(FV); 694f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 695f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall goto done; 696f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 697f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 698f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall case EHScope::Terminate: 699f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Terminate scopes are basically catch-alls. 700ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(!CatchAll.isValid()); 701ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall CatchAll = UnwindDest(getTerminateHandler(), 702ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.getEnclosingEHCleanup(I), 703ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall cast<EHTerminateScope>(*I).getDestIndex()); 704f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall goto done; 705f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 706f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall case EHScope::Catch: 707f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall break; 708f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 709f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 710f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHCatchScope &Catch = cast<EHCatchScope>(*I); 711f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned HI = 0, HE = Catch.getNumHandlers(); HI != HE; ++HI) { 712f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHCatchScope::Handler Handler = Catch.getHandler(HI); 713f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 714f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Catch-all. We should only have one of these per catch. 715f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!Handler.Type) { 716ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(!CatchAll.isValid()); 717ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall CatchAll = UnwindDest(Handler.Block, 718ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.getEnclosingEHCleanup(I), 719ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Handler.Index); 720f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall continue; 721f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 723f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Check whether we already have a handler for this type. 724ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall UnwindDest &Dest = EHHandlers[Handler.Type]; 725ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (Dest.isValid()) continue; 726f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 727f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHSelector.push_back(Handler.Type); 728ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest = UnwindDest(Handler.Block, 729ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.getEnclosingEHCleanup(I), 730ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Handler.Index); 7312bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 732f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 733f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Stop if we found a catch-all. 734ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (CatchAll.isValid()) break; 7352bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 7362bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 737f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall done: 738f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall unsigned LastToEmitInLoop = EHSelector.size(); 739f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 740f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If we have a catch-all, add null to the selector. 741ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (CatchAll.isValid()) { 742d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EHSelector.push_back(getCatchAllValue(*this)); 743f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 744f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If we have an EH filter, we need to add those handlers in the 745f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // right place in the selector, which is to say, at the end. 746f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else if (HasEHFilter) { 747f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create a filter expression: an integer constant saying how many 748f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // filters there are (+1 to avoid ambiguity with 0 for cleanup), 749f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // followed by the filter types. The personality routine only 750f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // lands here if the filter doesn't match. 751f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHSelector.push_back(llvm::ConstantInt::get(Builder.getInt32Ty(), 752f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHFilters.size() + 1)); 753f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHSelector.append(EHFilters.begin(), EHFilters.end()); 754f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 755f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Also check whether we need a cleanup. 75693c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (CleanupHackLevel == CHL_MandatoryCatchall || HasEHCleanup) 75793c332a8ba2c193c435b293966d343dab15f555bJohn McCall EHSelector.push_back(CleanupHackLevel == CHL_MandatoryCatchall 758d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ? getCatchAllValue(*this) 759d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall : getCleanupValue(*this)); 760f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 761f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, signal that we at least have cleanups. 76293c332a8ba2c193c435b293966d343dab15f555bJohn McCall } else if (CleanupHackLevel == CHL_MandatoryCatchall || HasEHCleanup) { 76393c332a8ba2c193c435b293966d343dab15f555bJohn McCall EHSelector.push_back(CleanupHackLevel == CHL_MandatoryCatchall 764d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ? getCatchAllValue(*this) 765d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall : getCleanupValue(*this)); 76693c332a8ba2c193c435b293966d343dab15f555bJohn McCall 76793c332a8ba2c193c435b293966d343dab15f555bJohn McCall // At the MandatoryCleanup hack level, we don't need to actually 76893c332a8ba2c193c435b293966d343dab15f555bJohn McCall // spuriously tell the unwinder that we have cleanups, but we do 76993c332a8ba2c193c435b293966d343dab15f555bJohn McCall // need to always be prepared to handle cleanups. 77093c332a8ba2c193c435b293966d343dab15f555bJohn McCall } else if (CleanupHackLevel == CHL_MandatoryCleanup) { 77193c332a8ba2c193c435b293966d343dab15f555bJohn McCall // Just don't decrement LastToEmitInLoop. 77293c332a8ba2c193c435b293966d343dab15f555bJohn McCall 773f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 774f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(LastToEmitInLoop > 2); 775f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall LastToEmitInLoop--; 7760f590be3808365e851352543faa6acbece50b686Mike Stump } 7772bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 778f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(EHSelector.size() >= 3 && "selector call has only two arguments!"); 779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 780f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Tell the backend how to generate the landing pad. 781f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Selection = 782f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector), 7834c7d9f1507d0f102bd4133bba63348636facd469Jay Foad EHSelector, "eh.selector"); 784f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Selection->setDoesNotThrow(); 78593c332a8ba2c193c435b293966d343dab15f555bJohn McCall 78693c332a8ba2c193c435b293966d343dab15f555bJohn McCall // Save the selector value in mandatory-cleanup mode. 78793c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (CleanupHackLevel == CHL_MandatoryCleanup) 78893c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateStore(Selection, getEHSelectorSlot()); 789f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 790f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Select the right handler. 791f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *llvm_eh_typeid_for = 792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 793f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The results of llvm_eh_typeid_for aren't reliable --- at least 795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // not locally --- so we basically have to do this as an 'if' chain. 796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We walk through the first N-1 catch clauses, testing and chaining, 797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // and then fall into the final clause (which is either a cleanup, a 798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // filter (possibly with a cleanup), a catch-all, or another catch). 799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 2; I != LastToEmitInLoop; ++I) { 800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *Type = EHSelector[I]; 801ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall UnwindDest Dest = EHHandlers[Type]; 802ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(Dest.isValid() && "no handler entry for value in selector?"); 803f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 804f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Figure out where to branch on a match. As a debug code-size 805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // optimization, if the scope depth matches the innermost cleanup, 806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // we branch directly to the catch handler. 807ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *Match = Dest.getBlock(); 808ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall bool MatchNeedsCleanup = 809ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest.getScopeDepth() != EHStack.getInnermostEHCleanup(); 810f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (MatchNeedsCleanup) 811f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Match = createBasicBlock("eh.match"); 812f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 813f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *Next = createBasicBlock("eh.next"); 814f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 815f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Check whether the exception matches. 816f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Id 817f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall = Builder.CreateCall(llvm_eh_typeid_for, 818d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Builder.CreateBitCast(Type, Int8PtrTy)); 819f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Id->setDoesNotThrow(); 820f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCondBr(Builder.CreateICmpEQ(Selection, Id), 821f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Match, Next); 822f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 823f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit match code if necessary. 824f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (MatchNeedsCleanup) { 8250f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Match); 826f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughEHCleanup(Dest); 8270f590be3808365e851352543faa6acbece50b686Mike Stump } 8280f590be3808365e851352543faa6acbece50b686Mike Stump 829f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Continue to the next match. 830f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(Next); 831f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 832f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 833f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the final case in the selector. 834f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // This might be a catch-all.... 835ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (CatchAll.isValid()) { 836f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(isa<llvm::ConstantPointerNull>(EHSelector.back())); 837f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughEHCleanup(CatchAll); 838f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 839f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ...or an EH filter... 840f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else if (HasEHFilter) { 841f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *SavedSelection = Selection; 842f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 843f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // First, unwind out to the outermost scope if necessary. 844f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (EHStack.hasEHCleanups()) { 845f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The end here might not dominate the beginning, so we might need to 846f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // save the selector if we need it. 847f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::AllocaInst *SelectorVar = 0; 848f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (HasEHCleanup) { 849f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall SelectorVar = CreateTempAlloca(Builder.getInt32Ty(), "selector.var"); 850f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateStore(Selection, SelectorVar); 851f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump } 852f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump 853f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *CleanupContBB = createBasicBlock("ehspec.cleanup.cont"); 854ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBranchThroughEHCleanup(UnwindDest(CleanupContBB, EHStack.stable_end(), 855ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.getNextEHDestIndex())); 856f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(CleanupContBB); 857f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 858f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (HasEHCleanup) 859f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall SavedSelection = Builder.CreateLoad(SelectorVar, "ehspec.saved-selector"); 8600f590be3808365e851352543faa6acbece50b686Mike Stump } 8610f590be3808365e851352543faa6acbece50b686Mike Stump 862f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If there was a cleanup, we'll need to actually check whether we 863f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // landed here because the filter triggered. 86493c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (CleanupHackLevel != CHL_Ideal || HasEHCleanup) { 865f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *UnexpectedBB = createBasicBlock("ehspec.unexpected"); 866f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 86793c332a8ba2c193c435b293966d343dab15f555bJohn McCall llvm::Constant *Zero = llvm::ConstantInt::get(Int32Ty, 0); 868f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *FailsFilter = 869f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateICmpSLT(SavedSelection, Zero, "ehspec.fails"); 87093c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateCondBr(FailsFilter, UnexpectedBB, getRethrowDest().getBlock()); 8710f590be3808365e851352543faa6acbece50b686Mike Stump 872f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(UnexpectedBB); 873f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 8740f590be3808365e851352543faa6acbece50b686Mike Stump 875f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call __cxa_call_unexpected. This doesn't need to be an invoke 876f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // because __cxa_call_unexpected magically filters exceptions 877f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // according to the last landing pad the exception was thrown 878f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // into. Seriously. 879f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCall(getUnexpectedFn(*this), 880f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateLoad(getExceptionSlot())) 881f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotReturn(); 882f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateUnreachable(); 8830f590be3808365e851352543faa6acbece50b686Mike Stump 884f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ...or a normal catch handler... 88593c332a8ba2c193c435b293966d343dab15f555bJohn McCall } else if (CleanupHackLevel == CHL_Ideal && !HasEHCleanup) { 886f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *Type = EHSelector.back(); 887f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughEHCleanup(EHHandlers[Type]); 8880f590be3808365e851352543faa6acbece50b686Mike Stump 889f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ...or a cleanup. 890f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 891ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBranchThroughEHCleanup(getRethrowDest()); 892f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 893f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 894f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Restore the old IR generation state. 895f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.restoreIP(SavedIP); 896f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 897f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return LP; 898f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 8990f590be3808365e851352543faa6acbece50b686Mike Stump 9008e3f86193995c47ee0d229e4336c3382410f09f5John McCallnamespace { 9018e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// A cleanup to call __cxa_end_catch. In many cases, the caught 9028e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// exception type lets us state definitively that the thrown exception 9038e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// type does not have a destructor. In particular: 9048e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// - Catch-alls tell us nothing, so we have to conservatively 9058e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// assume that the thrown exception might have a destructor. 9068e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// - Catches by reference behave according to their base types. 9078e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// - Catches of non-record types will only trigger for exceptions 9088e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// of non-record types, which never have destructors. 9098e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// - Catches of record types can trigger for arbitrary subclasses 9108e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// of the caught type, so we have to assume the actual thrown 9118e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// exception type might have a throwing destructor, even if the 9128e3f86193995c47ee0d229e4336c3382410f09f5John McCall /// caught type's destructor is trivial or nothrow. 9131f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallEndCatch : EHScopeStack::Cleanup { 9148e3f86193995c47ee0d229e4336c3382410f09f5John McCall CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {} 9158e3f86193995c47ee0d229e4336c3382410f09f5John McCall bool MightThrow; 9168e3f86193995c47ee0d229e4336c3382410f09f5John McCall 917ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 9188e3f86193995c47ee0d229e4336c3382410f09f5John McCall if (!MightThrow) { 9198e3f86193995c47ee0d229e4336c3382410f09f5John McCall CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow(); 9208e3f86193995c47ee0d229e4336c3382410f09f5John McCall return; 9218e3f86193995c47ee0d229e4336c3382410f09f5John McCall } 9228e3f86193995c47ee0d229e4336c3382410f09f5John McCall 9234c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(getEndCatchFn(CGF)); 9248e3f86193995c47ee0d229e4336c3382410f09f5John McCall } 9258e3f86193995c47ee0d229e4336c3382410f09f5John McCall }; 9268e3f86193995c47ee0d229e4336c3382410f09f5John McCall} 9278e3f86193995c47ee0d229e4336c3382410f09f5John McCall 928f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Emits a call to __cxa_begin_catch and enters a cleanup to call 929f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// __cxa_end_catch. 9308e3f86193995c47ee0d229e4336c3382410f09f5John McCall/// 9318e3f86193995c47ee0d229e4336c3382410f09f5John McCall/// \param EndMightThrow - true if __cxa_end_catch might throw 9328e3f86193995c47ee0d229e4336c3382410f09f5John McCallstatic llvm::Value *CallBeginCatch(CodeGenFunction &CGF, 9338e3f86193995c47ee0d229e4336c3382410f09f5John McCall llvm::Value *Exn, 9348e3f86193995c47ee0d229e4336c3382410f09f5John McCall bool EndMightThrow) { 935f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Call = CGF.Builder.CreateCall(getBeginCatchFn(CGF), Exn); 936f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Call->setDoesNotThrow(); 9370f590be3808365e851352543faa6acbece50b686Mike Stump 9381f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow); 939f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 940f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return Call; 941f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 942f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 943f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// A "special initializer" callback for initializing a catch 944f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// parameter during catch initialization. 945f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic void InitCatchParam(CodeGenFunction &CGF, 946f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const VarDecl &CatchParam, 947f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *ParamAddr) { 948f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Load the exception from where the landing pad saved it. 949f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn"); 950f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 951f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CanQualType CatchType = 952f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.CGM.getContext().getCanonicalType(CatchParam.getType()); 9532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType); 954f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 955f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If we're catching by reference, we can just cast the object 956f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // pointer to the appropriate pointer. 957f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (isa<ReferenceType>(CatchType)) { 958204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType(); 959204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall bool EndCatchMightThrow = CaughtType->isRecordType(); 9608e3f86193995c47ee0d229e4336c3382410f09f5John McCall 961f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // __cxa_begin_catch returns the adjusted object pointer. 9628e3f86193995c47ee0d229e4336c3382410f09f5John McCall llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow); 963204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 964204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // We have no way to tell the personality function that we're 965204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // catching by reference, so if we're catching a pointer, 966204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // __cxa_begin_catch will actually return that pointer by value. 967204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) { 968204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall QualType PointeeType = PT->getPointeeType(); 969204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 970204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // When catching by reference, generally we should just ignore 971204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // this by-value pointer and use the exception object instead. 972204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall if (!PointeeType->isRecordType()) { 973204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 974204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // Exn points to the struct _Unwind_Exception header, which 975204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // we have to skip past in order to reach the exception data. 976204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall unsigned HeaderSize = 977204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException(); 978204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize); 979204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 980204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // However, if we're catching a pointer-to-record type that won't 981204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // work, because the personality function might have adjusted 982204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // the pointer. There's actually no way for us to fully satisfy 983204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // the language/ABI contract here: we can't use Exn because it 984204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // might have the wrong adjustment, but we can't use the by-value 985204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // pointer because it's off by a level of abstraction. 986204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // 987204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // The current solution is to dump the adjusted pointer into an 988204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // alloca, which breaks language semantics (because changing the 989204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // pointer doesn't change the exception) but at least works. 990204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // The better solution would be to filter out non-exact matches 991204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // and rethrow them, but this is tricky because the rethrow 992204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // really needs to be catchable by other sites at this landing 993204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // pad. The best solution is to fix the personality function. 994204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall } else { 995204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // Pull the pointer for the reference type off. 9962acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = 997204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall cast<llvm::PointerType>(LLVMCatchTy)->getElementType(); 998204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 999204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // Create the temporary and write the adjusted pointer into it. 1000204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall llvm::Value *ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, "exn.byref.tmp"); 1001204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); 1002204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall CGF.Builder.CreateStore(Casted, ExnPtrTmp); 1003204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 1004204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall // Bind the reference to the temporary. 1005204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall AdjustedExn = ExnPtrTmp; 1006204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall } 1007204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall } 1008204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall 1009f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *ExnCast = 1010f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); 1011f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateStore(ExnCast, ParamAddr); 1012f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return; 1013a086783570f76062a345e761811296dc8df571c8Mike Stump } 10142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 1015f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Non-aggregates (plus complexes). 1016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall bool IsComplex = false; 1017f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!CGF.hasAggregateLLVMType(CatchType) || 1018f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall (IsComplex = CatchType->isAnyComplexType())) { 10198e3f86193995c47ee0d229e4336c3382410f09f5John McCall llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false); 1020f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1021f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If the catch type is a pointer type, __cxa_begin_catch returns 1022f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the pointer by value. 1023f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (CatchType->hasPointerRepresentation()) { 1024f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *CastExn = 1025f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); 1026f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateStore(CastExn, ParamAddr); 1027f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return; 1028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 10292bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 1030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, it returns a pointer into the exception object. 10312bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 10322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok 1033f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); 10342bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 1035f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (IsComplex) { 1036f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false), 1037f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ParamAddr, /*volatile*/ false); 1038f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 103991a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = 104091a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar CGF.getContext().getDeclAlign(&CatchParam).getQuantity(); 1041f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar"); 104291a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, Alignment, 104391a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar CatchType); 1044f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 1045f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return; 1046f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 10470f590be3808365e851352543faa6acbece50b686Mike Stump 1048acff696118d98c3acd09a16b96c95807057b5c99John McCall assert(isa<RecordType>(CatchType) && "unexpected catch type!"); 1049b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump 10502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok 1051f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1052acff696118d98c3acd09a16b96c95807057b5c99John McCall // Check for a copy expression. If we don't have a copy expression, 1053acff696118d98c3acd09a16b96c95807057b5c99John McCall // that means a trivial copy is okay. 1054e996ffd240f20a1048179d7727a6ee3227261921John McCall const Expr *copyExpr = CatchParam.getInit(); 1055e996ffd240f20a1048179d7727a6ee3227261921John McCall if (!copyExpr) { 1056acff696118d98c3acd09a16b96c95807057b5c99John McCall llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true); 1057acff696118d98c3acd09a16b96c95807057b5c99John McCall llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy); 1058acff696118d98c3acd09a16b96c95807057b5c99John McCall CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType); 1059f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return; 1060f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 1061f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1062f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We have to call __cxa_get_exception_ptr to get the adjusted 1063f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // pointer before copying. 1064e996ffd240f20a1048179d7727a6ee3227261921John McCall llvm::CallInst *rawAdjustedExn = 1065f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF), Exn); 1066e996ffd240f20a1048179d7727a6ee3227261921John McCall rawAdjustedExn->setDoesNotThrow(); 1067f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1068e996ffd240f20a1048179d7727a6ee3227261921John McCall // Cast that to the appropriate type. 1069e996ffd240f20a1048179d7727a6ee3227261921John McCall llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy); 1070f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1071e996ffd240f20a1048179d7727a6ee3227261921John McCall // The copy expression is defined in terms of an OpaqueValueExpr. 1072e996ffd240f20a1048179d7727a6ee3227261921John McCall // Find it and map it to the adjusted expression. 1073e996ffd240f20a1048179d7727a6ee3227261921John McCall CodeGenFunction::OpaqueValueMapping 107456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr), 107556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall CGF.MakeAddrLValue(adjustedExn, CatchParam.getType())); 1076f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1077f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call the copy ctor in a terminate scope. 1078f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.EHStack.pushTerminate(); 1079e996ffd240f20a1048179d7727a6ee3227261921John McCall 1080e996ffd240f20a1048179d7727a6ee3227261921John McCall // Perform the copy construction. 1081f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, Qualifiers(), 1082f85e193739c953358c865005855253af4f68a497John McCall false)); 1083e996ffd240f20a1048179d7727a6ee3227261921John McCall 1084e996ffd240f20a1048179d7727a6ee3227261921John McCall // Leave the terminate scope. 1085f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGF.EHStack.popTerminate(); 1086f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1087e996ffd240f20a1048179d7727a6ee3227261921John McCall // Undo the opaque value mapping. 1088e996ffd240f20a1048179d7727a6ee3227261921John McCall opaque.pop(); 1089e996ffd240f20a1048179d7727a6ee3227261921John McCall 1090f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Finally we can call __cxa_begin_catch. 10918e3f86193995c47ee0d229e4336c3382410f09f5John McCall CallBeginCatch(CGF, Exn, true); 1092f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1093f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1094f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Begins a catch statement by initializing the catch variable and 1095f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// calling __cxa_begin_catch. 1096e996ffd240f20a1048179d7727a6ee3227261921John McCallstatic void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) { 1097f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We have to be very careful with the ordering of cleanups here: 1098f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // C++ [except.throw]p4: 1099f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The destruction [of the exception temporary] occurs 1100f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // immediately after the destruction of the object declared in 1101f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the exception-declaration in the handler. 1102f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 1103f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // So the precise ordering is: 1104f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 1. Construct catch variable. 1105f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 2. __cxa_begin_catch 1106f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 3. Enter __cxa_end_catch cleanup 1107f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 4. Enter dtor cleanup 1108f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // 110934695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // We do this by using a slightly abnormal initialization process. 111034695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // Delegation sequence: 1111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - ExitCXXTryStmt opens a RunCleanupsScope 111234695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // - EmitAutoVarAlloca creates the variable and debug info 1113f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - InitCatchParam initializes the variable from the exception 111434695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // - CallBeginCatch calls __cxa_begin_catch 111534695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // - CallBeginCatch enters the __cxa_end_catch cleanup 111634695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall // - EmitAutoVarCleanups enters the variable destructor cleanup 1117f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - EmitCXXTryStmt emits the code for the catch body 1118f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // - EmitCXXTryStmt close the RunCleanupsScope 1119f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1120f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall VarDecl *CatchParam = S->getExceptionDecl(); 1121f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!CatchParam) { 1122f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn"); 11238e3f86193995c47ee0d229e4336c3382410f09f5John McCall CallBeginCatch(CGF, Exn, true); 1124f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return; 1125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 1126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the local. 112834695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam); 112934695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF)); 113034695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall CGF.EmitAutoVarCleanups(var); 1131f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1133fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCallnamespace { 11341f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallRethrow : EHScopeStack::Cleanup { 1135ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 11364c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(getReThrowFn(CGF)); 1137fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall } 1138fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall }; 1139fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall} 1140fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall 114159a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { 1142f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall unsigned NumHandlers = S.getNumHandlers(); 1143f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin()); 1144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall assert(CatchScope.getNumHandlers() == NumHandlers); 1145f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1146f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Copy the handler blocks off before we pop the EH stack. Emitting 1147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the handlers might scribble on this memory. 11485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<EHCatchScope::Handler, 8> Handlers(NumHandlers); 1149f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall memcpy(Handlers.data(), CatchScope.begin(), 1150f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall NumHandlers * sizeof(EHCatchScope::Handler)); 1151f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHStack.popCatch(); 1152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1153f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The fall-through block. 1154f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *ContBB = createBasicBlock("try.cont"); 1155f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1156f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // We just emitted the body of the try; jump to the continue block. 1157f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (HaveInsertPoint()) 1158f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateBr(ContBB); 1159f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 116059a7000a79118e4c140885ccbb2ac6a686a73092John McCall // Determine if we need an implicit rethrow for all these catch handlers. 116159a7000a79118e4c140885ccbb2ac6a686a73092John McCall bool ImplicitRethrow = false; 116259a7000a79118e4c140885ccbb2ac6a686a73092John McCall if (IsFnTryBlock) 116359a7000a79118e4c140885ccbb2ac6a686a73092John McCall ImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) || 116459a7000a79118e4c140885ccbb2ac6a686a73092John McCall isa<CXXConstructorDecl>(CurCodeDecl); 116559a7000a79118e4c140885ccbb2ac6a686a73092John McCall 1166f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0; I != NumHandlers; ++I) { 1167f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *CatchBlock = Handlers[I].Block; 1168f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(CatchBlock); 1169f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Catch the exception if this isn't a catch-all. 1171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXCatchStmt *C = S.getHandler(I); 1172f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1173f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Enter a cleanup scope, including the catch variable and the 1174f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // end-catch. 1175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope CatchScope(*this); 1176f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Initialize the catch variable and set up the cleanups. 1178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BeginCatch(*this, C); 1179f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 118059a7000a79118e4c140885ccbb2ac6a686a73092John McCall // If there's an implicit rethrow, push a normal "cleanup" to call 1181fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall // _cxa_rethrow. This needs to happen before __cxa_end_catch is 1182fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall // called, and so it is pushed after BeginCatch. 1183fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall if (ImplicitRethrow) 11841f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallRethrow>(NormalCleanup); 118559a7000a79118e4c140885ccbb2ac6a686a73092John McCall 1186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Perform the body of the catch. 1187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitStmt(C->getHandlerBlock()); 1188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1189f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Fall out through the catch cleanups. 1190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CatchScope.ForceCleanup(); 1191f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1192f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Branch out of the try. 1193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (HaveInsertPoint()) 1194f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateBr(ContBB); 1195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 11962bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 1197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(ContBB); 1198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 120055b20fc514678ff8ae1627cd9aef047d1f780119John McCallnamespace { 12011f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallEndCatchForFinally : EHScopeStack::Cleanup { 120255b20fc514678ff8ae1627cd9aef047d1f780119John McCall llvm::Value *ForEHVar; 120355b20fc514678ff8ae1627cd9aef047d1f780119John McCall llvm::Value *EndCatchFn; 120455b20fc514678ff8ae1627cd9aef047d1f780119John McCall CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn) 120555b20fc514678ff8ae1627cd9aef047d1f780119John McCall : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {} 120655b20fc514678ff8ae1627cd9aef047d1f780119John McCall 1207ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 120855b20fc514678ff8ae1627cd9aef047d1f780119John McCall llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch"); 120955b20fc514678ff8ae1627cd9aef047d1f780119John McCall llvm::BasicBlock *CleanupContBB = 121055b20fc514678ff8ae1627cd9aef047d1f780119John McCall CGF.createBasicBlock("finally.cleanup.cont"); 121155b20fc514678ff8ae1627cd9aef047d1f780119John McCall 121255b20fc514678ff8ae1627cd9aef047d1f780119John McCall llvm::Value *ShouldEndCatch = 121355b20fc514678ff8ae1627cd9aef047d1f780119John McCall CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch"); 121455b20fc514678ff8ae1627cd9aef047d1f780119John McCall CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB); 121555b20fc514678ff8ae1627cd9aef047d1f780119John McCall CGF.EmitBlock(EndCatchBB); 12164c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(EndCatchFn); // catch-all, so might throw 121755b20fc514678ff8ae1627cd9aef047d1f780119John McCall CGF.EmitBlock(CleanupContBB); 121855b20fc514678ff8ae1627cd9aef047d1f780119John McCall } 121955b20fc514678ff8ae1627cd9aef047d1f780119John McCall }; 122077199713ab56f87ffad9a535ff2a0877704eed87John McCall 12211f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct PerformFinally : EHScopeStack::Cleanup { 122277199713ab56f87ffad9a535ff2a0877704eed87John McCall const Stmt *Body; 122377199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *ForEHVar; 122477199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *EndCatchFn; 122577199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *RethrowFn; 122677199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *SavedExnVar; 122777199713ab56f87ffad9a535ff2a0877704eed87John McCall 122877199713ab56f87ffad9a535ff2a0877704eed87John McCall PerformFinally(const Stmt *Body, llvm::Value *ForEHVar, 122977199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *EndCatchFn, 123077199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *RethrowFn, llvm::Value *SavedExnVar) 123177199713ab56f87ffad9a535ff2a0877704eed87John McCall : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn), 123277199713ab56f87ffad9a535ff2a0877704eed87John McCall RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {} 123377199713ab56f87ffad9a535ff2a0877704eed87John McCall 1234ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 123577199713ab56f87ffad9a535ff2a0877704eed87John McCall // Enter a cleanup to call the end-catch function if one was provided. 123677199713ab56f87ffad9a535ff2a0877704eed87John McCall if (EndCatchFn) 12371f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup, 12381f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall ForEHVar, EndCatchFn); 123977199713ab56f87ffad9a535ff2a0877704eed87John McCall 1240d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Save the current cleanup destination in case there are 1241d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // cleanups in the finally block. 1242d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall llvm::Value *SavedCleanupDest = 1243d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(), 1244d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall "cleanup.dest.saved"); 1245d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall 124677199713ab56f87ffad9a535ff2a0877704eed87John McCall // Emit the finally block. 124777199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.EmitStmt(Body); 124877199713ab56f87ffad9a535ff2a0877704eed87John McCall 124977199713ab56f87ffad9a535ff2a0877704eed87John McCall // If the end of the finally is reachable, check whether this was 125077199713ab56f87ffad9a535ff2a0877704eed87John McCall // for EH. If so, rethrow. 125177199713ab56f87ffad9a535ff2a0877704eed87John McCall if (CGF.HaveInsertPoint()) { 125277199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow"); 125377199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont"); 125477199713ab56f87ffad9a535ff2a0877704eed87John McCall 125577199713ab56f87ffad9a535ff2a0877704eed87John McCall llvm::Value *ShouldRethrow = 125677199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.Builder.CreateLoad(ForEHVar, "finally.shouldthrow"); 125777199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB); 125877199713ab56f87ffad9a535ff2a0877704eed87John McCall 125977199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.EmitBlock(RethrowBB); 126077199713ab56f87ffad9a535ff2a0877704eed87John McCall if (SavedExnVar) { 12614c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(RethrowFn, CGF.Builder.CreateLoad(SavedExnVar)); 126277199713ab56f87ffad9a535ff2a0877704eed87John McCall } else { 12634c7d9f1507d0f102bd4133bba63348636facd469Jay Foad CGF.EmitCallOrInvoke(RethrowFn); 126477199713ab56f87ffad9a535ff2a0877704eed87John McCall } 126577199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.Builder.CreateUnreachable(); 126677199713ab56f87ffad9a535ff2a0877704eed87John McCall 126777199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.EmitBlock(ContBB); 1268d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall 1269d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall // Restore the cleanup destination. 1270d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.Builder.CreateStore(SavedCleanupDest, 1271d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall CGF.getNormalCleanupDestSlot()); 127277199713ab56f87ffad9a535ff2a0877704eed87John McCall } 127377199713ab56f87ffad9a535ff2a0877704eed87John McCall 127477199713ab56f87ffad9a535ff2a0877704eed87John McCall // Leave the end-catch cleanup. As an optimization, pretend that 127577199713ab56f87ffad9a535ff2a0877704eed87John McCall // the fallthrough path was inaccessible; we've dynamically proven 127677199713ab56f87ffad9a535ff2a0877704eed87John McCall // that we're not in the EH case along that path. 127777199713ab56f87ffad9a535ff2a0877704eed87John McCall if (EndCatchFn) { 127877199713ab56f87ffad9a535ff2a0877704eed87John McCall CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 127977199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.PopCleanupBlock(); 128077199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.Builder.restoreIP(SavedIP); 128177199713ab56f87ffad9a535ff2a0877704eed87John McCall } 128277199713ab56f87ffad9a535ff2a0877704eed87John McCall 128377199713ab56f87ffad9a535ff2a0877704eed87John McCall // Now make sure we actually have an insertion point or the 128477199713ab56f87ffad9a535ff2a0877704eed87John McCall // cleanup gods will hate us. 128577199713ab56f87ffad9a535ff2a0877704eed87John McCall CGF.EnsureInsertPoint(); 128677199713ab56f87ffad9a535ff2a0877704eed87John McCall } 128777199713ab56f87ffad9a535ff2a0877704eed87John McCall }; 128855b20fc514678ff8ae1627cd9aef047d1f780119John McCall} 128955b20fc514678ff8ae1627cd9aef047d1f780119John McCall 1290f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Enters a finally block for an implementation using zero-cost 1291f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// exceptions. This is mostly general, but hard-codes some 1292f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// language/ABI-specific behavior in the catch-all sections. 1293d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, 1294d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall const Stmt *body, 1295d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::Constant *beginCatchFn, 1296d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::Constant *endCatchFn, 1297d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::Constant *rethrowFn) { 1298d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall assert((beginCatchFn != 0) == (endCatchFn != 0) && 1299f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall "begin/end catch functions not paired"); 1300d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall assert(rethrowFn && "rethrow function is required"); 1301d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall 1302d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall BeginCatchFn = beginCatchFn; 1303f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The rethrow function has one of the following two types: 1305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // void (*)() 1306f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // void (*)(void*) 1307f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // In the latter case we need to pass it the exception object. 1308f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // But we can't use the exception slot because the @finally might 1309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // have a landing pad (which would overwrite the exception slot). 13102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *rethrowFnTy = 1311f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall cast<llvm::FunctionType>( 1312d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall cast<llvm::PointerType>(rethrowFn->getType())->getElementType()); 1313d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall SavedExnVar = 0; 1314d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall if (rethrowFnTy->getNumParams()) 1315d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn"); 1316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // A finally block is a statement which must be executed on any edge 1318f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // out of a given scope. Unlike a cleanup, the finally block may 1319f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // contain arbitrary control flow leading out of itself. In 1320f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // addition, finally blocks should always be executed, even if there 1321f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // are no catch handlers higher on the stack. Therefore, we 1322f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // surround the protected scope with a combination of a normal 1323f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // cleanup (to catch attempts to break out of the block via normal 1324f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // control flow) and an EH catch-all (semantically "outside" any try 1325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // statement to which the finally block might have been attached). 1326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // The finally block itself is generated in the context of a cleanup 1327f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // which conditionally leaves the catch-all. 1328f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1329f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Jump destination for performing the finally block on an exception 1330f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // edge. We'll never actually reach this block, so unreachable is 1331f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // fine. 1332d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock()); 1333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1334f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Whether the finally block is being executed for EH purposes. 1335d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh"); 1336d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.Builder.CreateStore(CGF.Builder.getFalse(), ForEHVar); 1337f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1338f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Enter a normal cleanup which will perform the @finally block. 1339d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body, 1340d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall ForEHVar, endCatchFn, 1341d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall rethrowFn, SavedExnVar); 1342f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1343f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Enter a catch-all scope. 1344d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall"); 1345d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall EHCatchScope *catchScope = CGF.EHStack.pushCatch(1); 1346d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall catchScope->setCatchAllHandler(0, catchBB); 1347d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall} 1348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1349d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) { 1350d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // Leave the finally catch-all. 1351d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin()); 1352d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block; 1353d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.EHStack.popCatch(); 1354f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1355d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // If there are any references to the catch-all block, emit it. 1356d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall if (catchBB->use_empty()) { 1357d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall delete catchBB; 1358d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall } else { 1359d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP(); 1360d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.EmitBlock(catchBB); 1361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1362d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall llvm::Value *exn = 0; 1363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1364d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // If there's a begin-catch function, call it. 1365d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall if (BeginCatchFn) { 1366d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot()); 1367d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.Builder.CreateCall(BeginCatchFn, exn)->setDoesNotThrow(); 1368d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall } 1369f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1370d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // If we need to remember the exception pointer to rethrow later, do so. 1371d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall if (SavedExnVar) { 1372d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall if (!exn) exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot()); 1373d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.Builder.CreateStore(exn, SavedExnVar); 1374d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall } 1375f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1376d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // Tell the cleanups in the finally block that we're do this for EH. 1377d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.Builder.CreateStore(CGF.Builder.getTrue(), ForEHVar); 1378f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1379d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // Thread a jump through the finally cleanup. 1380d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.EmitBranchThroughCleanup(RethrowDest); 1381f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1382d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.Builder.restoreIP(savedIP); 1383d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall } 1384f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1385d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall // Finally, leave the @finally cleanup. 1386d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall CGF.PopCleanupBlock(); 1387f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1389f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { 1390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (TerminateLandingPad) 1391f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return TerminateLandingPad; 1392f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1393f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); 1394f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1395f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // This will get inserted at the end of the function. 1396f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall TerminateLandingPad = createBasicBlock("terminate.lpad"); 1397f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.SetInsertPoint(TerminateLandingPad); 1398f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Tell the backend that this is a landing pad. 1400f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *Exn = 1401f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn"); 1402f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Exn->setDoesNotThrow(); 14038262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall 14048262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions()); 1405f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1406f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Tell the backend what the exception table should be: 1407f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // nothing but a catch-all. 1408b25938303de0976b9f189363d43033e5788e3d36John McCall llvm::Value *Args[3] = { Exn, getOpaquePersonalityFn(CGM, Personality), 1409f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall getCatchAllValue(*this) }; 1410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector), 14114c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Args, "eh.selector") 1412f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ->setDoesNotThrow(); 1413f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1414f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this)); 1415f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall TerminateCall->setDoesNotReturn(); 1416f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall TerminateCall->setDoesNotThrow(); 1417d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Builder.CreateUnreachable(); 1418d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 1419f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Restore the saved insertion state. 1420f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.restoreIP(SavedIP); 1421891f80ec2fb2d1730b769467d602689e1080845bJohn McCall 1422f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return TerminateLandingPad; 1423d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump} 14249b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 14259b39c51ae3c547568ac42325f94b4197618f6b18Mike Stumpllvm::BasicBlock *CodeGenFunction::getTerminateHandler() { 1426182f383db1782af752ecaf607fdff72a8542088bMike Stump if (TerminateHandler) 1427182f383db1782af752ecaf607fdff72a8542088bMike Stump return TerminateHandler; 1428182f383db1782af752ecaf607fdff72a8542088bMike Stump 1429f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); 14309b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 1431f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Set up the terminate handler. This block is inserted at the very 1432f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // end of the function by FinishFunction. 1433182f383db1782af752ecaf607fdff72a8542088bMike Stump TerminateHandler = createBasicBlock("terminate.handler"); 1434f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.SetInsertPoint(TerminateHandler); 1435f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this)); 14369b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump TerminateCall->setDoesNotReturn(); 14379b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump TerminateCall->setDoesNotThrow(); 14389b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Builder.CreateUnreachable(); 14399b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 14403d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall // Restore the saved insertion state. 1441f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.restoreIP(SavedIP); 144276958099828bac6ebd45abef9f76934b3e99e397Mike Stump 14439b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump return TerminateHandler; 14449b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump} 1445f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1446ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCallCodeGenFunction::UnwindDest CodeGenFunction::getRethrowDest() { 1447ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (RethrowBlock.isValid()) return RethrowBlock; 1448ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1449ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall CGBuilderTy::InsertPoint SavedIP = Builder.saveIP(); 1450ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1451ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall // We emit a jump to a notional label at the outermost unwind state. 1452ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *Unwind = createBasicBlock("eh.resume"); 1453ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Builder.SetInsertPoint(Unwind); 1454ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1455ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions()); 1456ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1457ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall // This can always be a call because we necessarily didn't find 1458ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall // anything on the EH stack which needs our help. 14595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef RethrowName = Personality.getCatchallRethrowFnName(); 146093c332a8ba2c193c435b293966d343dab15f555bJohn McCall if (!RethrowName.empty()) { 146193c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateCall(getCatchallRethrowFn(*this, RethrowName), 146293c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateLoad(getExceptionSlot())) 146393c332a8ba2c193c435b293966d343dab15f555bJohn McCall ->setDoesNotReturn(); 146493c332a8ba2c193c435b293966d343dab15f555bJohn McCall } else { 146593c332a8ba2c193c435b293966d343dab15f555bJohn McCall llvm::Value *Exn = Builder.CreateLoad(getExceptionSlot()); 146693c332a8ba2c193c435b293966d343dab15f555bJohn McCall 146793c332a8ba2c193c435b293966d343dab15f555bJohn McCall switch (CleanupHackLevel) { 146893c332a8ba2c193c435b293966d343dab15f555bJohn McCall case CHL_MandatoryCatchall: 146993c332a8ba2c193c435b293966d343dab15f555bJohn McCall // In mandatory-catchall mode, we need to use 147093c332a8ba2c193c435b293966d343dab15f555bJohn McCall // _Unwind_Resume_or_Rethrow, or whatever the personality's 147193c332a8ba2c193c435b293966d343dab15f555bJohn McCall // equivalent is. 147293c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateCall(getUnwindResumeOrRethrowFn(), Exn) 147393c332a8ba2c193c435b293966d343dab15f555bJohn McCall ->setDoesNotReturn(); 147493c332a8ba2c193c435b293966d343dab15f555bJohn McCall break; 147593c332a8ba2c193c435b293966d343dab15f555bJohn McCall case CHL_MandatoryCleanup: { 147693c332a8ba2c193c435b293966d343dab15f555bJohn McCall // In mandatory-cleanup mode, we should use llvm.eh.resume. 147793c332a8ba2c193c435b293966d343dab15f555bJohn McCall llvm::Value *Selector = Builder.CreateLoad(getEHSelectorSlot()); 147893c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateCall2(CGM.getIntrinsic(llvm::Intrinsic::eh_resume), 147993c332a8ba2c193c435b293966d343dab15f555bJohn McCall Exn, Selector) 148093c332a8ba2c193c435b293966d343dab15f555bJohn McCall ->setDoesNotReturn(); 148193c332a8ba2c193c435b293966d343dab15f555bJohn McCall break; 148293c332a8ba2c193c435b293966d343dab15f555bJohn McCall } 148393c332a8ba2c193c435b293966d343dab15f555bJohn McCall case CHL_Ideal: 148493c332a8ba2c193c435b293966d343dab15f555bJohn McCall // In an idealized mode where we don't have to worry about the 148593c332a8ba2c193c435b293966d343dab15f555bJohn McCall // optimizer combining landing pads, we should just use 148693c332a8ba2c193c435b293966d343dab15f555bJohn McCall // _Unwind_Resume (or the personality's equivalent). 148793c332a8ba2c193c435b293966d343dab15f555bJohn McCall Builder.CreateCall(getUnwindResumeFn(), Exn) 148893c332a8ba2c193c435b293966d343dab15f555bJohn McCall ->setDoesNotReturn(); 148993c332a8ba2c193c435b293966d343dab15f555bJohn McCall break; 149093c332a8ba2c193c435b293966d343dab15f555bJohn McCall } 149193c332a8ba2c193c435b293966d343dab15f555bJohn McCall } 1492ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1493ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Builder.CreateUnreachable(); 1494ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1495ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Builder.restoreIP(SavedIP); 1496ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1497ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall RethrowBlock = UnwindDest(Unwind, EHStack.stable_end(), 0); 1498ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall return RethrowBlock; 1499ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall} 1500ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 1501