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