1f4a2713aSLionel Sambuc //===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This contains code dealing with C++ exception related code generation.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "CodeGenFunction.h"
15*0a6a1f1dSLionel Sambuc #include "CGCXXABI.h"
16f4a2713aSLionel Sambuc #include "CGCleanup.h"
17f4a2713aSLionel Sambuc #include "CGObjCRuntime.h"
18f4a2713aSLionel Sambuc #include "TargetInfo.h"
19f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h"
20f4a2713aSLionel Sambuc #include "clang/AST/StmtObjC.h"
21*0a6a1f1dSLionel Sambuc #include "llvm/IR/CallSite.h"
22f4a2713aSLionel Sambuc #include "llvm/IR/Intrinsics.h"
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc using namespace clang;
25f4a2713aSLionel Sambuc using namespace CodeGen;
26f4a2713aSLionel Sambuc 
getAllocateExceptionFn(CodeGenModule & CGM)27f4a2713aSLionel Sambuc static llvm::Constant *getAllocateExceptionFn(CodeGenModule &CGM) {
28f4a2713aSLionel Sambuc   // void *__cxa_allocate_exception(size_t thrown_size);
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
31f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*IsVarArgs=*/false);
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
34f4a2713aSLionel Sambuc }
35f4a2713aSLionel Sambuc 
getFreeExceptionFn(CodeGenModule & CGM)36f4a2713aSLionel Sambuc static llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {
37f4a2713aSLionel Sambuc   // void __cxa_free_exception(void *thrown_exception);
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
40f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
43f4a2713aSLionel Sambuc }
44f4a2713aSLionel Sambuc 
getThrowFn(CodeGenModule & CGM)45f4a2713aSLionel Sambuc static llvm::Constant *getThrowFn(CodeGenModule &CGM) {
46f4a2713aSLionel Sambuc   // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
47f4a2713aSLionel Sambuc   //                  void (*dest) (void *));
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc   llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.Int8PtrTy, CGM.Int8PtrTy };
50f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
51f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, Args, /*IsVarArgs=*/false);
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
54f4a2713aSLionel Sambuc }
55f4a2713aSLionel Sambuc 
getGetExceptionPtrFn(CodeGenModule & CGM)56f4a2713aSLionel Sambuc static llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) {
57f4a2713aSLionel Sambuc   // void *__cxa_get_exception_ptr(void*);
58f4a2713aSLionel Sambuc 
59f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
60f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");
63f4a2713aSLionel Sambuc }
64f4a2713aSLionel Sambuc 
getBeginCatchFn(CodeGenModule & CGM)65f4a2713aSLionel Sambuc static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) {
66f4a2713aSLionel Sambuc   // void *__cxa_begin_catch(void*);
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
69f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
70f4a2713aSLionel Sambuc 
71f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
72f4a2713aSLionel Sambuc }
73f4a2713aSLionel Sambuc 
getEndCatchFn(CodeGenModule & CGM)74f4a2713aSLionel Sambuc static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) {
75f4a2713aSLionel Sambuc   // void __cxa_end_catch();
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
78f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
81f4a2713aSLionel Sambuc }
82f4a2713aSLionel Sambuc 
getUnexpectedFn(CodeGenModule & CGM)83f4a2713aSLionel Sambuc static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {
84f4a2713aSLionel Sambuc   // void __cxa_call_unexpected(void *thrown_exception);
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
87f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
88f4a2713aSLionel Sambuc 
89f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc 
getTerminateFn(CodeGenModule & CGM)92f4a2713aSLionel Sambuc static llvm::Constant *getTerminateFn(CodeGenModule &CGM) {
93f4a2713aSLionel Sambuc   // void __terminate();
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
96f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
97f4a2713aSLionel Sambuc 
98f4a2713aSLionel Sambuc   StringRef name;
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   // In C++, use std::terminate().
101f4a2713aSLionel Sambuc   if (CGM.getLangOpts().CPlusPlus)
102f4a2713aSLionel Sambuc     name = "_ZSt9terminatev"; // FIXME: mangling!
103f4a2713aSLionel Sambuc   else if (CGM.getLangOpts().ObjC1 &&
104f4a2713aSLionel Sambuc            CGM.getLangOpts().ObjCRuntime.hasTerminate())
105f4a2713aSLionel Sambuc     name = "objc_terminate";
106f4a2713aSLionel Sambuc   else
107f4a2713aSLionel Sambuc     name = "abort";
108f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, name);
109f4a2713aSLionel Sambuc }
110f4a2713aSLionel Sambuc 
getCatchallRethrowFn(CodeGenModule & CGM,StringRef Name)111f4a2713aSLionel Sambuc static llvm::Constant *getCatchallRethrowFn(CodeGenModule &CGM,
112f4a2713aSLionel Sambuc                                             StringRef Name) {
113f4a2713aSLionel Sambuc   llvm::FunctionType *FTy =
114f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc   return CGM.CreateRuntimeFunction(FTy, Name);
117f4a2713aSLionel Sambuc }
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc namespace {
120f4a2713aSLionel Sambuc   /// The exceptions personality for a function.
121f4a2713aSLionel Sambuc   struct EHPersonality {
122f4a2713aSLionel Sambuc     const char *PersonalityFn;
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc     // If this is non-null, this personality requires a non-standard
125f4a2713aSLionel Sambuc     // function for rethrowing an exception after a catchall cleanup.
126f4a2713aSLionel Sambuc     // This function must have prototype void(void*).
127f4a2713aSLionel Sambuc     const char *CatchallRethrowFn;
128f4a2713aSLionel Sambuc 
129*0a6a1f1dSLionel Sambuc     static const EHPersonality &get(CodeGenModule &CGM);
130f4a2713aSLionel Sambuc     static const EHPersonality GNU_C;
131f4a2713aSLionel Sambuc     static const EHPersonality GNU_C_SJLJ;
132*0a6a1f1dSLionel Sambuc     static const EHPersonality GNU_C_SEH;
133f4a2713aSLionel Sambuc     static const EHPersonality GNU_ObjC;
134f4a2713aSLionel Sambuc     static const EHPersonality GNUstep_ObjC;
135f4a2713aSLionel Sambuc     static const EHPersonality GNU_ObjCXX;
136f4a2713aSLionel Sambuc     static const EHPersonality NeXT_ObjC;
137f4a2713aSLionel Sambuc     static const EHPersonality GNU_CPlusPlus;
138f4a2713aSLionel Sambuc     static const EHPersonality GNU_CPlusPlus_SJLJ;
139*0a6a1f1dSLionel Sambuc     static const EHPersonality GNU_CPlusPlus_SEH;
140f4a2713aSLionel Sambuc   };
141f4a2713aSLionel Sambuc }
142f4a2713aSLionel Sambuc 
143*0a6a1f1dSLionel Sambuc const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
144f4a2713aSLionel Sambuc const EHPersonality
145*0a6a1f1dSLionel Sambuc EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
146*0a6a1f1dSLionel Sambuc const EHPersonality
147*0a6a1f1dSLionel Sambuc EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
148*0a6a1f1dSLionel Sambuc const EHPersonality
149*0a6a1f1dSLionel Sambuc EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
150*0a6a1f1dSLionel Sambuc const EHPersonality
151*0a6a1f1dSLionel Sambuc EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
152*0a6a1f1dSLionel Sambuc const EHPersonality
153*0a6a1f1dSLionel Sambuc EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
154*0a6a1f1dSLionel Sambuc const EHPersonality
155*0a6a1f1dSLionel Sambuc EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
156f4a2713aSLionel Sambuc const EHPersonality
157f4a2713aSLionel Sambuc EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
158f4a2713aSLionel Sambuc const EHPersonality
159*0a6a1f1dSLionel Sambuc EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
160f4a2713aSLionel Sambuc const EHPersonality
161*0a6a1f1dSLionel Sambuc EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
162f4a2713aSLionel Sambuc 
163*0a6a1f1dSLionel Sambuc /// On Win64, use libgcc's SEH personality function. We fall back to dwarf on
164*0a6a1f1dSLionel Sambuc /// other platforms, unless the user asked for SjLj exceptions.
useLibGCCSEHPersonality(const llvm::Triple & T)165*0a6a1f1dSLionel Sambuc static bool useLibGCCSEHPersonality(const llvm::Triple &T) {
166*0a6a1f1dSLionel Sambuc   return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
167*0a6a1f1dSLionel Sambuc }
168*0a6a1f1dSLionel Sambuc 
getCPersonality(const llvm::Triple & T,const LangOptions & L)169*0a6a1f1dSLionel Sambuc static const EHPersonality &getCPersonality(const llvm::Triple &T,
170*0a6a1f1dSLionel Sambuc                                             const LangOptions &L) {
171f4a2713aSLionel Sambuc   if (L.SjLjExceptions)
172f4a2713aSLionel Sambuc     return EHPersonality::GNU_C_SJLJ;
173*0a6a1f1dSLionel Sambuc   else if (useLibGCCSEHPersonality(T))
174*0a6a1f1dSLionel Sambuc     return EHPersonality::GNU_C_SEH;
175f4a2713aSLionel Sambuc   return EHPersonality::GNU_C;
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc 
getObjCPersonality(const llvm::Triple & T,const LangOptions & L)178*0a6a1f1dSLionel Sambuc static const EHPersonality &getObjCPersonality(const llvm::Triple &T,
179*0a6a1f1dSLionel Sambuc                                                const LangOptions &L) {
180f4a2713aSLionel Sambuc   switch (L.ObjCRuntime.getKind()) {
181f4a2713aSLionel Sambuc   case ObjCRuntime::FragileMacOSX:
182*0a6a1f1dSLionel Sambuc     return getCPersonality(T, L);
183f4a2713aSLionel Sambuc   case ObjCRuntime::MacOSX:
184f4a2713aSLionel Sambuc   case ObjCRuntime::iOS:
185f4a2713aSLionel Sambuc     return EHPersonality::NeXT_ObjC;
186f4a2713aSLionel Sambuc   case ObjCRuntime::GNUstep:
187f4a2713aSLionel Sambuc     if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
188f4a2713aSLionel Sambuc       return EHPersonality::GNUstep_ObjC;
189f4a2713aSLionel Sambuc     // fallthrough
190f4a2713aSLionel Sambuc   case ObjCRuntime::GCC:
191f4a2713aSLionel Sambuc   case ObjCRuntime::ObjFW:
192f4a2713aSLionel Sambuc     return EHPersonality::GNU_ObjC;
193f4a2713aSLionel Sambuc   }
194f4a2713aSLionel Sambuc   llvm_unreachable("bad runtime kind");
195f4a2713aSLionel Sambuc }
196f4a2713aSLionel Sambuc 
getCXXPersonality(const llvm::Triple & T,const LangOptions & L)197*0a6a1f1dSLionel Sambuc static const EHPersonality &getCXXPersonality(const llvm::Triple &T,
198*0a6a1f1dSLionel Sambuc                                               const LangOptions &L) {
199f4a2713aSLionel Sambuc   if (L.SjLjExceptions)
200f4a2713aSLionel Sambuc     return EHPersonality::GNU_CPlusPlus_SJLJ;
201*0a6a1f1dSLionel Sambuc   else if (useLibGCCSEHPersonality(T))
202*0a6a1f1dSLionel Sambuc     return EHPersonality::GNU_CPlusPlus_SEH;
203f4a2713aSLionel Sambuc   return EHPersonality::GNU_CPlusPlus;
204f4a2713aSLionel Sambuc }
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc /// Determines the personality function to use when both C++
207f4a2713aSLionel Sambuc /// and Objective-C exceptions are being caught.
getObjCXXPersonality(const llvm::Triple & T,const LangOptions & L)208*0a6a1f1dSLionel Sambuc static const EHPersonality &getObjCXXPersonality(const llvm::Triple &T,
209*0a6a1f1dSLionel Sambuc                                                  const LangOptions &L) {
210f4a2713aSLionel Sambuc   switch (L.ObjCRuntime.getKind()) {
211f4a2713aSLionel Sambuc   // The ObjC personality defers to the C++ personality for non-ObjC
212f4a2713aSLionel Sambuc   // handlers.  Unlike the C++ case, we use the same personality
213f4a2713aSLionel Sambuc   // function on targets using (backend-driven) SJLJ EH.
214f4a2713aSLionel Sambuc   case ObjCRuntime::MacOSX:
215f4a2713aSLionel Sambuc   case ObjCRuntime::iOS:
216f4a2713aSLionel Sambuc     return EHPersonality::NeXT_ObjC;
217f4a2713aSLionel Sambuc 
218f4a2713aSLionel Sambuc   // In the fragile ABI, just use C++ exception handling and hope
219f4a2713aSLionel Sambuc   // they're not doing crazy exception mixing.
220f4a2713aSLionel Sambuc   case ObjCRuntime::FragileMacOSX:
221*0a6a1f1dSLionel Sambuc     return getCXXPersonality(T, L);
222f4a2713aSLionel Sambuc 
223f4a2713aSLionel Sambuc   // The GCC runtime's personality function inherently doesn't support
224f4a2713aSLionel Sambuc   // mixed EH.  Use the C++ personality just to avoid returning null.
225f4a2713aSLionel Sambuc   case ObjCRuntime::GCC:
226f4a2713aSLionel Sambuc   case ObjCRuntime::ObjFW: // XXX: this will change soon
227f4a2713aSLionel Sambuc     return EHPersonality::GNU_ObjC;
228f4a2713aSLionel Sambuc   case ObjCRuntime::GNUstep:
229f4a2713aSLionel Sambuc     return EHPersonality::GNU_ObjCXX;
230f4a2713aSLionel Sambuc   }
231f4a2713aSLionel Sambuc   llvm_unreachable("bad runtime kind");
232f4a2713aSLionel Sambuc }
233f4a2713aSLionel Sambuc 
get(CodeGenModule & CGM)234*0a6a1f1dSLionel Sambuc const EHPersonality &EHPersonality::get(CodeGenModule &CGM) {
235*0a6a1f1dSLionel Sambuc   const llvm::Triple &T = CGM.getTarget().getTriple();
236*0a6a1f1dSLionel Sambuc   const LangOptions &L = CGM.getLangOpts();
237f4a2713aSLionel Sambuc   if (L.CPlusPlus && L.ObjC1)
238*0a6a1f1dSLionel Sambuc     return getObjCXXPersonality(T, L);
239f4a2713aSLionel Sambuc   else if (L.CPlusPlus)
240*0a6a1f1dSLionel Sambuc     return getCXXPersonality(T, L);
241f4a2713aSLionel Sambuc   else if (L.ObjC1)
242*0a6a1f1dSLionel Sambuc     return getObjCPersonality(T, L);
243f4a2713aSLionel Sambuc   else
244*0a6a1f1dSLionel Sambuc     return getCPersonality(T, L);
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc 
getPersonalityFn(CodeGenModule & CGM,const EHPersonality & Personality)247f4a2713aSLionel Sambuc static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
248f4a2713aSLionel Sambuc                                         const EHPersonality &Personality) {
249f4a2713aSLionel Sambuc   llvm::Constant *Fn =
250f4a2713aSLionel Sambuc     CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
251f4a2713aSLionel Sambuc                               Personality.PersonalityFn);
252f4a2713aSLionel Sambuc   return Fn;
253f4a2713aSLionel Sambuc }
254f4a2713aSLionel Sambuc 
getOpaquePersonalityFn(CodeGenModule & CGM,const EHPersonality & Personality)255f4a2713aSLionel Sambuc static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
256f4a2713aSLionel Sambuc                                         const EHPersonality &Personality) {
257f4a2713aSLionel Sambuc   llvm::Constant *Fn = getPersonalityFn(CGM, Personality);
258f4a2713aSLionel Sambuc   return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
259f4a2713aSLionel Sambuc }
260f4a2713aSLionel Sambuc 
261f4a2713aSLionel Sambuc /// Check whether a personality function could reasonably be swapped
262f4a2713aSLionel Sambuc /// for a C++ personality function.
PersonalityHasOnlyCXXUses(llvm::Constant * Fn)263f4a2713aSLionel Sambuc static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
264*0a6a1f1dSLionel Sambuc   for (llvm::User *U : Fn->users()) {
265f4a2713aSLionel Sambuc     // Conditionally white-list bitcasts.
266*0a6a1f1dSLionel Sambuc     if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
267f4a2713aSLionel Sambuc       if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
268f4a2713aSLionel Sambuc       if (!PersonalityHasOnlyCXXUses(CE))
269f4a2713aSLionel Sambuc         return false;
270f4a2713aSLionel Sambuc       continue;
271f4a2713aSLionel Sambuc     }
272f4a2713aSLionel Sambuc 
273f4a2713aSLionel Sambuc     // Otherwise, it has to be a landingpad instruction.
274*0a6a1f1dSLionel Sambuc     llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(U);
275f4a2713aSLionel Sambuc     if (!LPI) return false;
276f4a2713aSLionel Sambuc 
277f4a2713aSLionel Sambuc     for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
278f4a2713aSLionel Sambuc       // Look for something that would've been returned by the ObjC
279f4a2713aSLionel Sambuc       // runtime's GetEHType() method.
280f4a2713aSLionel Sambuc       llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
281f4a2713aSLionel Sambuc       if (LPI->isCatch(I)) {
282f4a2713aSLionel Sambuc         // Check if the catch value has the ObjC prefix.
283f4a2713aSLionel Sambuc         if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
284f4a2713aSLionel Sambuc           // ObjC EH selector entries are always global variables with
285f4a2713aSLionel Sambuc           // names starting like this.
286f4a2713aSLionel Sambuc           if (GV->getName().startswith("OBJC_EHTYPE"))
287f4a2713aSLionel Sambuc             return false;
288f4a2713aSLionel Sambuc       } else {
289f4a2713aSLionel Sambuc         // Check if any of the filter values have the ObjC prefix.
290f4a2713aSLionel Sambuc         llvm::Constant *CVal = cast<llvm::Constant>(Val);
291f4a2713aSLionel Sambuc         for (llvm::User::op_iterator
292f4a2713aSLionel Sambuc                II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
293f4a2713aSLionel Sambuc           if (llvm::GlobalVariable *GV =
294f4a2713aSLionel Sambuc               cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
295f4a2713aSLionel Sambuc             // ObjC EH selector entries are always global variables with
296f4a2713aSLionel Sambuc             // names starting like this.
297f4a2713aSLionel Sambuc             if (GV->getName().startswith("OBJC_EHTYPE"))
298f4a2713aSLionel Sambuc               return false;
299f4a2713aSLionel Sambuc         }
300f4a2713aSLionel Sambuc       }
301f4a2713aSLionel Sambuc     }
302f4a2713aSLionel Sambuc   }
303f4a2713aSLionel Sambuc 
304f4a2713aSLionel Sambuc   return true;
305f4a2713aSLionel Sambuc }
306f4a2713aSLionel Sambuc 
307f4a2713aSLionel Sambuc /// Try to use the C++ personality function in ObjC++.  Not doing this
308f4a2713aSLionel Sambuc /// can cause some incompatibilities with gcc, which is more
309f4a2713aSLionel Sambuc /// aggressive about only using the ObjC++ personality in a function
310f4a2713aSLionel Sambuc /// when it really needs it.
SimplifyPersonality()311f4a2713aSLionel Sambuc void CodeGenModule::SimplifyPersonality() {
312f4a2713aSLionel Sambuc   // If we're not in ObjC++ -fexceptions, there's nothing to do.
313f4a2713aSLionel Sambuc   if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
314f4a2713aSLionel Sambuc     return;
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc   // Both the problem this endeavors to fix and the way the logic
317f4a2713aSLionel Sambuc   // above works is specific to the NeXT runtime.
318f4a2713aSLionel Sambuc   if (!LangOpts.ObjCRuntime.isNeXTFamily())
319f4a2713aSLionel Sambuc     return;
320f4a2713aSLionel Sambuc 
321*0a6a1f1dSLionel Sambuc   const EHPersonality &ObjCXX = EHPersonality::get(*this);
322*0a6a1f1dSLionel Sambuc   const EHPersonality &CXX =
323*0a6a1f1dSLionel Sambuc       getCXXPersonality(getTarget().getTriple(), LangOpts);
324f4a2713aSLionel Sambuc   if (&ObjCXX == &CXX)
325f4a2713aSLionel Sambuc     return;
326f4a2713aSLionel Sambuc 
327f4a2713aSLionel Sambuc   assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
328f4a2713aSLionel Sambuc          "Different EHPersonalities using the same personality function.");
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc   llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc   // Nothing to do if it's unused.
333f4a2713aSLionel Sambuc   if (!Fn || Fn->use_empty()) return;
334f4a2713aSLionel Sambuc 
335f4a2713aSLionel Sambuc   // Can't do the optimization if it has non-C++ uses.
336f4a2713aSLionel Sambuc   if (!PersonalityHasOnlyCXXUses(Fn)) return;
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc   // Create the C++ personality function and kill off the old
339f4a2713aSLionel Sambuc   // function.
340f4a2713aSLionel Sambuc   llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
341f4a2713aSLionel Sambuc 
342f4a2713aSLionel Sambuc   // This can happen if the user is screwing with us.
343f4a2713aSLionel Sambuc   if (Fn->getType() != CXXFn->getType()) return;
344f4a2713aSLionel Sambuc 
345f4a2713aSLionel Sambuc   Fn->replaceAllUsesWith(CXXFn);
346f4a2713aSLionel Sambuc   Fn->eraseFromParent();
347f4a2713aSLionel Sambuc }
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc /// Returns the value to inject into a selector to indicate the
350f4a2713aSLionel Sambuc /// presence of a catch-all.
getCatchAllValue(CodeGenFunction & CGF)351f4a2713aSLionel Sambuc static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
352f4a2713aSLionel Sambuc   // Possibly we should use @llvm.eh.catch.all.value here.
353f4a2713aSLionel Sambuc   return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc 
356f4a2713aSLionel Sambuc namespace {
357f4a2713aSLionel Sambuc   /// A cleanup to free the exception object if its initialization
358f4a2713aSLionel Sambuc   /// throws.
359f4a2713aSLionel Sambuc   struct FreeException : EHScopeStack::Cleanup {
360f4a2713aSLionel Sambuc     llvm::Value *exn;
FreeException__anon2995a1420211::FreeException361f4a2713aSLionel Sambuc     FreeException(llvm::Value *exn) : exn(exn) {}
Emit__anon2995a1420211::FreeException362*0a6a1f1dSLionel Sambuc     void Emit(CodeGenFunction &CGF, Flags flags) override {
363f4a2713aSLionel Sambuc       CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);
364f4a2713aSLionel Sambuc     }
365f4a2713aSLionel Sambuc   };
366f4a2713aSLionel Sambuc }
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc // Emits an exception expression into the given location.  This
369f4a2713aSLionel Sambuc // differs from EmitAnyExprToMem only in that, if a final copy-ctor
370f4a2713aSLionel Sambuc // call is required, an exception within that copy ctor causes
371f4a2713aSLionel Sambuc // std::terminate to be invoked.
EmitAnyExprToExn(CodeGenFunction & CGF,const Expr * e,llvm::Value * addr)372f4a2713aSLionel Sambuc static void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *e,
373f4a2713aSLionel Sambuc                              llvm::Value *addr) {
374f4a2713aSLionel Sambuc   // Make sure the exception object is cleaned up if there's an
375f4a2713aSLionel Sambuc   // exception during initialization.
376f4a2713aSLionel Sambuc   CGF.pushFullExprCleanup<FreeException>(EHCleanup, addr);
377f4a2713aSLionel Sambuc   EHScopeStack::stable_iterator cleanup = CGF.EHStack.stable_begin();
378f4a2713aSLionel Sambuc 
379f4a2713aSLionel Sambuc   // __cxa_allocate_exception returns a void*;  we need to cast this
380f4a2713aSLionel Sambuc   // to the appropriate type for the object.
381f4a2713aSLionel Sambuc   llvm::Type *ty = CGF.ConvertTypeForMem(e->getType())->getPointerTo();
382f4a2713aSLionel Sambuc   llvm::Value *typedAddr = CGF.Builder.CreateBitCast(addr, ty);
383f4a2713aSLionel Sambuc 
384f4a2713aSLionel Sambuc   // FIXME: this isn't quite right!  If there's a final unelided call
385f4a2713aSLionel Sambuc   // to a copy constructor, then according to [except.terminate]p1 we
386f4a2713aSLionel Sambuc   // must call std::terminate() if that constructor throws, because
387f4a2713aSLionel Sambuc   // technically that copy occurs after the exception expression is
388f4a2713aSLionel Sambuc   // evaluated but before the exception is caught.  But the best way
389f4a2713aSLionel Sambuc   // to handle that is to teach EmitAggExpr to do the final copy
390f4a2713aSLionel Sambuc   // differently if it can't be elided.
391f4a2713aSLionel Sambuc   CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
392f4a2713aSLionel Sambuc                        /*IsInit*/ true);
393f4a2713aSLionel Sambuc 
394f4a2713aSLionel Sambuc   // Deactivate the cleanup block.
395f4a2713aSLionel Sambuc   CGF.DeactivateCleanupBlock(cleanup, cast<llvm::Instruction>(typedAddr));
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc 
getExceptionSlot()398f4a2713aSLionel Sambuc llvm::Value *CodeGenFunction::getExceptionSlot() {
399f4a2713aSLionel Sambuc   if (!ExceptionSlot)
400f4a2713aSLionel Sambuc     ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
401f4a2713aSLionel Sambuc   return ExceptionSlot;
402f4a2713aSLionel Sambuc }
403f4a2713aSLionel Sambuc 
getEHSelectorSlot()404f4a2713aSLionel Sambuc llvm::Value *CodeGenFunction::getEHSelectorSlot() {
405f4a2713aSLionel Sambuc   if (!EHSelectorSlot)
406f4a2713aSLionel Sambuc     EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
407f4a2713aSLionel Sambuc   return EHSelectorSlot;
408f4a2713aSLionel Sambuc }
409f4a2713aSLionel Sambuc 
getExceptionFromSlot()410f4a2713aSLionel Sambuc llvm::Value *CodeGenFunction::getExceptionFromSlot() {
411f4a2713aSLionel Sambuc   return Builder.CreateLoad(getExceptionSlot(), "exn");
412f4a2713aSLionel Sambuc }
413f4a2713aSLionel Sambuc 
getSelectorFromSlot()414f4a2713aSLionel Sambuc llvm::Value *CodeGenFunction::getSelectorFromSlot() {
415f4a2713aSLionel Sambuc   return Builder.CreateLoad(getEHSelectorSlot(), "sel");
416f4a2713aSLionel Sambuc }
417f4a2713aSLionel Sambuc 
EmitCXXThrowExpr(const CXXThrowExpr * E,bool KeepInsertionPoint)418f4a2713aSLionel Sambuc void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
419f4a2713aSLionel Sambuc                                        bool KeepInsertionPoint) {
420f4a2713aSLionel Sambuc   if (!E->getSubExpr()) {
421*0a6a1f1dSLionel Sambuc     CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/true);
422f4a2713aSLionel Sambuc 
423f4a2713aSLionel Sambuc     // throw is an expression, and the expression emitters expect us
424f4a2713aSLionel Sambuc     // to leave ourselves at a valid insertion point.
425f4a2713aSLionel Sambuc     if (KeepInsertionPoint)
426f4a2713aSLionel Sambuc       EmitBlock(createBasicBlock("throw.cont"));
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc     return;
429f4a2713aSLionel Sambuc   }
430f4a2713aSLionel Sambuc 
431*0a6a1f1dSLionel Sambuc   if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) {
432*0a6a1f1dSLionel Sambuc     ErrorUnsupported(E, "throw expression");
433*0a6a1f1dSLionel Sambuc     return;
434*0a6a1f1dSLionel Sambuc   }
435*0a6a1f1dSLionel Sambuc 
436f4a2713aSLionel Sambuc   QualType ThrowType = E->getSubExpr()->getType();
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   if (ThrowType->isObjCObjectPointerType()) {
439f4a2713aSLionel Sambuc     const Stmt *ThrowStmt = E->getSubExpr();
440f4a2713aSLionel Sambuc     const ObjCAtThrowStmt S(E->getExprLoc(),
441f4a2713aSLionel Sambuc                             const_cast<Stmt *>(ThrowStmt));
442f4a2713aSLionel Sambuc     CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
443f4a2713aSLionel Sambuc     // This will clear insertion point which was not cleared in
444f4a2713aSLionel Sambuc     // call to EmitThrowStmt.
445f4a2713aSLionel Sambuc     if (KeepInsertionPoint)
446f4a2713aSLionel Sambuc       EmitBlock(createBasicBlock("throw.cont"));
447f4a2713aSLionel Sambuc     return;
448f4a2713aSLionel Sambuc   }
449f4a2713aSLionel Sambuc 
450f4a2713aSLionel Sambuc   // Now allocate the exception object.
451f4a2713aSLionel Sambuc   llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
452f4a2713aSLionel Sambuc   uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
453f4a2713aSLionel Sambuc 
454f4a2713aSLionel Sambuc   llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(CGM);
455f4a2713aSLionel Sambuc   llvm::CallInst *ExceptionPtr =
456f4a2713aSLionel Sambuc     EmitNounwindRuntimeCall(AllocExceptionFn,
457f4a2713aSLionel Sambuc                             llvm::ConstantInt::get(SizeTy, TypeSize),
458f4a2713aSLionel Sambuc                             "exception");
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc   EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
461f4a2713aSLionel Sambuc 
462f4a2713aSLionel Sambuc   // Now throw the exception.
463f4a2713aSLionel Sambuc   llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
464f4a2713aSLionel Sambuc                                                          /*ForEH=*/true);
465f4a2713aSLionel Sambuc 
466f4a2713aSLionel Sambuc   // The address of the destructor.  If the exception type has a
467f4a2713aSLionel Sambuc   // trivial destructor (or isn't a record), we just pass null.
468*0a6a1f1dSLionel Sambuc   llvm::Constant *Dtor = nullptr;
469f4a2713aSLionel Sambuc   if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
470f4a2713aSLionel Sambuc     CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
471f4a2713aSLionel Sambuc     if (!Record->hasTrivialDestructor()) {
472f4a2713aSLionel Sambuc       CXXDestructorDecl *DtorD = Record->getDestructor();
473*0a6a1f1dSLionel Sambuc       Dtor = CGM.getAddrOfCXXStructor(DtorD, StructorType::Complete);
474f4a2713aSLionel Sambuc       Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);
475f4a2713aSLionel Sambuc     }
476f4a2713aSLionel Sambuc   }
477f4a2713aSLionel Sambuc   if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc   llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
480f4a2713aSLionel Sambuc   EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args);
481f4a2713aSLionel Sambuc 
482f4a2713aSLionel Sambuc   // throw is an expression, and the expression emitters expect us
483f4a2713aSLionel Sambuc   // to leave ourselves at a valid insertion point.
484f4a2713aSLionel Sambuc   if (KeepInsertionPoint)
485f4a2713aSLionel Sambuc     EmitBlock(createBasicBlock("throw.cont"));
486f4a2713aSLionel Sambuc }
487f4a2713aSLionel Sambuc 
EmitStartEHSpec(const Decl * D)488f4a2713aSLionel Sambuc void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
489f4a2713aSLionel Sambuc   if (!CGM.getLangOpts().CXXExceptions)
490f4a2713aSLionel Sambuc     return;
491f4a2713aSLionel Sambuc 
492f4a2713aSLionel Sambuc   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
493*0a6a1f1dSLionel Sambuc   if (!FD) {
494*0a6a1f1dSLionel Sambuc     // Check if CapturedDecl is nothrow and create terminate scope for it.
495*0a6a1f1dSLionel Sambuc     if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
496*0a6a1f1dSLionel Sambuc       if (CD->isNothrow())
497*0a6a1f1dSLionel Sambuc         EHStack.pushTerminate();
498*0a6a1f1dSLionel Sambuc     }
499f4a2713aSLionel Sambuc     return;
500*0a6a1f1dSLionel Sambuc   }
501f4a2713aSLionel Sambuc   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
502*0a6a1f1dSLionel Sambuc   if (!Proto)
503f4a2713aSLionel Sambuc     return;
504f4a2713aSLionel Sambuc 
505f4a2713aSLionel Sambuc   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
506f4a2713aSLionel Sambuc   if (isNoexceptExceptionSpec(EST)) {
507f4a2713aSLionel Sambuc     if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
508f4a2713aSLionel Sambuc       // noexcept functions are simple terminate scopes.
509f4a2713aSLionel Sambuc       EHStack.pushTerminate();
510f4a2713aSLionel Sambuc     }
511f4a2713aSLionel Sambuc   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
512f4a2713aSLionel Sambuc     unsigned NumExceptions = Proto->getNumExceptions();
513f4a2713aSLionel Sambuc     EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
514f4a2713aSLionel Sambuc 
515f4a2713aSLionel Sambuc     for (unsigned I = 0; I != NumExceptions; ++I) {
516f4a2713aSLionel Sambuc       QualType Ty = Proto->getExceptionType(I);
517f4a2713aSLionel Sambuc       QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
518f4a2713aSLionel Sambuc       llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
519f4a2713aSLionel Sambuc                                                         /*ForEH=*/true);
520f4a2713aSLionel Sambuc       Filter->setFilter(I, EHType);
521f4a2713aSLionel Sambuc     }
522f4a2713aSLionel Sambuc   }
523f4a2713aSLionel Sambuc }
524f4a2713aSLionel Sambuc 
525f4a2713aSLionel Sambuc /// Emit the dispatch block for a filter scope if necessary.
emitFilterDispatchBlock(CodeGenFunction & CGF,EHFilterScope & filterScope)526f4a2713aSLionel Sambuc static void emitFilterDispatchBlock(CodeGenFunction &CGF,
527f4a2713aSLionel Sambuc                                     EHFilterScope &filterScope) {
528f4a2713aSLionel Sambuc   llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
529f4a2713aSLionel Sambuc   if (!dispatchBlock) return;
530f4a2713aSLionel Sambuc   if (dispatchBlock->use_empty()) {
531f4a2713aSLionel Sambuc     delete dispatchBlock;
532f4a2713aSLionel Sambuc     return;
533f4a2713aSLionel Sambuc   }
534f4a2713aSLionel Sambuc 
535f4a2713aSLionel Sambuc   CGF.EmitBlockAfterUses(dispatchBlock);
536f4a2713aSLionel Sambuc 
537f4a2713aSLionel Sambuc   // If this isn't a catch-all filter, we need to check whether we got
538f4a2713aSLionel Sambuc   // here because the filter triggered.
539f4a2713aSLionel Sambuc   if (filterScope.getNumFilters()) {
540f4a2713aSLionel Sambuc     // Load the selector value.
541f4a2713aSLionel Sambuc     llvm::Value *selector = CGF.getSelectorFromSlot();
542f4a2713aSLionel Sambuc     llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
543f4a2713aSLionel Sambuc 
544f4a2713aSLionel Sambuc     llvm::Value *zero = CGF.Builder.getInt32(0);
545f4a2713aSLionel Sambuc     llvm::Value *failsFilter =
546f4a2713aSLionel Sambuc       CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
547f4a2713aSLionel Sambuc     CGF.Builder.CreateCondBr(failsFilter, unexpectedBB, CGF.getEHResumeBlock(false));
548f4a2713aSLionel Sambuc 
549f4a2713aSLionel Sambuc     CGF.EmitBlock(unexpectedBB);
550f4a2713aSLionel Sambuc   }
551f4a2713aSLionel Sambuc 
552f4a2713aSLionel Sambuc   // Call __cxa_call_unexpected.  This doesn't need to be an invoke
553f4a2713aSLionel Sambuc   // because __cxa_call_unexpected magically filters exceptions
554f4a2713aSLionel Sambuc   // according to the last landing pad the exception was thrown
555f4a2713aSLionel Sambuc   // into.  Seriously.
556f4a2713aSLionel Sambuc   llvm::Value *exn = CGF.getExceptionFromSlot();
557f4a2713aSLionel Sambuc   CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)
558f4a2713aSLionel Sambuc     ->setDoesNotReturn();
559f4a2713aSLionel Sambuc   CGF.Builder.CreateUnreachable();
560f4a2713aSLionel Sambuc }
561f4a2713aSLionel Sambuc 
EmitEndEHSpec(const Decl * D)562f4a2713aSLionel Sambuc void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
563f4a2713aSLionel Sambuc   if (!CGM.getLangOpts().CXXExceptions)
564f4a2713aSLionel Sambuc     return;
565f4a2713aSLionel Sambuc 
566f4a2713aSLionel Sambuc   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
567*0a6a1f1dSLionel Sambuc   if (!FD) {
568*0a6a1f1dSLionel Sambuc     // Check if CapturedDecl is nothrow and pop terminate scope for it.
569*0a6a1f1dSLionel Sambuc     if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
570*0a6a1f1dSLionel Sambuc       if (CD->isNothrow())
571*0a6a1f1dSLionel Sambuc         EHStack.popTerminate();
572*0a6a1f1dSLionel Sambuc     }
573f4a2713aSLionel Sambuc     return;
574*0a6a1f1dSLionel Sambuc   }
575f4a2713aSLionel Sambuc   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
576*0a6a1f1dSLionel Sambuc   if (!Proto)
577f4a2713aSLionel Sambuc     return;
578f4a2713aSLionel Sambuc 
579f4a2713aSLionel Sambuc   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
580f4a2713aSLionel Sambuc   if (isNoexceptExceptionSpec(EST)) {
581f4a2713aSLionel Sambuc     if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
582f4a2713aSLionel Sambuc       EHStack.popTerminate();
583f4a2713aSLionel Sambuc     }
584f4a2713aSLionel Sambuc   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
585f4a2713aSLionel Sambuc     EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
586f4a2713aSLionel Sambuc     emitFilterDispatchBlock(*this, filterScope);
587f4a2713aSLionel Sambuc     EHStack.popFilter();
588f4a2713aSLionel Sambuc   }
589f4a2713aSLionel Sambuc }
590f4a2713aSLionel Sambuc 
EmitCXXTryStmt(const CXXTryStmt & S)591f4a2713aSLionel Sambuc void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
592*0a6a1f1dSLionel Sambuc   if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) {
593*0a6a1f1dSLionel Sambuc     ErrorUnsupported(&S, "try statement");
594*0a6a1f1dSLionel Sambuc     return;
595*0a6a1f1dSLionel Sambuc   }
596*0a6a1f1dSLionel Sambuc 
597f4a2713aSLionel Sambuc   EnterCXXTryStmt(S);
598f4a2713aSLionel Sambuc   EmitStmt(S.getTryBlock());
599f4a2713aSLionel Sambuc   ExitCXXTryStmt(S);
600f4a2713aSLionel Sambuc }
601f4a2713aSLionel Sambuc 
EnterCXXTryStmt(const CXXTryStmt & S,bool IsFnTryBlock)602f4a2713aSLionel Sambuc void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
603f4a2713aSLionel Sambuc   unsigned NumHandlers = S.getNumHandlers();
604f4a2713aSLionel Sambuc   EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
605f4a2713aSLionel Sambuc 
606f4a2713aSLionel Sambuc   for (unsigned I = 0; I != NumHandlers; ++I) {
607f4a2713aSLionel Sambuc     const CXXCatchStmt *C = S.getHandler(I);
608f4a2713aSLionel Sambuc 
609f4a2713aSLionel Sambuc     llvm::BasicBlock *Handler = createBasicBlock("catch");
610f4a2713aSLionel Sambuc     if (C->getExceptionDecl()) {
611f4a2713aSLionel Sambuc       // FIXME: Dropping the reference type on the type into makes it
612f4a2713aSLionel Sambuc       // impossible to correctly implement catch-by-reference
613f4a2713aSLionel Sambuc       // semantics for pointers.  Unfortunately, this is what all
614f4a2713aSLionel Sambuc       // existing compilers do, and it's not clear that the standard
615f4a2713aSLionel Sambuc       // personality routine is capable of doing this right.  See C++ DR 388:
616f4a2713aSLionel Sambuc       //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
617*0a6a1f1dSLionel Sambuc       Qualifiers CaughtTypeQuals;
618*0a6a1f1dSLionel Sambuc       QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
619*0a6a1f1dSLionel Sambuc           C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
620f4a2713aSLionel Sambuc 
621*0a6a1f1dSLionel Sambuc       llvm::Constant *TypeInfo = nullptr;
622f4a2713aSLionel Sambuc       if (CaughtType->isObjCObjectPointerType())
623f4a2713aSLionel Sambuc         TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
624f4a2713aSLionel Sambuc       else
625f4a2713aSLionel Sambuc         TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);
626f4a2713aSLionel Sambuc       CatchScope->setHandler(I, TypeInfo, Handler);
627f4a2713aSLionel Sambuc     } else {
628f4a2713aSLionel Sambuc       // No exception decl indicates '...', a catch-all.
629f4a2713aSLionel Sambuc       CatchScope->setCatchAllHandler(I, Handler);
630f4a2713aSLionel Sambuc     }
631f4a2713aSLionel Sambuc   }
632f4a2713aSLionel Sambuc }
633f4a2713aSLionel Sambuc 
634f4a2713aSLionel Sambuc llvm::BasicBlock *
getEHDispatchBlock(EHScopeStack::stable_iterator si)635f4a2713aSLionel Sambuc CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
636f4a2713aSLionel Sambuc   // The dispatch block for the end of the scope chain is a block that
637f4a2713aSLionel Sambuc   // just resumes unwinding.
638f4a2713aSLionel Sambuc   if (si == EHStack.stable_end())
639f4a2713aSLionel Sambuc     return getEHResumeBlock(true);
640f4a2713aSLionel Sambuc 
641f4a2713aSLionel Sambuc   // Otherwise, we should look at the actual scope.
642f4a2713aSLionel Sambuc   EHScope &scope = *EHStack.find(si);
643f4a2713aSLionel Sambuc 
644f4a2713aSLionel Sambuc   llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
645f4a2713aSLionel Sambuc   if (!dispatchBlock) {
646f4a2713aSLionel Sambuc     switch (scope.getKind()) {
647f4a2713aSLionel Sambuc     case EHScope::Catch: {
648f4a2713aSLionel Sambuc       // Apply a special case to a single catch-all.
649f4a2713aSLionel Sambuc       EHCatchScope &catchScope = cast<EHCatchScope>(scope);
650f4a2713aSLionel Sambuc       if (catchScope.getNumHandlers() == 1 &&
651f4a2713aSLionel Sambuc           catchScope.getHandler(0).isCatchAll()) {
652f4a2713aSLionel Sambuc         dispatchBlock = catchScope.getHandler(0).Block;
653f4a2713aSLionel Sambuc 
654f4a2713aSLionel Sambuc       // Otherwise, make a dispatch block.
655f4a2713aSLionel Sambuc       } else {
656f4a2713aSLionel Sambuc         dispatchBlock = createBasicBlock("catch.dispatch");
657f4a2713aSLionel Sambuc       }
658f4a2713aSLionel Sambuc       break;
659f4a2713aSLionel Sambuc     }
660f4a2713aSLionel Sambuc 
661f4a2713aSLionel Sambuc     case EHScope::Cleanup:
662f4a2713aSLionel Sambuc       dispatchBlock = createBasicBlock("ehcleanup");
663f4a2713aSLionel Sambuc       break;
664f4a2713aSLionel Sambuc 
665f4a2713aSLionel Sambuc     case EHScope::Filter:
666f4a2713aSLionel Sambuc       dispatchBlock = createBasicBlock("filter.dispatch");
667f4a2713aSLionel Sambuc       break;
668f4a2713aSLionel Sambuc 
669f4a2713aSLionel Sambuc     case EHScope::Terminate:
670f4a2713aSLionel Sambuc       dispatchBlock = getTerminateHandler();
671f4a2713aSLionel Sambuc       break;
672f4a2713aSLionel Sambuc     }
673f4a2713aSLionel Sambuc     scope.setCachedEHDispatchBlock(dispatchBlock);
674f4a2713aSLionel Sambuc   }
675f4a2713aSLionel Sambuc   return dispatchBlock;
676f4a2713aSLionel Sambuc }
677f4a2713aSLionel Sambuc 
678f4a2713aSLionel Sambuc /// Check whether this is a non-EH scope, i.e. a scope which doesn't
679f4a2713aSLionel Sambuc /// affect exception handling.  Currently, the only non-EH scopes are
680f4a2713aSLionel Sambuc /// normal-only cleanup scopes.
isNonEHScope(const EHScope & S)681f4a2713aSLionel Sambuc static bool isNonEHScope(const EHScope &S) {
682f4a2713aSLionel Sambuc   switch (S.getKind()) {
683f4a2713aSLionel Sambuc   case EHScope::Cleanup:
684f4a2713aSLionel Sambuc     return !cast<EHCleanupScope>(S).isEHCleanup();
685f4a2713aSLionel Sambuc   case EHScope::Filter:
686f4a2713aSLionel Sambuc   case EHScope::Catch:
687f4a2713aSLionel Sambuc   case EHScope::Terminate:
688f4a2713aSLionel Sambuc     return false;
689f4a2713aSLionel Sambuc   }
690f4a2713aSLionel Sambuc 
691f4a2713aSLionel Sambuc   llvm_unreachable("Invalid EHScope Kind!");
692f4a2713aSLionel Sambuc }
693f4a2713aSLionel Sambuc 
getInvokeDestImpl()694f4a2713aSLionel Sambuc llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
695f4a2713aSLionel Sambuc   assert(EHStack.requiresLandingPad());
696f4a2713aSLionel Sambuc   assert(!EHStack.empty());
697f4a2713aSLionel Sambuc 
698f4a2713aSLionel Sambuc   if (!CGM.getLangOpts().Exceptions)
699*0a6a1f1dSLionel Sambuc     return nullptr;
700f4a2713aSLionel Sambuc 
701f4a2713aSLionel Sambuc   // Check the innermost scope for a cached landing pad.  If this is
702f4a2713aSLionel Sambuc   // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
703f4a2713aSLionel Sambuc   llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
704f4a2713aSLionel Sambuc   if (LP) return LP;
705f4a2713aSLionel Sambuc 
706f4a2713aSLionel Sambuc   // Build the landing pad for this scope.
707f4a2713aSLionel Sambuc   LP = EmitLandingPad();
708f4a2713aSLionel Sambuc   assert(LP);
709f4a2713aSLionel Sambuc 
710f4a2713aSLionel Sambuc   // Cache the landing pad on the innermost scope.  If this is a
711f4a2713aSLionel Sambuc   // non-EH scope, cache the landing pad on the enclosing scope, too.
712f4a2713aSLionel Sambuc   for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
713f4a2713aSLionel Sambuc     ir->setCachedLandingPad(LP);
714f4a2713aSLionel Sambuc     if (!isNonEHScope(*ir)) break;
715f4a2713aSLionel Sambuc   }
716f4a2713aSLionel Sambuc 
717f4a2713aSLionel Sambuc   return LP;
718f4a2713aSLionel Sambuc }
719f4a2713aSLionel Sambuc 
EmitLandingPad()720f4a2713aSLionel Sambuc llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
721f4a2713aSLionel Sambuc   assert(EHStack.requiresLandingPad());
722f4a2713aSLionel Sambuc 
723f4a2713aSLionel Sambuc   EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
724f4a2713aSLionel Sambuc   switch (innermostEHScope.getKind()) {
725f4a2713aSLionel Sambuc   case EHScope::Terminate:
726f4a2713aSLionel Sambuc     return getTerminateLandingPad();
727f4a2713aSLionel Sambuc 
728f4a2713aSLionel Sambuc   case EHScope::Catch:
729f4a2713aSLionel Sambuc   case EHScope::Cleanup:
730f4a2713aSLionel Sambuc   case EHScope::Filter:
731f4a2713aSLionel Sambuc     if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
732f4a2713aSLionel Sambuc       return lpad;
733f4a2713aSLionel Sambuc   }
734f4a2713aSLionel Sambuc 
735f4a2713aSLionel Sambuc   // Save the current IR generation state.
736f4a2713aSLionel Sambuc   CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
737*0a6a1f1dSLionel Sambuc   ApplyDebugLocation AutoRestoreLocation(*this, CurEHLocation);
738f4a2713aSLionel Sambuc 
739*0a6a1f1dSLionel Sambuc   const EHPersonality &personality = EHPersonality::get(CGM);
740f4a2713aSLionel Sambuc 
741f4a2713aSLionel Sambuc   // Create and configure the landing pad.
742f4a2713aSLionel Sambuc   llvm::BasicBlock *lpad = createBasicBlock("lpad");
743f4a2713aSLionel Sambuc   EmitBlock(lpad);
744f4a2713aSLionel Sambuc 
745f4a2713aSLionel Sambuc   llvm::LandingPadInst *LPadInst =
746*0a6a1f1dSLionel Sambuc     Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr),
747f4a2713aSLionel Sambuc                              getOpaquePersonalityFn(CGM, personality), 0);
748f4a2713aSLionel Sambuc 
749f4a2713aSLionel Sambuc   llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
750f4a2713aSLionel Sambuc   Builder.CreateStore(LPadExn, getExceptionSlot());
751f4a2713aSLionel Sambuc   llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
752f4a2713aSLionel Sambuc   Builder.CreateStore(LPadSel, getEHSelectorSlot());
753f4a2713aSLionel Sambuc 
754f4a2713aSLionel Sambuc   // Save the exception pointer.  It's safe to use a single exception
755f4a2713aSLionel Sambuc   // pointer per function because EH cleanups can never have nested
756f4a2713aSLionel Sambuc   // try/catches.
757f4a2713aSLionel Sambuc   // Build the landingpad instruction.
758f4a2713aSLionel Sambuc 
759f4a2713aSLionel Sambuc   // Accumulate all the handlers in scope.
760f4a2713aSLionel Sambuc   bool hasCatchAll = false;
761f4a2713aSLionel Sambuc   bool hasCleanup = false;
762f4a2713aSLionel Sambuc   bool hasFilter = false;
763f4a2713aSLionel Sambuc   SmallVector<llvm::Value*, 4> filterTypes;
764f4a2713aSLionel Sambuc   llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
765f4a2713aSLionel Sambuc   for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end();
766f4a2713aSLionel Sambuc          I != E; ++I) {
767f4a2713aSLionel Sambuc 
768f4a2713aSLionel Sambuc     switch (I->getKind()) {
769f4a2713aSLionel Sambuc     case EHScope::Cleanup:
770f4a2713aSLionel Sambuc       // If we have a cleanup, remember that.
771f4a2713aSLionel Sambuc       hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
772f4a2713aSLionel Sambuc       continue;
773f4a2713aSLionel Sambuc 
774f4a2713aSLionel Sambuc     case EHScope::Filter: {
775f4a2713aSLionel Sambuc       assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
776f4a2713aSLionel Sambuc       assert(!hasCatchAll && "EH filter reached after catch-all");
777f4a2713aSLionel Sambuc 
778f4a2713aSLionel Sambuc       // Filter scopes get added to the landingpad in weird ways.
779f4a2713aSLionel Sambuc       EHFilterScope &filter = cast<EHFilterScope>(*I);
780f4a2713aSLionel Sambuc       hasFilter = true;
781f4a2713aSLionel Sambuc 
782f4a2713aSLionel Sambuc       // Add all the filter values.
783f4a2713aSLionel Sambuc       for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
784f4a2713aSLionel Sambuc         filterTypes.push_back(filter.getFilter(i));
785f4a2713aSLionel Sambuc       goto done;
786f4a2713aSLionel Sambuc     }
787f4a2713aSLionel Sambuc 
788f4a2713aSLionel Sambuc     case EHScope::Terminate:
789f4a2713aSLionel Sambuc       // Terminate scopes are basically catch-alls.
790f4a2713aSLionel Sambuc       assert(!hasCatchAll);
791f4a2713aSLionel Sambuc       hasCatchAll = true;
792f4a2713aSLionel Sambuc       goto done;
793f4a2713aSLionel Sambuc 
794f4a2713aSLionel Sambuc     case EHScope::Catch:
795f4a2713aSLionel Sambuc       break;
796f4a2713aSLionel Sambuc     }
797f4a2713aSLionel Sambuc 
798f4a2713aSLionel Sambuc     EHCatchScope &catchScope = cast<EHCatchScope>(*I);
799f4a2713aSLionel Sambuc     for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
800f4a2713aSLionel Sambuc       EHCatchScope::Handler handler = catchScope.getHandler(hi);
801f4a2713aSLionel Sambuc 
802f4a2713aSLionel Sambuc       // If this is a catch-all, register that and abort.
803f4a2713aSLionel Sambuc       if (!handler.Type) {
804f4a2713aSLionel Sambuc         assert(!hasCatchAll);
805f4a2713aSLionel Sambuc         hasCatchAll = true;
806f4a2713aSLionel Sambuc         goto done;
807f4a2713aSLionel Sambuc       }
808f4a2713aSLionel Sambuc 
809f4a2713aSLionel Sambuc       // Check whether we already have a handler for this type.
810*0a6a1f1dSLionel Sambuc       if (catchTypes.insert(handler.Type).second)
811f4a2713aSLionel Sambuc         // If not, add it directly to the landingpad.
812f4a2713aSLionel Sambuc         LPadInst->addClause(handler.Type);
813f4a2713aSLionel Sambuc     }
814f4a2713aSLionel Sambuc   }
815f4a2713aSLionel Sambuc 
816f4a2713aSLionel Sambuc  done:
817f4a2713aSLionel Sambuc   // If we have a catch-all, add null to the landingpad.
818f4a2713aSLionel Sambuc   assert(!(hasCatchAll && hasFilter));
819f4a2713aSLionel Sambuc   if (hasCatchAll) {
820f4a2713aSLionel Sambuc     LPadInst->addClause(getCatchAllValue(*this));
821f4a2713aSLionel Sambuc 
822f4a2713aSLionel Sambuc   // If we have an EH filter, we need to add those handlers in the
823f4a2713aSLionel Sambuc   // right place in the landingpad, which is to say, at the end.
824f4a2713aSLionel Sambuc   } else if (hasFilter) {
825f4a2713aSLionel Sambuc     // Create a filter expression: a constant array indicating which filter
826f4a2713aSLionel Sambuc     // types there are. The personality routine only lands here if the filter
827f4a2713aSLionel Sambuc     // doesn't match.
828f4a2713aSLionel Sambuc     SmallVector<llvm::Constant*, 8> Filters;
829f4a2713aSLionel Sambuc     llvm::ArrayType *AType =
830f4a2713aSLionel Sambuc       llvm::ArrayType::get(!filterTypes.empty() ?
831f4a2713aSLionel Sambuc                              filterTypes[0]->getType() : Int8PtrTy,
832f4a2713aSLionel Sambuc                            filterTypes.size());
833f4a2713aSLionel Sambuc 
834f4a2713aSLionel Sambuc     for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
835f4a2713aSLionel Sambuc       Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
836f4a2713aSLionel Sambuc     llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
837f4a2713aSLionel Sambuc     LPadInst->addClause(FilterArray);
838f4a2713aSLionel Sambuc 
839f4a2713aSLionel Sambuc     // Also check whether we need a cleanup.
840f4a2713aSLionel Sambuc     if (hasCleanup)
841f4a2713aSLionel Sambuc       LPadInst->setCleanup(true);
842f4a2713aSLionel Sambuc 
843f4a2713aSLionel Sambuc   // Otherwise, signal that we at least have cleanups.
844*0a6a1f1dSLionel Sambuc   } else if (hasCleanup) {
845f4a2713aSLionel Sambuc     LPadInst->setCleanup(true);
846f4a2713aSLionel Sambuc   }
847f4a2713aSLionel Sambuc 
848f4a2713aSLionel Sambuc   assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
849f4a2713aSLionel Sambuc          "landingpad instruction has no clauses!");
850f4a2713aSLionel Sambuc 
851f4a2713aSLionel Sambuc   // Tell the backend how to generate the landing pad.
852f4a2713aSLionel Sambuc   Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
853f4a2713aSLionel Sambuc 
854f4a2713aSLionel Sambuc   // Restore the old IR generation state.
855f4a2713aSLionel Sambuc   Builder.restoreIP(savedIP);
856f4a2713aSLionel Sambuc 
857f4a2713aSLionel Sambuc   return lpad;
858f4a2713aSLionel Sambuc }
859f4a2713aSLionel Sambuc 
860f4a2713aSLionel Sambuc namespace {
861f4a2713aSLionel Sambuc   /// A cleanup to call __cxa_end_catch.  In many cases, the caught
862f4a2713aSLionel Sambuc   /// exception type lets us state definitively that the thrown exception
863f4a2713aSLionel Sambuc   /// type does not have a destructor.  In particular:
864f4a2713aSLionel Sambuc   ///   - Catch-alls tell us nothing, so we have to conservatively
865f4a2713aSLionel Sambuc   ///     assume that the thrown exception might have a destructor.
866f4a2713aSLionel Sambuc   ///   - Catches by reference behave according to their base types.
867f4a2713aSLionel Sambuc   ///   - Catches of non-record types will only trigger for exceptions
868f4a2713aSLionel Sambuc   ///     of non-record types, which never have destructors.
869f4a2713aSLionel Sambuc   ///   - Catches of record types can trigger for arbitrary subclasses
870f4a2713aSLionel Sambuc   ///     of the caught type, so we have to assume the actual thrown
871f4a2713aSLionel Sambuc   ///     exception type might have a throwing destructor, even if the
872f4a2713aSLionel Sambuc   ///     caught type's destructor is trivial or nothrow.
873f4a2713aSLionel Sambuc   struct CallEndCatch : EHScopeStack::Cleanup {
CallEndCatch__anon2995a1420311::CallEndCatch874f4a2713aSLionel Sambuc     CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
875f4a2713aSLionel Sambuc     bool MightThrow;
876f4a2713aSLionel Sambuc 
Emit__anon2995a1420311::CallEndCatch877*0a6a1f1dSLionel Sambuc     void Emit(CodeGenFunction &CGF, Flags flags) override {
878f4a2713aSLionel Sambuc       if (!MightThrow) {
879f4a2713aSLionel Sambuc         CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));
880f4a2713aSLionel Sambuc         return;
881f4a2713aSLionel Sambuc       }
882f4a2713aSLionel Sambuc 
883f4a2713aSLionel Sambuc       CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM));
884f4a2713aSLionel Sambuc     }
885f4a2713aSLionel Sambuc   };
886f4a2713aSLionel Sambuc }
887f4a2713aSLionel Sambuc 
888f4a2713aSLionel Sambuc /// Emits a call to __cxa_begin_catch and enters a cleanup to call
889f4a2713aSLionel Sambuc /// __cxa_end_catch.
890f4a2713aSLionel Sambuc ///
891f4a2713aSLionel Sambuc /// \param EndMightThrow - true if __cxa_end_catch might throw
CallBeginCatch(CodeGenFunction & CGF,llvm::Value * Exn,bool EndMightThrow)892f4a2713aSLionel Sambuc static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
893f4a2713aSLionel Sambuc                                    llvm::Value *Exn,
894f4a2713aSLionel Sambuc                                    bool EndMightThrow) {
895f4a2713aSLionel Sambuc   llvm::CallInst *call =
896f4a2713aSLionel Sambuc     CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);
897f4a2713aSLionel Sambuc 
898f4a2713aSLionel Sambuc   CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
899f4a2713aSLionel Sambuc 
900f4a2713aSLionel Sambuc   return call;
901f4a2713aSLionel Sambuc }
902f4a2713aSLionel Sambuc 
903f4a2713aSLionel Sambuc /// A "special initializer" callback for initializing a catch
904f4a2713aSLionel Sambuc /// parameter during catch initialization.
InitCatchParam(CodeGenFunction & CGF,const VarDecl & CatchParam,llvm::Value * ParamAddr,SourceLocation Loc)905f4a2713aSLionel Sambuc static void InitCatchParam(CodeGenFunction &CGF,
906f4a2713aSLionel Sambuc                            const VarDecl &CatchParam,
907f4a2713aSLionel Sambuc                            llvm::Value *ParamAddr,
908f4a2713aSLionel Sambuc                            SourceLocation Loc) {
909f4a2713aSLionel Sambuc   // Load the exception from where the landing pad saved it.
910f4a2713aSLionel Sambuc   llvm::Value *Exn = CGF.getExceptionFromSlot();
911f4a2713aSLionel Sambuc 
912f4a2713aSLionel Sambuc   CanQualType CatchType =
913f4a2713aSLionel Sambuc     CGF.CGM.getContext().getCanonicalType(CatchParam.getType());
914f4a2713aSLionel Sambuc   llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);
915f4a2713aSLionel Sambuc 
916f4a2713aSLionel Sambuc   // If we're catching by reference, we can just cast the object
917f4a2713aSLionel Sambuc   // pointer to the appropriate pointer.
918f4a2713aSLionel Sambuc   if (isa<ReferenceType>(CatchType)) {
919f4a2713aSLionel Sambuc     QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
920f4a2713aSLionel Sambuc     bool EndCatchMightThrow = CaughtType->isRecordType();
921f4a2713aSLionel Sambuc 
922f4a2713aSLionel Sambuc     // __cxa_begin_catch returns the adjusted object pointer.
923f4a2713aSLionel Sambuc     llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);
924f4a2713aSLionel Sambuc 
925f4a2713aSLionel Sambuc     // We have no way to tell the personality function that we're
926f4a2713aSLionel Sambuc     // catching by reference, so if we're catching a pointer,
927f4a2713aSLionel Sambuc     // __cxa_begin_catch will actually return that pointer by value.
928f4a2713aSLionel Sambuc     if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
929f4a2713aSLionel Sambuc       QualType PointeeType = PT->getPointeeType();
930f4a2713aSLionel Sambuc 
931f4a2713aSLionel Sambuc       // When catching by reference, generally we should just ignore
932f4a2713aSLionel Sambuc       // this by-value pointer and use the exception object instead.
933f4a2713aSLionel Sambuc       if (!PointeeType->isRecordType()) {
934f4a2713aSLionel Sambuc 
935f4a2713aSLionel Sambuc         // Exn points to the struct _Unwind_Exception header, which
936f4a2713aSLionel Sambuc         // we have to skip past in order to reach the exception data.
937f4a2713aSLionel Sambuc         unsigned HeaderSize =
938f4a2713aSLionel Sambuc           CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();
939f4a2713aSLionel Sambuc         AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize);
940f4a2713aSLionel Sambuc 
941f4a2713aSLionel Sambuc       // However, if we're catching a pointer-to-record type that won't
942f4a2713aSLionel Sambuc       // work, because the personality function might have adjusted
943f4a2713aSLionel Sambuc       // the pointer.  There's actually no way for us to fully satisfy
944f4a2713aSLionel Sambuc       // the language/ABI contract here:  we can't use Exn because it
945f4a2713aSLionel Sambuc       // might have the wrong adjustment, but we can't use the by-value
946f4a2713aSLionel Sambuc       // pointer because it's off by a level of abstraction.
947f4a2713aSLionel Sambuc       //
948f4a2713aSLionel Sambuc       // The current solution is to dump the adjusted pointer into an
949f4a2713aSLionel Sambuc       // alloca, which breaks language semantics (because changing the
950f4a2713aSLionel Sambuc       // pointer doesn't change the exception) but at least works.
951f4a2713aSLionel Sambuc       // The better solution would be to filter out non-exact matches
952f4a2713aSLionel Sambuc       // and rethrow them, but this is tricky because the rethrow
953f4a2713aSLionel Sambuc       // really needs to be catchable by other sites at this landing
954f4a2713aSLionel Sambuc       // pad.  The best solution is to fix the personality function.
955f4a2713aSLionel Sambuc       } else {
956f4a2713aSLionel Sambuc         // Pull the pointer for the reference type off.
957f4a2713aSLionel Sambuc         llvm::Type *PtrTy =
958f4a2713aSLionel Sambuc           cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
959f4a2713aSLionel Sambuc 
960f4a2713aSLionel Sambuc         // Create the temporary and write the adjusted pointer into it.
961f4a2713aSLionel Sambuc         llvm::Value *ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, "exn.byref.tmp");
962f4a2713aSLionel Sambuc         llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
963f4a2713aSLionel Sambuc         CGF.Builder.CreateStore(Casted, ExnPtrTmp);
964f4a2713aSLionel Sambuc 
965f4a2713aSLionel Sambuc         // Bind the reference to the temporary.
966f4a2713aSLionel Sambuc         AdjustedExn = ExnPtrTmp;
967f4a2713aSLionel Sambuc       }
968f4a2713aSLionel Sambuc     }
969f4a2713aSLionel Sambuc 
970f4a2713aSLionel Sambuc     llvm::Value *ExnCast =
971f4a2713aSLionel Sambuc       CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");
972f4a2713aSLionel Sambuc     CGF.Builder.CreateStore(ExnCast, ParamAddr);
973f4a2713aSLionel Sambuc     return;
974f4a2713aSLionel Sambuc   }
975f4a2713aSLionel Sambuc 
976f4a2713aSLionel Sambuc   // Scalars and complexes.
977f4a2713aSLionel Sambuc   TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType);
978f4a2713aSLionel Sambuc   if (TEK != TEK_Aggregate) {
979f4a2713aSLionel Sambuc     llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);
980f4a2713aSLionel Sambuc 
981f4a2713aSLionel Sambuc     // If the catch type is a pointer type, __cxa_begin_catch returns
982f4a2713aSLionel Sambuc     // the pointer by value.
983f4a2713aSLionel Sambuc     if (CatchType->hasPointerRepresentation()) {
984f4a2713aSLionel Sambuc       llvm::Value *CastExn =
985f4a2713aSLionel Sambuc         CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
986f4a2713aSLionel Sambuc 
987f4a2713aSLionel Sambuc       switch (CatchType.getQualifiers().getObjCLifetime()) {
988f4a2713aSLionel Sambuc       case Qualifiers::OCL_Strong:
989f4a2713aSLionel Sambuc         CastExn = CGF.EmitARCRetainNonBlock(CastExn);
990f4a2713aSLionel Sambuc         // fallthrough
991f4a2713aSLionel Sambuc 
992f4a2713aSLionel Sambuc       case Qualifiers::OCL_None:
993f4a2713aSLionel Sambuc       case Qualifiers::OCL_ExplicitNone:
994f4a2713aSLionel Sambuc       case Qualifiers::OCL_Autoreleasing:
995f4a2713aSLionel Sambuc         CGF.Builder.CreateStore(CastExn, ParamAddr);
996f4a2713aSLionel Sambuc         return;
997f4a2713aSLionel Sambuc 
998f4a2713aSLionel Sambuc       case Qualifiers::OCL_Weak:
999f4a2713aSLionel Sambuc         CGF.EmitARCInitWeak(ParamAddr, CastExn);
1000f4a2713aSLionel Sambuc         return;
1001f4a2713aSLionel Sambuc       }
1002f4a2713aSLionel Sambuc       llvm_unreachable("bad ownership qualifier!");
1003f4a2713aSLionel Sambuc     }
1004f4a2713aSLionel Sambuc 
1005f4a2713aSLionel Sambuc     // Otherwise, it returns a pointer into the exception object.
1006f4a2713aSLionel Sambuc 
1007f4a2713aSLionel Sambuc     llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
1008f4a2713aSLionel Sambuc     llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
1009f4a2713aSLionel Sambuc 
1010f4a2713aSLionel Sambuc     LValue srcLV = CGF.MakeNaturalAlignAddrLValue(Cast, CatchType);
1011f4a2713aSLionel Sambuc     LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType,
1012f4a2713aSLionel Sambuc                                   CGF.getContext().getDeclAlign(&CatchParam));
1013f4a2713aSLionel Sambuc     switch (TEK) {
1014f4a2713aSLionel Sambuc     case TEK_Complex:
1015f4a2713aSLionel Sambuc       CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV,
1016f4a2713aSLionel Sambuc                              /*init*/ true);
1017f4a2713aSLionel Sambuc       return;
1018f4a2713aSLionel Sambuc     case TEK_Scalar: {
1019f4a2713aSLionel Sambuc       llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc);
1020f4a2713aSLionel Sambuc       CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true);
1021f4a2713aSLionel Sambuc       return;
1022f4a2713aSLionel Sambuc     }
1023f4a2713aSLionel Sambuc     case TEK_Aggregate:
1024f4a2713aSLionel Sambuc       llvm_unreachable("evaluation kind filtered out!");
1025f4a2713aSLionel Sambuc     }
1026f4a2713aSLionel Sambuc     llvm_unreachable("bad evaluation kind");
1027f4a2713aSLionel Sambuc   }
1028f4a2713aSLionel Sambuc 
1029f4a2713aSLionel Sambuc   assert(isa<RecordType>(CatchType) && "unexpected catch type!");
1030f4a2713aSLionel Sambuc 
1031f4a2713aSLionel Sambuc   llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
1032f4a2713aSLionel Sambuc 
1033f4a2713aSLionel Sambuc   // Check for a copy expression.  If we don't have a copy expression,
1034f4a2713aSLionel Sambuc   // that means a trivial copy is okay.
1035f4a2713aSLionel Sambuc   const Expr *copyExpr = CatchParam.getInit();
1036f4a2713aSLionel Sambuc   if (!copyExpr) {
1037f4a2713aSLionel Sambuc     llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);
1038f4a2713aSLionel Sambuc     llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);
1039f4a2713aSLionel Sambuc     CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType);
1040f4a2713aSLionel Sambuc     return;
1041f4a2713aSLionel Sambuc   }
1042f4a2713aSLionel Sambuc 
1043f4a2713aSLionel Sambuc   // We have to call __cxa_get_exception_ptr to get the adjusted
1044f4a2713aSLionel Sambuc   // pointer before copying.
1045f4a2713aSLionel Sambuc   llvm::CallInst *rawAdjustedExn =
1046f4a2713aSLionel Sambuc     CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn);
1047f4a2713aSLionel Sambuc 
1048f4a2713aSLionel Sambuc   // Cast that to the appropriate type.
1049f4a2713aSLionel Sambuc   llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);
1050f4a2713aSLionel Sambuc 
1051f4a2713aSLionel Sambuc   // The copy expression is defined in terms of an OpaqueValueExpr.
1052f4a2713aSLionel Sambuc   // Find it and map it to the adjusted expression.
1053f4a2713aSLionel Sambuc   CodeGenFunction::OpaqueValueMapping
1054f4a2713aSLionel Sambuc     opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr),
1055f4a2713aSLionel Sambuc            CGF.MakeAddrLValue(adjustedExn, CatchParam.getType()));
1056f4a2713aSLionel Sambuc 
1057f4a2713aSLionel Sambuc   // Call the copy ctor in a terminate scope.
1058f4a2713aSLionel Sambuc   CGF.EHStack.pushTerminate();
1059f4a2713aSLionel Sambuc 
1060f4a2713aSLionel Sambuc   // Perform the copy construction.
1061f4a2713aSLionel Sambuc   CharUnits Alignment = CGF.getContext().getDeclAlign(&CatchParam);
1062f4a2713aSLionel Sambuc   CGF.EmitAggExpr(copyExpr,
1063f4a2713aSLionel Sambuc                   AggValueSlot::forAddr(ParamAddr, Alignment, Qualifiers(),
1064f4a2713aSLionel Sambuc                                         AggValueSlot::IsNotDestructed,
1065f4a2713aSLionel Sambuc                                         AggValueSlot::DoesNotNeedGCBarriers,
1066f4a2713aSLionel Sambuc                                         AggValueSlot::IsNotAliased));
1067f4a2713aSLionel Sambuc 
1068f4a2713aSLionel Sambuc   // Leave the terminate scope.
1069f4a2713aSLionel Sambuc   CGF.EHStack.popTerminate();
1070f4a2713aSLionel Sambuc 
1071f4a2713aSLionel Sambuc   // Undo the opaque value mapping.
1072f4a2713aSLionel Sambuc   opaque.pop();
1073f4a2713aSLionel Sambuc 
1074f4a2713aSLionel Sambuc   // Finally we can call __cxa_begin_catch.
1075f4a2713aSLionel Sambuc   CallBeginCatch(CGF, Exn, true);
1076f4a2713aSLionel Sambuc }
1077f4a2713aSLionel Sambuc 
1078f4a2713aSLionel Sambuc /// Begins a catch statement by initializing the catch variable and
1079f4a2713aSLionel Sambuc /// calling __cxa_begin_catch.
BeginCatch(CodeGenFunction & CGF,const CXXCatchStmt * S)1080f4a2713aSLionel Sambuc static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {
1081f4a2713aSLionel Sambuc   // We have to be very careful with the ordering of cleanups here:
1082f4a2713aSLionel Sambuc   //   C++ [except.throw]p4:
1083f4a2713aSLionel Sambuc   //     The destruction [of the exception temporary] occurs
1084f4a2713aSLionel Sambuc   //     immediately after the destruction of the object declared in
1085f4a2713aSLionel Sambuc   //     the exception-declaration in the handler.
1086f4a2713aSLionel Sambuc   //
1087f4a2713aSLionel Sambuc   // So the precise ordering is:
1088f4a2713aSLionel Sambuc   //   1.  Construct catch variable.
1089f4a2713aSLionel Sambuc   //   2.  __cxa_begin_catch
1090f4a2713aSLionel Sambuc   //   3.  Enter __cxa_end_catch cleanup
1091f4a2713aSLionel Sambuc   //   4.  Enter dtor cleanup
1092f4a2713aSLionel Sambuc   //
1093f4a2713aSLionel Sambuc   // We do this by using a slightly abnormal initialization process.
1094f4a2713aSLionel Sambuc   // Delegation sequence:
1095f4a2713aSLionel Sambuc   //   - ExitCXXTryStmt opens a RunCleanupsScope
1096f4a2713aSLionel Sambuc   //     - EmitAutoVarAlloca creates the variable and debug info
1097f4a2713aSLionel Sambuc   //       - InitCatchParam initializes the variable from the exception
1098f4a2713aSLionel Sambuc   //       - CallBeginCatch calls __cxa_begin_catch
1099f4a2713aSLionel Sambuc   //       - CallBeginCatch enters the __cxa_end_catch cleanup
1100f4a2713aSLionel Sambuc   //     - EmitAutoVarCleanups enters the variable destructor cleanup
1101f4a2713aSLionel Sambuc   //   - EmitCXXTryStmt emits the code for the catch body
1102f4a2713aSLionel Sambuc   //   - EmitCXXTryStmt close the RunCleanupsScope
1103f4a2713aSLionel Sambuc 
1104f4a2713aSLionel Sambuc   VarDecl *CatchParam = S->getExceptionDecl();
1105f4a2713aSLionel Sambuc   if (!CatchParam) {
1106f4a2713aSLionel Sambuc     llvm::Value *Exn = CGF.getExceptionFromSlot();
1107f4a2713aSLionel Sambuc     CallBeginCatch(CGF, Exn, true);
1108f4a2713aSLionel Sambuc     return;
1109f4a2713aSLionel Sambuc   }
1110f4a2713aSLionel Sambuc 
1111f4a2713aSLionel Sambuc   // Emit the local.
1112f4a2713aSLionel Sambuc   CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
1113f4a2713aSLionel Sambuc   InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getLocStart());
1114f4a2713aSLionel Sambuc   CGF.EmitAutoVarCleanups(var);
1115f4a2713aSLionel Sambuc }
1116f4a2713aSLionel Sambuc 
1117f4a2713aSLionel Sambuc /// Emit the structure of the dispatch block for the given catch scope.
1118f4a2713aSLionel Sambuc /// It is an invariant that the dispatch block already exists.
emitCatchDispatchBlock(CodeGenFunction & CGF,EHCatchScope & catchScope)1119f4a2713aSLionel Sambuc static void emitCatchDispatchBlock(CodeGenFunction &CGF,
1120f4a2713aSLionel Sambuc                                    EHCatchScope &catchScope) {
1121f4a2713aSLionel Sambuc   llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
1122f4a2713aSLionel Sambuc   assert(dispatchBlock);
1123f4a2713aSLionel Sambuc 
1124f4a2713aSLionel Sambuc   // If there's only a single catch-all, getEHDispatchBlock returned
1125f4a2713aSLionel Sambuc   // that catch-all as the dispatch block.
1126f4a2713aSLionel Sambuc   if (catchScope.getNumHandlers() == 1 &&
1127f4a2713aSLionel Sambuc       catchScope.getHandler(0).isCatchAll()) {
1128f4a2713aSLionel Sambuc     assert(dispatchBlock == catchScope.getHandler(0).Block);
1129f4a2713aSLionel Sambuc     return;
1130f4a2713aSLionel Sambuc   }
1131f4a2713aSLionel Sambuc 
1132f4a2713aSLionel Sambuc   CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
1133f4a2713aSLionel Sambuc   CGF.EmitBlockAfterUses(dispatchBlock);
1134f4a2713aSLionel Sambuc 
1135f4a2713aSLionel Sambuc   // Select the right handler.
1136f4a2713aSLionel Sambuc   llvm::Value *llvm_eh_typeid_for =
1137f4a2713aSLionel Sambuc     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
1138f4a2713aSLionel Sambuc 
1139f4a2713aSLionel Sambuc   // Load the selector value.
1140f4a2713aSLionel Sambuc   llvm::Value *selector = CGF.getSelectorFromSlot();
1141f4a2713aSLionel Sambuc 
1142f4a2713aSLionel Sambuc   // Test against each of the exception types we claim to catch.
1143f4a2713aSLionel Sambuc   for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
1144f4a2713aSLionel Sambuc     assert(i < e && "ran off end of handlers!");
1145f4a2713aSLionel Sambuc     const EHCatchScope::Handler &handler = catchScope.getHandler(i);
1146f4a2713aSLionel Sambuc 
1147f4a2713aSLionel Sambuc     llvm::Value *typeValue = handler.Type;
1148f4a2713aSLionel Sambuc     assert(typeValue && "fell into catch-all case!");
1149f4a2713aSLionel Sambuc     typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy);
1150f4a2713aSLionel Sambuc 
1151f4a2713aSLionel Sambuc     // Figure out the next block.
1152f4a2713aSLionel Sambuc     bool nextIsEnd;
1153f4a2713aSLionel Sambuc     llvm::BasicBlock *nextBlock;
1154f4a2713aSLionel Sambuc 
1155f4a2713aSLionel Sambuc     // If this is the last handler, we're at the end, and the next
1156f4a2713aSLionel Sambuc     // block is the block for the enclosing EH scope.
1157f4a2713aSLionel Sambuc     if (i + 1 == e) {
1158f4a2713aSLionel Sambuc       nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
1159f4a2713aSLionel Sambuc       nextIsEnd = true;
1160f4a2713aSLionel Sambuc 
1161f4a2713aSLionel Sambuc     // If the next handler is a catch-all, we're at the end, and the
1162f4a2713aSLionel Sambuc     // next block is that handler.
1163f4a2713aSLionel Sambuc     } else if (catchScope.getHandler(i+1).isCatchAll()) {
1164f4a2713aSLionel Sambuc       nextBlock = catchScope.getHandler(i+1).Block;
1165f4a2713aSLionel Sambuc       nextIsEnd = true;
1166f4a2713aSLionel Sambuc 
1167f4a2713aSLionel Sambuc     // Otherwise, we're not at the end and we need a new block.
1168f4a2713aSLionel Sambuc     } else {
1169f4a2713aSLionel Sambuc       nextBlock = CGF.createBasicBlock("catch.fallthrough");
1170f4a2713aSLionel Sambuc       nextIsEnd = false;
1171f4a2713aSLionel Sambuc     }
1172f4a2713aSLionel Sambuc 
1173f4a2713aSLionel Sambuc     // Figure out the catch type's index in the LSDA's type table.
1174f4a2713aSLionel Sambuc     llvm::CallInst *typeIndex =
1175f4a2713aSLionel Sambuc       CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1176f4a2713aSLionel Sambuc     typeIndex->setDoesNotThrow();
1177f4a2713aSLionel Sambuc 
1178f4a2713aSLionel Sambuc     llvm::Value *matchesTypeIndex =
1179f4a2713aSLionel Sambuc       CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
1180f4a2713aSLionel Sambuc     CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
1181f4a2713aSLionel Sambuc 
1182f4a2713aSLionel Sambuc     // If the next handler is a catch-all, we're completely done.
1183f4a2713aSLionel Sambuc     if (nextIsEnd) {
1184f4a2713aSLionel Sambuc       CGF.Builder.restoreIP(savedIP);
1185f4a2713aSLionel Sambuc       return;
1186f4a2713aSLionel Sambuc     }
1187f4a2713aSLionel Sambuc     // Otherwise we need to emit and continue at that block.
1188f4a2713aSLionel Sambuc     CGF.EmitBlock(nextBlock);
1189f4a2713aSLionel Sambuc   }
1190f4a2713aSLionel Sambuc }
1191f4a2713aSLionel Sambuc 
popCatchScope()1192f4a2713aSLionel Sambuc void CodeGenFunction::popCatchScope() {
1193f4a2713aSLionel Sambuc   EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1194f4a2713aSLionel Sambuc   if (catchScope.hasEHBranches())
1195f4a2713aSLionel Sambuc     emitCatchDispatchBlock(*this, catchScope);
1196f4a2713aSLionel Sambuc   EHStack.popCatch();
1197f4a2713aSLionel Sambuc }
1198f4a2713aSLionel Sambuc 
ExitCXXTryStmt(const CXXTryStmt & S,bool IsFnTryBlock)1199f4a2713aSLionel Sambuc void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1200f4a2713aSLionel Sambuc   unsigned NumHandlers = S.getNumHandlers();
1201f4a2713aSLionel Sambuc   EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1202f4a2713aSLionel Sambuc   assert(CatchScope.getNumHandlers() == NumHandlers);
1203f4a2713aSLionel Sambuc 
1204f4a2713aSLionel Sambuc   // If the catch was not required, bail out now.
1205f4a2713aSLionel Sambuc   if (!CatchScope.hasEHBranches()) {
1206*0a6a1f1dSLionel Sambuc     CatchScope.clearHandlerBlocks();
1207f4a2713aSLionel Sambuc     EHStack.popCatch();
1208f4a2713aSLionel Sambuc     return;
1209f4a2713aSLionel Sambuc   }
1210f4a2713aSLionel Sambuc 
1211f4a2713aSLionel Sambuc   // Emit the structure of the EH dispatch for this catch.
1212f4a2713aSLionel Sambuc   emitCatchDispatchBlock(*this, CatchScope);
1213f4a2713aSLionel Sambuc 
1214f4a2713aSLionel Sambuc   // Copy the handler blocks off before we pop the EH stack.  Emitting
1215f4a2713aSLionel Sambuc   // the handlers might scribble on this memory.
1216f4a2713aSLionel Sambuc   SmallVector<EHCatchScope::Handler, 8> Handlers(NumHandlers);
1217f4a2713aSLionel Sambuc   memcpy(Handlers.data(), CatchScope.begin(),
1218f4a2713aSLionel Sambuc          NumHandlers * sizeof(EHCatchScope::Handler));
1219f4a2713aSLionel Sambuc 
1220f4a2713aSLionel Sambuc   EHStack.popCatch();
1221f4a2713aSLionel Sambuc 
1222f4a2713aSLionel Sambuc   // The fall-through block.
1223f4a2713aSLionel Sambuc   llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1224f4a2713aSLionel Sambuc 
1225f4a2713aSLionel Sambuc   // We just emitted the body of the try; jump to the continue block.
1226f4a2713aSLionel Sambuc   if (HaveInsertPoint())
1227f4a2713aSLionel Sambuc     Builder.CreateBr(ContBB);
1228f4a2713aSLionel Sambuc 
1229f4a2713aSLionel Sambuc   // Determine if we need an implicit rethrow for all these catch handlers;
1230f4a2713aSLionel Sambuc   // see the comment below.
1231f4a2713aSLionel Sambuc   bool doImplicitRethrow = false;
1232f4a2713aSLionel Sambuc   if (IsFnTryBlock)
1233f4a2713aSLionel Sambuc     doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1234f4a2713aSLionel Sambuc                         isa<CXXConstructorDecl>(CurCodeDecl);
1235f4a2713aSLionel Sambuc 
1236f4a2713aSLionel Sambuc   // Perversely, we emit the handlers backwards precisely because we
1237f4a2713aSLionel Sambuc   // want them to appear in source order.  In all of these cases, the
1238f4a2713aSLionel Sambuc   // catch block will have exactly one predecessor, which will be a
1239f4a2713aSLionel Sambuc   // particular block in the catch dispatch.  However, in the case of
1240f4a2713aSLionel Sambuc   // a catch-all, one of the dispatch blocks will branch to two
1241f4a2713aSLionel Sambuc   // different handlers, and EmitBlockAfterUses will cause the second
1242f4a2713aSLionel Sambuc   // handler to be moved before the first.
1243f4a2713aSLionel Sambuc   for (unsigned I = NumHandlers; I != 0; --I) {
1244f4a2713aSLionel Sambuc     llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1245f4a2713aSLionel Sambuc     EmitBlockAfterUses(CatchBlock);
1246f4a2713aSLionel Sambuc 
1247f4a2713aSLionel Sambuc     // Catch the exception if this isn't a catch-all.
1248f4a2713aSLionel Sambuc     const CXXCatchStmt *C = S.getHandler(I-1);
1249f4a2713aSLionel Sambuc 
1250f4a2713aSLionel Sambuc     // Enter a cleanup scope, including the catch variable and the
1251f4a2713aSLionel Sambuc     // end-catch.
1252f4a2713aSLionel Sambuc     RunCleanupsScope CatchScope(*this);
1253f4a2713aSLionel Sambuc 
1254f4a2713aSLionel Sambuc     // Initialize the catch variable and set up the cleanups.
1255f4a2713aSLionel Sambuc     BeginCatch(*this, C);
1256f4a2713aSLionel Sambuc 
1257*0a6a1f1dSLionel Sambuc     // Emit the PGO counter increment.
1258*0a6a1f1dSLionel Sambuc     RegionCounter CatchCnt = getPGORegionCounter(C);
1259*0a6a1f1dSLionel Sambuc     CatchCnt.beginRegion(Builder);
1260*0a6a1f1dSLionel Sambuc 
1261f4a2713aSLionel Sambuc     // Perform the body of the catch.
1262f4a2713aSLionel Sambuc     EmitStmt(C->getHandlerBlock());
1263f4a2713aSLionel Sambuc 
1264f4a2713aSLionel Sambuc     // [except.handle]p11:
1265f4a2713aSLionel Sambuc     //   The currently handled exception is rethrown if control
1266f4a2713aSLionel Sambuc     //   reaches the end of a handler of the function-try-block of a
1267f4a2713aSLionel Sambuc     //   constructor or destructor.
1268f4a2713aSLionel Sambuc 
1269f4a2713aSLionel Sambuc     // It is important that we only do this on fallthrough and not on
1270f4a2713aSLionel Sambuc     // return.  Note that it's illegal to put a return in a
1271f4a2713aSLionel Sambuc     // constructor function-try-block's catch handler (p14), so this
1272f4a2713aSLionel Sambuc     // really only applies to destructors.
1273f4a2713aSLionel Sambuc     if (doImplicitRethrow && HaveInsertPoint()) {
1274*0a6a1f1dSLionel Sambuc       CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1275f4a2713aSLionel Sambuc       Builder.CreateUnreachable();
1276f4a2713aSLionel Sambuc       Builder.ClearInsertionPoint();
1277f4a2713aSLionel Sambuc     }
1278f4a2713aSLionel Sambuc 
1279f4a2713aSLionel Sambuc     // Fall out through the catch cleanups.
1280f4a2713aSLionel Sambuc     CatchScope.ForceCleanup();
1281f4a2713aSLionel Sambuc 
1282f4a2713aSLionel Sambuc     // Branch out of the try.
1283f4a2713aSLionel Sambuc     if (HaveInsertPoint())
1284f4a2713aSLionel Sambuc       Builder.CreateBr(ContBB);
1285f4a2713aSLionel Sambuc   }
1286f4a2713aSLionel Sambuc 
1287*0a6a1f1dSLionel Sambuc   RegionCounter ContCnt = getPGORegionCounter(&S);
1288f4a2713aSLionel Sambuc   EmitBlock(ContBB);
1289*0a6a1f1dSLionel Sambuc   ContCnt.beginRegion(Builder);
1290f4a2713aSLionel Sambuc }
1291f4a2713aSLionel Sambuc 
1292f4a2713aSLionel Sambuc namespace {
1293f4a2713aSLionel Sambuc   struct CallEndCatchForFinally : EHScopeStack::Cleanup {
1294f4a2713aSLionel Sambuc     llvm::Value *ForEHVar;
1295f4a2713aSLionel Sambuc     llvm::Value *EndCatchFn;
CallEndCatchForFinally__anon2995a1420411::CallEndCatchForFinally1296f4a2713aSLionel Sambuc     CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
1297f4a2713aSLionel Sambuc       : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1298f4a2713aSLionel Sambuc 
Emit__anon2995a1420411::CallEndCatchForFinally1299*0a6a1f1dSLionel Sambuc     void Emit(CodeGenFunction &CGF, Flags flags) override {
1300f4a2713aSLionel Sambuc       llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1301f4a2713aSLionel Sambuc       llvm::BasicBlock *CleanupContBB =
1302f4a2713aSLionel Sambuc         CGF.createBasicBlock("finally.cleanup.cont");
1303f4a2713aSLionel Sambuc 
1304f4a2713aSLionel Sambuc       llvm::Value *ShouldEndCatch =
1305f4a2713aSLionel Sambuc         CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch");
1306f4a2713aSLionel Sambuc       CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1307f4a2713aSLionel Sambuc       CGF.EmitBlock(EndCatchBB);
1308f4a2713aSLionel Sambuc       CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1309f4a2713aSLionel Sambuc       CGF.EmitBlock(CleanupContBB);
1310f4a2713aSLionel Sambuc     }
1311f4a2713aSLionel Sambuc   };
1312f4a2713aSLionel Sambuc 
1313f4a2713aSLionel Sambuc   struct PerformFinally : EHScopeStack::Cleanup {
1314f4a2713aSLionel Sambuc     const Stmt *Body;
1315f4a2713aSLionel Sambuc     llvm::Value *ForEHVar;
1316f4a2713aSLionel Sambuc     llvm::Value *EndCatchFn;
1317f4a2713aSLionel Sambuc     llvm::Value *RethrowFn;
1318f4a2713aSLionel Sambuc     llvm::Value *SavedExnVar;
1319f4a2713aSLionel Sambuc 
PerformFinally__anon2995a1420411::PerformFinally1320f4a2713aSLionel Sambuc     PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1321f4a2713aSLionel Sambuc                    llvm::Value *EndCatchFn,
1322f4a2713aSLionel Sambuc                    llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
1323f4a2713aSLionel Sambuc       : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1324f4a2713aSLionel Sambuc         RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1325f4a2713aSLionel Sambuc 
Emit__anon2995a1420411::PerformFinally1326*0a6a1f1dSLionel Sambuc     void Emit(CodeGenFunction &CGF, Flags flags) override {
1327f4a2713aSLionel Sambuc       // Enter a cleanup to call the end-catch function if one was provided.
1328f4a2713aSLionel Sambuc       if (EndCatchFn)
1329f4a2713aSLionel Sambuc         CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1330f4a2713aSLionel Sambuc                                                         ForEHVar, EndCatchFn);
1331f4a2713aSLionel Sambuc 
1332f4a2713aSLionel Sambuc       // Save the current cleanup destination in case there are
1333f4a2713aSLionel Sambuc       // cleanups in the finally block.
1334f4a2713aSLionel Sambuc       llvm::Value *SavedCleanupDest =
1335f4a2713aSLionel Sambuc         CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),
1336f4a2713aSLionel Sambuc                                "cleanup.dest.saved");
1337f4a2713aSLionel Sambuc 
1338f4a2713aSLionel Sambuc       // Emit the finally block.
1339f4a2713aSLionel Sambuc       CGF.EmitStmt(Body);
1340f4a2713aSLionel Sambuc 
1341f4a2713aSLionel Sambuc       // If the end of the finally is reachable, check whether this was
1342f4a2713aSLionel Sambuc       // for EH.  If so, rethrow.
1343f4a2713aSLionel Sambuc       if (CGF.HaveInsertPoint()) {
1344f4a2713aSLionel Sambuc         llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1345f4a2713aSLionel Sambuc         llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1346f4a2713aSLionel Sambuc 
1347f4a2713aSLionel Sambuc         llvm::Value *ShouldRethrow =
1348f4a2713aSLionel Sambuc           CGF.Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
1349f4a2713aSLionel Sambuc         CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1350f4a2713aSLionel Sambuc 
1351f4a2713aSLionel Sambuc         CGF.EmitBlock(RethrowBB);
1352f4a2713aSLionel Sambuc         if (SavedExnVar) {
1353f4a2713aSLionel Sambuc           CGF.EmitRuntimeCallOrInvoke(RethrowFn,
1354f4a2713aSLionel Sambuc                                       CGF.Builder.CreateLoad(SavedExnVar));
1355f4a2713aSLionel Sambuc         } else {
1356f4a2713aSLionel Sambuc           CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1357f4a2713aSLionel Sambuc         }
1358f4a2713aSLionel Sambuc         CGF.Builder.CreateUnreachable();
1359f4a2713aSLionel Sambuc 
1360f4a2713aSLionel Sambuc         CGF.EmitBlock(ContBB);
1361f4a2713aSLionel Sambuc 
1362f4a2713aSLionel Sambuc         // Restore the cleanup destination.
1363f4a2713aSLionel Sambuc         CGF.Builder.CreateStore(SavedCleanupDest,
1364f4a2713aSLionel Sambuc                                 CGF.getNormalCleanupDestSlot());
1365f4a2713aSLionel Sambuc       }
1366f4a2713aSLionel Sambuc 
1367f4a2713aSLionel Sambuc       // Leave the end-catch cleanup.  As an optimization, pretend that
1368f4a2713aSLionel Sambuc       // the fallthrough path was inaccessible; we've dynamically proven
1369f4a2713aSLionel Sambuc       // that we're not in the EH case along that path.
1370f4a2713aSLionel Sambuc       if (EndCatchFn) {
1371f4a2713aSLionel Sambuc         CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1372f4a2713aSLionel Sambuc         CGF.PopCleanupBlock();
1373f4a2713aSLionel Sambuc         CGF.Builder.restoreIP(SavedIP);
1374f4a2713aSLionel Sambuc       }
1375f4a2713aSLionel Sambuc 
1376f4a2713aSLionel Sambuc       // Now make sure we actually have an insertion point or the
1377f4a2713aSLionel Sambuc       // cleanup gods will hate us.
1378f4a2713aSLionel Sambuc       CGF.EnsureInsertPoint();
1379f4a2713aSLionel Sambuc     }
1380f4a2713aSLionel Sambuc   };
1381f4a2713aSLionel Sambuc }
1382f4a2713aSLionel Sambuc 
1383f4a2713aSLionel Sambuc /// Enters a finally block for an implementation using zero-cost
1384f4a2713aSLionel Sambuc /// exceptions.  This is mostly general, but hard-codes some
1385f4a2713aSLionel Sambuc /// language/ABI-specific behavior in the catch-all sections.
enter(CodeGenFunction & CGF,const Stmt * body,llvm::Constant * beginCatchFn,llvm::Constant * endCatchFn,llvm::Constant * rethrowFn)1386f4a2713aSLionel Sambuc void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
1387f4a2713aSLionel Sambuc                                          const Stmt *body,
1388f4a2713aSLionel Sambuc                                          llvm::Constant *beginCatchFn,
1389f4a2713aSLionel Sambuc                                          llvm::Constant *endCatchFn,
1390f4a2713aSLionel Sambuc                                          llvm::Constant *rethrowFn) {
1391*0a6a1f1dSLionel Sambuc   assert((beginCatchFn != nullptr) == (endCatchFn != nullptr) &&
1392f4a2713aSLionel Sambuc          "begin/end catch functions not paired");
1393f4a2713aSLionel Sambuc   assert(rethrowFn && "rethrow function is required");
1394f4a2713aSLionel Sambuc 
1395f4a2713aSLionel Sambuc   BeginCatchFn = beginCatchFn;
1396f4a2713aSLionel Sambuc 
1397f4a2713aSLionel Sambuc   // The rethrow function has one of the following two types:
1398f4a2713aSLionel Sambuc   //   void (*)()
1399f4a2713aSLionel Sambuc   //   void (*)(void*)
1400f4a2713aSLionel Sambuc   // In the latter case we need to pass it the exception object.
1401f4a2713aSLionel Sambuc   // But we can't use the exception slot because the @finally might
1402f4a2713aSLionel Sambuc   // have a landing pad (which would overwrite the exception slot).
1403f4a2713aSLionel Sambuc   llvm::FunctionType *rethrowFnTy =
1404f4a2713aSLionel Sambuc     cast<llvm::FunctionType>(
1405f4a2713aSLionel Sambuc       cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
1406*0a6a1f1dSLionel Sambuc   SavedExnVar = nullptr;
1407f4a2713aSLionel Sambuc   if (rethrowFnTy->getNumParams())
1408f4a2713aSLionel Sambuc     SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1409f4a2713aSLionel Sambuc 
1410f4a2713aSLionel Sambuc   // A finally block is a statement which must be executed on any edge
1411f4a2713aSLionel Sambuc   // out of a given scope.  Unlike a cleanup, the finally block may
1412f4a2713aSLionel Sambuc   // contain arbitrary control flow leading out of itself.  In
1413f4a2713aSLionel Sambuc   // addition, finally blocks should always be executed, even if there
1414f4a2713aSLionel Sambuc   // are no catch handlers higher on the stack.  Therefore, we
1415f4a2713aSLionel Sambuc   // surround the protected scope with a combination of a normal
1416f4a2713aSLionel Sambuc   // cleanup (to catch attempts to break out of the block via normal
1417f4a2713aSLionel Sambuc   // control flow) and an EH catch-all (semantically "outside" any try
1418f4a2713aSLionel Sambuc   // statement to which the finally block might have been attached).
1419f4a2713aSLionel Sambuc   // The finally block itself is generated in the context of a cleanup
1420f4a2713aSLionel Sambuc   // which conditionally leaves the catch-all.
1421f4a2713aSLionel Sambuc 
1422f4a2713aSLionel Sambuc   // Jump destination for performing the finally block on an exception
1423f4a2713aSLionel Sambuc   // edge.  We'll never actually reach this block, so unreachable is
1424f4a2713aSLionel Sambuc   // fine.
1425f4a2713aSLionel Sambuc   RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1426f4a2713aSLionel Sambuc 
1427f4a2713aSLionel Sambuc   // Whether the finally block is being executed for EH purposes.
1428f4a2713aSLionel Sambuc   ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1429f4a2713aSLionel Sambuc   CGF.Builder.CreateStore(CGF.Builder.getFalse(), ForEHVar);
1430f4a2713aSLionel Sambuc 
1431f4a2713aSLionel Sambuc   // Enter a normal cleanup which will perform the @finally block.
1432f4a2713aSLionel Sambuc   CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1433f4a2713aSLionel Sambuc                                           ForEHVar, endCatchFn,
1434f4a2713aSLionel Sambuc                                           rethrowFn, SavedExnVar);
1435f4a2713aSLionel Sambuc 
1436f4a2713aSLionel Sambuc   // Enter a catch-all scope.
1437f4a2713aSLionel Sambuc   llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1438f4a2713aSLionel Sambuc   EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1439f4a2713aSLionel Sambuc   catchScope->setCatchAllHandler(0, catchBB);
1440f4a2713aSLionel Sambuc }
1441f4a2713aSLionel Sambuc 
exit(CodeGenFunction & CGF)1442f4a2713aSLionel Sambuc void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1443f4a2713aSLionel Sambuc   // Leave the finally catch-all.
1444f4a2713aSLionel Sambuc   EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1445f4a2713aSLionel Sambuc   llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1446f4a2713aSLionel Sambuc 
1447f4a2713aSLionel Sambuc   CGF.popCatchScope();
1448f4a2713aSLionel Sambuc 
1449f4a2713aSLionel Sambuc   // If there are any references to the catch-all block, emit it.
1450f4a2713aSLionel Sambuc   if (catchBB->use_empty()) {
1451f4a2713aSLionel Sambuc     delete catchBB;
1452f4a2713aSLionel Sambuc   } else {
1453f4a2713aSLionel Sambuc     CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1454f4a2713aSLionel Sambuc     CGF.EmitBlock(catchBB);
1455f4a2713aSLionel Sambuc 
1456*0a6a1f1dSLionel Sambuc     llvm::Value *exn = nullptr;
1457f4a2713aSLionel Sambuc 
1458f4a2713aSLionel Sambuc     // If there's a begin-catch function, call it.
1459f4a2713aSLionel Sambuc     if (BeginCatchFn) {
1460f4a2713aSLionel Sambuc       exn = CGF.getExceptionFromSlot();
1461f4a2713aSLionel Sambuc       CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1462f4a2713aSLionel Sambuc     }
1463f4a2713aSLionel Sambuc 
1464f4a2713aSLionel Sambuc     // If we need to remember the exception pointer to rethrow later, do so.
1465f4a2713aSLionel Sambuc     if (SavedExnVar) {
1466f4a2713aSLionel Sambuc       if (!exn) exn = CGF.getExceptionFromSlot();
1467f4a2713aSLionel Sambuc       CGF.Builder.CreateStore(exn, SavedExnVar);
1468f4a2713aSLionel Sambuc     }
1469f4a2713aSLionel Sambuc 
1470f4a2713aSLionel Sambuc     // Tell the cleanups in the finally block that we're do this for EH.
1471f4a2713aSLionel Sambuc     CGF.Builder.CreateStore(CGF.Builder.getTrue(), ForEHVar);
1472f4a2713aSLionel Sambuc 
1473f4a2713aSLionel Sambuc     // Thread a jump through the finally cleanup.
1474f4a2713aSLionel Sambuc     CGF.EmitBranchThroughCleanup(RethrowDest);
1475f4a2713aSLionel Sambuc 
1476f4a2713aSLionel Sambuc     CGF.Builder.restoreIP(savedIP);
1477f4a2713aSLionel Sambuc   }
1478f4a2713aSLionel Sambuc 
1479f4a2713aSLionel Sambuc   // Finally, leave the @finally cleanup.
1480f4a2713aSLionel Sambuc   CGF.PopCleanupBlock();
1481f4a2713aSLionel Sambuc }
1482f4a2713aSLionel Sambuc 
1483f4a2713aSLionel Sambuc /// In a terminate landing pad, should we use __clang__call_terminate
1484f4a2713aSLionel Sambuc /// or just a naked call to std::terminate?
1485f4a2713aSLionel Sambuc ///
1486f4a2713aSLionel Sambuc /// __clang_call_terminate calls __cxa_begin_catch, which then allows
1487f4a2713aSLionel Sambuc /// std::terminate to usefully report something about the
1488f4a2713aSLionel Sambuc /// violating exception.
useClangCallTerminate(CodeGenModule & CGM)1489f4a2713aSLionel Sambuc static bool useClangCallTerminate(CodeGenModule &CGM) {
1490f4a2713aSLionel Sambuc   // Only do this for Itanium-family ABIs in C++ mode.
1491f4a2713aSLionel Sambuc   return (CGM.getLangOpts().CPlusPlus &&
1492f4a2713aSLionel Sambuc           CGM.getTarget().getCXXABI().isItaniumFamily());
1493f4a2713aSLionel Sambuc }
1494f4a2713aSLionel Sambuc 
1495f4a2713aSLionel Sambuc /// Get or define the following function:
1496f4a2713aSLionel Sambuc ///   void @__clang_call_terminate(i8* %exn) nounwind noreturn
1497f4a2713aSLionel Sambuc /// This code is used only in C++.
getClangCallTerminateFn(CodeGenModule & CGM)1498f4a2713aSLionel Sambuc static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) {
1499f4a2713aSLionel Sambuc   llvm::FunctionType *fnTy =
1500f4a2713aSLionel Sambuc     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
1501f4a2713aSLionel Sambuc   llvm::Constant *fnRef =
1502f4a2713aSLionel Sambuc     CGM.CreateRuntimeFunction(fnTy, "__clang_call_terminate");
1503f4a2713aSLionel Sambuc 
1504f4a2713aSLionel Sambuc   llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
1505f4a2713aSLionel Sambuc   if (fn && fn->empty()) {
1506f4a2713aSLionel Sambuc     fn->setDoesNotThrow();
1507f4a2713aSLionel Sambuc     fn->setDoesNotReturn();
1508f4a2713aSLionel Sambuc 
1509f4a2713aSLionel Sambuc     // What we really want is to massively penalize inlining without
1510f4a2713aSLionel Sambuc     // forbidding it completely.  The difference between that and
1511f4a2713aSLionel Sambuc     // 'noinline' is negligible.
1512f4a2713aSLionel Sambuc     fn->addFnAttr(llvm::Attribute::NoInline);
1513f4a2713aSLionel Sambuc 
1514f4a2713aSLionel Sambuc     // Allow this function to be shared across translation units, but
1515f4a2713aSLionel Sambuc     // we don't want it to turn into an exported symbol.
1516f4a2713aSLionel Sambuc     fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
1517f4a2713aSLionel Sambuc     fn->setVisibility(llvm::Function::HiddenVisibility);
1518f4a2713aSLionel Sambuc 
1519f4a2713aSLionel Sambuc     // Set up the function.
1520f4a2713aSLionel Sambuc     llvm::BasicBlock *entry =
1521f4a2713aSLionel Sambuc       llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn);
1522f4a2713aSLionel Sambuc     CGBuilderTy builder(entry);
1523f4a2713aSLionel Sambuc 
1524f4a2713aSLionel Sambuc     // Pull the exception pointer out of the parameter list.
1525f4a2713aSLionel Sambuc     llvm::Value *exn = &*fn->arg_begin();
1526f4a2713aSLionel Sambuc 
1527f4a2713aSLionel Sambuc     // Call __cxa_begin_catch(exn).
1528f4a2713aSLionel Sambuc     llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn);
1529f4a2713aSLionel Sambuc     catchCall->setDoesNotThrow();
1530f4a2713aSLionel Sambuc     catchCall->setCallingConv(CGM.getRuntimeCC());
1531f4a2713aSLionel Sambuc 
1532f4a2713aSLionel Sambuc     // Call std::terminate().
1533f4a2713aSLionel Sambuc     llvm::CallInst *termCall = builder.CreateCall(getTerminateFn(CGM));
1534f4a2713aSLionel Sambuc     termCall->setDoesNotThrow();
1535f4a2713aSLionel Sambuc     termCall->setDoesNotReturn();
1536f4a2713aSLionel Sambuc     termCall->setCallingConv(CGM.getRuntimeCC());
1537f4a2713aSLionel Sambuc 
1538f4a2713aSLionel Sambuc     // std::terminate cannot return.
1539f4a2713aSLionel Sambuc     builder.CreateUnreachable();
1540f4a2713aSLionel Sambuc   }
1541f4a2713aSLionel Sambuc 
1542f4a2713aSLionel Sambuc   return fnRef;
1543f4a2713aSLionel Sambuc }
1544f4a2713aSLionel Sambuc 
getTerminateLandingPad()1545f4a2713aSLionel Sambuc llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
1546f4a2713aSLionel Sambuc   if (TerminateLandingPad)
1547f4a2713aSLionel Sambuc     return TerminateLandingPad;
1548f4a2713aSLionel Sambuc 
1549f4a2713aSLionel Sambuc   CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1550f4a2713aSLionel Sambuc 
1551f4a2713aSLionel Sambuc   // This will get inserted at the end of the function.
1552f4a2713aSLionel Sambuc   TerminateLandingPad = createBasicBlock("terminate.lpad");
1553f4a2713aSLionel Sambuc   Builder.SetInsertPoint(TerminateLandingPad);
1554f4a2713aSLionel Sambuc 
1555f4a2713aSLionel Sambuc   // Tell the backend that this is a landing pad.
1556*0a6a1f1dSLionel Sambuc   const EHPersonality &Personality = EHPersonality::get(CGM);
1557f4a2713aSLionel Sambuc   llvm::LandingPadInst *LPadInst =
1558*0a6a1f1dSLionel Sambuc     Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr),
1559f4a2713aSLionel Sambuc                              getOpaquePersonalityFn(CGM, Personality), 0);
1560f4a2713aSLionel Sambuc   LPadInst->addClause(getCatchAllValue(*this));
1561f4a2713aSLionel Sambuc 
1562f4a2713aSLionel Sambuc   llvm::CallInst *terminateCall;
1563f4a2713aSLionel Sambuc   if (useClangCallTerminate(CGM)) {
1564f4a2713aSLionel Sambuc     // Extract out the exception pointer.
1565f4a2713aSLionel Sambuc     llvm::Value *exn = Builder.CreateExtractValue(LPadInst, 0);
1566f4a2713aSLionel Sambuc     terminateCall = EmitNounwindRuntimeCall(getClangCallTerminateFn(CGM), exn);
1567f4a2713aSLionel Sambuc   } else {
1568f4a2713aSLionel Sambuc     terminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM));
1569f4a2713aSLionel Sambuc   }
1570f4a2713aSLionel Sambuc   terminateCall->setDoesNotReturn();
1571f4a2713aSLionel Sambuc   Builder.CreateUnreachable();
1572f4a2713aSLionel Sambuc 
1573f4a2713aSLionel Sambuc   // Restore the saved insertion state.
1574f4a2713aSLionel Sambuc   Builder.restoreIP(SavedIP);
1575f4a2713aSLionel Sambuc 
1576f4a2713aSLionel Sambuc   return TerminateLandingPad;
1577f4a2713aSLionel Sambuc }
1578f4a2713aSLionel Sambuc 
getTerminateHandler()1579f4a2713aSLionel Sambuc llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
1580f4a2713aSLionel Sambuc   if (TerminateHandler)
1581f4a2713aSLionel Sambuc     return TerminateHandler;
1582f4a2713aSLionel Sambuc 
1583f4a2713aSLionel Sambuc   CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1584f4a2713aSLionel Sambuc 
1585f4a2713aSLionel Sambuc   // Set up the terminate handler.  This block is inserted at the very
1586f4a2713aSLionel Sambuc   // end of the function by FinishFunction.
1587f4a2713aSLionel Sambuc   TerminateHandler = createBasicBlock("terminate.handler");
1588f4a2713aSLionel Sambuc   Builder.SetInsertPoint(TerminateHandler);
1589f4a2713aSLionel Sambuc   llvm::CallInst *terminateCall;
1590f4a2713aSLionel Sambuc   if (useClangCallTerminate(CGM)) {
1591f4a2713aSLionel Sambuc     // Load the exception pointer.
1592f4a2713aSLionel Sambuc     llvm::Value *exn = getExceptionFromSlot();
1593f4a2713aSLionel Sambuc     terminateCall = EmitNounwindRuntimeCall(getClangCallTerminateFn(CGM), exn);
1594f4a2713aSLionel Sambuc   } else {
1595f4a2713aSLionel Sambuc     terminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM));
1596f4a2713aSLionel Sambuc   }
1597f4a2713aSLionel Sambuc   terminateCall->setDoesNotReturn();
1598f4a2713aSLionel Sambuc   Builder.CreateUnreachable();
1599f4a2713aSLionel Sambuc 
1600f4a2713aSLionel Sambuc   // Restore the saved insertion state.
1601f4a2713aSLionel Sambuc   Builder.restoreIP(SavedIP);
1602f4a2713aSLionel Sambuc 
1603f4a2713aSLionel Sambuc   return TerminateHandler;
1604f4a2713aSLionel Sambuc }
1605f4a2713aSLionel Sambuc 
getEHResumeBlock(bool isCleanup)1606f4a2713aSLionel Sambuc llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1607f4a2713aSLionel Sambuc   if (EHResumeBlock) return EHResumeBlock;
1608f4a2713aSLionel Sambuc 
1609f4a2713aSLionel Sambuc   CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1610f4a2713aSLionel Sambuc 
1611f4a2713aSLionel Sambuc   // We emit a jump to a notional label at the outermost unwind state.
1612f4a2713aSLionel Sambuc   EHResumeBlock = createBasicBlock("eh.resume");
1613f4a2713aSLionel Sambuc   Builder.SetInsertPoint(EHResumeBlock);
1614f4a2713aSLionel Sambuc 
1615*0a6a1f1dSLionel Sambuc   const EHPersonality &Personality = EHPersonality::get(CGM);
1616f4a2713aSLionel Sambuc 
1617f4a2713aSLionel Sambuc   // This can always be a call because we necessarily didn't find
1618f4a2713aSLionel Sambuc   // anything on the EH stack which needs our help.
1619f4a2713aSLionel Sambuc   const char *RethrowName = Personality.CatchallRethrowFn;
1620*0a6a1f1dSLionel Sambuc   if (RethrowName != nullptr && !isCleanup) {
1621f4a2713aSLionel Sambuc     EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),
1622f4a2713aSLionel Sambuc                     getExceptionFromSlot())
1623f4a2713aSLionel Sambuc       ->setDoesNotReturn();
1624*0a6a1f1dSLionel Sambuc     Builder.CreateUnreachable();
1625*0a6a1f1dSLionel Sambuc     Builder.restoreIP(SavedIP);
1626*0a6a1f1dSLionel Sambuc     return EHResumeBlock;
1627*0a6a1f1dSLionel Sambuc   }
1628f4a2713aSLionel Sambuc 
1629f4a2713aSLionel Sambuc   // Recreate the landingpad's return value for the 'resume' instruction.
1630f4a2713aSLionel Sambuc   llvm::Value *Exn = getExceptionFromSlot();
1631f4a2713aSLionel Sambuc   llvm::Value *Sel = getSelectorFromSlot();
1632f4a2713aSLionel Sambuc 
1633f4a2713aSLionel Sambuc   llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1634*0a6a1f1dSLionel Sambuc                                                Sel->getType(), nullptr);
1635f4a2713aSLionel Sambuc   llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1636f4a2713aSLionel Sambuc   LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1637f4a2713aSLionel Sambuc   LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1638f4a2713aSLionel Sambuc 
1639f4a2713aSLionel Sambuc   Builder.CreateResume(LPadVal);
1640f4a2713aSLionel Sambuc   Builder.restoreIP(SavedIP);
1641f4a2713aSLionel Sambuc   return EHResumeBlock;
1642f4a2713aSLionel Sambuc }
1643f4a2713aSLionel Sambuc 
EmitSEHTryStmt(const SEHTryStmt & S)1644f4a2713aSLionel Sambuc void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
1645f4a2713aSLionel Sambuc   CGM.ErrorUnsupported(&S, "SEH __try");
1646f4a2713aSLionel Sambuc }
1647*0a6a1f1dSLionel Sambuc 
EmitSEHLeaveStmt(const SEHLeaveStmt & S)1648*0a6a1f1dSLionel Sambuc void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {
1649*0a6a1f1dSLionel Sambuc   CGM.ErrorUnsupported(&S, "SEH __leave");
1650*0a6a1f1dSLionel Sambuc }
1651