CGException.cpp revision f394078fde147dcf27e9b6a7965517388d64dcb6
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
24240ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // Otherwise, it has to be a landingpad instruction.
24340ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(User);
24440ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    if (!LPI) return false;
245b25938303de0976b9f189363d43033e5788e3d36John McCall
24640ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
247b25938303de0976b9f189363d43033e5788e3d36John McCall      // Look for something that would've been returned by the ObjC
248b25938303de0976b9f189363d43033e5788e3d36John McCall      // runtime's GetEHType() method.
24940ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling      llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
25040ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling      if (LPI->isCatch(I)) {
25140ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling        // Check if the catch value has the ObjC prefix.
252eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling        if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
253eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling          // ObjC EH selector entries are always global variables with
254eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling          // names starting like this.
255eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling          if (GV->getName().startswith("OBJC_EHTYPE"))
256eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling            return false;
25740ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling      } else {
25840ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling        // Check if any of the filter values have the ObjC prefix.
25940ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling        llvm::Constant *CVal = cast<llvm::Constant>(Val);
26040ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling        for (llvm::User::op_iterator
26140ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling               II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
262eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling          if (llvm::GlobalVariable *GV =
263eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling              cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
264eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling            // ObjC EH selector entries are always global variables with
265eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling            // names starting like this.
266eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling            if (GV->getName().startswith("OBJC_EHTYPE"))
267eecb6a1e8b95fcdb7d1a0d92b0a0311c041440cdBill Wendling              return false;
26840ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling        }
26940ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling      }
270b25938303de0976b9f189363d43033e5788e3d36John McCall    }
271b25938303de0976b9f189363d43033e5788e3d36John McCall  }
272b25938303de0976b9f189363d43033e5788e3d36John McCall
273b25938303de0976b9f189363d43033e5788e3d36John McCall  return true;
274b25938303de0976b9f189363d43033e5788e3d36John McCall}
275b25938303de0976b9f189363d43033e5788e3d36John McCall
276b25938303de0976b9f189363d43033e5788e3d36John McCall/// Try to use the C++ personality function in ObjC++.  Not doing this
277b25938303de0976b9f189363d43033e5788e3d36John McCall/// can cause some incompatibilities with gcc, which is more
278b25938303de0976b9f189363d43033e5788e3d36John McCall/// aggressive about only using the ObjC++ personality in a function
279b25938303de0976b9f189363d43033e5788e3d36John McCall/// when it really needs it.
280b25938303de0976b9f189363d43033e5788e3d36John McCallvoid CodeGenModule::SimplifyPersonality() {
281b25938303de0976b9f189363d43033e5788e3d36John McCall  // For now, this is really a Darwin-specific operation.
282bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (!Context.getTargetInfo().getTriple().isOSDarwin())
283b25938303de0976b9f189363d43033e5788e3d36John McCall    return;
284b25938303de0976b9f189363d43033e5788e3d36John McCall
285b25938303de0976b9f189363d43033e5788e3d36John McCall  // If we're not in ObjC++ -fexceptions, there's nothing to do.
286b25938303de0976b9f189363d43033e5788e3d36John McCall  if (!Features.CPlusPlus || !Features.ObjC1 || !Features.Exceptions)
287b25938303de0976b9f189363d43033e5788e3d36John McCall    return;
288b25938303de0976b9f189363d43033e5788e3d36John McCall
289b25938303de0976b9f189363d43033e5788e3d36John McCall  const EHPersonality &ObjCXX = EHPersonality::get(Features);
290b25938303de0976b9f189363d43033e5788e3d36John McCall  const EHPersonality &CXX = getCXXPersonality(Features);
291b25938303de0976b9f189363d43033e5788e3d36John McCall  if (&ObjCXX == &CXX ||
292b25938303de0976b9f189363d43033e5788e3d36John McCall      ObjCXX.getPersonalityFnName() == CXX.getPersonalityFnName())
293b25938303de0976b9f189363d43033e5788e3d36John McCall    return;
294b25938303de0976b9f189363d43033e5788e3d36John McCall
295b25938303de0976b9f189363d43033e5788e3d36John McCall  llvm::Function *Fn =
296b25938303de0976b9f189363d43033e5788e3d36John McCall    getModule().getFunction(ObjCXX.getPersonalityFnName());
297b25938303de0976b9f189363d43033e5788e3d36John McCall
298b25938303de0976b9f189363d43033e5788e3d36John McCall  // Nothing to do if it's unused.
299b25938303de0976b9f189363d43033e5788e3d36John McCall  if (!Fn || Fn->use_empty()) return;
300b25938303de0976b9f189363d43033e5788e3d36John McCall
301b25938303de0976b9f189363d43033e5788e3d36John McCall  // Can't do the optimization if it has non-C++ uses.
302b25938303de0976b9f189363d43033e5788e3d36John McCall  if (!PersonalityHasOnlyCXXUses(Fn)) return;
303b25938303de0976b9f189363d43033e5788e3d36John McCall
304b25938303de0976b9f189363d43033e5788e3d36John McCall  // Create the C++ personality function and kill off the old
305b25938303de0976b9f189363d43033e5788e3d36John McCall  // function.
306b25938303de0976b9f189363d43033e5788e3d36John McCall  llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
307b25938303de0976b9f189363d43033e5788e3d36John McCall
308b25938303de0976b9f189363d43033e5788e3d36John McCall  // This can happen if the user is screwing with us.
309b25938303de0976b9f189363d43033e5788e3d36John McCall  if (Fn->getType() != CXXFn->getType()) return;
310b25938303de0976b9f189363d43033e5788e3d36John McCall
311b25938303de0976b9f189363d43033e5788e3d36John McCall  Fn->replaceAllUsesWith(CXXFn);
312b25938303de0976b9f189363d43033e5788e3d36John McCall  Fn->eraseFromParent();
313f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
314f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the
316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a catch-all.
317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
318f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Possibly we should use @llvm.eh.catch.all.value here.
319d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
320f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
321f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
32209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCallnamespace {
32309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// A cleanup to free the exception object if its initialization
32409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// throws.
325c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall  struct FreeException : EHScopeStack::Cleanup {
326c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall    llvm::Value *exn;
327c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall    FreeException(llvm::Value *exn) : exn(exn) {}
328ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
3293ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall      CGF.Builder.CreateCall(getFreeExceptionFn(CGF), exn)
33009faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall        ->setDoesNotThrow();
33109faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    }
33209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  };
33309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall}
33409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
335ac418162692a951ca3796d6830496a85a2d12493John McCall// Emits an exception expression into the given location.  This
336ac418162692a951ca3796d6830496a85a2d12493John McCall// differs from EmitAnyExprToMem only in that, if a final copy-ctor
337ac418162692a951ca3796d6830496a85a2d12493John McCall// call is required, an exception within that copy ctor causes
338ac418162692a951ca3796d6830496a85a2d12493John McCall// std::terminate to be invoked.
3393ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCallstatic void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *e,
3403ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall                             llvm::Value *addr) {
341f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Make sure the exception object is cleaned up if there's an
342f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // exception during initialization.
3433ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall  CGF.pushFullExprCleanup<FreeException>(EHCleanup, addr);
3443ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall  EHScopeStack::stable_iterator cleanup = CGF.EHStack.stable_begin();
345ac418162692a951ca3796d6830496a85a2d12493John McCall
346ac418162692a951ca3796d6830496a85a2d12493John McCall  // __cxa_allocate_exception returns a void*;  we need to cast this
347ac418162692a951ca3796d6830496a85a2d12493John McCall  // to the appropriate type for the object.
3482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *ty = CGF.ConvertTypeForMem(e->getType())->getPointerTo();
3493ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall  llvm::Value *typedAddr = CGF.Builder.CreateBitCast(addr, ty);
350ac418162692a951ca3796d6830496a85a2d12493John McCall
351ac418162692a951ca3796d6830496a85a2d12493John McCall  // FIXME: this isn't quite right!  If there's a final unelided call
352ac418162692a951ca3796d6830496a85a2d12493John McCall  // to a copy constructor, then according to [except.terminate]p1 we
353ac418162692a951ca3796d6830496a85a2d12493John McCall  // must call std::terminate() if that constructor throws, because
354ac418162692a951ca3796d6830496a85a2d12493John McCall  // technically that copy occurs after the exception expression is
355ac418162692a951ca3796d6830496a85a2d12493John McCall  // evaluated but before the exception is caught.  But the best way
356ac418162692a951ca3796d6830496a85a2d12493John McCall  // to handle that is to teach EmitAggExpr to do the final copy
357ac418162692a951ca3796d6830496a85a2d12493John McCall  // differently if it can't be elided.
358f85e193739c953358c865005855253af4f68a497John McCall  CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
359f85e193739c953358c865005855253af4f68a497John McCall                       /*IsInit*/ true);
360ac418162692a951ca3796d6830496a85a2d12493John McCall
3613ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall  // Deactivate the cleanup block.
3626f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  CGF.DeactivateCleanupBlock(cleanup, cast<llvm::Instruction>(typedAddr));
363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
364f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
365f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::Value *CodeGenFunction::getExceptionSlot() {
36693c332a8ba2c193c435b293966d343dab15f555bJohn McCall  if (!ExceptionSlot)
36793c332a8ba2c193c435b293966d343dab15f555bJohn McCall    ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
368f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return ExceptionSlot;
3690f590be3808365e851352543faa6acbece50b686Mike Stump}
3700f590be3808365e851352543faa6acbece50b686Mike Stump
37193c332a8ba2c193c435b293966d343dab15f555bJohn McCallllvm::Value *CodeGenFunction::getEHSelectorSlot() {
37293c332a8ba2c193c435b293966d343dab15f555bJohn McCall  if (!EHSelectorSlot)
37393c332a8ba2c193c435b293966d343dab15f555bJohn McCall    EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
37493c332a8ba2c193c435b293966d343dab15f555bJohn McCall  return EHSelectorSlot;
37593c332a8ba2c193c435b293966d343dab15f555bJohn McCall}
37693c332a8ba2c193c435b293966d343dab15f555bJohn McCall
377ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendlingllvm::Value *CodeGenFunction::getExceptionFromSlot() {
378ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  return Builder.CreateLoad(getExceptionSlot(), "exn");
379ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling}
380ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling
381ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendlingllvm::Value *CodeGenFunction::getSelectorFromSlot() {
382ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  return Builder.CreateLoad(getEHSelectorSlot(), "sel");
383ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling}
384ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling
385756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
386d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  if (!E->getSubExpr()) {
3871eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor    if (getInvokeDest()) {
388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateInvoke(getReThrowFn(*this),
389f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           getUnreachableBlock(),
390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           getInvokeDest())
3911eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor        ->setDoesNotReturn();
392f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
3931eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor      Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
394f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateUnreachable();
395f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
3961eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor
397cd5b22e12b6513163dd131589746c194090f14e6John McCall    // throw is an expression, and the expression emitters expect us
398cd5b22e12b6513163dd131589746c194090f14e6John McCall    // to leave ourselves at a valid insertion point.
399cd5b22e12b6513163dd131589746c194090f14e6John McCall    EmitBlock(createBasicBlock("throw.cont"));
400cd5b22e12b6513163dd131589746c194090f14e6John McCall
401d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson    return;
402d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  }
4038755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
404d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  QualType ThrowType = E->getSubExpr()->getType();
4058755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
406d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // Now allocate the exception object.
4072acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
4083d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall  uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
4098755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
410d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *ExceptionPtr =
4128755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    Builder.CreateCall(AllocExceptionFn,
413d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson                       llvm::ConstantInt::get(SizeTy, TypeSize),
414d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson                       "exception");
415f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  ExceptionPtr->setDoesNotThrow();
4168370c58b9295b32bee50443fe3ac43a47a2047e8Anders Carlsson
417ac418162692a951ca3796d6830496a85a2d12493John McCall  EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
4188755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
419d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // Now throw the exception.
42082a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
42182a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson                                                         /*ForEH=*/true);
422ac418162692a951ca3796d6830496a85a2d12493John McCall
423ac418162692a951ca3796d6830496a85a2d12493John McCall  // The address of the destructor.  If the exception type has a
424ac418162692a951ca3796d6830496a85a2d12493John McCall  // trivial destructor (or isn't a record), we just pass null.
425ac418162692a951ca3796d6830496a85a2d12493John McCall  llvm::Constant *Dtor = 0;
426ac418162692a951ca3796d6830496a85a2d12493John McCall  if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
427ac418162692a951ca3796d6830496a85a2d12493John McCall    CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
428ac418162692a951ca3796d6830496a85a2d12493John McCall    if (!Record->hasTrivialDestructor()) {
4291d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor      CXXDestructorDecl *DtorD = Record->getDestructor();
430ac418162692a951ca3796d6830496a85a2d12493John McCall      Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete);
431ac418162692a951ca3796d6830496a85a2d12493John McCall      Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);
432ac418162692a951ca3796d6830496a85a2d12493John McCall    }
433ac418162692a951ca3796d6830496a85a2d12493John McCall  }
434ac418162692a951ca3796d6830496a85a2d12493John McCall  if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);
4358755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
4360a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  if (getInvokeDest()) {
4378755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    llvm::InvokeInst *ThrowCall =
438f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateInvoke3(getThrowFn(*this),
439f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                            getUnreachableBlock(), getInvokeDest(),
4400a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump                            ExceptionPtr, TypeInfo, Dtor);
4410a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump    ThrowCall->setDoesNotReturn();
4420a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  } else {
4438755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    llvm::CallInst *ThrowCall =
4440a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump      Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
4450a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump    ThrowCall->setDoesNotReturn();
446f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateUnreachable();
4470a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  }
4488755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
449cd5b22e12b6513163dd131589746c194090f14e6John McCall  // throw is an expression, and the expression emitters expect us
450cd5b22e12b6513163dd131589746c194090f14e6John McCall  // to leave ourselves at a valid insertion point.
451cd5b22e12b6513163dd131589746c194090f14e6John McCall  EmitBlock(createBasicBlock("throw.cont"));
452756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson}
4532bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
454cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) {
45515348aeb81285c75b2e92b5bf8d2db3445d147c2Anders Carlsson  if (!CGM.getLangOptions().CXXExceptions)
456a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
457a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
458cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
459cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (FD == 0)
460cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
461cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
462cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (Proto == 0)
463cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
464cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
465a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
466a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  if (isNoexceptExceptionSpec(EST)) {
467a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
468a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      // noexcept functions are simple terminate scopes.
469a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      EHStack.pushTerminate();
470a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
471a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
472a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    unsigned NumExceptions = Proto->getNumExceptions();
473a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
474a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl
475a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    for (unsigned I = 0; I != NumExceptions; ++I) {
476a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      QualType Ty = Proto->getExceptionType(I);
477a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
478a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
479a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl                                                        /*ForEH=*/true);
480a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      Filter->setFilter(I, EHType);
481a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
482cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  }
483cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
484cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
485777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// Emit the dispatch block for a filter scope if necessary.
486777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallstatic void emitFilterDispatchBlock(CodeGenFunction &CGF,
487777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                                    EHFilterScope &filterScope) {
488777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
489777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!dispatchBlock) return;
490777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (dispatchBlock->use_empty()) {
491777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    delete dispatchBlock;
492777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
493777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
494777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
495777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.EmitBlockAfterUses(dispatchBlock);
496777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
497777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If this isn't a catch-all filter, we need to check whether we got
498777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // here because the filter triggered.
499777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (filterScope.getNumFilters()) {
500777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Load the selector value.
501ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling    llvm::Value *selector = CGF.getSelectorFromSlot();
502777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
503777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
504777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *zero = CGF.Builder.getInt32(0);
505777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *failsFilter =
506777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
507777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.Builder.CreateCondBr(failsFilter, unexpectedBB, CGF.getEHResumeBlock());
508777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
509777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.EmitBlock(unexpectedBB);
510777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
511777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
512777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Call __cxa_call_unexpected.  This doesn't need to be an invoke
513777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // because __cxa_call_unexpected magically filters exceptions
514777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // according to the last landing pad the exception was thrown
515777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // into.  Seriously.
516ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  llvm::Value *exn = CGF.getExceptionFromSlot();
517777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.Builder.CreateCall(getUnexpectedFn(CGF), exn)
518777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    ->setDoesNotReturn();
519777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.Builder.CreateUnreachable();
520777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
521777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
522cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) {
52315348aeb81285c75b2e92b5bf8d2db3445d147c2Anders Carlsson  if (!CGM.getLangOptions().CXXExceptions)
524a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
525a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
526cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
527cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (FD == 0)
528cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
529cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
530cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (Proto == 0)
531cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
532cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
533a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
534a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  if (isNoexceptExceptionSpec(EST)) {
535a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
536a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      EHStack.popTerminate();
537a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
538a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
539777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
540777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    emitFilterDispatchBlock(*this, filterScope);
541a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    EHStack.popFilter();
542a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  }
543cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
544cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
5452bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
54659a7000a79118e4c140885ccbb2ac6a686a73092John McCall  EnterCXXTryStmt(S);
5479fc6a7774643a810c8501dae2323e863fefb623eJohn McCall  EmitStmt(S.getTryBlock());
54859a7000a79118e4c140885ccbb2ac6a686a73092John McCall  ExitCXXTryStmt(S);
5499fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
5509fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
55159a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
552f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
553f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
554f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
555f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0; I != NumHandlers; ++I) {
556f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const CXXCatchStmt *C = S.getHandler(I);
557f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
558f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Handler = createBasicBlock("catch");
559f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (C->getExceptionDecl()) {
560f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // FIXME: Dropping the reference type on the type into makes it
561f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // impossible to correctly implement catch-by-reference
562f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // semantics for pointers.  Unfortunately, this is what all
563f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // existing compilers do, and it's not clear that the standard
564f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // personality routine is capable of doing this right.  See C++ DR 388:
565f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
566f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      QualType CaughtType = C->getCaughtType();
567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
5685a180397870944548aaadeaebf58e415885b9489John McCall
5695a180397870944548aaadeaebf58e415885b9489John McCall      llvm::Value *TypeInfo = 0;
5705a180397870944548aaadeaebf58e415885b9489John McCall      if (CaughtType->isObjCObjectPointerType())
571cf5abc7ba032bd35158e4d75b0bc92a482fc67e8Fariborz Jahanian        TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
5725a180397870944548aaadeaebf58e415885b9489John McCall      else
57382a113adf8063baa70251dfa269d039ca22e2537Anders Carlsson        TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);
574f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchScope->setHandler(I, TypeInfo, Handler);
575f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
576f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // No exception decl indicates '...', a catch-all.
577f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchScope->setCatchAllHandler(I, Handler);
578f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
579f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
580f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
581f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
582777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallllvm::BasicBlock *
583777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallCodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
584777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // The dispatch block for the end of the scope chain is a block that
585777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // just resumes unwinding.
586777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (si == EHStack.stable_end())
587777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return getEHResumeBlock();
588777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
589777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Otherwise, we should look at the actual scope.
590777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScope &scope = *EHStack.find(si);
591777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
592777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
593777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!dispatchBlock) {
594777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    switch (scope.getKind()) {
595777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Catch: {
596777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // Apply a special case to a single catch-all.
597777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHCatchScope &catchScope = cast<EHCatchScope>(scope);
598777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      if (catchScope.getNumHandlers() == 1 &&
599777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall          catchScope.getHandler(0).isCatchAll()) {
600777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        dispatchBlock = catchScope.getHandler(0).Block;
601777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
602777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // Otherwise, make a dispatch block.
603777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      } else {
604777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        dispatchBlock = createBasicBlock("catch.dispatch");
605777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      }
606777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
607777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
608777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
609777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Cleanup:
610777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = createBasicBlock("ehcleanup");
611777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
612777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
613777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Filter:
614777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = createBasicBlock("filter.dispatch");
615777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
616777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
617777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Terminate:
618777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = getTerminateHandler();
619777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
620777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
621777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    scope.setCachedEHDispatchBlock(dispatchBlock);
622777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
623777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return dispatchBlock;
624777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
625777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
626f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Check whether this is a non-EH scope, i.e. a scope which doesn't
627f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// affect exception handling.  Currently, the only non-EH scopes are
628f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// normal-only cleanup scopes.
629f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic bool isNonEHScope(const EHScope &S) {
630da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  switch (S.getKind()) {
6311f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  case EHScope::Cleanup:
6321f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall    return !cast<EHCleanupScope>(S).isEHCleanup();
633da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Filter:
634da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Catch:
635da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Terminate:
636da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return false;
637da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  }
638da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
639da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  // Suppress warning.
640da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  return false;
641f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
6429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
643f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
644f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
645f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(!EHStack.empty());
6469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
6477a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson  if (!CGM.getLangOptions().Exceptions)
648da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return 0;
649da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
650f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Check the innermost scope for a cached landing pad.  If this is
651f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
652f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
653f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (LP) return LP;
654f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
655f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Build the landing pad for this scope.
656f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  LP = EmitLandingPad();
657f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(LP);
658f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
659f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Cache the landing pad on the innermost scope.  If this is a
660f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // non-EH scope, cache the landing pad on the enclosing scope, too.
661f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
662f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ir->setCachedLandingPad(LP);
663f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (!isNonEHScope(*ir)) break;
664f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
665f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
666f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return LP;
6679fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
6689fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
66993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// This code contains a hack to work around a design flaw in
67093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// LLVM's EH IR which breaks semantics after inlining.  This same
67193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// hack is implemented in llvm-gcc.
67293c332a8ba2c193c435b293966d343dab15f555bJohn McCall//
67393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// The LLVM EH abstraction is basically a thin veneer over the
67493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// traditional GCC zero-cost design: for each range of instructions
67593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// in the function, there is (at most) one "landing pad" with an
67693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// associated chain of EH actions.  A language-specific personality
67793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// function interprets this chain of actions and (1) decides whether
67893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// or not to resume execution at the landing pad and (2) if so,
67993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// provides an integer indicating why it's stopping.  In LLVM IR,
68093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the association of a landing pad with a range of instructions is
68193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// achieved via an invoke instruction, the chain of actions becomes
68293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the arguments to the @llvm.eh.selector call, and the selector
68393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// call returns the integer indicator.  Other than the required
68493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// presence of two intrinsic function calls in the landing pad,
68593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the IR exactly describes the layout of the output code.
68693c332a8ba2c193c435b293966d343dab15f555bJohn McCall//
68793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// A principal advantage of this design is that it is completely
68893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// language-agnostic; in theory, the LLVM optimizers can treat
68993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// landing pads neutrally, and targets need only know how to lower
69093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the intrinsics to have a functioning exceptions system (assuming
69193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// that platform exceptions follow something approximately like the
69293c332a8ba2c193c435b293966d343dab15f555bJohn McCall// GCC design).  Unfortunately, landing pads cannot be combined in a
69393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// language-agnostic way: given selectors A and B, there is no way
69493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// to make a single landing pad which faithfully represents the
69593c332a8ba2c193c435b293966d343dab15f555bJohn McCall// semantics of propagating an exception first through A, then
69693c332a8ba2c193c435b293966d343dab15f555bJohn McCall// through B, without knowing how the personality will interpret the
69793c332a8ba2c193c435b293966d343dab15f555bJohn McCall// (lowered form of the) selectors.  This means that inlining has no
69893c332a8ba2c193c435b293966d343dab15f555bJohn McCall// choice but to crudely chain invokes (i.e., to ignore invokes in
69993c332a8ba2c193c435b293966d343dab15f555bJohn McCall// the inlined function, but to turn all unwindable calls into
70093c332a8ba2c193c435b293966d343dab15f555bJohn McCall// invokes), which is only semantically valid if every unwind stops
70193c332a8ba2c193c435b293966d343dab15f555bJohn McCall// at every landing pad.
70293c332a8ba2c193c435b293966d343dab15f555bJohn McCall//
70393c332a8ba2c193c435b293966d343dab15f555bJohn McCall// Therefore, the invoke-inline hack is to guarantee that every
70493c332a8ba2c193c435b293966d343dab15f555bJohn McCall// landing pad has a catch-all.
70593c332a8ba2c193c435b293966d343dab15f555bJohn McCallenum CleanupHackLevel_t {
70693c332a8ba2c193c435b293966d343dab15f555bJohn McCall  /// A level of hack that requires that all landing pads have
70793c332a8ba2c193c435b293966d343dab15f555bJohn McCall  /// catch-alls.
70893c332a8ba2c193c435b293966d343dab15f555bJohn McCall  CHL_MandatoryCatchall,
70993c332a8ba2c193c435b293966d343dab15f555bJohn McCall
71093c332a8ba2c193c435b293966d343dab15f555bJohn McCall  /// A level of hack that requires that all landing pads handle
71193c332a8ba2c193c435b293966d343dab15f555bJohn McCall  /// cleanups.
71293c332a8ba2c193c435b293966d343dab15f555bJohn McCall  CHL_MandatoryCleanup,
71393c332a8ba2c193c435b293966d343dab15f555bJohn McCall
71493c332a8ba2c193c435b293966d343dab15f555bJohn McCall  /// No hacks at all;  ideal IR generation.
71593c332a8ba2c193c435b293966d343dab15f555bJohn McCall  CHL_Ideal
71693c332a8ba2c193c435b293966d343dab15f555bJohn McCall};
71793c332a8ba2c193c435b293966d343dab15f555bJohn McCallconst CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup;
71893c332a8ba2c193c435b293966d343dab15f555bJohn McCall
719f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
720f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
721f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
722777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
723777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  switch (innermostEHScope.getKind()) {
724777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Terminate:
725777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return getTerminateLandingPad();
726f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
727777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Catch:
728777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Cleanup:
729777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Filter:
730777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
731777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      return lpad;
732f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
733f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
734f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the current IR generation state.
735777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
736f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
737777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  const EHPersonality &personality = EHPersonality::get(getLangOptions());
7388262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall
739f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Create and configure the landing pad.
740777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *lpad = createBasicBlock("lpad");
741777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EmitBlock(lpad);
742f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
743285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::LandingPadInst *LPadInst =
744285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
745285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                             getOpaquePersonalityFn(CGM, personality), 0);
746285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
747285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
748285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  Builder.CreateStore(LPadExn, getExceptionSlot());
749285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
750285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  Builder.CreateStore(LPadSel, getEHSelectorSlot());
751285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
752f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the exception pointer.  It's safe to use a single exception
753f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer per function because EH cleanups can never have nested
754f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // try/catches.
755285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // Build the landingpad instruction.
756f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
757f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Accumulate all the handlers in scope.
758777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasCatchAll = false;
759777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasCleanup = false;
760777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasFilter = false;
761777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  SmallVector<llvm::Value*, 4> filterTypes;
762777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
763f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end();
764f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         I != E; ++I) {
765f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
766f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    switch (I->getKind()) {
7671f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall    case EHScope::Cleanup:
768777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // If we have a cleanup, remember that.
769777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
770da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      continue;
771da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
772f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Filter: {
773f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
774777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      assert(!hasCatchAll && "EH filter reached after catch-all");
775f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
776285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      // Filter scopes get added to the landingpad in weird ways.
777777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHFilterScope &filter = cast<EHFilterScope>(*I);
778777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasFilter = true;
779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
7808990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling      // Add all the filter values.
7818990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling      for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
7828990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling        filterTypes.push_back(filter.getFilter(i));
783f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
784f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
785f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
786f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Terminate:
787f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Terminate scopes are basically catch-alls.
788777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      assert(!hasCatchAll);
789777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasCatchAll = true;
790f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
791f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Catch:
793f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      break;
794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
796777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHCatchScope &catchScope = cast<EHCatchScope>(*I);
797777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
798777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHCatchScope::Handler handler = catchScope.getHandler(hi);
799777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
800777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // If this is a catch-all, register that and abort.
801777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      if (!handler.Type) {
802777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        assert(!hasCatchAll);
803777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        hasCatchAll = true;
804777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        goto done;
805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      }
806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
807f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Check whether we already have a handler for this type.
808285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      if (catchTypes.insert(handler.Type))
809285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling        // If not, add it directly to the landingpad.
810285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling        LPadInst->addClause(handler.Type);
8112bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump    }
8122bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  }
8132bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
814f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall done:
815285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // If we have a catch-all, add null to the landingpad.
816777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(!(hasCatchAll && hasFilter));
817777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (hasCatchAll) {
818285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    LPadInst->addClause(getCatchAllValue(*this));
819f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
820f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we have an EH filter, we need to add those handlers in the
821285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // right place in the landingpad, which is to say, at the end.
822777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  } else if (hasFilter) {
82340ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // Create a filter expression: a constant array indicating which filter
82440ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // types there are. The personality routine only lands here if the filter
82540ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // doesn't match.
826285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    llvm::SmallVector<llvm::Constant*, 8> Filters;
827285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    llvm::ArrayType *AType =
828285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::ArrayType::get(!filterTypes.empty() ?
829285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                             filterTypes[0]->getType() : Int8PtrTy,
830285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                           filterTypes.size());
831285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
832285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
833285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
834285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
835285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    LPadInst->addClause(FilterArray);
836f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
837f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Also check whether we need a cleanup.
838285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    if (hasCleanup)
839285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadInst->setCleanup(true);
840f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
841f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, signal that we at least have cleanups.
842777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  } else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {
843285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    if (CleanupHackLevel == CHL_MandatoryCatchall)
844285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadInst->addClause(getCatchAllValue(*this));
845285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    else
846285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadInst->setCleanup(true);
8470f590be3808365e851352543faa6acbece50b686Mike Stump  }
8482bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
849285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
850285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling         "landingpad instruction has no clauses!");
851f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
852f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend how to generate the landing pad.
853777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
854f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
855f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the old IR generation state.
856777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.restoreIP(savedIP);
857f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
858777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return lpad;
859f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
8600f590be3808365e851352543faa6acbece50b686Mike Stump
8618e3f86193995c47ee0d229e4336c3382410f09f5John McCallnamespace {
8628e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// A cleanup to call __cxa_end_catch.  In many cases, the caught
8638e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// exception type lets us state definitively that the thrown exception
8648e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// type does not have a destructor.  In particular:
8658e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catch-alls tell us nothing, so we have to conservatively
8668e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     assume that the thrown exception might have a destructor.
8678e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches by reference behave according to their base types.
8688e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches of non-record types will only trigger for exceptions
8698e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     of non-record types, which never have destructors.
8708e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches of record types can trigger for arbitrary subclasses
8718e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     of the caught type, so we have to assume the actual thrown
8728e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     exception type might have a throwing destructor, even if the
8738e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     caught type's destructor is trivial or nothrow.
8741f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct CallEndCatch : EHScopeStack::Cleanup {
8758e3f86193995c47ee0d229e4336c3382410f09f5John McCall    CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
8768e3f86193995c47ee0d229e4336c3382410f09f5John McCall    bool MightThrow;
8778e3f86193995c47ee0d229e4336c3382410f09f5John McCall
878ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
8798e3f86193995c47ee0d229e4336c3382410f09f5John McCall      if (!MightThrow) {
8808e3f86193995c47ee0d229e4336c3382410f09f5John McCall        CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow();
8818e3f86193995c47ee0d229e4336c3382410f09f5John McCall        return;
8828e3f86193995c47ee0d229e4336c3382410f09f5John McCall      }
8838e3f86193995c47ee0d229e4336c3382410f09f5John McCall
8844c7d9f1507d0f102bd4133bba63348636facd469Jay Foad      CGF.EmitCallOrInvoke(getEndCatchFn(CGF));
8858e3f86193995c47ee0d229e4336c3382410f09f5John McCall    }
8868e3f86193995c47ee0d229e4336c3382410f09f5John McCall  };
8878e3f86193995c47ee0d229e4336c3382410f09f5John McCall}
8888e3f86193995c47ee0d229e4336c3382410f09f5John McCall
889f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Emits a call to __cxa_begin_catch and enters a cleanup to call
890f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// __cxa_end_catch.
8918e3f86193995c47ee0d229e4336c3382410f09f5John McCall///
8928e3f86193995c47ee0d229e4336c3382410f09f5John McCall/// \param EndMightThrow - true if __cxa_end_catch might throw
8938e3f86193995c47ee0d229e4336c3382410f09f5John McCallstatic llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
8948e3f86193995c47ee0d229e4336c3382410f09f5John McCall                                   llvm::Value *Exn,
8958e3f86193995c47ee0d229e4336c3382410f09f5John McCall                                   bool EndMightThrow) {
896f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *Call = CGF.Builder.CreateCall(getBeginCatchFn(CGF), Exn);
897f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Call->setDoesNotThrow();
8980f590be3808365e851352543faa6acbece50b686Mike Stump
8991f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
900f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
901f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return Call;
902f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
903f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
904f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// A "special initializer" callback for initializing a catch
905f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// parameter during catch initialization.
906f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic void InitCatchParam(CodeGenFunction &CGF,
907f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const VarDecl &CatchParam,
908f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           llvm::Value *ParamAddr) {
909f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Load the exception from where the landing pad saved it.
910ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  llvm::Value *Exn = CGF.getExceptionFromSlot();
911f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
912f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CanQualType CatchType =
913f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.CGM.getContext().getCanonicalType(CatchParam.getType());
9142acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);
915f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
916f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we're catching by reference, we can just cast the object
917f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer to the appropriate pointer.
918f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (isa<ReferenceType>(CatchType)) {
919204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
920204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    bool EndCatchMightThrow = CaughtType->isRecordType();
9218e3f86193995c47ee0d229e4336c3382410f09f5John McCall
922f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // __cxa_begin_catch returns the adjusted object pointer.
9238e3f86193995c47ee0d229e4336c3382410f09f5John McCall    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);
924204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
925204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    // We have no way to tell the personality function that we're
926204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    // catching by reference, so if we're catching a pointer,
927204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    // __cxa_begin_catch will actually return that pointer by value.
928204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
929204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      QualType PointeeType = PT->getPointeeType();
930204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
931204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // When catching by reference, generally we should just ignore
932204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // this by-value pointer and use the exception object instead.
933204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      if (!PointeeType->isRecordType()) {
934204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
935204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        // Exn points to the struct _Unwind_Exception header, which
936204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        // we have to skip past in order to reach the exception data.
937204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        unsigned HeaderSize =
938204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall          CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();
939204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize);
940204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
941204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // However, if we're catching a pointer-to-record type that won't
942204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // work, because the personality function might have adjusted
943204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // the pointer.  There's actually no way for us to fully satisfy
944204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // the language/ABI contract here:  we can't use Exn because it
945204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // might have the wrong adjustment, but we can't use the by-value
946204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // pointer because it's off by a level of abstraction.
947204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      //
948204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // The current solution is to dump the adjusted pointer into an
949204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // alloca, which breaks language semantics (because changing the
950204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // pointer doesn't change the exception) but at least works.
951204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // The better solution would be to filter out non-exact matches
952204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // and rethrow them, but this is tricky because the rethrow
953204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // really needs to be catchable by other sites at this landing
954204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      // pad.  The best solution is to fix the personality function.
955204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      } else {
956204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        // Pull the pointer for the reference type off.
9572acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner        llvm::Type *PtrTy =
958204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall          cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
959204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
960204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        // Create the temporary and write the adjusted pointer into it.
961204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        llvm::Value *ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, "exn.byref.tmp");
962204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
963204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        CGF.Builder.CreateStore(Casted, ExnPtrTmp);
964204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
965204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        // Bind the reference to the temporary.
966204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall        AdjustedExn = ExnPtrTmp;
967204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall      }
968204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall    }
969204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall
970f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *ExnCast =
971f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");
972f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateStore(ExnCast, ParamAddr);
973f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
974a086783570f76062a345e761811296dc8df571c8Mike Stump  }
9752bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
976f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Non-aggregates (plus complexes).
977f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  bool IsComplex = false;
978f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!CGF.hasAggregateLLVMType(CatchType) ||
979f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      (IsComplex = CatchType->isAnyComplexType())) {
9808e3f86193995c47ee0d229e4336c3382410f09f5John McCall    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);
981f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
982f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If the catch type is a pointer type, __cxa_begin_catch returns
983f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // the pointer by value.
984f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (CatchType->hasPointerRepresentation()) {
985f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *CastExn =
986f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
987f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.Builder.CreateStore(CastExn, ParamAddr);
988f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return;
989f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
9902bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
991f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Otherwise, it returns a pointer into the exception object.
9922bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
9932acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
994f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
9952bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
996f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (IsComplex) {
997f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false),
998f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                             ParamAddr, /*volatile*/ false);
999f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
100091a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar      unsigned Alignment =
100191a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar        CGF.getContext().getDeclAlign(&CatchParam).getQuantity();
1002f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar");
100391a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar      CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, Alignment,
100491a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar                            CatchType);
1005f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
1006f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1007f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
10080f590be3808365e851352543faa6acbece50b686Mike Stump
1009acff696118d98c3acd09a16b96c95807057b5c99John McCall  assert(isa<RecordType>(CatchType) && "unexpected catch type!");
1010b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump
10112acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
1012f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1013acff696118d98c3acd09a16b96c95807057b5c99John McCall  // Check for a copy expression.  If we don't have a copy expression,
1014acff696118d98c3acd09a16b96c95807057b5c99John McCall  // that means a trivial copy is okay.
1015e996ffd240f20a1048179d7727a6ee3227261921John McCall  const Expr *copyExpr = CatchParam.getInit();
1016e996ffd240f20a1048179d7727a6ee3227261921John McCall  if (!copyExpr) {
1017acff696118d98c3acd09a16b96c95807057b5c99John McCall    llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);
1018acff696118d98c3acd09a16b96c95807057b5c99John McCall    llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);
1019acff696118d98c3acd09a16b96c95807057b5c99John McCall    CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType);
1020f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1021f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1022f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1023f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We have to call __cxa_get_exception_ptr to get the adjusted
1024f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer before copying.
1025e996ffd240f20a1048179d7727a6ee3227261921John McCall  llvm::CallInst *rawAdjustedExn =
1026f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF), Exn);
1027e996ffd240f20a1048179d7727a6ee3227261921John McCall  rawAdjustedExn->setDoesNotThrow();
1028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1029e996ffd240f20a1048179d7727a6ee3227261921John McCall  // Cast that to the appropriate type.
1030e996ffd240f20a1048179d7727a6ee3227261921John McCall  llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);
1031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1032e996ffd240f20a1048179d7727a6ee3227261921John McCall  // The copy expression is defined in terms of an OpaqueValueExpr.
1033e996ffd240f20a1048179d7727a6ee3227261921John McCall  // Find it and map it to the adjusted expression.
1034e996ffd240f20a1048179d7727a6ee3227261921John McCall  CodeGenFunction::OpaqueValueMapping
103556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr),
103656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall           CGF.MakeAddrLValue(adjustedExn, CatchParam.getType()));
1037f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1038f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Call the copy ctor in a terminate scope.
1039f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.pushTerminate();
1040e996ffd240f20a1048179d7727a6ee3227261921John McCall
1041e996ffd240f20a1048179d7727a6ee3227261921John McCall  // Perform the copy construction.
1042f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman  unsigned Alignment = CGF.getContext().getDeclAlign(&CatchParam).getQuantity();
1043f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman  CGF.EmitAggExpr(copyExpr,
1044f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman                  AggValueSlot::forAddr(ParamAddr, Alignment, Qualifiers(),
1045f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman                                        AggValueSlot::IsNotDestructed,
1046f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman                                        AggValueSlot::DoesNotNeedGCBarriers,
1047f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman                                        AggValueSlot::IsNotAliased));
1048e996ffd240f20a1048179d7727a6ee3227261921John McCall
1049e996ffd240f20a1048179d7727a6ee3227261921John McCall  // Leave the terminate scope.
1050f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.popTerminate();
1051f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1052e996ffd240f20a1048179d7727a6ee3227261921John McCall  // Undo the opaque value mapping.
1053e996ffd240f20a1048179d7727a6ee3227261921John McCall  opaque.pop();
1054e996ffd240f20a1048179d7727a6ee3227261921John McCall
1055f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Finally we can call __cxa_begin_catch.
10568e3f86193995c47ee0d229e4336c3382410f09f5John McCall  CallBeginCatch(CGF, Exn, true);
1057f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1058f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1059f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Begins a catch statement by initializing the catch variable and
1060f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// calling __cxa_begin_catch.
1061e996ffd240f20a1048179d7727a6ee3227261921John McCallstatic void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {
1062f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We have to be very careful with the ordering of cleanups here:
1063f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   C++ [except.throw]p4:
1064f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     The destruction [of the exception temporary] occurs
1065f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     immediately after the destruction of the object declared in
1066f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     the exception-declaration in the handler.
1067f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
1068f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // So the precise ordering is:
1069f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   1.  Construct catch variable.
1070f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   2.  __cxa_begin_catch
1071f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   3.  Enter __cxa_end_catch cleanup
1072f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   4.  Enter dtor cleanup
1073f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
107434695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  // We do this by using a slightly abnormal initialization process.
107534695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  // Delegation sequence:
1076f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - ExitCXXTryStmt opens a RunCleanupsScope
107734695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  //     - EmitAutoVarAlloca creates the variable and debug info
1078f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //       - InitCatchParam initializes the variable from the exception
107934695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  //       - CallBeginCatch calls __cxa_begin_catch
108034695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  //       - CallBeginCatch enters the __cxa_end_catch cleanup
108134695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  //     - EmitAutoVarCleanups enters the variable destructor cleanup
1082f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - EmitCXXTryStmt emits the code for the catch body
1083f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - EmitCXXTryStmt close the RunCleanupsScope
1084f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1085f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  VarDecl *CatchParam = S->getExceptionDecl();
1086f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!CatchParam) {
1087ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling    llvm::Value *Exn = CGF.getExceptionFromSlot();
10888e3f86193995c47ee0d229e4336c3382410f09f5John McCall    CallBeginCatch(CGF, Exn, true);
1089f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1090f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1091f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1092f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the local.
109334695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
109434695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF));
109534695856c0e67b3765b46304cc71b5d2cd5b71c7John McCall  CGF.EmitAutoVarCleanups(var);
1096f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1097f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1098fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCallnamespace {
10991f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct CallRethrow : EHScopeStack::Cleanup {
1100ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
11014c7d9f1507d0f102bd4133bba63348636facd469Jay Foad      CGF.EmitCallOrInvoke(getReThrowFn(CGF));
1102fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    }
1103fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall  };
1104fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall}
1105fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall
1106777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// Emit the structure of the dispatch block for the given catch scope.
1107777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// It is an invariant that the dispatch block already exists.
1108777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallstatic void emitCatchDispatchBlock(CodeGenFunction &CGF,
1109777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                                   EHCatchScope &catchScope) {
1110777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
1111777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(dispatchBlock);
1112777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1113777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If there's only a single catch-all, getEHDispatchBlock returned
1114777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // that catch-all as the dispatch block.
1115777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (catchScope.getNumHandlers() == 1 &&
1116777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      catchScope.getHandler(0).isCatchAll()) {
1117777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(dispatchBlock == catchScope.getHandler(0).Block);
1118777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
1119777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
1120777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1121777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
1122777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.EmitBlockAfterUses(dispatchBlock);
1123777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1124777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Select the right handler.
1125777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::Value *llvm_eh_typeid_for =
1126777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
1127777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1128777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Load the selector value.
1129ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  llvm::Value *selector = CGF.getSelectorFromSlot();
1130777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1131777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Test against each of the exception types we claim to catch.
1132777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
1133777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(i < e && "ran off end of handlers!");
1134777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    const EHCatchScope::Handler &handler = catchScope.getHandler(i);
1135777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1136777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *typeValue = handler.Type;
1137777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(typeValue && "fell into catch-all case!");
1138777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy);
1139777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1140777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Figure out the next block.
1141777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    bool nextIsEnd;
1142777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *nextBlock;
1143777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1144777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If this is the last handler, we're at the end, and the next
1145777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // block is the block for the enclosing EH scope.
1146777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (i + 1 == e) {
1147777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
1148777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = true;
1149777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1150777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If the next handler is a catch-all, we're at the end, and the
1151777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // next block is that handler.
1152777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    } else if (catchScope.getHandler(i+1).isCatchAll()) {
1153777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = catchScope.getHandler(i+1).Block;
1154777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = true;
1155777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1156777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Otherwise, we're not at the end and we need a new block.
1157777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    } else {
1158777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = CGF.createBasicBlock("catch.fallthrough");
1159777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = false;
1160777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
1161777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1162777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Figure out the catch type's index in the LSDA's type table.
1163777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::CallInst *typeIndex =
1164777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1165777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    typeIndex->setDoesNotThrow();
1166777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1167777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *matchesTypeIndex =
1168777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
1169777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
1170777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1171777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If the next handler is a catch-all, we're completely done.
1172777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (nextIsEnd) {
1173777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.restoreIP(savedIP);
1174777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      return;
1175777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1176777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Otherwise we need to emit and continue at that block.
1177777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    } else {
1178777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.EmitBlock(nextBlock);
1179777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
1180777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
1181777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1182777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm_unreachable("fell out of loop!");
1183777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
1184777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1185777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallvoid CodeGenFunction::popCatchScope() {
1186777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1187777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (catchScope.hasEHBranches())
1188777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    emitCatchDispatchBlock(*this, catchScope);
1189777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHStack.popCatch();
1190777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
1191777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
119259a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
1194f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(CatchScope.getNumHandlers() == NumHandlers);
1196f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1197777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If the catch was not required, bail out now.
1198777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!CatchScope.hasEHBranches()) {
1199777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHStack.popCatch();
1200777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
1201777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
1202777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1203777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Emit the structure of the EH dispatch for this catch.
1204777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  emitCatchDispatchBlock(*this, CatchScope);
1205777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1206f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Copy the handler blocks off before we pop the EH stack.  Emitting
1207f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the handlers might scribble on this memory.
12085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<EHCatchScope::Handler, 8> Handlers(NumHandlers);
1209f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  memcpy(Handlers.data(), CatchScope.begin(),
1210f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         NumHandlers * sizeof(EHCatchScope::Handler));
1211777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1212f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHStack.popCatch();
1213f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1214f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The fall-through block.
1215f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1216f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1217f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We just emitted the body of the try; jump to the continue block.
1218f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (HaveInsertPoint())
1219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateBr(ContBB);
1220f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
122159a7000a79118e4c140885ccbb2ac6a686a73092John McCall  // Determine if we need an implicit rethrow for all these catch handlers.
122259a7000a79118e4c140885ccbb2ac6a686a73092John McCall  bool ImplicitRethrow = false;
122359a7000a79118e4c140885ccbb2ac6a686a73092John McCall  if (IsFnTryBlock)
122459a7000a79118e4c140885ccbb2ac6a686a73092John McCall    ImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
122559a7000a79118e4c140885ccbb2ac6a686a73092John McCall                      isa<CXXConstructorDecl>(CurCodeDecl);
122659a7000a79118e4c140885ccbb2ac6a686a73092John McCall
1227777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Perversely, we emit the handlers backwards precisely because we
1228777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // want them to appear in source order.  In all of these cases, the
1229777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // catch block will have exactly one predecessor, which will be a
1230777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // particular block in the catch dispatch.  However, in the case of
1231777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // a catch-all, one of the dispatch blocks will branch to two
1232777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // different handlers, and EmitBlockAfterUses will cause the second
1233777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // handler to be moved before the first.
1234777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (unsigned I = NumHandlers; I != 0; --I) {
1235777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1236777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EmitBlockAfterUses(CatchBlock);
1237f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1238f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Catch the exception if this isn't a catch-all.
1239777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    const CXXCatchStmt *C = S.getHandler(I-1);
1240f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1241f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Enter a cleanup scope, including the catch variable and the
1242f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // end-catch.
1243f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    RunCleanupsScope CatchScope(*this);
1244f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1245f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Initialize the catch variable and set up the cleanups.
1246f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    BeginCatch(*this, C);
1247f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
124859a7000a79118e4c140885ccbb2ac6a686a73092John McCall    // If there's an implicit rethrow, push a normal "cleanup" to call
1249fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    // _cxa_rethrow.  This needs to happen before __cxa_end_catch is
1250fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    // called, and so it is pushed after BeginCatch.
1251fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    if (ImplicitRethrow)
12521f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall      EHStack.pushCleanup<CallRethrow>(NormalCleanup);
125359a7000a79118e4c140885ccbb2ac6a686a73092John McCall
1254f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Perform the body of the catch.
1255f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitStmt(C->getHandlerBlock());
1256f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1257f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Fall out through the catch cleanups.
1258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CatchScope.ForceCleanup();
1259f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1260f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Branch out of the try.
1261f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (HaveInsertPoint())
1262f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateBr(ContBB);
1263f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
12642bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1265f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBlock(ContBB);
1266f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1267f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
126855b20fc514678ff8ae1627cd9aef047d1f780119John McCallnamespace {
12691f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct CallEndCatchForFinally : EHScopeStack::Cleanup {
127055b20fc514678ff8ae1627cd9aef047d1f780119John McCall    llvm::Value *ForEHVar;
127155b20fc514678ff8ae1627cd9aef047d1f780119John McCall    llvm::Value *EndCatchFn;
127255b20fc514678ff8ae1627cd9aef047d1f780119John McCall    CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
127355b20fc514678ff8ae1627cd9aef047d1f780119John McCall      : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
127455b20fc514678ff8ae1627cd9aef047d1f780119John McCall
1275ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
127655b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
127755b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::BasicBlock *CleanupContBB =
127855b20fc514678ff8ae1627cd9aef047d1f780119John McCall        CGF.createBasicBlock("finally.cleanup.cont");
127955b20fc514678ff8ae1627cd9aef047d1f780119John McCall
128055b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::Value *ShouldEndCatch =
128155b20fc514678ff8ae1627cd9aef047d1f780119John McCall        CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch");
128255b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
128355b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.EmitBlock(EndCatchBB);
12844c7d9f1507d0f102bd4133bba63348636facd469Jay Foad      CGF.EmitCallOrInvoke(EndCatchFn); // catch-all, so might throw
128555b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.EmitBlock(CleanupContBB);
128655b20fc514678ff8ae1627cd9aef047d1f780119John McCall    }
128755b20fc514678ff8ae1627cd9aef047d1f780119John McCall  };
128877199713ab56f87ffad9a535ff2a0877704eed87John McCall
12891f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  struct PerformFinally : EHScopeStack::Cleanup {
129077199713ab56f87ffad9a535ff2a0877704eed87John McCall    const Stmt *Body;
129177199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *ForEHVar;
129277199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *EndCatchFn;
129377199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *RethrowFn;
129477199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *SavedExnVar;
129577199713ab56f87ffad9a535ff2a0877704eed87John McCall
129677199713ab56f87ffad9a535ff2a0877704eed87John McCall    PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
129777199713ab56f87ffad9a535ff2a0877704eed87John McCall                   llvm::Value *EndCatchFn,
129877199713ab56f87ffad9a535ff2a0877704eed87John McCall                   llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
129977199713ab56f87ffad9a535ff2a0877704eed87John McCall      : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
130077199713ab56f87ffad9a535ff2a0877704eed87John McCall        RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
130177199713ab56f87ffad9a535ff2a0877704eed87John McCall
1302ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
130377199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Enter a cleanup to call the end-catch function if one was provided.
130477199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (EndCatchFn)
13051f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall        CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
13061f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                        ForEHVar, EndCatchFn);
130777199713ab56f87ffad9a535ff2a0877704eed87John McCall
1308d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      // Save the current cleanup destination in case there are
1309d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      // cleanups in the finally block.
1310d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      llvm::Value *SavedCleanupDest =
1311d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),
1312d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                               "cleanup.dest.saved");
1313d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
131477199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Emit the finally block.
131577199713ab56f87ffad9a535ff2a0877704eed87John McCall      CGF.EmitStmt(Body);
131677199713ab56f87ffad9a535ff2a0877704eed87John McCall
131777199713ab56f87ffad9a535ff2a0877704eed87John McCall      // If the end of the finally is reachable, check whether this was
131877199713ab56f87ffad9a535ff2a0877704eed87John McCall      // for EH.  If so, rethrow.
131977199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (CGF.HaveInsertPoint()) {
132077199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
132177199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
132277199713ab56f87ffad9a535ff2a0877704eed87John McCall
132377199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::Value *ShouldRethrow =
132477199713ab56f87ffad9a535ff2a0877704eed87John McCall          CGF.Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
132577199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
132677199713ab56f87ffad9a535ff2a0877704eed87John McCall
132777199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.EmitBlock(RethrowBB);
132877199713ab56f87ffad9a535ff2a0877704eed87John McCall        if (SavedExnVar) {
13294c7d9f1507d0f102bd4133bba63348636facd469Jay Foad          CGF.EmitCallOrInvoke(RethrowFn, CGF.Builder.CreateLoad(SavedExnVar));
133077199713ab56f87ffad9a535ff2a0877704eed87John McCall        } else {
13314c7d9f1507d0f102bd4133bba63348636facd469Jay Foad          CGF.EmitCallOrInvoke(RethrowFn);
133277199713ab56f87ffad9a535ff2a0877704eed87John McCall        }
133377199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.CreateUnreachable();
133477199713ab56f87ffad9a535ff2a0877704eed87John McCall
133577199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.EmitBlock(ContBB);
1336d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
1337d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        // Restore the cleanup destination.
1338d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        CGF.Builder.CreateStore(SavedCleanupDest,
1339d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                                CGF.getNormalCleanupDestSlot());
134077199713ab56f87ffad9a535ff2a0877704eed87John McCall      }
134177199713ab56f87ffad9a535ff2a0877704eed87John McCall
134277199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Leave the end-catch cleanup.  As an optimization, pretend that
134377199713ab56f87ffad9a535ff2a0877704eed87John McCall      // the fallthrough path was inaccessible; we've dynamically proven
134477199713ab56f87ffad9a535ff2a0877704eed87John McCall      // that we're not in the EH case along that path.
134577199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (EndCatchFn) {
134677199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
134777199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.PopCleanupBlock();
134877199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.restoreIP(SavedIP);
134977199713ab56f87ffad9a535ff2a0877704eed87John McCall      }
135077199713ab56f87ffad9a535ff2a0877704eed87John McCall
135177199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Now make sure we actually have an insertion point or the
135277199713ab56f87ffad9a535ff2a0877704eed87John McCall      // cleanup gods will hate us.
135377199713ab56f87ffad9a535ff2a0877704eed87John McCall      CGF.EnsureInsertPoint();
135477199713ab56f87ffad9a535ff2a0877704eed87John McCall    }
135577199713ab56f87ffad9a535ff2a0877704eed87John McCall  };
135655b20fc514678ff8ae1627cd9aef047d1f780119John McCall}
135755b20fc514678ff8ae1627cd9aef047d1f780119John McCall
1358f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Enters a finally block for an implementation using zero-cost
1359f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// exceptions.  This is mostly general, but hard-codes some
1360f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// language/ABI-specific behavior in the catch-all sections.
1361d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
1362d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         const Stmt *body,
1363d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *beginCatchFn,
1364d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *endCatchFn,
1365d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *rethrowFn) {
1366d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  assert((beginCatchFn != 0) == (endCatchFn != 0) &&
1367f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         "begin/end catch functions not paired");
1368d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  assert(rethrowFn && "rethrow function is required");
1369d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall
1370d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  BeginCatchFn = beginCatchFn;
1371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1372f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The rethrow function has one of the following two types:
1373f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)()
1374f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)(void*)
1375f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // In the latter case we need to pass it the exception object.
1376f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // But we can't use the exception slot because the @finally might
1377f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // have a landing pad (which would overwrite the exception slot).
13782acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *rethrowFnTy =
1379f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    cast<llvm::FunctionType>(
1380d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall      cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
1381d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  SavedExnVar = 0;
1382d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  if (rethrowFnTy->getNumParams())
1383d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1384f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1385f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A finally block is a statement which must be executed on any edge
1386f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // out of a given scope.  Unlike a cleanup, the finally block may
1387f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // contain arbitrary control flow leading out of itself.  In
1388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // addition, finally blocks should always be executed, even if there
1389f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // are no catch handlers higher on the stack.  Therefore, we
1390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // surround the protected scope with a combination of a normal
1391f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // cleanup (to catch attempts to break out of the block via normal
1392f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // control flow) and an EH catch-all (semantically "outside" any try
1393f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // statement to which the finally block might have been attached).
1394f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The finally block itself is generated in the context of a cleanup
1395f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // which conditionally leaves the catch-all.
1396f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1397f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Jump destination for performing the finally block on an exception
1398f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // edge.  We'll never actually reach this block, so unreachable is
1399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // fine.
1400d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1401f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1402f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Whether the finally block is being executed for EH purposes.
1403d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1404d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  CGF.Builder.CreateStore(CGF.Builder.getFalse(), ForEHVar);
1405f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1406f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a normal cleanup which will perform the @finally block.
1407d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1408d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                          ForEHVar, endCatchFn,
1409d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                          rethrowFn, SavedExnVar);
1410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a catch-all scope.
1412d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1413d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1414d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  catchScope->setCatchAllHandler(0, catchBB);
1415d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall}
1416f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1417d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1418d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // Leave the finally catch-all.
1419d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1420d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1421777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1422777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.popCatchScope();
1423f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1424d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // If there are any references to the catch-all block, emit it.
1425d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  if (catchBB->use_empty()) {
1426d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    delete catchBB;
1427d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  } else {
1428d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1429d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.EmitBlock(catchBB);
1430f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1431d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    llvm::Value *exn = 0;
1432f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1433d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // If there's a begin-catch function, call it.
1434d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    if (BeginCatchFn) {
1435ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling      exn = CGF.getExceptionFromSlot();
1436d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall      CGF.Builder.CreateCall(BeginCatchFn, exn)->setDoesNotThrow();
1437d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    }
1438f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1439d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // If we need to remember the exception pointer to rethrow later, do so.
1440d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    if (SavedExnVar) {
1441ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling      if (!exn) exn = CGF.getExceptionFromSlot();
1442d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall      CGF.Builder.CreateStore(exn, SavedExnVar);
1443d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    }
1444f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1445d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // Tell the cleanups in the finally block that we're do this for EH.
1446d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.Builder.CreateStore(CGF.Builder.getTrue(), ForEHVar);
1447f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1448d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // Thread a jump through the finally cleanup.
1449d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.EmitBranchThroughCleanup(RethrowDest);
1450f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1451d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.Builder.restoreIP(savedIP);
1452d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  }
1453f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1454d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // Finally, leave the @finally cleanup.
1455d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  CGF.PopCleanupBlock();
1456f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1457f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1458f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
1459f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (TerminateLandingPad)
1460f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return TerminateLandingPad;
1461f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1462f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1463f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1464f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // This will get inserted at the end of the function.
1465f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateLandingPad = createBasicBlock("terminate.lpad");
1466f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateLandingPad);
1467f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1468f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend that this is a landing pad.
14698262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
1470285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::LandingPadInst *LPadInst =
1471285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
1472285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                             getOpaquePersonalityFn(CGM, Personality), 0);
1473285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  LPadInst->addClause(getCatchAllValue(*this));
1474f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1475f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
1476f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateCall->setDoesNotReturn();
1477f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateCall->setDoesNotThrow();
1478d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  Builder.CreateUnreachable();
1479d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump
1480f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the saved insertion state.
1481f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1482891f80ec2fb2d1730b769467d602689e1080845bJohn McCall
1483f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return TerminateLandingPad;
1484d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump}
14859b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
14869b39c51ae3c547568ac42325f94b4197618f6b18Mike Stumpllvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
1487182f383db1782af752ecaf607fdff72a8542088bMike Stump  if (TerminateHandler)
1488182f383db1782af752ecaf607fdff72a8542088bMike Stump    return TerminateHandler;
1489182f383db1782af752ecaf607fdff72a8542088bMike Stump
1490f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
14919b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
1492f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Set up the terminate handler.  This block is inserted at the very
1493f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // end of the function by FinishFunction.
1494182f383db1782af752ecaf607fdff72a8542088bMike Stump  TerminateHandler = createBasicBlock("terminate.handler");
1495f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateHandler);
1496f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
14979b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  TerminateCall->setDoesNotReturn();
14989b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  TerminateCall->setDoesNotThrow();
14999b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  Builder.CreateUnreachable();
15009b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
15013d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall  // Restore the saved insertion state.
1502f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
150376958099828bac6ebd45abef9f76934b3e99e397Mike Stump
15049b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  return TerminateHandler;
15059b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump}
1506f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1507777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallllvm::BasicBlock *CodeGenFunction::getEHResumeBlock() {
1508777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (EHResumeBlock) return EHResumeBlock;
1509ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1510ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1511ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1512ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // We emit a jump to a notional label at the outermost unwind state.
1513777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHResumeBlock = createBasicBlock("eh.resume");
1514777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.SetInsertPoint(EHResumeBlock);
1515ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1516ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
1517ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1518ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // This can always be a call because we necessarily didn't find
1519ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // anything on the EH stack which needs our help.
15205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef RethrowName = Personality.getCatchallRethrowFnName();
152193c332a8ba2c193c435b293966d343dab15f555bJohn McCall  if (!RethrowName.empty()) {
152293c332a8ba2c193c435b293966d343dab15f555bJohn McCall    Builder.CreateCall(getCatchallRethrowFn(*this, RethrowName),
1523ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling                       getExceptionFromSlot())
152493c332a8ba2c193c435b293966d343dab15f555bJohn McCall      ->setDoesNotReturn();
152593c332a8ba2c193c435b293966d343dab15f555bJohn McCall  } else {
1526ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling    llvm::Value *Exn = getExceptionFromSlot();
152793c332a8ba2c193c435b293966d343dab15f555bJohn McCall
152893c332a8ba2c193c435b293966d343dab15f555bJohn McCall    switch (CleanupHackLevel) {
152993c332a8ba2c193c435b293966d343dab15f555bJohn McCall    case CHL_MandatoryCatchall:
153093c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // In mandatory-catchall mode, we need to use
153193c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // _Unwind_Resume_or_Rethrow, or whatever the personality's
153293c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // equivalent is.
153393c332a8ba2c193c435b293966d343dab15f555bJohn McCall      Builder.CreateCall(getUnwindResumeOrRethrowFn(), Exn)
153493c332a8ba2c193c435b293966d343dab15f555bJohn McCall        ->setDoesNotReturn();
153593c332a8ba2c193c435b293966d343dab15f555bJohn McCall      break;
153693c332a8ba2c193c435b293966d343dab15f555bJohn McCall    case CHL_MandatoryCleanup: {
1537285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      // In mandatory-cleanup mode, we should use 'resume'.
1538285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
1539285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      // Recreate the landingpad's return value for the 'resume' instruction.
1540285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::Value *Exn = getExceptionFromSlot();
1541285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::Value *Sel = getSelectorFromSlot();
1542285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
1543285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1544285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                                                   Sel->getType(), NULL);
1545285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1546285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1547285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1548285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
1549285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      Builder.CreateResume(LPadVal);
1550285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      Builder.restoreIP(SavedIP);
1551285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      return EHResumeBlock;
155293c332a8ba2c193c435b293966d343dab15f555bJohn McCall    }
155393c332a8ba2c193c435b293966d343dab15f555bJohn McCall    case CHL_Ideal:
155493c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // In an idealized mode where we don't have to worry about the
155593c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // optimizer combining landing pads, we should just use
155693c332a8ba2c193c435b293966d343dab15f555bJohn McCall      // _Unwind_Resume (or the personality's equivalent).
155793c332a8ba2c193c435b293966d343dab15f555bJohn McCall      Builder.CreateCall(getUnwindResumeFn(), Exn)
155893c332a8ba2c193c435b293966d343dab15f555bJohn McCall        ->setDoesNotReturn();
155993c332a8ba2c193c435b293966d343dab15f555bJohn McCall      break;
156093c332a8ba2c193c435b293966d343dab15f555bJohn McCall    }
156193c332a8ba2c193c435b293966d343dab15f555bJohn McCall  }
1562ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1563ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  Builder.CreateUnreachable();
1564ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1565ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  Builder.restoreIP(SavedIP);
1566ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1567777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return EHResumeBlock;
1568ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall}
1569