187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//
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
14756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson#include "CodeGenFunction.h"
150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "CGCXXABI.h"
1636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CGCleanup.h"
17af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer#include "CGObjCRuntime.h"
18204b075fcc47c3f2aa7276dfba9b42eb25840b53John McCall#include "TargetInfo.h"
190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "clang/AST/Mangle.h"
20af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer#include "clang/AST/StmtCXX.h"
21b1ba0efc3d1dc1daa5d82c40bc504e1f368c4fa0Chandler Carruth#include "clang/AST/StmtObjC.h"
2258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar#include "clang/AST/StmtVisitor.h"
2387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#include "clang/Basic/TargetBuiltins.h"
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/IR/CallSite.h"
253b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Intrinsics.h"
2658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar#include "llvm/IR/IntrinsicInst.h"
2758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar#include "llvm/Support/SaveAndRestore.h"
28f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
29756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace clang;
30756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace CodeGen;
31756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson
32629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCallstatic llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {
3399533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __cxa_free_exception(void *thrown_exception);
348755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *FTy =
36629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
378755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
38629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall  return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
3999533834ba8f3658559f334e68a518ebb6388ceaMike Stump}
4099533834ba8f3658559f334e68a518ebb6388ceaMike Stump
41629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCallstatic llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {
4214b0e4b4d55111e2b00db0072d20f4a8209fa5a4Richard Smith  // void __cxa_call_unexpected(void *thrown_exception);
43cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *FTy =
45629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
468755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
47629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall  return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
48cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
49cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::Constant *CodeGenModule::getTerminateFn() {
5199533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __terminate();
5299533834ba8f3658559f334e68a518ebb6388ceaMike Stump
532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *FTy =
543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    llvm::FunctionType::get(VoidTy, /*IsVarArgs=*/false);
558755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef name;
57256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall
58256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall  // In C++, use std::terminate().
593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  if (getLangOpts().CPlusPlus &&
603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      getTarget().getCXXABI().isItaniumFamily()) {
610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    name = "_ZSt9terminatev";
623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  } else if (getLangOpts().CPlusPlus &&
633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar             getTarget().getCXXABI().isMicrosoft()) {
64b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
65b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      name = "__std_terminate";
66b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    else
67b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      name = "\01?terminate@@YAXXZ";
683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  } else if (getLangOpts().ObjC1 &&
693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar             getLangOpts().ObjCRuntime.hasTerminate())
70256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall    name = "objc_terminate";
71256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall  else
72256a76e0b0e0c9e65a3122917d553ef10bc84d29John McCall    name = "abort";
733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return CreateRuntimeFunction(FTy, name);
7479a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall}
7579a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall
76629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCallstatic llvm::Constant *getCatchallRethrowFn(CodeGenModule &CGM,
775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                            StringRef Name) {
782acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *FTy =
79629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
808262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall
81629df0196eb305221d2c8aa9ab72293d05846f0bJohn McCall  return CGM.CreateRuntimeFunction(FTy, Name);
82f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
83f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
85af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramerconst EHPersonality
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst EHPersonality
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesEHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesconst EHPersonality
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst EHPersonality
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst EHPersonality
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
95af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramerconst EHPersonality
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesEHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesconst EHPersonality
98af2771b147f1a5934c6c91574f1c2df986034e74Benjamin KramerEHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
99af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramerconst EHPersonality
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
10165bd4ac6ffbf6de30cd6f36735539ff8172a904aDavid Chisnallconst EHPersonality
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesEHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
1030e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesconst EHPersonality
1040e2c34f92f00628d48968dfea096d36381f494cbStephen HinesEHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
1050e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesconst EHPersonality
1060e2c34f92f00628d48968dfea096d36381f494cbStephen HinesEHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
1070e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesconst EHPersonality
1080e2c34f92f00628d48968dfea096d36381f494cbStephen HinesEHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
1098262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// On Win64, use libgcc's SEH personality function. We fall back to dwarf on
111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// other platforms, unless the user asked for SjLj exceptions.
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic bool useLibGCCSEHPersonality(const llvm::Triple &T) {
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic const EHPersonality &getCPersonality(const llvm::Triple &T,
117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                            const LangOptions &L) {
11844680786286f4f651603c6811f8412a3ee7fe975John McCall  if (L.SjLjExceptions)
11944680786286f4f651603c6811f8412a3ee7fe975John McCall    return EHPersonality::GNU_C_SJLJ;
120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  else if (useLibGCCSEHPersonality(T))
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return EHPersonality::GNU_C_SEH;
1228262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  return EHPersonality::GNU_C;
1238262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall}
1248262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic const EHPersonality &getObjCPersonality(const llvm::Triple &T,
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                               const LangOptions &L) {
127260611a32535c851237926bfcf78869b13c07d5bJohn McCall  switch (L.ObjCRuntime.getKind()) {
128260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::FragileMacOSX:
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getCPersonality(T, L);
130260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::MacOSX:
131260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::iOS:
13287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case ObjCRuntime::WatchOS:
133260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return EHPersonality::NeXT_ObjC;
13411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GNUstep:
13565bd4ac6ffbf6de30cd6f36735539ff8172a904aDavid Chisnall    if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
13665bd4ac6ffbf6de30cd6f36735539ff8172a904aDavid Chisnall      return EHPersonality::GNUstep_ObjC;
13765bd4ac6ffbf6de30cd6f36735539ff8172a904aDavid Chisnall    // fallthrough
13811d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GCC:
139f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall  case ObjCRuntime::ObjFW:
1408262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall    return EHPersonality::GNU_ObjC;
141f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
142260611a32535c851237926bfcf78869b13c07d5bJohn McCall  llvm_unreachable("bad runtime kind");
143f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
145176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic const EHPersonality &getCXXPersonality(const llvm::Triple &T,
146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                              const LangOptions &L) {
1478262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  if (L.SjLjExceptions)
1488262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall    return EHPersonality::GNU_CPlusPlus_SJLJ;
149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  else if (useLibGCCSEHPersonality(T))
150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return EHPersonality::GNU_CPlusPlus_SEH;
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return EHPersonality::GNU_CPlusPlus;
152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
153f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
154f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Determines the personality function to use when both C++
155f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// and Objective-C exceptions are being caught.
156176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic const EHPersonality &getObjCXXPersonality(const llvm::Triple &T,
157176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                                 const LangOptions &L) {
158260611a32535c851237926bfcf78869b13c07d5bJohn McCall  switch (L.ObjCRuntime.getKind()) {
159f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The ObjC personality defers to the C++ personality for non-ObjC
160f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // handlers.  Unlike the C++ case, we use the same personality
161f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // function on targets using (backend-driven) SJLJ EH.
162260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::MacOSX:
163260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::iOS:
16487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case ObjCRuntime::WatchOS:
165260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return EHPersonality::NeXT_ObjC;
166260611a32535c851237926bfcf78869b13c07d5bJohn McCall
167260611a32535c851237926bfcf78869b13c07d5bJohn McCall  // In the fragile ABI, just use C++ exception handling and hope
168260611a32535c851237926bfcf78869b13c07d5bJohn McCall  // they're not doing crazy exception mixing.
169260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::FragileMacOSX:
170176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getCXXPersonality(T, L);
17179a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall
17211d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  // The GCC runtime's personality function inherently doesn't support
1738262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  // mixed EH.  Use the C++ personality just to avoid returning null.
17411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GCC:
175f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall  case ObjCRuntime::ObjFW: // XXX: this will change soon
17611d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    return EHPersonality::GNU_ObjC;
17711d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GNUstep:
178260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return EHPersonality::GNU_ObjCXX;
179260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
180260611a32535c851237926bfcf78869b13c07d5bJohn McCall  llvm_unreachable("bad runtime kind");
181f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
182f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1830e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
1840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (T.getArch() == llvm::Triple::x86)
1850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return EHPersonality::MSVC_except_handler;
1860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return EHPersonality::MSVC_C_specific_handler;
1870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
1880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1890e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesconst EHPersonality &EHPersonality::get(CodeGenModule &CGM,
1900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                        const FunctionDecl *FD) {
191176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const llvm::Triple &T = CGM.getTarget().getTriple();
192176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const LangOptions &L = CGM.getLangOpts();
1930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
19487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Functions using SEH get an SEH personality.
19587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (FD && FD->usesSEHTry())
19687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return getSEHPersonalityMSVC(T);
19787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
1980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Try to pick a personality function that is compatible with MSVC if we're
1990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // not compiling Obj-C. Obj-C users better have an Obj-C runtime that supports
2000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // the GCC-style personality function.
2010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
2020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (L.SjLjExceptions)
2030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return EHPersonality::GNU_CPlusPlus_SJLJ;
2040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    else
2050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return EHPersonality::MSVC_CxxFrameHandler3;
2060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
2070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2088262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  if (L.CPlusPlus && L.ObjC1)
209176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getObjCXXPersonality(T, L);
2108262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  else if (L.CPlusPlus)
211176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getCXXPersonality(T, L);
2128262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  else if (L.ObjC1)
213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getObjCPersonality(T, L);
214f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  else
215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return getCPersonality(T, L);
2168262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall}
2178262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall
21887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarconst EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
21987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));
22087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
22187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
222b25938303de0976b9f189363d43033e5788e3d36John McCallstatic llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
2238262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall                                        const EHPersonality &Personality) {
2248262b6a44c98cf14e1d5f347a01e6bf44858198fJohn McCall  llvm::Constant *Fn =
2258b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner    CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
226af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer                              Personality.PersonalityFn);
227b25938303de0976b9f189363d43033e5788e3d36John McCall  return Fn;
228b25938303de0976b9f189363d43033e5788e3d36John McCall}
229b25938303de0976b9f189363d43033e5788e3d36John McCall
230b25938303de0976b9f189363d43033e5788e3d36John McCallstatic llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
231b25938303de0976b9f189363d43033e5788e3d36John McCall                                        const EHPersonality &Personality) {
232b25938303de0976b9f189363d43033e5788e3d36John McCall  llvm::Constant *Fn = getPersonalityFn(CGM, Personality);
233d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
234b25938303de0976b9f189363d43033e5788e3d36John McCall}
235b25938303de0976b9f189363d43033e5788e3d36John McCall
23687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Check whether a landingpad instruction only uses C++ features.
23787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
23887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
23987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Look for something that would've been returned by the ObjC
24087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // runtime's GetEHType() method.
24187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
24287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (LPI->isCatch(I)) {
24387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Check if the catch value has the ObjC prefix.
24487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
24587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        // ObjC EH selector entries are always global variables with
24687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        // names starting like this.
24787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        if (GV->getName().startswith("OBJC_EHTYPE"))
24887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          return false;
24987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else {
25087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // Check if any of the filter values have the ObjC prefix.
25187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::Constant *CVal = cast<llvm::Constant>(Val);
25287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      for (llvm::User::op_iterator
25387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar              II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
25487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        if (llvm::GlobalVariable *GV =
25587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
25687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          // ObjC EH selector entries are always global variables with
25787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          // names starting like this.
25887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          if (GV->getName().startswith("OBJC_EHTYPE"))
25987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            return false;
26087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      }
26187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
26287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
26387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return true;
26487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
26587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
266b25938303de0976b9f189363d43033e5788e3d36John McCall/// Check whether a personality function could reasonably be swapped
267b25938303de0976b9f189363d43033e5788e3d36John McCall/// for a C++ personality function.
268b25938303de0976b9f189363d43033e5788e3d36John McCallstatic bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (llvm::User *U : Fn->users()) {
270b25938303de0976b9f189363d43033e5788e3d36John McCall    // Conditionally white-list bitcasts.
271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
272b25938303de0976b9f189363d43033e5788e3d36John McCall      if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
273b25938303de0976b9f189363d43033e5788e3d36John McCall      if (!PersonalityHasOnlyCXXUses(CE))
274b25938303de0976b9f189363d43033e5788e3d36John McCall        return false;
275b25938303de0976b9f189363d43033e5788e3d36John McCall      continue;
276b25938303de0976b9f189363d43033e5788e3d36John McCall    }
277b25938303de0976b9f189363d43033e5788e3d36John McCall
27887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Otherwise it must be a function.
27987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Function *F = dyn_cast<llvm::Function>(U);
28087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (!F) return false;
28187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
28287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
28387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (BB->isLandingPad())
28487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        if (!LandingPadHasOnlyCXXUses(BB->getLandingPadInst()))
28587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          return false;
286b25938303de0976b9f189363d43033e5788e3d36John McCall    }
287b25938303de0976b9f189363d43033e5788e3d36John McCall  }
288b25938303de0976b9f189363d43033e5788e3d36John McCall
289b25938303de0976b9f189363d43033e5788e3d36John McCall  return true;
290b25938303de0976b9f189363d43033e5788e3d36John McCall}
291b25938303de0976b9f189363d43033e5788e3d36John McCall
292b25938303de0976b9f189363d43033e5788e3d36John McCall/// Try to use the C++ personality function in ObjC++.  Not doing this
293b25938303de0976b9f189363d43033e5788e3d36John McCall/// can cause some incompatibilities with gcc, which is more
294b25938303de0976b9f189363d43033e5788e3d36John McCall/// aggressive about only using the ObjC++ personality in a function
295b25938303de0976b9f189363d43033e5788e3d36John McCall/// when it really needs it.
296b25938303de0976b9f189363d43033e5788e3d36John McCallvoid CodeGenModule::SimplifyPersonality() {
297b25938303de0976b9f189363d43033e5788e3d36John McCall  // If we're not in ObjC++ -fexceptions, there's nothing to do.
2984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
299b25938303de0976b9f189363d43033e5788e3d36John McCall    return;
300b25938303de0976b9f189363d43033e5788e3d36John McCall
30170cd619e74306b1599d5579e6fd6a14bd9592281John McCall  // Both the problem this endeavors to fix and the way the logic
30270cd619e74306b1599d5579e6fd6a14bd9592281John McCall  // above works is specific to the NeXT runtime.
30370cd619e74306b1599d5579e6fd6a14bd9592281John McCall  if (!LangOpts.ObjCRuntime.isNeXTFamily())
30470cd619e74306b1599d5579e6fd6a14bd9592281John McCall    return;
30570cd619e74306b1599d5579e6fd6a14bd9592281John McCall
3060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
307176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const EHPersonality &CXX =
308176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      getCXXPersonality(getTarget().getTriple(), LangOpts);
309af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer  if (&ObjCXX == &CXX)
310b25938303de0976b9f189363d43033e5788e3d36John McCall    return;
311b25938303de0976b9f189363d43033e5788e3d36John McCall
312af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer  assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
313af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer         "Different EHPersonalities using the same personality function.");
314af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer
315af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer  llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);
316b25938303de0976b9f189363d43033e5788e3d36John McCall
317b25938303de0976b9f189363d43033e5788e3d36John McCall  // Nothing to do if it's unused.
318b25938303de0976b9f189363d43033e5788e3d36John McCall  if (!Fn || Fn->use_empty()) return;
319b25938303de0976b9f189363d43033e5788e3d36John McCall
320b25938303de0976b9f189363d43033e5788e3d36John McCall  // Can't do the optimization if it has non-C++ uses.
321b25938303de0976b9f189363d43033e5788e3d36John McCall  if (!PersonalityHasOnlyCXXUses(Fn)) return;
322b25938303de0976b9f189363d43033e5788e3d36John McCall
323b25938303de0976b9f189363d43033e5788e3d36John McCall  // Create the C++ personality function and kill off the old
324b25938303de0976b9f189363d43033e5788e3d36John McCall  // function.
325b25938303de0976b9f189363d43033e5788e3d36John McCall  llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
326b25938303de0976b9f189363d43033e5788e3d36John McCall
327b25938303de0976b9f189363d43033e5788e3d36John McCall  // This can happen if the user is screwing with us.
328b25938303de0976b9f189363d43033e5788e3d36John McCall  if (Fn->getType() != CXXFn->getType()) return;
329b25938303de0976b9f189363d43033e5788e3d36John McCall
330b25938303de0976b9f189363d43033e5788e3d36John McCall  Fn->replaceAllUsesWith(CXXFn);
331b25938303de0976b9f189363d43033e5788e3d36John McCall  Fn->eraseFromParent();
332f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
334f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the
335f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a catch-all.
336f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
337f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Possibly we should use @llvm.eh.catch.all.value here.
338d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
340f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
34109faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCallnamespace {
34209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// A cleanup to free the exception object if its initialization
34309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// throws.
34487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  struct FreeException final : EHScopeStack::Cleanup {
345c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall    llvm::Value *exn;
346c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCall    FreeException(llvm::Value *exn) : exn(exn) {}
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Emit(CodeGenFunction &CGF, Flags flags) override {
348bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall      CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);
34909faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    }
35009faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  };
35187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace
35209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
353ac418162692a951ca3796d6830496a85a2d12493John McCall// Emits an exception expression into the given location.  This
354ac418162692a951ca3796d6830496a85a2d12493John McCall// differs from EmitAnyExprToMem only in that, if a final copy-ctor
355ac418162692a951ca3796d6830496a85a2d12493John McCall// call is required, an exception within that copy ctor causes
356ac418162692a951ca3796d6830496a85a2d12493John McCall// std::terminate to be invoked.
35787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) {
358f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Make sure the exception object is cleaned up if there's an
359f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // exception during initialization.
36087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  pushFullExprCleanup<FreeException>(EHCleanup, addr.getPointer());
3613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EHScopeStack::stable_iterator cleanup = EHStack.stable_begin();
362ac418162692a951ca3796d6830496a85a2d12493John McCall
363ac418162692a951ca3796d6830496a85a2d12493John McCall  // __cxa_allocate_exception returns a void*;  we need to cast this
364ac418162692a951ca3796d6830496a85a2d12493John McCall  // to the appropriate type for the object.
3653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::Type *ty = ConvertTypeForMem(e->getType())->getPointerTo();
36687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address typedAddr = Builder.CreateBitCast(addr, ty);
367ac418162692a951ca3796d6830496a85a2d12493John McCall
368ac418162692a951ca3796d6830496a85a2d12493John McCall  // FIXME: this isn't quite right!  If there's a final unelided call
369ac418162692a951ca3796d6830496a85a2d12493John McCall  // to a copy constructor, then according to [except.terminate]p1 we
370ac418162692a951ca3796d6830496a85a2d12493John McCall  // must call std::terminate() if that constructor throws, because
371ac418162692a951ca3796d6830496a85a2d12493John McCall  // technically that copy occurs after the exception expression is
372ac418162692a951ca3796d6830496a85a2d12493John McCall  // evaluated but before the exception is caught.  But the best way
373ac418162692a951ca3796d6830496a85a2d12493John McCall  // to handle that is to teach EmitAggExpr to do the final copy
374ac418162692a951ca3796d6830496a85a2d12493John McCall  // differently if it can't be elided.
3753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
3763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                   /*IsInit*/ true);
377ac418162692a951ca3796d6830496a85a2d12493John McCall
3783ad32c8d93eb65d1d4943d7df567fc9b4f55d137John McCall  // Deactivate the cleanup block.
37987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  DeactivateCleanupBlock(cleanup,
38087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                         cast<llvm::Instruction>(typedAddr.getPointer()));
381f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
382f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
38387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::getExceptionSlot() {
38493c332a8ba2c193c435b293966d343dab15f555bJohn McCall  if (!ExceptionSlot)
38593c332a8ba2c193c435b293966d343dab15f555bJohn McCall    ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
38687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Address(ExceptionSlot, getPointerAlign());
3870f590be3808365e851352543faa6acbece50b686Mike Stump}
3880f590be3808365e851352543faa6acbece50b686Mike Stump
38987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::getEHSelectorSlot() {
39093c332a8ba2c193c435b293966d343dab15f555bJohn McCall  if (!EHSelectorSlot)
39193c332a8ba2c193c435b293966d343dab15f555bJohn McCall    EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
39287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Address(EHSelectorSlot, CharUnits::fromQuantity(4));
39393c332a8ba2c193c435b293966d343dab15f555bJohn McCall}
39493c332a8ba2c193c435b293966d343dab15f555bJohn McCall
395ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendlingllvm::Value *CodeGenFunction::getExceptionFromSlot() {
396ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  return Builder.CreateLoad(getExceptionSlot(), "exn");
397ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling}
398ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling
399ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendlingllvm::Value *CodeGenFunction::getSelectorFromSlot() {
400ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  return Builder.CreateLoad(getEHSelectorSlot(), "sel");
401ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling}
402ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling
4034c71b8cded575b0cfc133c5da4502ca613982094Richard Smithvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
4044c71b8cded575b0cfc133c5da4502ca613982094Richard Smith                                       bool KeepInsertionPoint) {
4053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  if (const Expr *SubExpr = E->getSubExpr()) {
4063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    QualType ThrowType = SubExpr->getType();
4073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    if (ThrowType->isObjCObjectPointerType()) {
4083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      const Stmt *ThrowStmt = E->getSubExpr();
4093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt));
4103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
4113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    } else {
4123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGM.getCXXABI().emitThrow(*this, E);
413ac418162692a951ca3796d6830496a85a2d12493John McCall    }
4143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  } else {
4153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
416ac418162692a951ca3796d6830496a85a2d12493John McCall  }
4178755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
418cd5b22e12b6513163dd131589746c194090f14e6John McCall  // throw is an expression, and the expression emitters expect us
419cd5b22e12b6513163dd131589746c194090f14e6John McCall  // to leave ourselves at a valid insertion point.
4204c71b8cded575b0cfc133c5da4502ca613982094Richard Smith  if (KeepInsertionPoint)
4214c71b8cded575b0cfc133c5da4502ca613982094Richard Smith    EmitBlock(createBasicBlock("throw.cont"));
422756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson}
4232bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
424cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) {
4254e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!CGM.getLangOpts().CXXExceptions)
426a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
427a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
428cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
4296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!FD) {
4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Check if CapturedDecl is nothrow and create terminate scope for it.
4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (CD->isNothrow())
4336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        EHStack.pushTerminate();
4346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
435cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
437cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
4386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Proto)
439cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
440cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
441a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
442a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  if (isNoexceptExceptionSpec(EST)) {
443a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
444a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      // noexcept functions are simple terminate scopes.
445a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      EHStack.pushTerminate();
446a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
447a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
44858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // TODO: Revisit exception specifications for the MS ABI.  There is a way to
44958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // encode these in an object file but MSVC doesn't do anything with it.
45058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (getTarget().getCXXABI().isMicrosoft())
45158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      return;
452a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    unsigned NumExceptions = Proto->getNumExceptions();
453a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
454a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl
455a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    for (unsigned I = 0; I != NumExceptions; ++I) {
456a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      QualType Ty = Proto->getExceptionType(I);
457a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
458a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
459a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl                                                        /*ForEH=*/true);
460a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      Filter->setFilter(I, EHType);
461a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
462cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  }
463cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
464cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
465777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// Emit the dispatch block for a filter scope if necessary.
466777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallstatic void emitFilterDispatchBlock(CodeGenFunction &CGF,
467777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                                    EHFilterScope &filterScope) {
468777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
469777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!dispatchBlock) return;
470777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (dispatchBlock->use_empty()) {
471777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    delete dispatchBlock;
472777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
473777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
474777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
475777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.EmitBlockAfterUses(dispatchBlock);
476777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
477777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If this isn't a catch-all filter, we need to check whether we got
478777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // here because the filter triggered.
479777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (filterScope.getNumFilters()) {
480777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Load the selector value.
481ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling    llvm::Value *selector = CGF.getSelectorFromSlot();
482777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
483777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
484777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *zero = CGF.Builder.getInt32(0);
485777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *failsFilter =
4860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
4870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,
4880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                             CGF.getEHResumeBlock(false));
489777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
490777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.EmitBlock(unexpectedBB);
491777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
492777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
493777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Call __cxa_call_unexpected.  This doesn't need to be an invoke
494777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // because __cxa_call_unexpected magically filters exceptions
495777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // according to the last landing pad the exception was thrown
496777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // into.  Seriously.
497ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  llvm::Value *exn = CGF.getExceptionFromSlot();
498bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall  CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)
499777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    ->setDoesNotReturn();
500777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.Builder.CreateUnreachable();
501777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
502777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
503cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) {
5044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!CGM.getLangOpts().CXXExceptions)
505a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
506a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
507cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
5086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!FD) {
5096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Check if CapturedDecl is nothrow and pop terminate scope for it.
5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
5116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (CD->isNothrow())
5126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        EHStack.popTerminate();
5136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
514cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
5156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
516cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Proto)
518cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
519cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
520a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
521a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  if (isNoexceptExceptionSpec(EST)) {
522a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
523a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl      EHStack.popTerminate();
524a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    }
525a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
52658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // TODO: Revisit exception specifications for the MS ABI.  There is a way to
52758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // encode these in an object file but MSVC doesn't do anything with it.
52858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (getTarget().getCXXABI().isMicrosoft())
52958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      return;
530777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
531777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    emitFilterDispatchBlock(*this, filterScope);
532a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl    EHStack.popFilter();
533a968e97947b1281c3bb3c4d47a952b3801d9bb02Sebastian Redl  }
534cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
535cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
5362bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
53759a7000a79118e4c140885ccbb2ac6a686a73092John McCall  EnterCXXTryStmt(S);
5389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall  EmitStmt(S.getTryBlock());
53959a7000a79118e4c140885ccbb2ac6a686a73092John McCall  ExitCXXTryStmt(S);
5409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
5419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
54259a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
543f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
544f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
545f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
546f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0; I != NumHandlers; ++I) {
547f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const CXXCatchStmt *C = S.getHandler(I);
548f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
549f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Handler = createBasicBlock("catch");
550f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (C->getExceptionDecl()) {
551f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // FIXME: Dropping the reference type on the type into makes it
552f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // impossible to correctly implement catch-by-reference
553f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // semantics for pointers.  Unfortunately, this is what all
554f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // existing compilers do, and it's not clear that the standard
555f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // personality routine is capable of doing this right.  See C++ DR 388:
556f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
557176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      Qualifiers CaughtTypeQuals;
558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
559176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
5605a180397870944548aaadeaebf58e415885b9489John McCall
56187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CatchTypeInfo TypeInfo{nullptr, 0};
5625a180397870944548aaadeaebf58e415885b9489John McCall      if (CaughtType->isObjCObjectPointerType())
56387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
5645a180397870944548aaadeaebf58e415885b9489John McCall      else
56587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
56687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CaughtType, C->getCaughtType());
567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchScope->setHandler(I, TypeInfo, Handler);
568f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
569f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // No exception decl indicates '...', a catch-all.
57087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
571f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
572f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
573f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
574f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
575777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallllvm::BasicBlock *
576777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallCodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
57787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (EHPersonality::get(*this).usesFuncletPads())
57887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return getMSVCDispatchBlock(si);
57987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
580777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // The dispatch block for the end of the scope chain is a block that
581777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // just resumes unwinding.
582777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (si == EHStack.stable_end())
583c686004145b1f4dbeb38173a0886ba7040ae0089David Chisnall    return getEHResumeBlock(true);
584777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
585777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Otherwise, we should look at the actual scope.
586777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScope &scope = *EHStack.find(si);
587777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
588777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
589777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!dispatchBlock) {
590777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    switch (scope.getKind()) {
591777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Catch: {
592777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // Apply a special case to a single catch-all.
593777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHCatchScope &catchScope = cast<EHCatchScope>(scope);
594777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      if (catchScope.getNumHandlers() == 1 &&
595777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall          catchScope.getHandler(0).isCatchAll()) {
596777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        dispatchBlock = catchScope.getHandler(0).Block;
597777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
598777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // Otherwise, make a dispatch block.
599777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      } else {
600777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        dispatchBlock = createBasicBlock("catch.dispatch");
601777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      }
602777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
603777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
604777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
605777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Cleanup:
606777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = createBasicBlock("ehcleanup");
607777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
608777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
609777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Filter:
610777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = createBasicBlock("filter.dispatch");
611777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
612777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
613777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    case EHScope::Terminate:
614777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      dispatchBlock = getTerminateHandler();
615777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      break;
61687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
61787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case EHScope::PadEnd:
61887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm_unreachable("PadEnd unnecessary for Itanium!");
619777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
620777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    scope.setCachedEHDispatchBlock(dispatchBlock);
621777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
622777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return dispatchBlock;
623777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
624777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
62587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarllvm::BasicBlock *
62687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarCodeGenFunction::getMSVCDispatchBlock(EHScopeStack::stable_iterator SI) {
62787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Returning nullptr indicates that the previous dispatch block should unwind
62887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // to caller.
62987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (SI == EHStack.stable_end())
63087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return nullptr;
63187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
63287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Otherwise, we should look at the actual scope.
63387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  EHScope &EHS = *EHStack.find(SI);
63487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
63587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::BasicBlock *DispatchBlock = EHS.getCachedEHDispatchBlock();
63687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (DispatchBlock)
63787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return DispatchBlock;
63887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
63987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (EHS.getKind() == EHScope::Terminate)
64087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DispatchBlock = getTerminateHandler();
64187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  else
64287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DispatchBlock = createBasicBlock();
64387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGBuilderTy Builder(*this, DispatchBlock);
64487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
64587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  switch (EHS.getKind()) {
64687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::Catch:
64787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DispatchBlock->setName("catch.dispatch");
64887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
64987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
65087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::Cleanup:
65187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DispatchBlock->setName("ehcleanup");
65287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
65387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
65487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::Filter:
65587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm_unreachable("exception specifications not handled yet!");
65687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
65787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::Terminate:
65887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    DispatchBlock->setName("terminate");
65987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    break;
66087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
66187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::PadEnd:
66287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm_unreachable("PadEnd dispatch block missing!");
66387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
66487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  EHS.setCachedEHDispatchBlock(DispatchBlock);
66587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return DispatchBlock;
66687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
66787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
668f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Check whether this is a non-EH scope, i.e. a scope which doesn't
669f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// affect exception handling.  Currently, the only non-EH scopes are
670f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// normal-only cleanup scopes.
671f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic bool isNonEHScope(const EHScope &S) {
672da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  switch (S.getKind()) {
6731f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  case EHScope::Cleanup:
6741f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall    return !cast<EHCleanupScope>(S).isEHCleanup();
675da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Filter:
676da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Catch:
677da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Terminate:
67887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::PadEnd:
679da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return false;
680da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  }
681da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
6823026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie  llvm_unreachable("Invalid EHScope Kind!");
683f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
6849fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
685f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
686f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
687f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(!EHStack.empty());
6889fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
6894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // If exceptions are disabled and SEH is not in use, then there is no invoke
6904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // destination. SEH "works" even if exceptions are off. In practice, this
6914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // means that C++ destructors and other EH cleanups don't run, which is
6924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // consistent with MSVC's behavior.
6930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const LangOptions &LO = CGM.getLangOpts();
6940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (!LO.Exceptions) {
6950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (!LO.Borland && !LO.MicrosoftExt)
6960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return nullptr;
6970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (!currentFunctionUsesSEHTry())
6980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return nullptr;
6990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
700da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
701f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Check the innermost scope for a cached landing pad.  If this is
702f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
703f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
704f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (LP) return LP;
705f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
70687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const EHPersonality &Personality = EHPersonality::get(*this);
70787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
70887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CurFn->hasPersonalityFn())
70987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
71087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
71187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (Personality.usesFuncletPads()) {
71287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // We don't need separate landing pads in the funclet model.
71387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
71487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
71587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Build the landing pad for this scope.
71687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    LP = EmitLandingPad();
71787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
71887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
719f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(LP);
720f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
721f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Cache the landing pad on the innermost scope.  If this is a
722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // non-EH scope, cache the landing pad on the enclosing scope, too.
723f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
724f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ir->setCachedLandingPad(LP);
725f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (!isNonEHScope(*ir)) break;
726f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
727f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
728f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return LP;
7299fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
7309fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
731f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
732f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
733f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
734777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
735777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  switch (innermostEHScope.getKind()) {
736777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Terminate:
737777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return getTerminateLandingPad();
738f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
73987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  case EHScope::PadEnd:
74087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm_unreachable("PadEnd unnecessary for Itanium!");
74187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
742777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Catch:
743777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Cleanup:
744777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  case EHScope::Filter:
745777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
746777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      return lpad;
747f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
748f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
749f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the current IR generation state.
750777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
7510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
752f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
753f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Create and configure the landing pad.
754777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *lpad = createBasicBlock("lpad");
755777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EmitBlock(lpad);
756f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
75787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
75887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
759285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
760285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
761285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  Builder.CreateStore(LPadExn, getExceptionSlot());
762285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
763285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  Builder.CreateStore(LPadSel, getEHSelectorSlot());
764285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
765f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the exception pointer.  It's safe to use a single exception
766f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer per function because EH cleanups can never have nested
767f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // try/catches.
768285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // Build the landingpad instruction.
769f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
770f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Accumulate all the handlers in scope.
771777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasCatchAll = false;
772777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasCleanup = false;
773777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool hasFilter = false;
774777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  SmallVector<llvm::Value*, 4> filterTypes;
775777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
7760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E;
7770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines       ++I) {
778f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    switch (I->getKind()) {
7801f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall    case EHScope::Cleanup:
781777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // If we have a cleanup, remember that.
782777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
783da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      continue;
784da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
785f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Filter: {
786f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
787777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      assert(!hasCatchAll && "EH filter reached after catch-all");
788f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
789285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      // Filter scopes get added to the landingpad in weird ways.
790777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHFilterScope &filter = cast<EHFilterScope>(*I);
791777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasFilter = true;
792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
7938990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling      // Add all the filter values.
7948990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling      for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
7958990daf237a48fa2eed3d0546687fc097a004db6Bill Wendling        filterTypes.push_back(filter.getFilter(i));
796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Terminate:
800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Terminate scopes are basically catch-alls.
801777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      assert(!hasCatchAll);
802777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      hasCatchAll = true;
803f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
804f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Catch:
806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      break;
80787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
80887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case EHScope::PadEnd:
80987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm_unreachable("PadEnd unnecessary for Itanium!");
810f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
811f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
812777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHCatchScope &catchScope = cast<EHCatchScope>(*I);
813777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
814777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      EHCatchScope::Handler handler = catchScope.getHandler(hi);
81587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      assert(handler.Type.Flags == 0 &&
81687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar             "landingpads do not support catch handler flags");
817777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
818777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      // If this is a catch-all, register that and abort.
81987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (!handler.Type.RTTI) {
820777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        assert(!hasCatchAll);
821777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        hasCatchAll = true;
822777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall        goto done;
823f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      }
824f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
825f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Check whether we already have a handler for this type.
82687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (catchTypes.insert(handler.Type.RTTI).second)
827285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling        // If not, add it directly to the landingpad.
82887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        LPadInst->addClause(handler.Type.RTTI);
8292bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump    }
8302bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  }
8312bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
832f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall done:
833285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // If we have a catch-all, add null to the landingpad.
834777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(!(hasCatchAll && hasFilter));
835777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (hasCatchAll) {
836285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    LPadInst->addClause(getCatchAllValue(*this));
837f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
838f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we have an EH filter, we need to add those handlers in the
839285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  // right place in the landingpad, which is to say, at the end.
840777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  } else if (hasFilter) {
84140ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // Create a filter expression: a constant array indicating which filter
84240ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // types there are. The personality routine only lands here if the filter
84340ccaccd21a4377cd76d6adda2b192dcf9514ef6Bill Wendling    // doesn't match.
844cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    SmallVector<llvm::Constant*, 8> Filters;
845285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    llvm::ArrayType *AType =
846285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      llvm::ArrayType::get(!filterTypes.empty() ?
847285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                             filterTypes[0]->getType() : Int8PtrTy,
848285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling                           filterTypes.size());
849285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling
850285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
851285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
852285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
853285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    LPadInst->addClause(FilterArray);
854f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
855f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Also check whether we need a cleanup.
856285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling    if (hasCleanup)
857285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling      LPadInst->setCleanup(true);
858f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
859f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, signal that we at least have cleanups.
860c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  } else if (hasCleanup) {
861c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    LPadInst->setCleanup(true);
8620f590be3808365e851352543faa6acbece50b686Mike Stump  }
8632bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
864285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
865285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling         "landingpad instruction has no clauses!");
866f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
867f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend how to generate the landing pad.
868777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
869f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
870f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the old IR generation state.
871777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.restoreIP(savedIP);
872f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
873777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return lpad;
874f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
8750f590be3808365e851352543faa6acbece50b686Mike Stump
87687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {
87787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
87887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(DispatchBlock);
87987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
88087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
88187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.EmitBlockAfterUses(DispatchBlock);
88287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
88387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *ParentPad = CGF.CurrentFuncletPad;
88487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!ParentPad)
88587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
88687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::BasicBlock *UnwindBB =
88787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
88887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
88987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  unsigned NumHandlers = CatchScope.getNumHandlers();
89087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::CatchSwitchInst *CatchSwitch =
89187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
89287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
89387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Test against each of the exception types we claim to catch.
89487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  for (unsigned I = 0; I < NumHandlers; ++I) {
89587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
89687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
89787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CatchTypeInfo TypeInfo = Handler.Type;
89887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (!TypeInfo.RTTI)
89987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
90087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
90187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.Builder.SetInsertPoint(Handler.Block);
90287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
90387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (EHPersonality::get(CGF).isMSVCXXPersonality()) {
90487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateCatchPad(
90587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),
90687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                        llvm::Constant::getNullValue(CGF.VoidPtrTy)});
90787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else {
90887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});
90987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
91087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
91187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CatchSwitch->addHandler(Handler.Block);
91287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
91387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.Builder.restoreIP(SavedIP);
91487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
91587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
916777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// Emit the structure of the dispatch block for the given catch scope.
917777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall/// It is an invariant that the dispatch block already exists.
918777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallstatic void emitCatchDispatchBlock(CodeGenFunction &CGF,
919777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                                   EHCatchScope &catchScope) {
92087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (EHPersonality::get(CGF).usesFuncletPads())
92187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return emitCatchPadBlock(CGF, catchScope);
92287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
923777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
924777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(dispatchBlock);
925777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
926777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If there's only a single catch-all, getEHDispatchBlock returned
927777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // that catch-all as the dispatch block.
928777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (catchScope.getNumHandlers() == 1 &&
929777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      catchScope.getHandler(0).isCatchAll()) {
930777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(dispatchBlock == catchScope.getHandler(0).Block);
931777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
932777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
933777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
934777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
935777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.EmitBlockAfterUses(dispatchBlock);
936777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
937777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Select the right handler.
938777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::Value *llvm_eh_typeid_for =
939777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
940777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
941777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Load the selector value.
942ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling  llvm::Value *selector = CGF.getSelectorFromSlot();
943777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
944777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Test against each of the exception types we claim to catch.
945777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
946777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(i < e && "ran off end of handlers!");
947777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    const EHCatchScope::Handler &handler = catchScope.getHandler(i);
948777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
94987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *typeValue = handler.Type.RTTI;
95087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    assert(handler.Type.Flags == 0 &&
95187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar           "landingpads do not support catch handler flags");
952777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(typeValue && "fell into catch-all case!");
953777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy);
954777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
955777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Figure out the next block.
956777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    bool nextIsEnd;
957777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *nextBlock;
958777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
959777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If this is the last handler, we're at the end, and the next
960777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // block is the block for the enclosing EH scope.
961777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (i + 1 == e) {
962777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
963777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = true;
964777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
965777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If the next handler is a catch-all, we're at the end, and the
966777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // next block is that handler.
967777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    } else if (catchScope.getHandler(i+1).isCatchAll()) {
968777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = catchScope.getHandler(i+1).Block;
969777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = true;
970777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
971777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Otherwise, we're not at the end and we need a new block.
972777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    } else {
973777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextBlock = CGF.createBasicBlock("catch.fallthrough");
974777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      nextIsEnd = false;
975777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
976777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
977777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Figure out the catch type's index in the LSDA's type table.
978777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::CallInst *typeIndex =
979777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
980777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    typeIndex->setDoesNotThrow();
981777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
982777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::Value *matchesTypeIndex =
983777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
984777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
985777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
986777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // If the next handler is a catch-all, we're completely done.
987777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (nextIsEnd) {
988777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      CGF.Builder.restoreIP(savedIP);
989777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      return;
990777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    }
991e8e92b9dccc362be33a7f9bb84a114b18db65b10Ahmed Charles    // Otherwise we need to emit and continue at that block.
992e8e92b9dccc362be33a7f9bb84a114b18db65b10Ahmed Charles    CGF.EmitBlock(nextBlock);
993777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
994777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
995777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
996777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallvoid CodeGenFunction::popCatchScope() {
997777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
998777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (catchScope.hasEHBranches())
999777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    emitCatchDispatchBlock(*this, catchScope);
1000777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHStack.popCatch();
1001777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
1002777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
100359a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1004f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
1005f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1006f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(CatchScope.getNumHandlers() == NumHandlers);
1007f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1008777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // If the catch was not required, bail out now.
1009777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (!CatchScope.hasEHBranches()) {
1010651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    CatchScope.clearHandlerBlocks();
1011777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHStack.popCatch();
1012777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return;
1013777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
1014777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1015777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Emit the structure of the EH dispatch for this catch.
1016777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  emitCatchDispatchBlock(*this, CatchScope);
1017777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1018f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Copy the handler blocks off before we pop the EH stack.  Emitting
1019f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the handlers might scribble on this memory.
102087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  SmallVector<EHCatchScope::Handler, 8> Handlers(
102187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CatchScope.begin(), CatchScope.begin() + NumHandlers);
1022777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1023f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHStack.popCatch();
1024f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1025f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The fall-through block.
1026f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1027f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1028f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We just emitted the body of the try; jump to the continue block.
1029f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (HaveInsertPoint())
1030f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateBr(ContBB);
1031f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1032f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall  // Determine if we need an implicit rethrow for all these catch handlers;
1033f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall  // see the comment below.
1034f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall  bool doImplicitRethrow = false;
103559a7000a79118e4c140885ccbb2ac6a686a73092John McCall  if (IsFnTryBlock)
1036f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1037f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall                        isa<CXXConstructorDecl>(CurCodeDecl);
103859a7000a79118e4c140885ccbb2ac6a686a73092John McCall
1039777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // Perversely, we emit the handlers backwards precisely because we
1040777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // want them to appear in source order.  In all of these cases, the
1041777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // catch block will have exactly one predecessor, which will be a
1042777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // particular block in the catch dispatch.  However, in the case of
1043777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // a catch-all, one of the dispatch blocks will branch to two
1044777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // different handlers, and EmitBlockAfterUses will cause the second
1045777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  // handler to be moved before the first.
1046777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (unsigned I = NumHandlers; I != 0; --I) {
1047777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1048777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EmitBlockAfterUses(CatchBlock);
1049f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1050f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Catch the exception if this isn't a catch-all.
1051777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    const CXXCatchStmt *C = S.getHandler(I-1);
1052f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1053f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Enter a cleanup scope, including the catch variable and the
1054f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // end-catch.
1055f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    RunCleanupsScope CatchScope(*this);
1056f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1057f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Initialize the catch variable and set up the cleanups.
105887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
105987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CurrentFuncletPad);
10603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CGM.getCXXABI().emitBeginCatch(*this, C);
1061f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1062651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Emit the PGO counter increment.
1063b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar    incrementProfileCounter(C);
1064651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1065f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Perform the body of the catch.
1066f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitStmt(C->getHandlerBlock());
1067f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1068f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    // [except.handle]p11:
1069f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    //   The currently handled exception is rethrown if control
1070f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    //   reaches the end of a handler of the function-try-block of a
1071f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    //   constructor or destructor.
1072f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall
1073f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    // It is important that we only do this on fallthrough and not on
1074f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    // return.  Note that it's illegal to put a return in a
1075f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    // constructor function-try-block's catch handler (p14), so this
1076f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    // really only applies to destructors.
1077f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    if (doImplicitRethrow && HaveInsertPoint()) {
10780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1079f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall      Builder.CreateUnreachable();
1080f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall      Builder.ClearInsertionPoint();
1081f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall    }
1082f5533019fb70d62917fd080f6152b6469e2c6cd5John McCall
1083f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Fall out through the catch cleanups.
1084f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CatchScope.ForceCleanup();
1085f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1086f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Branch out of the try.
1087f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (HaveInsertPoint())
1088f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateBr(ContBB);
1089f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
10902bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1091f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBlock(ContBB);
1092b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  incrementProfileCounter(&S);
1093f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1094f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
109555b20fc514678ff8ae1627cd9aef047d1f780119John McCallnamespace {
109687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
109755b20fc514678ff8ae1627cd9aef047d1f780119John McCall    llvm::Value *ForEHVar;
109855b20fc514678ff8ae1627cd9aef047d1f780119John McCall    llvm::Value *EndCatchFn;
109955b20fc514678ff8ae1627cd9aef047d1f780119John McCall    CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
110055b20fc514678ff8ae1627cd9aef047d1f780119John McCall      : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
110155b20fc514678ff8ae1627cd9aef047d1f780119John McCall
1102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Emit(CodeGenFunction &CGF, Flags flags) override {
110355b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
110455b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::BasicBlock *CleanupContBB =
110555b20fc514678ff8ae1627cd9aef047d1f780119John McCall        CGF.createBasicBlock("finally.cleanup.cont");
110655b20fc514678ff8ae1627cd9aef047d1f780119John McCall
110755b20fc514678ff8ae1627cd9aef047d1f780119John McCall      llvm::Value *ShouldEndCatch =
110887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
110955b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
111055b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.EmitBlock(EndCatchBB);
1111bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall      CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
111255b20fc514678ff8ae1627cd9aef047d1f780119John McCall      CGF.EmitBlock(CleanupContBB);
111355b20fc514678ff8ae1627cd9aef047d1f780119John McCall    }
111455b20fc514678ff8ae1627cd9aef047d1f780119John McCall  };
111577199713ab56f87ffad9a535ff2a0877704eed87John McCall
111687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  struct PerformFinally final : EHScopeStack::Cleanup {
111777199713ab56f87ffad9a535ff2a0877704eed87John McCall    const Stmt *Body;
111877199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *ForEHVar;
111977199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *EndCatchFn;
112077199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *RethrowFn;
112177199713ab56f87ffad9a535ff2a0877704eed87John McCall    llvm::Value *SavedExnVar;
112277199713ab56f87ffad9a535ff2a0877704eed87John McCall
112377199713ab56f87ffad9a535ff2a0877704eed87John McCall    PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
112477199713ab56f87ffad9a535ff2a0877704eed87John McCall                   llvm::Value *EndCatchFn,
112577199713ab56f87ffad9a535ff2a0877704eed87John McCall                   llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
112677199713ab56f87ffad9a535ff2a0877704eed87John McCall      : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
112777199713ab56f87ffad9a535ff2a0877704eed87John McCall        RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
112877199713ab56f87ffad9a535ff2a0877704eed87John McCall
1129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Emit(CodeGenFunction &CGF, Flags flags) override {
113077199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Enter a cleanup to call the end-catch function if one was provided.
113177199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (EndCatchFn)
11321f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall        CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
11331f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall                                                        ForEHVar, EndCatchFn);
113477199713ab56f87ffad9a535ff2a0877704eed87John McCall
1135d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      // Save the current cleanup destination in case there are
1136d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      // cleanups in the finally block.
1137d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall      llvm::Value *SavedCleanupDest =
1138d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),
1139d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                               "cleanup.dest.saved");
1140d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
114177199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Emit the finally block.
114277199713ab56f87ffad9a535ff2a0877704eed87John McCall      CGF.EmitStmt(Body);
114377199713ab56f87ffad9a535ff2a0877704eed87John McCall
114477199713ab56f87ffad9a535ff2a0877704eed87John McCall      // If the end of the finally is reachable, check whether this was
114577199713ab56f87ffad9a535ff2a0877704eed87John McCall      // for EH.  If so, rethrow.
114677199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (CGF.HaveInsertPoint()) {
114777199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
114877199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
114977199713ab56f87ffad9a535ff2a0877704eed87John McCall
115077199713ab56f87ffad9a535ff2a0877704eed87John McCall        llvm::Value *ShouldRethrow =
115187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
115277199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
115377199713ab56f87ffad9a535ff2a0877704eed87John McCall
115477199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.EmitBlock(RethrowBB);
115577199713ab56f87ffad9a535ff2a0877704eed87John McCall        if (SavedExnVar) {
1156bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall          CGF.EmitRuntimeCallOrInvoke(RethrowFn,
115787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar            CGF.Builder.CreateAlignedLoad(SavedExnVar, CGF.getPointerAlign()));
115877199713ab56f87ffad9a535ff2a0877704eed87John McCall        } else {
1159bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall          CGF.EmitRuntimeCallOrInvoke(RethrowFn);
116077199713ab56f87ffad9a535ff2a0877704eed87John McCall        }
116177199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.CreateUnreachable();
116277199713ab56f87ffad9a535ff2a0877704eed87John McCall
116377199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.EmitBlock(ContBB);
1164d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall
1165d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        // Restore the cleanup destination.
1166d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall        CGF.Builder.CreateStore(SavedCleanupDest,
1167d96a8e771ca9f406f0fa1dd4639997335ae444a7John McCall                                CGF.getNormalCleanupDestSlot());
116877199713ab56f87ffad9a535ff2a0877704eed87John McCall      }
116977199713ab56f87ffad9a535ff2a0877704eed87John McCall
117077199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Leave the end-catch cleanup.  As an optimization, pretend that
117177199713ab56f87ffad9a535ff2a0877704eed87John McCall      // the fallthrough path was inaccessible; we've dynamically proven
117277199713ab56f87ffad9a535ff2a0877704eed87John McCall      // that we're not in the EH case along that path.
117377199713ab56f87ffad9a535ff2a0877704eed87John McCall      if (EndCatchFn) {
117477199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
117577199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.PopCleanupBlock();
117677199713ab56f87ffad9a535ff2a0877704eed87John McCall        CGF.Builder.restoreIP(SavedIP);
117777199713ab56f87ffad9a535ff2a0877704eed87John McCall      }
117877199713ab56f87ffad9a535ff2a0877704eed87John McCall
117977199713ab56f87ffad9a535ff2a0877704eed87John McCall      // Now make sure we actually have an insertion point or the
118077199713ab56f87ffad9a535ff2a0877704eed87John McCall      // cleanup gods will hate us.
118177199713ab56f87ffad9a535ff2a0877704eed87John McCall      CGF.EnsureInsertPoint();
118277199713ab56f87ffad9a535ff2a0877704eed87John McCall    }
118377199713ab56f87ffad9a535ff2a0877704eed87John McCall  };
118487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace
118555b20fc514678ff8ae1627cd9aef047d1f780119John McCall
1186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Enters a finally block for an implementation using zero-cost
1187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// exceptions.  This is mostly general, but hard-codes some
1188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// language/ABI-specific behavior in the catch-all sections.
1189d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
1190d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         const Stmt *body,
1191d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *beginCatchFn,
1192d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *endCatchFn,
1193d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                         llvm::Constant *rethrowFn) {
11946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert((beginCatchFn != nullptr) == (endCatchFn != nullptr) &&
1195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         "begin/end catch functions not paired");
1196d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  assert(rethrowFn && "rethrow function is required");
1197d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall
1198d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  BeginCatchFn = beginCatchFn;
1199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1200f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The rethrow function has one of the following two types:
1201f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)()
1202f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)(void*)
1203f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // In the latter case we need to pass it the exception object.
1204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // But we can't use the exception slot because the @finally might
1205f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // have a landing pad (which would overwrite the exception slot).
12062acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::FunctionType *rethrowFnTy =
1207f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    cast<llvm::FunctionType>(
1208d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall      cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
12096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SavedExnVar = nullptr;
1210d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  if (rethrowFnTy->getNumParams())
1211d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1212f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1213f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A finally block is a statement which must be executed on any edge
1214f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // out of a given scope.  Unlike a cleanup, the finally block may
1215f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // contain arbitrary control flow leading out of itself.  In
1216f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // addition, finally blocks should always be executed, even if there
1217f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // are no catch handlers higher on the stack.  Therefore, we
1218f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // surround the protected scope with a combination of a normal
1219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // cleanup (to catch attempts to break out of the block via normal
1220f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // control flow) and an EH catch-all (semantically "outside" any try
1221f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // statement to which the finally block might have been attached).
1222f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The finally block itself is generated in the context of a cleanup
1223f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // which conditionally leaves the catch-all.
1224f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1225f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Jump destination for performing the finally block on an exception
1226f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // edge.  We'll never actually reach this block, so unreachable is
1227f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // fine.
1228d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1230f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Whether the finally block is being executed for EH purposes.
1231d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
123287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGF.Builder.CreateFlagStore(false, ForEHVar);
1233f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1234f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a normal cleanup which will perform the @finally block.
1235d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1236d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                          ForEHVar, endCatchFn,
1237d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                                          rethrowFn, SavedExnVar);
1238f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1239f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a catch-all scope.
1240d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1241d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1242d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  catchScope->setCatchAllHandler(0, catchBB);
1243d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall}
1244f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1245d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCallvoid CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1246d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // Leave the finally catch-all.
1247d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1248d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1249777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
1250777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  CGF.popCatchScope();
1251f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1252d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // If there are any references to the catch-all block, emit it.
1253d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  if (catchBB->use_empty()) {
1254d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    delete catchBB;
1255d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  } else {
1256d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1257d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.EmitBlock(catchBB);
1258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
12596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    llvm::Value *exn = nullptr;
1260f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1261d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // If there's a begin-catch function, call it.
1262d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    if (BeginCatchFn) {
1263ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling      exn = CGF.getExceptionFromSlot();
1264bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall      CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1265d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    }
1266f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1267d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // If we need to remember the exception pointer to rethrow later, do so.
1268d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    if (SavedExnVar) {
1269ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling      if (!exn) exn = CGF.getExceptionFromSlot();
127087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1271d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    }
1272f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1273d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // Tell the cleanups in the finally block that we're do this for EH.
127487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CGF.Builder.CreateFlagStore(true, ForEHVar);
1275f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1276d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    // Thread a jump through the finally cleanup.
1277d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.EmitBranchThroughCleanup(RethrowDest);
1278f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1279d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    CGF.Builder.restoreIP(savedIP);
1280d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  }
1281f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1282d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // Finally, leave the @finally cleanup.
1283d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  CGF.PopCleanupBlock();
1284f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1285f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1286f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
1287f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (TerminateLandingPad)
1288f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return TerminateLandingPad;
1289f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1290f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1291f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1292f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // This will get inserted at the end of the function.
1293f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateLandingPad = createBasicBlock("terminate.lpad");
1294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateLandingPad);
1295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1296f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend that this is a landing pad.
12970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const EHPersonality &Personality = EHPersonality::get(*this);
129887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
129987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!CurFn->hasPersonalityFn())
130087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
130187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
130287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
130387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
1304285cfd8953d4ca4da613a47a0d691f7234068f8cBill Wendling  LPadInst->addClause(getCatchAllValue(*this));
1305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
130687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Exn = nullptr;
13073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  if (getLangOpts().CPlusPlus)
13083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    Exn = Builder.CreateExtractValue(LPadInst, 0);
13093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::CallInst *terminateCall =
13103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
131166b22771fc0a1dba598e50469f2961048e7edd55John McCall  terminateCall->setDoesNotReturn();
1312d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall  Builder.CreateUnreachable();
1313d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump
1314f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the saved insertion state.
1315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1316891f80ec2fb2d1730b769467d602689e1080845bJohn McCall
1317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return TerminateLandingPad;
1318d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump}
13199b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
13209b39c51ae3c547568ac42325f94b4197618f6b18Mike Stumpllvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
1321182f383db1782af752ecaf607fdff72a8542088bMike Stump  if (TerminateHandler)
1322182f383db1782af752ecaf607fdff72a8542088bMike Stump    return TerminateHandler;
1323182f383db1782af752ecaf607fdff72a8542088bMike Stump
1324f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
13259b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
1326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Set up the terminate handler.  This block is inserted at the very
1327f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // end of the function by FinishFunction.
1328182f383db1782af752ecaf607fdff72a8542088bMike Stump  TerminateHandler = createBasicBlock("terminate.handler");
1329f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateHandler);
133087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Exn = nullptr;
13314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
13324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      CurrentFuncletPad);
133387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (EHPersonality::get(*this).usesFuncletPads()) {
133487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *ParentPad = CurrentFuncletPad;
133587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (!ParentPad)
133687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
13374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
133887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
133987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (getLangOpts().CPlusPlus)
134087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Exn = getExceptionFromSlot();
134187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
13423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  llvm::CallInst *terminateCall =
13433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
134445ff3807ef06bca715afb9eb7e16c4c89880e40eJohn McCall  terminateCall->setDoesNotReturn();
13459b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  Builder.CreateUnreachable();
13469b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
13473d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall  // Restore the saved insertion state.
1348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
134976958099828bac6ebd45abef9f76934b3e99e397Mike Stump
13509b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  return TerminateHandler;
13519b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump}
1352f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1353c686004145b1f4dbeb38173a0886ba7040ae0089David Chisnallllvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1354777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (EHResumeBlock) return EHResumeBlock;
1355ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1356ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1357ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1358ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // We emit a jump to a notional label at the outermost unwind state.
1359777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHResumeBlock = createBasicBlock("eh.resume");
1360777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  Builder.SetInsertPoint(EHResumeBlock);
1361ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
13620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const EHPersonality &Personality = EHPersonality::get(*this);
1363ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1364ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // This can always be a call because we necessarily didn't find
1365ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  // anything on the EH stack which needs our help.
1366af2771b147f1a5934c6c91574f1c2df986034e74Benjamin Kramer  const char *RethrowName = Personality.CatchallRethrowFn;
13676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (RethrowName != nullptr && !isCleanup) {
1368bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall    EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),
13690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                    getExceptionFromSlot())->setDoesNotReturn();
1370c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    Builder.CreateUnreachable();
1371c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    Builder.restoreIP(SavedIP);
1372c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return EHResumeBlock;
137393c332a8ba2c193c435b293966d343dab15f555bJohn McCall  }
1374ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1375c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // Recreate the landingpad's return value for the 'resume' instruction.
1376c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  llvm::Value *Exn = getExceptionFromSlot();
1377c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  llvm::Value *Sel = getSelectorFromSlot();
1378ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1379c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
13800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                               Sel->getType(), nullptr);
1381c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1382c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1383c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1384ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall
1385c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  Builder.CreateResume(LPadVal);
1386c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  Builder.restoreIP(SavedIP);
1387777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return EHResumeBlock;
1388ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall}
138998592d9c4dff79480fdc25b83988de03f912b647Reid Kleckner
139098592d9c4dff79480fdc25b83988de03f912b647Reid Klecknervoid CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
139158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  EnterSEHTryStmt(S);
13920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  {
13930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
13940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
13950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    SEHTryEpilogueStack.push_back(&TryExit);
13960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    EmitStmt(S.getTryBlock());
13970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    SEHTryEpilogueStack.pop_back();
13980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
13990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (!TryExit.getBlock()->use_empty())
14000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
14010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    else
14020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      delete TryExit.getBlock();
14030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
140458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  ExitSEHTryStmt(S);
14050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
14060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
14070e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesnamespace {
140887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstruct PerformSEHFinally final : EHScopeStack::Cleanup {
140958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Function *OutlinedFinally;
141058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  PerformSEHFinally(llvm::Function *OutlinedFinally)
141158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      : OutlinedFinally(OutlinedFinally) {}
14120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
14130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void Emit(CodeGenFunction &CGF, Flags F) override {
141458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    ASTContext &Context = CGF.getContext();
141587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    CodeGenModule &CGM = CGF.CGM;
141658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
141758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    CallArgList Args;
141887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
141987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Compute the two argument values.
142087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
142187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
142287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
142358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Value *IsForEH =
142458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
142558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    Args.add(RValue::get(IsForEH), ArgTys[0]);
142658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    Args.add(RValue::get(FP), ArgTys[1]);
142758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
142887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Arrange a two-arg function info and type.
142958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    const CGFunctionInfo &FnInfo =
14304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
143187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
143258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
143358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
143458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar};
143587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace
14360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
143758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarnamespace {
143858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// Find all local variable captures in the statement.
143958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarstruct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
144058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CodeGenFunction &ParentCGF;
144158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const VarDecl *ParentThis;
144287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::SmallSetVector<const VarDecl *, 4> Captures;
144387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Address SEHCodeSlot = Address::invalid();
144458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
144558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
144658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
144787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Return true if we need to do any capturing work.
144887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  bool foundCaptures() {
144987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return !Captures.empty() || SEHCodeSlot.isValid();
145087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
145187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
145258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void Visit(const Stmt *S) {
145358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // See if this is a capture, then recurse.
145458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    ConstStmtVisitor<CaptureFinder>::Visit(S);
145558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    for (const Stmt *Child : S->children())
145658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      if (Child)
145758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        Visit(Child);
145858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
145958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
146058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void VisitDeclRefExpr(const DeclRefExpr *E) {
146158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // If this is already a capture, just make sure we capture 'this'.
146258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (E->refersToEnclosingVariableOrCapture()) {
146387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Captures.insert(ParentThis);
146458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      return;
14650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    }
146658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
146758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    const auto *D = dyn_cast<VarDecl>(E->getDecl());
146858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
146987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Captures.insert(D);
147058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
147158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
147258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void VisitCXXThisExpr(const CXXThisExpr *E) {
147387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Captures.insert(ParentThis);
147487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
147587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
147687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void VisitCallExpr(const CallExpr *E) {
147787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // We only need to add parent frame allocations for these builtins in x86.
147887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
147987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      return;
148087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
148187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    unsigned ID = E->getBuiltinCallee();
148287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    switch (ID) {
148387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case Builtin::BI__exception_code:
148487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    case Builtin::BI_exception_code:
148587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // This is the simple case where we are the outermost finally. All we
148687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // have to do here is make sure we escape this and recover it in the
148787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      // outlined handler.
148887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      if (!SEHCodeSlot.isValid())
148987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
149087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      break;
149187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
14920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
14930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
149487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace
149587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
149687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarAddress CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
149787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                   Address ParentVar,
149887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                                   llvm::Value *ParentFP) {
149987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::CallInst *RecoverCall = nullptr;
150087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGBuilderTy Builder(*this, AllocaInsertPt);
150187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.getPointer())) {
150287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Mark the variable escaped if nobody else referenced it and compute the
150387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // localescape index.
150487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto InsertPair = ParentCGF.EscapedLocals.insert(
150587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
150687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    int FrameEscapeIdx = InsertPair.first->second;
150787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // call i8* @llvm.localrecover(i8* bitcast(@parentFn), i8* %fp, i32 N)
150887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
150987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        &CGM.getModule(), llvm::Intrinsic::localrecover);
151087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Constant *ParentI8Fn =
151187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
151287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RecoverCall = Builder.CreateCall(
151387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        FrameRecoverFn, {ParentI8Fn, ParentFP,
151487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                         llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
151587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
151687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
151787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // If the parent didn't have an alloca, we're doing some nested outlining.
151887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Just clone the existing localrecover call, but tweak the FP argument to
151987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // use our FP value. All other arguments are constants.
152087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto *ParentRecover =
152187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        cast<llvm::IntrinsicInst>(ParentVar.getPointer()->stripPointerCasts());
152287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
152387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar           "expected alloca or localrecover in parent LocalDeclMap");
152487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
152587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RecoverCall->setArgOperand(1, ParentFP);
152687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    RecoverCall->insertBefore(AllocaInsertPt);
152787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
152887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
152987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Bitcast the variable, rename it, and insert it in the local decl map.
153087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *ChildVar =
153187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Builder.CreateBitCast(RecoverCall, ParentVar.getType());
153287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  ChildVar->setName(ParentVar.getName());
153387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Address(ChildVar, ParentVar.getAlignment());
15340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
15350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
153658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
153758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                         const Stmt *OutlinedStmt,
153887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                         bool IsFilter) {
153958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Find all captures in the Stmt.
154058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
154158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  Finder.Visit(OutlinedStmt);
15420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
154387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // We can exit early on x86_64 when there are no captures. We just have to
154487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // save the exception code in filters so that __exception_code() works.
154587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!Finder.foundCaptures() &&
154687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
154787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (IsFilter)
154887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
154958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return;
155087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
155187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
155287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *EntryFP = nullptr;
155387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGBuilderTy Builder(CGM, AllocaInsertPt);
155487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
155587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // 32-bit SEH filters need to be careful about FP recovery.  The end of the
155687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // EH registration is passed in as the EBP physical register.  We can
155787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // recover that with llvm.frameaddress(1).
155887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    EntryFP = Builder.CreateCall(
155987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
156087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
156187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
156287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // second parameter.
156387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    auto AI = CurFn->arg_begin();
156487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ++AI;
156587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    EntryFP = &*AI;
156687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
15670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
156887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *ParentFP = EntryFP;
156987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (IsFilter) {
157087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Given whatever FP the runtime provided us in EntryFP, recover the true
157187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // frame pointer of the parent function. We only need to do this in filters,
157287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // since finally funclets recover the parent FP for us.
157387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Function *RecoverFPIntrin =
157487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp);
157587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Constant *ParentI8Fn =
157687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
157787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
157887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
157958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
158087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Create llvm.localrecover calls for all captures.
158158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  for (const VarDecl *VD : Finder.Captures) {
158258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (isa<ImplicitParamDecl>(VD)) {
158358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CGM.ErrorUnsupported(VD, "'this' captured by SEH");
158458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CXXThisValue = llvm::UndefValue::get(ConvertTypeForMem(VD->getType()));
158558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      continue;
158658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    }
158758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (VD->getType()->isVariablyModifiedType()) {
158858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      CGM.ErrorUnsupported(VD, "VLA captured by SEH");
158958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      continue;
159058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    }
159158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
159258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar           "captured non-local variable");
159358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
159458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // If this decl hasn't been declared yet, it will be declared in the
159558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    // OutlinedStmt.
159658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    auto I = ParentCGF.LocalDeclMap.find(VD);
159758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    if (I == ParentCGF.LocalDeclMap.end())
159858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      continue;
159958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
160087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Address ParentVar = I->second;
160187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    setAddrOfLocalVar(
160287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
160387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
160458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
160587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (Finder.SEHCodeSlot.isValid()) {
160687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHCodeSlotStack.push_back(
160787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
16080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
160987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
161087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (IsFilter)
161187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
161258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar}
16130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
161458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// Arrange a function prototype that can be called by Windows exception
161558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// handling personalities. On Win64, the prototype looks like:
161658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// RetTy func(void *EHPtrs, void *ParentFP);
161758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
161887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                             bool IsFilter,
161958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                             const Stmt *OutlinedStmt) {
162087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  SourceLocation StartLoc = OutlinedStmt->getLocStart();
162187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
162287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Get the mangled function name.
162387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  SmallString<128> Name;
162487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  {
162587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::raw_svector_ostream OS(Name);
16264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const FunctionDecl *ParentSEHFn = ParentCGF.CurSEHParent;
16274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(ParentSEHFn && "No CurSEHParent!");
162887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
162987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (IsFilter)
16304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
163187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    else
16324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
163387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
163487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
163587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  FunctionArgList Args;
163687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
163787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // All SEH finally functions take two parameters. Win64 filters take two
163887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // parameters. Win32 filters take no parameters.
163987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    if (IsFilter) {
164087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Args.push_back(ImplicitParamDecl::Create(
164187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          getContext(), nullptr, StartLoc,
164287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          &getContext().Idents.get("exception_pointers"),
164387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          getContext().VoidPtrTy));
164487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    } else {
164587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      Args.push_back(ImplicitParamDecl::Create(
164687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          getContext(), nullptr, StartLoc,
164787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          &getContext().Idents.get("abnormal_termination"),
164887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar          getContext().UnsignedCharTy));
164987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    }
165087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Args.push_back(ImplicitParamDecl::Create(
165187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        getContext(), nullptr, StartLoc,
165287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
165387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
165487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
165587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
165687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
165758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Function *ParentFn = ParentCGF.CurFn;
16584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const CGFunctionInfo &FnInfo =
16594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
166058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
16610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
166258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Function *Fn = llvm::Function::Create(
166358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
16640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // The filter is either in the same comdat as the function, or it's internal.
16650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (llvm::Comdat *C = ParentFn->getComdat()) {
16660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Fn->setComdat(C);
16670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
16680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ParentFn->getName());
16690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ParentFn->setComdat(C);
16700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Fn->setComdat(C);
16710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } else {
16720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
16730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
16740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
167558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  IsOutlinedSEHHelper = true;
167658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
16770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
167858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
16794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CurSEHParent = ParentCGF.CurSEHParent;
16800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
168158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
168287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
168358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar}
168458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
168558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// Create a stub filter function that will ultimately hold the code of the
168658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// filter expression. The EH preparation passes in LLVM will outline the code
168758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar/// from the main function body into this stub.
168858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarllvm::Function *
168958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga NainarCodeGenFunction::GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
169058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                           const SEHExceptStmt &Except) {
169158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const Expr *FilterExpr = Except.getFilterExpr();
169287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
169358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
16940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Emit the original filter expression, convert to i32, and return.
16950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Value *R = EmitScalarExpr(FilterExpr);
1696b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar  R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
16970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                            FilterExpr->getType()->isSignedIntegerType());
16980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Builder.CreateStore(R, ReturnValue);
16990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
17000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  FinishFunction(FilterExpr->getLocEnd());
17010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
170258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  return CurFn;
170358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar}
170458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
170558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarllvm::Function *
170658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga NainarCodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
170758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar                                            const SEHFinallyStmt &Finally) {
170858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const Stmt *FinallyBlock = Finally.getBlock();
170987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
171058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
171158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Emit the original filter expression, convert to i32, and return.
171258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  EmitStmt(FinallyBlock);
171358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
171458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  FinishFunction(FinallyBlock->getLocEnd());
171558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
171658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  return CurFn;
17170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
17180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
171987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
172087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                               llvm::Value *ParentFP,
172187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                               llvm::Value *EntryFP) {
172287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
172387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // __exception_info intrinsic.
172487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
172587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // On Win64, the info is passed as the first parameter to the filter.
172687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHInfo = &*CurFn->arg_begin();
172787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHCodeSlotStack.push_back(
172887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CreateMemTemp(getContext().IntTy, "__exception_code"));
172987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } else {
173087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // On Win32, the EBP on entry to the filter points to the end of an
173187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // exception registration object. It contains 6 32-bit fields, and the info
173287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // pointer is stored in the second field. So, GEP 20 bytes backwards and
173387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // load the pointer.
173487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
173587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo());
173687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
173787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
173887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
173987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
174087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
17410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Save the exception code in the exception slot to unify exception access in
17420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // the filter function and the landing pad.
17430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // struct EXCEPTION_POINTERS {
17440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   EXCEPTION_RECORD *ExceptionRecord;
17450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  //   CONTEXT *ContextRecord;
17460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // };
174787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
17480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
17490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy, nullptr);
175087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
175158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
175287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Rec = Builder.CreateAlignedLoad(Rec, getPointerAlign());
175387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::Value *Code = Builder.CreateAlignedLoad(Rec, getIntAlign());
175487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
175587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Builder.CreateStore(Code, SEHCodeSlotStack.back());
17560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
17570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
17580e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CodeGenFunction::EmitSEHExceptionInfo() {
17590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Sema should diagnose calling this builtin outside of a filter context, but
17600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // don't crash if we screw up.
176187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (!SEHInfo)
17620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return llvm::UndefValue::get(Int8PtrTy);
176387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(SEHInfo->getType() == Int8PtrTy);
176487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return SEHInfo;
17650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
17660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
17670e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CodeGenFunction::EmitSEHExceptionCode() {
176887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
176987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return Builder.CreateLoad(SEHCodeSlotStack.back());
17700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
17710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
17720e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesllvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {
177358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Abnormal termination is just the first parameter to the outlined finally
177458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // helper.
177558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  auto AI = CurFn->arg_begin();
177658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  return Builder.CreateZExt(&*AI, Int32Ty);
17770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
17780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
177958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
178058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
178158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
178287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Outline the finally block.
178358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    llvm::Function *FinallyFunc =
178458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar        HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
178587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
178687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    // Push a cleanup for __finally blocks.
178758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
17880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return;
17890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
17900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
17910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Otherwise, we must have an __except block.
179258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  const SEHExceptStmt *Except = S.getExceptHandler();
17930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  assert(Except);
17940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EHCatchScope *CatchScope = EHStack.pushCatch(1);
179587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  SEHCodeSlotStack.push_back(
179687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      CreateMemTemp(getContext().IntTy, "__exception_code"));
17970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
179887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // If the filter is known to evaluate to 1, then we can use the clause
179987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // "catch i8* null". We can't do this on x86 because the filter has to save
180087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // the exception code.
18010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Constant *C =
18020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this);
180387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
180487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      C->isOneValue()) {
18050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
18060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return;
18070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
18080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // In general, we have to emit an outlined filter function. Use the function
18100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // in place of the RTTI typeinfo global that C++ EH uses.
18110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Function *FilterFunc =
181258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar      HelperCGF.GenerateSEHFilterFunction(*this, *Except);
18130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::Constant *OpaqueFunc =
18140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      llvm::ConstantExpr::getBitCast(FilterFunc, Int8PtrTy);
181587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CatchScope->setHandler(0, OpaqueFunc, createBasicBlock("__except.ret"));
18160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
18170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
181858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
18190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Just pop the cleanup if it's a __finally block.
182058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  if (S.getFinallyHandler()) {
18210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    PopCleanupBlock();
18220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return;
18230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
18240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Otherwise, we must have an __except block.
18260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const SEHExceptStmt *Except = S.getExceptHandler();
18270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  assert(Except && "__try must have __finally xor __except");
18280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
18290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Don't emit the __except block if the __try block lacked invokes.
18310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // TODO: Model unwind edges from instructions, either with iload / istore or
18320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // a try body function.
18330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (!CatchScope.hasEHBranches()) {
18340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    CatchScope.clearHandlerBlocks();
18350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    EHStack.popCatch();
183687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    SEHCodeSlotStack.pop_back();
18370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return;
18380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
18390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // The fall-through block.
18410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
18420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // We just emitted the body of the __try; jump to the continue block.
18440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (HaveInsertPoint())
18450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Builder.CreateBr(ContBB);
18460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Check if our filter function returned true.
18480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  emitCatchDispatchBlock(*this, CatchScope);
18490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Grab the block before we pop the handler.
185187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
18520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EHStack.popCatch();
18530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
185487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  EmitBlockAfterUses(CatchPadBB);
185587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
185687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // __except blocks don't get outlined into funclets, so immediately do a
185787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // catchret.
185887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::CatchPadInst *CPI =
185987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
186087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
186187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Builder.CreateCatchRet(CPI, ExceptBB);
186287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  EmitBlock(ExceptBB);
186387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
186487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // On Win64, the exception code is returned in EAX. Copy it into the slot.
186587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
186687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Function *SEHCodeIntrin =
186787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
186887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
186987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    Builder.CreateStore(Code, SEHCodeSlotStack.back());
187087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
18710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Emit the __except body.
18730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EmitStmt(Except->getBlock());
18740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
187587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // End the lifetime of the exception code.
187687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  SEHCodeSlotStack.pop_back();
187787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
18780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (HaveInsertPoint())
18790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Builder.CreateBr(ContBB);
18800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
18810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EmitBlock(ContBB);
188298592d9c4dff79480fdc25b83988de03f912b647Reid Kleckner}
1883c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
1884c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {
18850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // If this code is reachable then emit a stop point (if generating
18860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // debug info). We have to do this ourselves because we are on the
18870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // "simple" statement path.
18880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (HaveInsertPoint())
18890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    EmitStopPoint(&S);
18900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
189158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // This must be a __leave from a __finally block, which we warn on and is UB.
189258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  // Just emit unreachable.
189358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  if (!isSEHTryScope()) {
189458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    Builder.CreateUnreachable();
189558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    Builder.ClearInsertionPoint();
189658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar    return;
189758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  }
189858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar
18990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  EmitBranchThroughCleanup(*SEHTryEpilogueStack.back());
1900c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
1901