clang 24.0.0git
CGException.cpp
Go to the documentation of this file.
1//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with C++ exception related code generation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGCXXABI.h"
14#include "CGCleanup.h"
15#include "CGDebugInfo.h"
16#include "CGObjCRuntime.h"
17#include "CodeGenFunction.h"
18#include "ConstantEmitter.h"
19#include "TargetInfo.h"
20#include "clang/AST/Mangle.h"
21#include "clang/AST/StmtCXX.h"
22#include "clang/AST/StmtObjC.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsWebAssembly.h"
28#include "llvm/Support/SaveAndRestore.h"
29
30using namespace clang;
31using namespace CodeGen;
32
33static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM) {
34 // void __cxa_free_exception(void *thrown_exception);
35
36 llvm::FunctionType *FTy =
37 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
38
39 return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
40}
41
42static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM) {
43 llvm::FunctionType *FTy =
44 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
45 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");
46}
47
48static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM) {
49 llvm::FunctionType *FTy =
50 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
51 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");
52}
53
54static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {
55 // void __cxa_call_unexpected(void *thrown_exception);
56
57 llvm::FunctionType *FTy =
58 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
59
60 return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
61}
62
63llvm::FunctionCallee CodeGenModule::getTerminateFn() {
64 // void __terminate();
65
66 llvm::FunctionType *FTy =
67 llvm::FunctionType::get(VoidTy, /*isVarArg=*/false);
68
69 StringRef name;
70
71 // In C++, use std::terminate().
72 if (getLangOpts().CPlusPlus &&
73 getTarget().getCXXABI().isItaniumFamily()) {
74 name = "_ZSt9terminatev";
75 } else if (getLangOpts().CPlusPlus &&
76 getTarget().getCXXABI().isMicrosoft()) {
77 if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
78 name = "__std_terminate";
79 else
80 name = "?terminate@@YAXXZ";
81 } else if (getLangOpts().ObjC &&
82 getLangOpts().ObjCRuntime.hasTerminate())
83 name = "objc_terminate";
84 else
85 name = "abort";
86 return CreateRuntimeFunction(FTy, name);
87}
88
89static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,
90 StringRef Name) {
91 llvm::FunctionType *FTy =
92 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
93
94 return CGM.CreateRuntimeFunction(FTy, Name);
95}
96
97const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
98const EHPersonality
99EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
100const EHPersonality
101EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
102const EHPersonality
103EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
104const EHPersonality
105EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
106const EHPersonality
107EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
108const EHPersonality
109EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
110const EHPersonality
111EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
112const EHPersonality
113EHPersonality::GNU_ObjC_SJLJ = {"__gnu_objc_personality_sj0", "objc_exception_throw"};
114const EHPersonality
115EHPersonality::GNU_ObjC_SEH = {"__gnu_objc_personality_seh0", "objc_exception_throw"};
116const EHPersonality
117EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
118const EHPersonality
119EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
120const EHPersonality
121EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
122const EHPersonality
123EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
124const EHPersonality
125EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
126const EHPersonality
127EHPersonality::GNU_Wasm_CPlusPlus = { "__gxx_wasm_personality_v0", nullptr };
128const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
129 nullptr};
130const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
131 nullptr};
132
134 const CodeGenOptions &CGOpts) {
135 const llvm::Triple &T = Target.getTriple();
136 if (T.isWindowsMSVCEnvironment())
138 if (CGOpts.hasSjLjExceptions())
140 if (CGOpts.hasDWARFExceptions())
142 if (CGOpts.hasSEHExceptions())
145}
146
148 const CodeGenOptions &CGOpts,
149 const LangOptions &L) {
150 const llvm::Triple &T = Target.getTriple();
151 if (T.isWindowsMSVCEnvironment())
153 if (T.isWasm())
155
156 switch (L.ObjCRuntime.getKind()) {
158 return getCPersonality(Target, CGOpts);
160 case ObjCRuntime::iOS:
164 if (T.isOSCygMing())
166 if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
168 [[fallthrough]];
169 case ObjCRuntime::GCC:
171 if (CGOpts.hasSjLjExceptions())
173 if (CGOpts.hasSEHExceptions())
176 }
177 llvm_unreachable("bad runtime kind");
178}
179
181 const CodeGenOptions &CGOpts) {
182 const llvm::Triple &T = Target.getTriple();
183 if (T.isWindowsMSVCEnvironment())
185 if (T.isOSAIX())
187 if (CGOpts.hasSjLjExceptions())
189 if (CGOpts.hasDWARFExceptions())
191 if (CGOpts.hasSEHExceptions())
193 if (CGOpts.hasWasmExceptions())
195 if (T.isOSzOS())
198}
199
200/// Determines the personality function to use when both C++
201/// and Objective-C exceptions are being caught.
203 const CodeGenOptions &CGOpts,
204 const LangOptions &L) {
205 auto Triple = Target.getTriple();
206 if (Triple.isWindowsMSVCEnvironment())
208 if (Triple.isWasm())
210
211 switch (L.ObjCRuntime.getKind()) {
212 // In the fragile ABI, just use C++ exception handling and hope
213 // they're not doing crazy exception mixing.
215 return getCXXPersonality(Target, CGOpts);
216
217 // The ObjC personality defers to the C++ personality for non-ObjC
218 // handlers. Unlike the C++ case, we use the same personality
219 // function on targets using (backend-driven) SJLJ EH.
221 case ObjCRuntime::iOS:
223 return getObjCPersonality(Target, CGOpts, L);
224
226 if (Triple.isOSCygMing())
229
230 // The GCC runtime's personality function inherently doesn't support
231 // mixed EH. Use the ObjC personality just to avoid returning null.
232 case ObjCRuntime::GCC:
234 return getObjCPersonality(Target, CGOpts, L);
235 }
236 llvm_unreachable("bad runtime kind");
237}
238
239static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
240 if (T.getArch() == llvm::Triple::x86)
243}
244
246 const FunctionDecl *FD) {
247 const llvm::Triple &T = CGM.getTarget().getTriple();
248 const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();
249 const LangOptions &L = CGM.getLangOpts();
250 const TargetInfo &Target = CGM.getTarget();
251
252 // Functions using SEH get an SEH personality.
253 if (FD && FD->usesSEHTry())
254 return getSEHPersonalityMSVC(T);
255
256 if (L.ObjC)
257 return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)
258 : getObjCPersonality(Target, CGOpts, L);
259 return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)
260 : getCPersonality(Target, CGOpts);
261}
262
264 const auto *FD = CGF.CurCodeDecl;
265 // For outlined finallys and filters, use the SEH personality in case they
266 // contain more SEH. This mostly only affects finallys. Filters could
267 // hypothetically use gnu statement expressions to sneak in nested SEH.
268 FD = FD ? FD : CGF.CurSEHParent.getDecl();
269 return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
270}
271
272static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,
273 const EHPersonality &Personality) {
274 llvm::FunctionType *FTy;
275
276 if (Personality.isWasmPersonality()) {
277 FTy = llvm::FunctionType::get(CGM.Int32Ty, {CGM.VoidPtrTy}, false);
278 } else {
279 FTy = llvm::FunctionType::get(CGM.Int32Ty, true);
280 }
281 return CGM.CreateRuntimeFunction(FTy, Personality.PersonalityFn,
282 llvm::AttributeList(), /*Local=*/true);
283}
284
285static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
286 const EHPersonality &Personality) {
287 llvm::FunctionCallee Fn = getPersonalityFn(CGM, Personality);
288 return cast<llvm::Constant>(Fn.getCallee());
289}
290
291/// Check whether a landingpad instruction only uses C++ features.
292static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
293 for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
294 // Look for something that would've been returned by the ObjC
295 // runtime's GetEHType() method.
296 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
297 if (LPI->isCatch(I)) {
298 // Check if the catch value has the ObjC prefix.
299 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
300 // ObjC EH selector entries are always global variables with
301 // names starting like this.
302 if (GV->getName().starts_with("OBJC_EHTYPE"))
303 return false;
304 } else {
305 // Check if any of the filter values have the ObjC prefix.
306 llvm::Constant *CVal = cast<llvm::Constant>(Val);
307 for (llvm::User::op_iterator
308 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
309 if (llvm::GlobalVariable *GV =
310 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
311 // ObjC EH selector entries are always global variables with
312 // names starting like this.
313 if (GV->getName().starts_with("OBJC_EHTYPE"))
314 return false;
315 }
316 }
317 }
318 return true;
319}
320
321/// Check whether a personality function could reasonably be swapped
322/// for a C++ personality function.
323static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
324 for (llvm::User *U : Fn->users()) {
325 // Conditionally white-list bitcasts.
326 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
327 if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
329 return false;
330 continue;
331 }
332
333 // Otherwise it must be a function.
334 llvm::Function *F = dyn_cast<llvm::Function>(U);
335 if (!F) return false;
336
337 for (llvm::BasicBlock &BB : *F) {
338 if (BB.isLandingPad())
339 if (!LandingPadHasOnlyCXXUses(BB.getLandingPadInst()))
340 return false;
341 }
342 }
343
344 return true;
345}
346
347/// Try to use the C++ personality function in ObjC++. Not doing this
348/// can cause some incompatibilities with gcc, which is more
349/// aggressive about only using the ObjC++ personality in a function
350/// when it really needs it.
351void CodeGenModule::SimplifyPersonality() {
352 // If we're not in ObjC++ -fexceptions, there's nothing to do.
353 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
354 return;
355
356 // Both the problem this endeavors to fix and the way the logic
357 // above works is specific to the NeXT runtime.
358 if (!LangOpts.ObjCRuntime.isNeXTFamily())
359 return;
360
361 const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
362 const EHPersonality &CXX = getCXXPersonality(getTarget(), CodeGenOpts);
363 if (&ObjCXX == &CXX)
364 return;
365
366 assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
367 "Different EHPersonalities using the same personality function.");
368
369 llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);
370
371 // Nothing to do if it's unused.
372 if (!Fn || Fn->use_empty()) return;
373
374 // Can't do the optimization if it has non-C++ uses.
375 if (!PersonalityHasOnlyCXXUses(Fn)) return;
376
377 // Create the C++ personality function and kill off the old
378 // function.
379 llvm::FunctionCallee CXXFn = getPersonalityFn(*this, CXX);
380
381 // This can happen if the user is screwing with us.
382 if (Fn->getType() != CXXFn.getCallee()->getType())
383 return;
384
385 Fn->replaceAllUsesWith(CXXFn.getCallee());
386 Fn->eraseFromParent();
387}
388
389/// Returns the value to inject into a selector to indicate the
390/// presence of a catch-all.
391static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
392 // Possibly we should use @llvm.eh.catch.all.value here.
393 return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
394}
395
396namespace {
397 /// A cleanup to free the exception object if its initialization
398 /// throws.
399 struct FreeException final : EHScopeStack::Cleanup {
400 llvm::Value *exn;
401 FreeException(llvm::Value *exn) : exn(exn) {}
402 void Emit(CodeGenFunction &CGF, Flags flags) override {
404 }
405 };
406} // end anonymous namespace
407
408// Emits an exception expression into the given location. This
409// differs from EmitAnyExprToMem only in that, if a final copy-ctor
410// call is required, an exception within that copy ctor causes
411// std::terminate to be invoked.
413 // Make sure the exception object is cleaned up if there's an
414 // exception during initialization.
416 EHScopeStack::stable_iterator cleanup = EHStack.stable_begin();
417
418 // __cxa_allocate_exception returns a void*; we need to cast this
419 // to the appropriate type for the object.
420 llvm::Type *ty = ConvertTypeForMem(e->getType());
421 Address typedAddr = addr.withElementType(ty);
422
423 // FIXME: this isn't quite right! If there's a final unelided call
424 // to a copy constructor, then according to [except.terminate]p1 we
425 // must call std::terminate() if that constructor throws, because
426 // technically that copy occurs after the exception expression is
427 // evaluated but before the exception is caught. But the best way
428 // to handle that is to teach EmitAggExpr to do the final copy
429 // differently if it can't be elided.
430 EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
431 /*IsInit*/ true);
432
433 // Deactivate the cleanup block.
435 cleanup, cast<llvm::Instruction>(typedAddr.emitRawPointer(*this)));
436}
437
443
449
451 return Builder.CreateLoad(getExceptionSlot(), "exn");
452}
453
455 return Builder.CreateLoad(getEHSelectorSlot(), "sel");
456}
457
459 bool KeepInsertionPoint) {
460 // If the exception is being emitted in an OpenMP target region,
461 // and the target is a GPU, we do not support exception handling.
462 // Therefore, we emit a trap which will abort the program, and
463 // prompt a warning indicating that a trap will be emitted.
464 const llvm::Triple &T = Target.getTriple();
465 if (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU()) {
466 EmitTrapCall(llvm::Intrinsic::trap);
467 return;
468 }
469 if (const Expr *SubExpr = E->getSubExpr()) {
470 QualType ThrowType = SubExpr->getType();
471 if (ThrowType->isObjCObjectPointerType()) {
472 const Stmt *ThrowStmt = E->getSubExpr();
473 const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt));
474 CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
475 } else {
476 CGM.getCXXABI().emitThrow(*this, E);
477 }
478 } else {
479 CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
480 }
481
482 // throw is an expression, and the expression emitters expect us
483 // to leave ourselves at a valid insertion point.
484 if (KeepInsertionPoint)
485 EmitBlock(createBasicBlock("throw.cont"));
486}
487
489 if (!CGM.getLangOpts().CXXExceptions)
490 return;
491
492 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
493 if (!FD) {
494 // Check if CapturedDecl is nothrow and create terminate scope for it.
495 if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
496 if (CD->isNothrow())
497 EHStack.pushTerminate();
498 }
499 return;
500 }
501 const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
502 if (!Proto)
503 return;
504
506 // In C++17 and later, 'throw()' aka EST_DynamicNone is treated the same way
507 // as noexcept. In earlier standards, it is handled in this block, along with
508 // 'throw(X...)'.
509 if (EST == EST_Dynamic ||
510 (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {
511 // TODO: Revisit exception specifications for the MS ABI. There is a way to
512 // encode these in an object file but MSVC doesn't do anything with it.
513 if (getTarget().getCXXABI().isMicrosoft())
514 return;
515 // In Wasm EH we currently treat 'throw()' in the same way as 'noexcept'. In
516 // case of throw with types, we ignore it and print a warning for now.
517 // TODO Correctly handle exception specification in Wasm EH
518 if (CGM.getCodeGenOpts().hasWasmExceptions()) {
519 if (EST == EST_DynamicNone)
520 EHStack.pushTerminate();
521 else
522 CGM.getDiags().Report(D->getLocation(),
523 diag::warn_wasm_dynamic_exception_spec_ignored)
525 return;
526 }
527 // Currently Emscripten EH only handles 'throw()' but not 'throw' with
528 // types. 'throw()' handling will be done in JS glue code so we don't need
529 // to do anything in that case. Just print a warning message in case of
530 // throw with types.
531 // TODO Correctly handle exception specification in Emscripten EH
532 if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
533 CGM.getCodeGenOpts().getExceptionHandling() ==
535 EST == EST_Dynamic)
536 CGM.getDiags().Report(D->getLocation(),
537 diag::warn_wasm_dynamic_exception_spec_ignored)
539
540 unsigned NumExceptions = Proto->getNumExceptions();
541 EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
542
543 for (unsigned I = 0; I != NumExceptions; ++I) {
544 QualType Ty = Proto->getExceptionType(I);
546 llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
547 /*ForEH=*/true);
548 Filter->setFilter(I, EHType);
549 }
550 } else if (Proto->canThrow() == CT_Cannot) {
551 // noexcept functions are simple terminate scopes.
552 if (!getLangOpts().EHAsynch) // -EHa: HW exception still can occur
553 EHStack.pushTerminate();
554 }
555}
556
557/// Emit the dispatch block for a filter scope if necessary.
559 EHFilterScope &filterScope) {
560 llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
561 if (!dispatchBlock) return;
562 if (dispatchBlock->use_empty()) {
563 delete dispatchBlock;
564 return;
565 }
566
567 CGF.EmitBlockAfterUses(dispatchBlock);
568
569 // If this isn't a catch-all filter, we need to check whether we got
570 // here because the filter triggered.
571 if (filterScope.getNumFilters()) {
572 // Load the selector value.
573 llvm::Value *selector = CGF.getSelectorFromSlot();
574 llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
575
576 llvm::Value *zero = CGF.Builder.getInt32(0);
577 llvm::Value *failsFilter =
578 CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
579 CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,
580 CGF.getEHResumeBlock(false));
581
582 CGF.EmitBlock(unexpectedBB);
583 }
584
585 // Call __cxa_call_unexpected. This doesn't need to be an invoke
586 // because __cxa_call_unexpected magically filters exceptions
587 // according to the last landing pad the exception was thrown
588 // into. Seriously.
589 llvm::Value *exn = CGF.getExceptionFromSlot();
590 CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)
591 ->setDoesNotReturn();
592 CGF.Builder.CreateUnreachable();
593}
594
596 if (!CGM.getLangOpts().CXXExceptions)
597 return;
598
599 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
600 if (!FD) {
601 // Check if CapturedDecl is nothrow and pop terminate scope for it.
602 if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
603 if (CD->isNothrow() && !EHStack.empty())
604 EHStack.popTerminate();
605 }
606 return;
607 }
608 const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
609 if (!Proto)
610 return;
611
613 if (EST == EST_Dynamic ||
614 (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {
615 // TODO: Revisit exception specifications for the MS ABI. There is a way to
616 // encode these in an object file but MSVC doesn't do anything with it.
617 if (getTarget().getCXXABI().isMicrosoft())
618 return;
619 // In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
620 // case of throw with types, we ignore it and print a warning for now.
621 // TODO Correctly handle exception specification in wasm
622 if (CGM.getCodeGenOpts().hasWasmExceptions()) {
623 if (EST == EST_DynamicNone)
624 EHStack.popTerminate();
625 return;
626 }
627 EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
628 emitFilterDispatchBlock(*this, filterScope);
629 EHStack.popFilter();
630 } else if (Proto->canThrow() == CT_Cannot &&
631 /* possible empty when under async exceptions */
632 !EHStack.empty()) {
633 EHStack.popTerminate();
634 }
635}
636
638 const llvm::Triple &T = Target.getTriple();
639 // If we encounter a try statement on in an OpenMP target region offloaded to
640 // a GPU, we treat it as a basic block.
641 const bool IsTargetDevice =
642 (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU());
643 if (!IsTargetDevice)
646 if (!IsTargetDevice)
648}
649
650void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
651 unsigned NumHandlers = S.getNumHandlers();
652 EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
653
654 for (unsigned I = 0; I != NumHandlers; ++I) {
655 const CXXCatchStmt *C = S.getHandler(I);
656
657 llvm::BasicBlock *Handler = createBasicBlock("catch");
658 if (C->getExceptionDecl()) {
659 // FIXME: Dropping the reference type on the type into makes it
660 // impossible to correctly implement catch-by-reference
661 // semantics for pointers. Unfortunately, this is what all
662 // existing compilers do, and it's not clear that the standard
663 // personality routine is capable of doing this right. See C++ DR 388:
664 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
665 Qualifiers CaughtTypeQuals;
666 QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
667 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
668
669 CatchTypeInfo TypeInfo{nullptr, 0};
670 if (CaughtType->isObjCObjectPointerType())
671 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
672 else
673 TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
674 CaughtType, C->getCaughtType());
675 CatchScope->setHandler(I, TypeInfo, Handler);
676 } else {
677 // No exception decl indicates '...', a catch-all.
678 CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
679 // Under async exceptions, catch(...) need to catch HW exception too
680 // Mark scope with SehTryBegin as a SEH __try scope
681 if (getLangOpts().EHAsynch)
683 }
684 }
685}
686
687llvm::BasicBlock *
689 if (EHPersonality::get(*this).usesFuncletPads())
690 return getFuncletEHDispatchBlock(si);
691
692 // The dispatch block for the end of the scope chain is a block that
693 // just resumes unwinding.
694 if (si == EHStack.stable_end())
695 return getEHResumeBlock(true);
696
697 // Otherwise, we should look at the actual scope.
698 EHScope &scope = *EHStack.find(si);
699
700 llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
701 if (!dispatchBlock) {
702 switch (scope.getKind()) {
703 case EHScope::Catch: {
704 // Apply a special case to a single catch-all.
705 EHCatchScope &catchScope = cast<EHCatchScope>(scope);
706 if (catchScope.getNumHandlers() == 1 &&
707 catchScope.getHandler(0).isCatchAll()) {
708 dispatchBlock = catchScope.getHandler(0).Block;
709
710 // Otherwise, make a dispatch block.
711 } else {
712 dispatchBlock = createBasicBlock("catch.dispatch");
713 }
714 break;
715 }
716
717 case EHScope::Cleanup:
718 dispatchBlock = createBasicBlock("ehcleanup");
719 break;
720
721 case EHScope::Filter:
722 dispatchBlock = createBasicBlock("filter.dispatch");
723 break;
724
726 dispatchBlock = getTerminateHandler();
727 break;
728 }
729 scope.setCachedEHDispatchBlock(dispatchBlock);
730 }
731 return dispatchBlock;
732}
733
734llvm::BasicBlock *
736 // Returning nullptr indicates that the previous dispatch block should unwind
737 // to caller.
738 if (SI == EHStack.stable_end())
739 return nullptr;
740
741 // Otherwise, we should look at the actual scope.
742 EHScope &EHS = *EHStack.find(SI);
743
744 llvm::BasicBlock *DispatchBlock = EHS.getCachedEHDispatchBlock();
745 if (DispatchBlock)
746 return DispatchBlock;
747
748 if (EHS.getKind() == EHScope::Terminate)
749 DispatchBlock = getTerminateFunclet();
750 else
751 DispatchBlock = createBasicBlock();
752 CGBuilderTy Builder(CGM, DispatchBlock);
753
754 switch (EHS.getKind()) {
755 case EHScope::Catch:
756 DispatchBlock->setName("catch.dispatch");
757 break;
758
759 case EHScope::Cleanup:
760 DispatchBlock->setName("ehcleanup");
761 break;
762
763 case EHScope::Filter:
764 llvm_unreachable("exception specifications not handled yet!");
765
767 DispatchBlock->setName("terminate");
768 break;
769 }
770 EHS.setCachedEHDispatchBlock(DispatchBlock);
771 return DispatchBlock;
772}
773
774/// Check whether this is a non-EH scope, i.e. a scope which doesn't
775/// affect exception handling. Currently, the only non-EH scopes are
776/// normal-only cleanup scopes.
777static bool isNonEHScope(const EHScope &S) {
778 switch (S.getKind()) {
779 case EHScope::Cleanup:
780 return !cast<EHCleanupScope>(S).isEHCleanup();
781 case EHScope::Filter:
782 case EHScope::Catch:
784 return false;
785 }
786
787 llvm_unreachable("Invalid EHScope Kind!");
788}
789
791 assert(EHStack.requiresLandingPad());
792 assert(!EHStack.empty());
793
794 // If exceptions are disabled/ignored and SEH is not in use, then there is no
795 // invoke destination. SEH "works" even if exceptions are off. In practice,
796 // this means that C++ destructors and other EH cleanups don't run, which is
797 // consistent with MSVC's behavior, except in the presence of -EHa
798 const LangOptions &LO = CGM.getLangOpts();
799 if (!LO.Exceptions || LO.IgnoreExceptions) {
800 if (!LO.Borland && !LO.MicrosoftExt)
801 return nullptr;
803 return nullptr;
804 }
805
806 // CUDA device code doesn't have exceptions.
807 if (LO.CUDA && LO.CUDAIsDevice)
808 return nullptr;
809
810 // Check the innermost scope for a cached landing pad. If this is
811 // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
812 llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
813 if (LP) return LP;
814
815 const EHPersonality &Personality = EHPersonality::get(*this);
816
817 if (!CurFn->hasPersonalityFn())
818 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
819
820 if (Personality.usesFuncletPads()) {
821 // We don't need separate landing pads in the funclet model.
822 LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
823 } else {
824 // Build the landing pad for this scope.
825 LP = EmitLandingPad();
826 }
827
828 assert(LP);
829
830 // Cache the landing pad on the innermost scope. If this is a
831 // non-EH scope, cache the landing pad on the enclosing scope, too.
832 for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
833 ir->setCachedLandingPad(LP);
834 if (!isNonEHScope(*ir)) break;
835 }
836
837 return LP;
838}
839
841 assert(EHStack.requiresLandingPad());
842 assert(!CGM.getLangOpts().IgnoreExceptions &&
843 "LandingPad should not be emitted when -fignore-exceptions are in "
844 "effect.");
845 EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
846 switch (innermostEHScope.getKind()) {
848 return getTerminateLandingPad();
849
850 case EHScope::Catch:
851 case EHScope::Cleanup:
852 case EHScope::Filter:
853 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
854 return lpad;
855 }
856
857 // Save the current IR generation state.
858 CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
859 auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
860
861 // Create and configure the landing pad.
862 llvm::BasicBlock *lpad = createBasicBlock("lpad");
863 EmitBlock(lpad);
864
865 llvm::LandingPadInst *LPadInst =
866 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
867
868 llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
869 Builder.CreateStore(LPadExn, getExceptionSlot());
870 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
871 Builder.CreateStore(LPadSel, getEHSelectorSlot());
872
873 // Save the exception pointer. It's safe to use a single exception
874 // pointer per function because EH cleanups can never have nested
875 // try/catches.
876 // Build the landingpad instruction.
877
878 // Accumulate all the handlers in scope.
879 bool hasCatchAll = false;
880 bool hasCleanup = false;
881 bool hasFilter = false;
884 for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E;
885 ++I) {
886
887 switch (I->getKind()) {
888 case EHScope::Cleanup:
889 // If we have a cleanup, remember that.
890 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
891 continue;
892
893 case EHScope::Filter: {
894 assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
895 assert(!hasCatchAll && "EH filter reached after catch-all");
896
897 // Filter scopes get added to the landingpad in weird ways.
899 hasFilter = true;
900
901 // Add all the filter values.
902 for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
903 filterTypes.push_back(filter.getFilter(i));
904 goto done;
905 }
906
908 // Terminate scopes are basically catch-alls.
909 assert(!hasCatchAll);
910 hasCatchAll = true;
911 goto done;
912
913 case EHScope::Catch:
914 break;
915 }
916
917 EHCatchScope &catchScope = cast<EHCatchScope>(*I);
918 for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
919 EHCatchScope::Handler handler = catchScope.getHandler(hi);
920 assert(handler.Type.Flags == 0 &&
921 "landingpads do not support catch handler flags");
922
923 // If this is a catch-all, register that and abort.
924 if (!handler.Type.RTTI) {
925 assert(!hasCatchAll);
926 hasCatchAll = true;
927 goto done;
928 }
929
930 // Check whether we already have a handler for this type.
931 if (catchTypes.insert(handler.Type.RTTI).second)
932 // If not, add it directly to the landingpad.
933 LPadInst->addClause(handler.Type.RTTI);
934 }
935 }
936
937 done:
938 // If we have a catch-all, add null to the landingpad.
939 assert(!(hasCatchAll && hasFilter));
940 if (hasCatchAll) {
941 LPadInst->addClause(getCatchAllValue(*this));
942
943 // If we have an EH filter, we need to add those handlers in the
944 // right place in the landingpad, which is to say, at the end.
945 } else if (hasFilter) {
946 // Create a filter expression: a constant array indicating which filter
947 // types there are. The personality routine only lands here if the filter
948 // doesn't match.
950 llvm::ArrayType *AType =
951 llvm::ArrayType::get(!filterTypes.empty() ?
952 filterTypes[0]->getType() : Int8PtrTy,
953 filterTypes.size());
954
955 for (llvm::Value *filterType : filterTypes)
956 Filters.push_back(cast<llvm::Constant>(filterType));
957 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
958 LPadInst->addClause(FilterArray);
959
960 // Also check whether we need a cleanup.
961 if (hasCleanup)
962 LPadInst->setCleanup(true);
963
964 // Otherwise, signal that we at least have cleanups.
965 } else if (hasCleanup) {
966 LPadInst->setCleanup(true);
967 }
968
969 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
970 "landingpad instruction has no clauses!");
971
972 // Tell the backend how to generate the landing pad.
973 Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
974
975 // Restore the old IR generation state.
976 Builder.restoreIP(savedIP);
977
978 return lpad;
979}
980
981static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {
982 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
983 assert(DispatchBlock);
984
985 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
986 CGF.EmitBlockAfterUses(DispatchBlock);
987
988 llvm::Value *ParentPad = CGF.CurrentFuncletPad;
989 if (!ParentPad)
990 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
991 llvm::BasicBlock *UnwindBB =
992 CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
993
994 unsigned NumHandlers = CatchScope.getNumHandlers();
995 llvm::CatchSwitchInst *CatchSwitch =
996 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
997
998 // Test against each of the exception types we claim to catch.
999 for (unsigned I = 0; I < NumHandlers; ++I) {
1000 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
1001
1002 CatchTypeInfo TypeInfo = Handler.Type;
1003 if (!TypeInfo.RTTI)
1004 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
1005
1006 CGF.Builder.SetInsertPoint(Handler.Block);
1007
1008 if (EHPersonality::get(CGF).isMSVCXXPersonality()) {
1009 CGF.Builder.CreateCatchPad(
1010 CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),
1011 llvm::Constant::getNullValue(CGF.VoidPtrTy)});
1012 } else {
1013 CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});
1014 }
1015
1016 CatchSwitch->addHandler(Handler.Block);
1017 }
1018 CGF.Builder.restoreIP(SavedIP);
1019}
1020
1021// Wasm uses Windows-style EH instructions, but it merges all catch clauses into
1022// one big catchpad, within which we use Itanium's landingpad-style selector
1023// comparison instructions.
1025 EHCatchScope &CatchScope) {
1026 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
1027 assert(DispatchBlock);
1028
1029 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
1030 CGF.EmitBlockAfterUses(DispatchBlock);
1031
1032 llvm::Value *ParentPad = CGF.CurrentFuncletPad;
1033 if (!ParentPad)
1034 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
1035 llvm::BasicBlock *UnwindBB =
1036 CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
1037
1038 unsigned NumHandlers = CatchScope.getNumHandlers();
1039 llvm::CatchSwitchInst *CatchSwitch =
1040 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1041
1042 // We don't use a landingpad instruction, so generate intrinsic calls to
1043 // provide exception and selector values.
1044 llvm::BasicBlock *WasmCatchStartBlock = CGF.createBasicBlock("catch.start");
1045 CatchSwitch->addHandler(WasmCatchStartBlock);
1046 CGF.EmitBlockAfterUses(WasmCatchStartBlock);
1047
1048 // Create a catchpad instruction.
1050 for (unsigned I = 0, E = NumHandlers; I < E; ++I) {
1051 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
1052 CatchTypeInfo TypeInfo = Handler.Type;
1053 if (!TypeInfo.RTTI)
1054 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
1055 CatchTypes.push_back(TypeInfo.RTTI);
1056 }
1057 auto *CPI = CGF.Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1058
1059 // Create calls to wasm.get.exception and wasm.get.ehselector intrinsics.
1060 // Before they are lowered appropriately later, they provide values for the
1061 // exception and selector.
1062 llvm::Function *GetExnFn =
1063 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
1064 llvm::Function *GetSelectorFn =
1065 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_ehselector);
1066 llvm::CallInst *Exn = CGF.Builder.CreateCall(GetExnFn, CPI);
1067 CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());
1068 llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
1069
1070 llvm::Function *TypeIDFn =
1071 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
1072
1073 // If there's only a single catch-all, branch directly to its handler.
1074 if (CatchScope.getNumHandlers() == 1 &&
1075 CatchScope.getHandler(0).isCatchAll()) {
1076 CGF.Builder.CreateBr(CatchScope.getHandler(0).Block);
1077 CGF.Builder.restoreIP(SavedIP);
1078 return;
1079 }
1080
1081 // Test against each of the exception types we claim to catch.
1082 for (unsigned I = 0, E = NumHandlers;; ++I) {
1083 assert(I < E && "ran off end of handlers!");
1084 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
1085 CatchTypeInfo TypeInfo = Handler.Type;
1086 if (!TypeInfo.RTTI)
1087 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
1088
1089 // Figure out the next block.
1090 llvm::BasicBlock *NextBlock;
1091
1092 bool EmitNextBlock = false, NextIsEnd = false;
1093
1094 // If this is the last handler, we're at the end, and the next block is a
1095 // block that contains a call to the rethrow function, so we can unwind to
1096 // the enclosing EH scope. The call itself will be generated later.
1097 if (I + 1 == E) {
1098 NextBlock = CGF.createBasicBlock("rethrow");
1099 EmitNextBlock = true;
1100 NextIsEnd = true;
1101
1102 // If the next handler is a catch-all, we're at the end, and the
1103 // next block is that handler.
1104 } else if (CatchScope.getHandler(I + 1).isCatchAll()) {
1105 NextBlock = CatchScope.getHandler(I + 1).Block;
1106 NextIsEnd = true;
1107
1108 // Otherwise, we're not at the end and we need a new block.
1109 } else {
1110 NextBlock = CGF.createBasicBlock("catch.fallthrough");
1111 EmitNextBlock = true;
1112 }
1113
1114 // Figure out the catch type's index in the LSDA's type table.
1115 llvm::CallInst *TypeIndex = CGF.Builder.CreateCall(TypeIDFn, TypeInfo.RTTI);
1116 TypeIndex->setDoesNotThrow();
1117
1118 llvm::Value *MatchesTypeIndex =
1119 CGF.Builder.CreateICmpEQ(Selector, TypeIndex, "matches");
1120 CGF.Builder.CreateCondBr(MatchesTypeIndex, Handler.Block, NextBlock);
1121
1122 if (EmitNextBlock)
1123 CGF.EmitBlock(NextBlock);
1124 if (NextIsEnd)
1125 break;
1126 }
1127
1128 CGF.Builder.restoreIP(SavedIP);
1129}
1130
1131/// Emit the structure of the dispatch block for the given catch scope.
1132/// It is an invariant that the dispatch block already exists.
1134 EHCatchScope &catchScope) {
1135 if (EHPersonality::get(CGF).isWasmPersonality())
1136 return emitWasmCatchPadBlock(CGF, catchScope);
1137 if (EHPersonality::get(CGF).usesFuncletPads())
1138 return emitCatchPadBlock(CGF, catchScope);
1139
1140 llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
1141 assert(dispatchBlock);
1142
1143 // If there's only a single catch-all, getEHDispatchBlock returned
1144 // that catch-all as the dispatch block.
1145 if (catchScope.getNumHandlers() == 1 &&
1146 catchScope.getHandler(0).isCatchAll()) {
1147 assert(dispatchBlock == catchScope.getHandler(0).Block);
1148 return;
1149 }
1150
1151 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
1152 CGF.EmitBlockAfterUses(dispatchBlock);
1153
1154 // Select the right handler.
1155 llvm::Function *llvm_eh_typeid_for =
1156 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
1157 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1158
1159 // Load the selector value.
1160 llvm::Value *selector = CGF.getSelectorFromSlot();
1161
1162 // Test against each of the exception types we claim to catch.
1163 for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
1164 assert(i < e && "ran off end of handlers!");
1165 const EHCatchScope::Handler &handler = catchScope.getHandler(i);
1166
1167 llvm::Value *typeValue = handler.Type.RTTI;
1168 assert(handler.Type.Flags == 0 &&
1169 "landingpads do not support catch handler flags");
1170 assert(typeValue && "fell into catch-all case!");
1171 // With opaque ptrs, only the address space can be a mismatch.
1172 if (typeValue->getType() != argTy)
1173 typeValue = CGF.performAddrSpaceCast(typeValue, argTy);
1174
1175 // Figure out the next block.
1176 bool nextIsEnd;
1177 llvm::BasicBlock *nextBlock;
1178
1179 // If this is the last handler, we're at the end, and the next
1180 // block is the block for the enclosing EH scope.
1181 if (i + 1 == e) {
1182 nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
1183 nextIsEnd = true;
1184
1185 // If the next handler is a catch-all, we're at the end, and the
1186 // next block is that handler.
1187 } else if (catchScope.getHandler(i+1).isCatchAll()) {
1188 nextBlock = catchScope.getHandler(i+1).Block;
1189 nextIsEnd = true;
1190
1191 // Otherwise, we're not at the end and we need a new block.
1192 } else {
1193 nextBlock = CGF.createBasicBlock("catch.fallthrough");
1194 nextIsEnd = false;
1195 }
1196
1197 // Figure out the catch type's index in the LSDA's type table.
1198 llvm::CallInst *typeIndex =
1199 CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1200 typeIndex->setDoesNotThrow();
1201
1202 llvm::Value *matchesTypeIndex =
1203 CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
1204 CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
1205
1206 // If the next handler is a catch-all, we're completely done.
1207 if (nextIsEnd) {
1208 CGF.Builder.restoreIP(savedIP);
1209 return;
1210 }
1211 // Otherwise we need to emit and continue at that block.
1212 CGF.EmitBlock(nextBlock);
1213 }
1214}
1215
1217 EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1218 if (catchScope.hasEHBranches())
1219 emitCatchDispatchBlock(*this, catchScope);
1220 EHStack.popCatch();
1221}
1222
1224 llvm::BasicBlock *WasmCatchStartBlock) {
1225 assert(WasmCatchStartBlock);
1226 // Navigate for the "rethrow" block. For CXX exceptions this was created in
1227 // emitWasmCatchPadBlock(). Wasm uses landingpad-style conditional branches
1228 // to compare selectors, so we follow the false destination for each of the
1229 // cond branches to reach the rethrow block.
1230 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1231 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1232 RethrowBlock = cast<llvm::CondBrInst>(TI)->getSuccessor(1);
1233 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1234 Builder.SetInsertPoint(RethrowBlock);
1235 llvm::Function *RethrowInCatchFn =
1236 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1237 EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
1238}
1239
1240void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1241 unsigned NumHandlers = S.getNumHandlers();
1242 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1243 assert(CatchScope.getNumHandlers() == NumHandlers);
1244 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
1245
1246 // If the catch was not required, bail out now.
1247 if (!CatchScope.hasEHBranches()) {
1248 CatchScope.clearHandlerBlocks();
1249 EHStack.popCatch();
1250 return;
1251 }
1252
1253 // Emit the structure of the EH dispatch for this catch.
1254 emitCatchDispatchBlock(*this, CatchScope);
1255
1256 // Copy the handler blocks off before we pop the EH stack. Emitting
1257 // the handlers might scribble on this memory.
1259 CatchScope.begin(), CatchScope.begin() + NumHandlers);
1260
1261 EHStack.popCatch();
1262
1263 // The fall-through block.
1264 llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1265
1266 // We just emitted the body of the try; jump to the continue block.
1267 if (HaveInsertPoint())
1268 Builder.CreateBr(ContBB);
1269
1270 // Determine if we need an implicit rethrow for all these catch handlers;
1271 // see the comment below.
1272 bool doImplicitRethrow = false;
1273 if (IsFnTryBlock)
1274 doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1276
1277 // Wasm uses Windows-style EH instructions, but merges all catch clauses into
1278 // one big catchpad. So we save the old funclet pad here before we traverse
1279 // each catch handler.
1280 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1281 llvm::BasicBlock *WasmCatchStartBlock = nullptr;
1282 if (EHPersonality::get(*this).isWasmPersonality()) {
1283 auto *CatchSwitch =
1284 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHIIt());
1285 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1286 ? CatchSwitch->getSuccessor(1)
1287 : CatchSwitch->getSuccessor(0);
1288 auto *CPI =
1289 cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHIIt());
1290 CurrentFuncletPad = CPI;
1291 }
1292
1293 // Perversely, we emit the handlers backwards precisely because we
1294 // want them to appear in source order. In all of these cases, the
1295 // catch block will have exactly one predecessor, which will be a
1296 // particular block in the catch dispatch. However, in the case of
1297 // a catch-all, one of the dispatch blocks will branch to two
1298 // different handlers, and EmitBlockAfterUses will cause the second
1299 // handler to be moved before the first.
1300 bool HasCatchAll = false;
1301 for (unsigned I = NumHandlers; I != 0; --I) {
1302 HasCatchAll |= Handlers[I - 1].isCatchAll();
1303 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1304 EmitBlockAfterUses(CatchBlock);
1305
1306 // Catch the exception if this isn't a catch-all.
1307 const CXXCatchStmt *C = S.getHandler(I-1);
1308
1309 // Enter a cleanup scope, including the catch variable and the
1310 // end-catch.
1311 RunCleanupsScope CatchScope(*this);
1312
1313 // Initialize the catch variable and set up the cleanups.
1314 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1315 CGM.getCXXABI().emitBeginCatch(*this, C);
1316
1317 // Emit the PGO counter increment.
1319
1320 // Perform the body of the catch.
1321 EmitStmt(C->getHandlerBlock());
1322
1323 // [except.handle]p11:
1324 // The currently handled exception is rethrown if control
1325 // reaches the end of a handler of the function-try-block of a
1326 // constructor or destructor.
1327
1328 // It is important that we only do this on fallthrough and not on
1329 // return. Note that it's illegal to put a return in a
1330 // constructor function-try-block's catch handler (p14), so this
1331 // really only applies to destructors.
1332 if (doImplicitRethrow && HaveInsertPoint()) {
1333 CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1334 Builder.CreateUnreachable();
1335 Builder.ClearInsertionPoint();
1336 }
1337
1338 // Fall out through the catch cleanups.
1339 CatchScope.ForceCleanup();
1340
1341 // Branch out of the try.
1342 if (HaveInsertPoint())
1343 Builder.CreateBr(ContBB);
1344 }
1345
1346 if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {
1347 WasmEmitFallthroughRethrow(WasmCatchStartBlock);
1348 }
1349
1350 EmitBlock(ContBB);
1352}
1353
1354namespace {
1355 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1356 llvm::Value *ForEHVar;
1357 llvm::FunctionCallee EndCatchFn;
1358 CallEndCatchForFinally(llvm::Value *ForEHVar,
1359 llvm::FunctionCallee EndCatchFn)
1360 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1361
1362 void Emit(CodeGenFunction &CGF, Flags flags) override {
1363 llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1364 llvm::BasicBlock *CleanupContBB =
1365 CGF.createBasicBlock("finally.cleanup.cont");
1366
1367 llvm::Value *ShouldEndCatch =
1368 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
1369 CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1370 CGF.EmitBlock(EndCatchBB);
1371 CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1372 CGF.EmitBlock(CleanupContBB);
1373 }
1374 };
1375
1376 struct PerformFinally final : EHScopeStack::Cleanup {
1377 const Stmt *Body;
1378 llvm::Value *ForEHVar;
1379 llvm::FunctionCallee EndCatchFn;
1380 llvm::FunctionCallee RethrowFn;
1381 llvm::Value *SavedExnVar;
1382
1383 PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1384 llvm::FunctionCallee EndCatchFn,
1385 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1386 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1387 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1388
1389 void Emit(CodeGenFunction &CGF, Flags flags) override {
1390 // Enter a cleanup to call the end-catch function if one was provided.
1391 if (EndCatchFn)
1392 CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1393 ForEHVar, EndCatchFn);
1394
1395 // Save the current cleanup destination in case there are
1396 // cleanups in the finally block.
1397 llvm::Value *SavedCleanupDest =
1399 "cleanup.dest.saved");
1400
1401 // Emit the finally block.
1402 CGF.EmitStmt(Body);
1403
1404 // If the end of the finally is reachable, check whether this was
1405 // for EH. If so, rethrow.
1406 if (CGF.HaveInsertPoint()) {
1407 llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1408 llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1409
1410 llvm::Value *ShouldRethrow =
1411 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
1412 CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1413
1414 CGF.EmitBlock(RethrowBB);
1415 if (SavedExnVar) {
1417 CGF.Int8PtrTy, SavedExnVar,
1418 CGF.getPointerAlign()));
1419
1420 } else {
1421 CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1422 }
1423 CGF.Builder.CreateUnreachable();
1424
1425 CGF.EmitBlock(ContBB);
1426
1427 // Restore the cleanup destination.
1428 CGF.Builder.CreateStore(SavedCleanupDest,
1430 }
1431
1432 // Leave the end-catch cleanup. As an optimization, pretend that
1433 // the fallthrough path was inaccessible; we've dynamically proven
1434 // that we're not in the EH case along that path.
1435 if (EndCatchFn) {
1436 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1437 CGF.PopCleanupBlock();
1438 CGF.Builder.restoreIP(SavedIP);
1439 }
1440
1441 // Now make sure we actually have an insertion point or the
1442 // cleanup gods will hate us.
1443 CGF.EnsureInsertPoint();
1444 }
1445 };
1446} // end anonymous namespace
1447
1448/// Enters a finally block for an implementation using zero-cost
1449/// exceptions. This is mostly general, but hard-codes some
1450/// language/ABI-specific behavior in the catch-all sections.
1451void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, const Stmt *body,
1452 llvm::FunctionCallee beginCatchFn,
1453 llvm::FunctionCallee endCatchFn,
1454 llvm::FunctionCallee rethrowFn) {
1455 assert((!!beginCatchFn) == (!!endCatchFn) &&
1456 "begin/end catch functions not paired");
1457 assert(rethrowFn && "rethrow function is required");
1458
1459 BeginCatchFn = beginCatchFn;
1460
1461 // The rethrow function has one of the following two types:
1462 // void (*)()
1463 // void (*)(void*)
1464 // In the latter case we need to pass it the exception object.
1465 // But we can't use the exception slot because the @finally might
1466 // have a landing pad (which would overwrite the exception slot).
1467 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1468 SavedExnVar = nullptr;
1469 if (rethrowFnTy->getNumParams())
1470 SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1471
1472 // A finally block is a statement which must be executed on any edge
1473 // out of a given scope. Unlike a cleanup, the finally block may
1474 // contain arbitrary control flow leading out of itself. In
1475 // addition, finally blocks should always be executed, even if there
1476 // are no catch handlers higher on the stack. Therefore, we
1477 // surround the protected scope with a combination of a normal
1478 // cleanup (to catch attempts to break out of the block via normal
1479 // control flow) and an EH catch-all (semantically "outside" any try
1480 // statement to which the finally block might have been attached).
1481 // The finally block itself is generated in the context of a cleanup
1482 // which conditionally leaves the catch-all.
1483
1484 // Jump destination for performing the finally block on an exception
1485 // edge. We'll never actually reach this block, so unreachable is
1486 // fine.
1487 RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1488
1489 // Whether the finally block is being executed for EH purposes.
1490 ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1491 CGF.Builder.CreateFlagStore(false, ForEHVar);
1492
1493 // Enter a normal cleanup which will perform the @finally block.
1494 CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1495 ForEHVar, endCatchFn,
1496 rethrowFn, SavedExnVar);
1497
1498 // Enter a catch-all scope.
1499 llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1500 EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1501 catchScope->setCatchAllHandler(0, catchBB);
1502}
1503
1504void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1505 // Leave the finally catch-all.
1506 EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1507 llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1508
1509 CGF.popCatchScope();
1510
1511 // If there are any references to the catch-all block, emit it.
1512 if (catchBB->use_empty()) {
1513 delete catchBB;
1514 } else {
1515 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1516 CGF.EmitBlock(catchBB);
1517
1518 llvm::Value *exn = nullptr;
1519
1520 // If there's a begin-catch function, call it.
1521 if (BeginCatchFn) {
1522 exn = CGF.getExceptionFromSlot();
1523 CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1524 }
1525
1526 // If we need to remember the exception pointer to rethrow later, do so.
1527 if (SavedExnVar) {
1528 if (!exn) exn = CGF.getExceptionFromSlot();
1529 CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1530 }
1531
1532 // Tell the cleanups in the finally block that we're do this for EH.
1533 CGF.Builder.CreateFlagStore(true, ForEHVar);
1534
1535 // Thread a jump through the finally cleanup.
1536 CGF.EmitBranchThroughCleanup(RethrowDest);
1537
1538 CGF.Builder.restoreIP(savedIP);
1539 }
1540
1541 // Finally, leave the @finally cleanup.
1542 CGF.PopCleanupBlock();
1543}
1544
1546 if (TerminateLandingPad)
1547 return TerminateLandingPad;
1548
1549 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1550
1551 // This will get inserted at the end of the function.
1552 TerminateLandingPad = createBasicBlock("terminate.lpad");
1553 Builder.SetInsertPoint(TerminateLandingPad);
1554
1555 // Tell the backend that this is a landing pad.
1556 const EHPersonality &Personality = EHPersonality::get(*this);
1557
1558 if (!CurFn->hasPersonalityFn())
1559 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
1560
1561 llvm::LandingPadInst *LPadInst =
1562 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
1563 LPadInst->addClause(getCatchAllValue(*this));
1564
1565 llvm::Value *Exn = nullptr;
1566 if (getLangOpts().CPlusPlus)
1567 Exn = Builder.CreateExtractValue(LPadInst, 0);
1568 llvm::CallInst *terminateCall =
1569 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1570 terminateCall->setDoesNotReturn();
1571 Builder.CreateUnreachable();
1572
1573 // Restore the saved insertion state.
1574 Builder.restoreIP(SavedIP);
1575
1576 return TerminateLandingPad;
1577}
1578
1580 if (TerminateHandler)
1581 return TerminateHandler;
1582
1583 // Set up the terminate handler. This block is inserted at the very
1584 // end of the function by FinishFunction.
1585 TerminateHandler = createBasicBlock("terminate.handler");
1586 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1587 Builder.SetInsertPoint(TerminateHandler);
1588
1589 llvm::Value *Exn = nullptr;
1590 if (getLangOpts().CPlusPlus)
1591 Exn = getExceptionFromSlot();
1592 llvm::CallInst *terminateCall =
1593 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1594 terminateCall->setDoesNotReturn();
1595 Builder.CreateUnreachable();
1596
1597 // Restore the saved insertion state.
1598 Builder.restoreIP(SavedIP);
1599
1600 return TerminateHandler;
1601}
1602
1604 assert(EHPersonality::get(*this).usesFuncletPads() &&
1605 "use getTerminateLandingPad for non-funclet EH");
1606
1607 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1608 if (TerminateFunclet)
1609 return TerminateFunclet;
1610
1611 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1612
1613 // Set up the terminate handler. This block is inserted at the very
1614 // end of the function by FinishFunction.
1615 TerminateFunclet = createBasicBlock("terminate.handler");
1616 Builder.SetInsertPoint(TerminateFunclet);
1617
1618 // Create the cleanuppad using the current parent pad as its token. Use 'none'
1619 // if this is a top-level terminate scope, which is the common case.
1620 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1621 llvm::Value *ParentPad = CurrentFuncletPad;
1622 if (!ParentPad)
1623 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1624 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1625
1626 // Emit the __std_terminate call.
1627 llvm::CallInst *terminateCall =
1628 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);
1629 terminateCall->setDoesNotReturn();
1630 Builder.CreateUnreachable();
1631
1632 // Restore the saved insertion state.
1633 Builder.restoreIP(SavedIP);
1634
1635 return TerminateFunclet;
1636}
1637
1638llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1639 if (EHResumeBlock) return EHResumeBlock;
1640
1641 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1642
1643 // We emit a jump to a notional label at the outermost unwind state.
1644 EHResumeBlock = createBasicBlock("eh.resume");
1645 Builder.SetInsertPoint(EHResumeBlock);
1646
1647 const EHPersonality &Personality = EHPersonality::get(*this);
1648
1649 // This can always be a call because we necessarily didn't find
1650 // anything on the EH stack which needs our help.
1651 const char *RethrowName = Personality.CatchallRethrowFn;
1652 if (RethrowName != nullptr && !isCleanup) {
1654 getExceptionFromSlot())->setDoesNotReturn();
1655 Builder.CreateUnreachable();
1656 Builder.restoreIP(SavedIP);
1657 return EHResumeBlock;
1658 }
1659
1660 // Recreate the landingpad's return value for the 'resume' instruction.
1661 llvm::Value *Exn = getExceptionFromSlot();
1662 llvm::Value *Sel = getSelectorFromSlot();
1663
1664 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1665 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1666 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1667 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1668
1669 Builder.CreateResume(LPadVal);
1670 Builder.restoreIP(SavedIP);
1671 return EHResumeBlock;
1672}
1673
1675 EnterSEHTryStmt(S);
1676 {
1677 JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
1678
1679 SEHTryEpilogueStack.push_back(&TryExit);
1680
1681 llvm::BasicBlock *TryBB = nullptr;
1682 // IsEHa: emit an invoke to _seh_try_begin() runtime for -EHa
1683 if (getLangOpts().EHAsynch) {
1685 if (SEHTryEpilogueStack.size() == 1) // outermost only
1686 TryBB = Builder.GetInsertBlock();
1687 }
1688
1689 EmitStmt(S.getTryBlock());
1690
1691 // Volatilize all blocks in Try, till current insert point
1692 if (TryBB) {
1694 VolatilizeTryBlocks(TryBB, Visited);
1695 }
1696
1697 SEHTryEpilogueStack.pop_back();
1698
1699 if (!TryExit.getBlock()->use_empty())
1700 EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
1701 else
1702 delete TryExit.getBlock();
1703 }
1704 ExitSEHTryStmt(S);
1705}
1706
1707// Recursively walk through blocks in a _try
1708// and make all memory instructions volatile
1710 llvm::BasicBlock *BB, llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V) {
1711 if (BB == SEHTryEpilogueStack.back()->getBlock() /* end of Try */ ||
1712 !V.insert(BB).second /* already visited */ ||
1713 !BB->getParent() /* not emitted */ || BB->empty())
1714 return;
1715
1716 if (!BB->isEHPad()) {
1717 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1718 ++J) {
1719 if (auto LI = dyn_cast<llvm::LoadInst>(J)) {
1720 LI->setVolatile(true);
1721 } else if (auto SI = dyn_cast<llvm::StoreInst>(J)) {
1722 SI->setVolatile(true);
1723 } else if (auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1724 MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));
1725 }
1726 }
1727 }
1728 if (const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1729 unsigned N = TI->getNumSuccessors();
1730 for (unsigned I = 0; I < N; I++)
1731 VolatilizeTryBlocks(TI->getSuccessor(I), V);
1732 }
1733}
1734
1735namespace {
1736struct PerformSEHFinally final : EHScopeStack::Cleanup {
1737 llvm::Function *OutlinedFinally;
1738 PerformSEHFinally(llvm::Function *OutlinedFinally)
1739 : OutlinedFinally(OutlinedFinally) {}
1740
1741 void Emit(CodeGenFunction &CGF, Flags F) override {
1742 ASTContext &Context = CGF.getContext();
1743 CodeGenModule &CGM = CGF.CGM;
1744
1745 CallArgList Args;
1746
1747 // Compute the two argument values.
1748 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1749 llvm::Value *FP = nullptr;
1750 // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
1751 if (CGF.IsOutlinedSEHHelper) {
1752 FP = &CGF.CurFn->arg_begin()[1];
1753 } else {
1754 llvm::Function *LocalAddrFn =
1755 CGM.getIntrinsic(llvm::Intrinsic::localaddress);
1756 FP = CGF.Builder.CreateCall(LocalAddrFn);
1757 }
1758
1759 llvm::Value *IsForEH =
1760 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
1761
1762 // Except _leave and fall-through at the end, all other exits in a _try
1763 // (return/goto/continue/break) are considered as abnormal terminations
1764 // since _leave/fall-through is always Indexed 0,
1765 // just use NormalCleanupDestSlot (>= 1 for goto/return/..),
1766 // as 1st Arg to indicate abnormal termination
1767 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1769 llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
1770 llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
1771 IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
1772 }
1773
1774 Args.add(RValue::get(IsForEH), ArgTys[0]);
1775 Args.add(RValue::get(FP), ArgTys[1]);
1776
1777 // Arrange a two-arg function info and type.
1778 const CGFunctionInfo &FnInfo =
1779 CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
1780
1781 auto Callee = CGCallee::forDirect(OutlinedFinally);
1782 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1783 }
1784};
1785} // end anonymous namespace
1786
1787namespace {
1788/// Find all local variable captures in the statement.
1789struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1790 CodeGenFunction &ParentCGF;
1791 const VarDecl *ParentThis;
1792 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1793 Address SEHCodeSlot = Address::invalid();
1794 CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
1795 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1796
1797 // Return true if we need to do any capturing work.
1798 bool foundCaptures() {
1799 return !Captures.empty() || SEHCodeSlot.isValid();
1800 }
1801
1802 void Visit(const Stmt *S) {
1803 // See if this is a capture, then recurse.
1804 ConstStmtVisitor<CaptureFinder>::Visit(S);
1805 for (const Stmt *Child : S->children())
1806 if (Child)
1807 Visit(Child);
1808 }
1809
1810 void VisitDeclRefExpr(const DeclRefExpr *E) {
1811 // If this is already a capture, just make sure we capture 'this'.
1813 Captures.insert(ParentThis);
1814
1815 const auto *D = dyn_cast<VarDecl>(E->getDecl());
1816 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1817 Captures.insert(D);
1818 }
1819
1820 void VisitCXXThisExpr(const CXXThisExpr *E) {
1821 Captures.insert(ParentThis);
1822 }
1823
1824 void VisitCallExpr(const CallExpr *E) {
1825 // We only need to add parent frame allocations for these builtins in x86.
1826 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1827 return;
1828
1829 unsigned ID = E->getBuiltinCallee();
1830 switch (ID) {
1831 case Builtin::BI__exception_code:
1832 case Builtin::BI_exception_code:
1833 // This is the simple case where we are the outermost finally. All we
1834 // have to do here is make sure we escape this and recover it in the
1835 // outlined handler.
1836 if (!SEHCodeSlot.isValid())
1837 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1838 break;
1839 }
1840 }
1841};
1842} // end anonymous namespace
1843
1845 Address ParentVar,
1846 llvm::Value *ParentFP) {
1847 llvm::Value *RecoverCall = nullptr;
1849 // We are currently handling the following case:
1850 // ParentAlloca: An alloca for a local variable/direct argument
1851 // ParentArg: An argument pointer, pointing to an argument passed indirectly
1852 // Other case: A call to localrecover, if this is a nested __try.
1853 auto *ParentAlloca =
1854 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer());
1855 auto *ParentArg =
1856 dyn_cast_or_null<llvm::Argument>(ParentVar.getBasePointer());
1857 if (!ParentAlloca) {
1858 if (ParentArg) {
1859 llvm::BasicBlock &EntryBB = ParentCGF.CurFn->getEntryBlock();
1860 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1861 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1862 ParentArg->getType(), nullptr, ParentArg->getName() + ".spill");
1863 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1864 }
1865 }
1866
1867 if (ParentAlloca) {
1868 // Mark the variable escaped if nobody else referenced it and compute the
1869 // localescape index.
1870 auto InsertPair = ParentCGF.EscapedLocals.insert(
1871 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1872 int FrameEscapeIdx = InsertPair.first->second;
1873 // call ptr @llvm.localrecover(ptr @parentFn, ptr %fp, i32 N)
1874 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1875 &CGM.getModule(), llvm::Intrinsic::localrecover);
1876 RecoverCall = Builder.CreateCall(
1877 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1878 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1879 if (ParentArg)
1880 RecoverCall = Builder.CreateLoad(
1881 Address(RecoverCall, ParentArg->getType(), getPointerAlign()));
1882 } else {
1883 // If the parent didn't have an alloca, we're doing some nested outlining.
1884 // Just clone the existing localrecover call, but tweak the FP argument to
1885 // use our FP value. All other arguments are constants.
1886 auto *ParentRecover = cast<llvm::IntrinsicInst>(
1887 ParentVar.emitRawPointer(*this)->stripPointerCasts());
1888 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1889 "expected alloca or localrecover in parent LocalDeclMap");
1890 RecoverCall = ParentRecover->clone();
1891 cast<llvm::CallInst>(RecoverCall)->setArgOperand(1, ParentFP);
1892 cast<llvm::CallInst>(RecoverCall)
1893 ->insertBefore(AllocaInsertPt->getIterator());
1894 }
1895
1896 // Bitcast the variable, rename it, and insert it in the local decl map.
1897 llvm::Value *ChildVar =
1898 Builder.CreateBitCast(RecoverCall, ParentVar.getType());
1899 ChildVar->setName(ParentVar.getName());
1900 return ParentVar.withPointer(ChildVar, KnownNonNull);
1901}
1902
1904 const Stmt *OutlinedStmt,
1905 bool IsFilter) {
1906 // Find all captures in the Stmt.
1907 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1908 Finder.Visit(OutlinedStmt);
1909
1910 // We can exit early on x86_64 when there are no captures. We just have to
1911 // save the exception code in filters so that __exception_code() works.
1912 if (!Finder.foundCaptures() &&
1913 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1914 if (IsFilter)
1915 EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
1916 return;
1917 }
1918
1919 llvm::Value *EntryFP = nullptr;
1921 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1922 // 32-bit SEH filters need to be careful about FP recovery. The end of the
1923 // EH registration is passed in as the EBP physical register. We can
1924 // recover that with llvm.frameaddress(1).
1925 EntryFP = Builder.CreateCall(
1926 CGM.getIntrinsic(llvm::Intrinsic::frameaddress, AllocaInt8PtrTy),
1927 {Builder.getInt32(1)});
1928 } else {
1929 // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
1930 // second parameter.
1931 auto AI = CurFn->arg_begin();
1932 ++AI;
1933 EntryFP = &*AI;
1934 }
1935
1936 llvm::Value *ParentFP = EntryFP;
1937 if (IsFilter) {
1938 // Given whatever FP the runtime provided us in EntryFP, recover the true
1939 // frame pointer of the parent function. We only need to do this in filters,
1940 // since finally funclets recover the parent FP for us.
1941 llvm::Function *RecoverFPIntrin =
1942 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1943 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});
1944
1945 // if the parent is a _finally, the passed-in ParentFP is the FP
1946 // of parent _finally, not Establisher's FP (FP of outermost function).
1947 // Establkisher FP is 2nd paramenter passed into parent _finally.
1948 // Fortunately, it's always saved in parent's frame. The following
1949 // code retrieves it, and escapes it so that spill instruction won't be
1950 // optimized away.
1951 if (ParentCGF.ParentCGF != nullptr) {
1952 // Locate and escape Parent's frame_pointer.addr alloca
1953 // Depending on target, should be 1st/2nd one in LocalDeclMap.
1954 // Let's just scan for ImplicitParamDecl with VoidPtrTy.
1955 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
1956 for (auto &I : ParentCGF.LocalDeclMap) {
1957 const VarDecl *D = cast<VarDecl>(I.first);
1958 if (isa<ImplicitParamDecl>(D) &&
1959 D->getType() == getContext().VoidPtrTy) {
1960 assert(D->getName().starts_with("frame_pointer"));
1961 FramePtrAddrAlloca =
1962 cast<llvm::AllocaInst>(I.second.getBasePointer());
1963 break;
1964 }
1965 }
1966 assert(FramePtrAddrAlloca);
1967 auto InsertPair = ParentCGF.EscapedLocals.insert(
1968 std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
1969 int FrameEscapeIdx = InsertPair.first->second;
1970
1971 // an example of a filter's prolog::
1972 // %0 = call ptr @llvm.eh.recoverfp(@"?fin$0@0@main@@",..)
1973 // %1 = call ptr @llvm.localrecover(@"?fin$0@0@main@@",..)
1974 // %2 = load ptr, ptr %1, align 8
1975 // ==> %2 is the frame-pointer of outermost host function
1976 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1977 &CGM.getModule(), llvm::Intrinsic::localrecover);
1978 ParentFP = Builder.CreateCall(
1979 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1980 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1981 ParentFP = Builder.CreateLoad(
1982 Address(ParentFP, CGM.VoidPtrTy, getPointerAlign()));
1983 }
1984 }
1985
1986 // Create llvm.localrecover calls for all captures.
1987 for (const VarDecl *VD : Finder.Captures) {
1988 if (VD->getType()->isVariablyModifiedType()) {
1989 CGM.ErrorUnsupported(VD, "VLA captured by SEH");
1990 continue;
1991 }
1992 assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
1993 "captured non-local variable");
1994
1995 auto L = ParentCGF.LambdaCaptureFields.find(VD);
1996 if (L != ParentCGF.LambdaCaptureFields.end()) {
1997 LambdaCaptureFields[VD] = L->second;
1998 continue;
1999 }
2000
2001 // If this decl hasn't been declared yet, it will be declared in the
2002 // OutlinedStmt.
2003 auto I = ParentCGF.LocalDeclMap.find(VD);
2004 if (I == ParentCGF.LocalDeclMap.end())
2005 continue;
2006
2007 Address ParentVar = I->second;
2008 Address Recovered =
2009 recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);
2010 setAddrOfLocalVar(VD, Recovered);
2011
2012 if (isa<ImplicitParamDecl>(VD)) {
2013 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
2014 CXXThisAlignment = ParentCGF.CXXThisAlignment;
2015 CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
2016 if (ParentCGF.LambdaThisCaptureField) {
2017 LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
2018 // We are in a lambda function where "this" is captured so the
2019 // CXXThisValue need to be loaded from the lambda capture
2020 LValue ThisFieldLValue =
2022 if (!LambdaThisCaptureField->getType()->isPointerType()) {
2023 CXXThisValue = ThisFieldLValue.getAddress().emitRawPointer(*this);
2024 } else {
2025 CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
2026 .getScalarVal();
2027 }
2028 } else {
2029 CXXThisValue = CXXABIThisValue;
2030 }
2031 }
2032 }
2033
2034 if (Finder.SEHCodeSlot.isValid()) {
2035 SEHCodeSlotStack.push_back(
2036 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
2037 }
2038
2039 if (IsFilter)
2040 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
2041}
2042
2043/// Arrange a function prototype that can be called by Windows exception
2044/// handling personalities. On Win64, the prototype looks like:
2045/// RetTy func(void *EHPtrs, void *ParentFP);
2047 bool IsFilter,
2048 const Stmt *OutlinedStmt) {
2049 SourceLocation StartLoc = OutlinedStmt->getBeginLoc();
2050
2051 // Get the mangled function name.
2052 SmallString<128> Name;
2053 {
2054 llvm::raw_svector_ostream OS(Name);
2055 GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;
2056 assert(ParentSEHFn && "No CurSEHParent!");
2057 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
2058 if (IsFilter)
2059 Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
2060 else
2061 Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
2062 }
2063
2064 FunctionArgList Args;
2065 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2066 // All SEH finally functions take two parameters. Win64 filters take two
2067 // parameters. Win32 filters take no parameters.
2068 if (IsFilter) {
2069 Args.push_back(ImplicitParamDecl::Create(
2070 getContext(), /*DC=*/nullptr, StartLoc,
2071 &getContext().Idents.get("exception_pointers"),
2073 } else {
2074 Args.push_back(ImplicitParamDecl::Create(
2075 getContext(), /*DC=*/nullptr, StartLoc,
2076 &getContext().Idents.get("abnormal_termination"),
2077 getContext().UnsignedCharTy, ImplicitParamKind::Other));
2078 }
2079 Args.push_back(ImplicitParamDecl::Create(
2080 getContext(), /*DC=*/nullptr, StartLoc,
2081 &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy,
2083 }
2084
2085 QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
2086
2087 const CGFunctionInfo &FnInfo =
2088 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2089
2090 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
2091 llvm::Function *Fn = llvm::Function::Create(
2092 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
2093
2094 IsOutlinedSEHHelper = true;
2095
2096 StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
2097 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
2098 CurSEHParent = ParentCGF.CurSEHParent;
2099
2100 CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
2101 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
2102}
2103
2104/// Create a stub filter function that will ultimately hold the code of the
2105/// filter expression. The EH preparation passes in LLVM will outline the code
2106/// from the main function body into this stub.
2107llvm::Function *
2109 const SEHExceptStmt &Except) {
2110 const Expr *FilterExpr = Except.getFilterExpr();
2111 startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
2112
2113 // Emit the original filter expression, convert to i32, and return.
2114 llvm::Value *R = EmitScalarExpr(FilterExpr);
2115 R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
2116 FilterExpr->getType()->isSignedIntegerType());
2117 Builder.CreateStore(R, ReturnValue);
2118
2119 FinishFunction(FilterExpr->getEndLoc());
2120
2121 return CurFn;
2122}
2123
2124llvm::Function *
2126 const SEHFinallyStmt &Finally) {
2127 const Stmt *FinallyBlock = Finally.getBlock();
2128 startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
2129
2130 // Emit the original filter expression, convert to i32, and return.
2131 EmitStmt(FinallyBlock);
2132
2133 FinishFunction(FinallyBlock->getEndLoc());
2134
2135 return CurFn;
2136}
2137
2139 llvm::Value *ParentFP,
2140 llvm::Value *EntryFP) {
2141 // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
2142 // __exception_info intrinsic.
2143 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2144 // On Win64, the info is passed as the first parameter to the filter.
2145 SEHInfo = &*CurFn->arg_begin();
2146 SEHCodeSlotStack.push_back(
2147 CreateMemTempWithoutCast(getContext().IntTy, "__exception_code"));
2148 } else {
2149 // On Win32, the EBP on entry to the filter points to the end of an
2150 // exception registration object. It contains 6 32-bit fields, and the info
2151 // pointer is stored in the second field. So, GEP 20 bytes backwards and
2152 // load the pointer.
2153 SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
2154 SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
2156 ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
2157 }
2158
2159 // Save the exception code in the exception slot to unify exception access in
2160 // the filter function and the landing pad.
2161 // struct EXCEPTION_POINTERS {
2162 // EXCEPTION_RECORD *ExceptionRecord;
2163 // CONTEXT *ContextRecord;
2164 // };
2165 // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
2166 llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());
2167 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
2168 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);
2169 Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign());
2170 llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign());
2171 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2172 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2173}
2174
2176 // Sema should diagnose calling this builtin outside of a filter context, but
2177 // don't crash if we screw up.
2178 if (!SEHInfo)
2179 return llvm::PoisonValue::get(Int8PtrTy);
2180 assert(SEHInfo->getType() == Int8PtrTy);
2181 return SEHInfo;
2182}
2183
2185 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2186 return Builder.CreateLoad(SEHCodeSlotStack.back());
2187}
2188
2190 // Abnormal termination is just the first parameter to the outlined finally
2191 // helper.
2192 auto AI = CurFn->arg_begin();
2193 return Builder.CreateZExt(&*AI, Int32Ty);
2194}
2195
2197 llvm::Function *FinallyFunc) {
2198 EHStack.pushCleanup<PerformSEHFinally>(
2199 static_cast<CleanupKind>(Kind | SEHFinallyCleanup), FinallyFunc);
2200}
2201
2203 CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
2204 HelperCGF.ParentCGF = this;
2205 if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
2206 // Outline the finally block.
2207 llvm::Function *FinallyFunc =
2208 HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
2209
2210 // Push a cleanup for __finally blocks.
2211 EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHSEHFinallyCleanup,
2212 FinallyFunc);
2213 return;
2214 }
2215
2216 // Otherwise, we must have an __except block.
2217 const SEHExceptStmt *Except = S.getExceptHandler();
2218 assert(Except);
2219 EHCatchScope *CatchScope = EHStack.pushCatch(1);
2220 SEHCodeSlotStack.push_back(
2221 CreateMemTempWithoutCast(getContext().IntTy, "__exception_code"));
2222
2223 // If the filter is known to evaluate to 1, then we can use the clause
2224 // "catch i8* null". We can't do this on x86 because the filter has to save
2225 // the exception code.
2226 llvm::Constant *C =
2228 getContext().IntTy);
2229 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2230 C->isOneValue()) {
2231 CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
2232 return;
2233 }
2234
2235 // In general, we have to emit an outlined filter function. Use the function
2236 // in place of the RTTI typeinfo global that C++ EH uses.
2237 llvm::Function *FilterFunc =
2238 HelperCGF.GenerateSEHFilterFunction(*this, *Except);
2239 CatchScope->setHandler(0, FilterFunc, createBasicBlock("__except.ret"));
2240}
2241
2243 // Just pop the cleanup if it's a __finally block.
2244 if (S.getFinallyHandler()) {
2246 return;
2247 }
2248
2249 // IsEHa: emit an invoke _seh_try_end() to mark end of FT flow
2250 if (getLangOpts().EHAsynch && Builder.GetInsertBlock()) {
2251 llvm::FunctionCallee SehTryEnd = getSehTryEndFn(CGM);
2252 EmitRuntimeCallOrInvoke(SehTryEnd);
2253 }
2254
2255 // Otherwise, we must have an __except block.
2256 const SEHExceptStmt *Except = S.getExceptHandler();
2257 assert(Except && "__try must have __finally xor __except");
2258 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2259
2260 // Don't emit the __except block if the __try block lacked invokes.
2261 // TODO: Model unwind edges from instructions, either with iload / istore or
2262 // a try body function.
2263 if (!CatchScope.hasEHBranches()) {
2264 // Even though we skip emitting the __except body, diagnose variables
2265 // with non-trivial destructors that would normally be caught by
2266 // EmitAutoVarCleanups.
2267 if (getLangOpts().CXXExceptions && currentFunctionUsesSEHTry())
2268 for (const Stmt *S : Except->getBlock()->body())
2269 if (const auto *DS = dyn_cast<DeclStmt>(S))
2270 for (const Decl *D : DS->decls())
2271 if (const auto *VD = dyn_cast<VarDecl>(D))
2272 if (VD->needsDestruction(getContext()))
2274 VD->getLocation(), diag::err_seh_object_unwinding);
2275 CatchScope.clearHandlerBlocks();
2276 EHStack.popCatch();
2277 SEHCodeSlotStack.pop_back();
2278 return;
2279 }
2280
2281 // The fall-through block.
2282 llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
2283
2284 // We just emitted the body of the __try; jump to the continue block.
2285 if (HaveInsertPoint())
2286 Builder.CreateBr(ContBB);
2287
2288 // Check if our filter function returned true.
2289 emitCatchDispatchBlock(*this, CatchScope);
2290
2291 // Grab the block before we pop the handler.
2292 llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
2293 EHStack.popCatch();
2294
2295 EmitBlockAfterUses(CatchPadBB);
2296
2297 // __except blocks don't get outlined into funclets, so immediately do a
2298 // catchret.
2299 llvm::CatchPadInst *CPI =
2300 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
2301 llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
2302 Builder.CreateCatchRet(CPI, ExceptBB);
2303 EmitBlock(ExceptBB);
2304
2305 // On Win64, the exception code is returned in EAX. Copy it into the slot.
2306 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2307 llvm::Function *SEHCodeIntrin =
2308 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2309 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2310 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2311 }
2312
2313 // Emit the __except body.
2314 EmitStmt(Except->getBlock());
2315
2316 // End the lifetime of the exception code.
2317 SEHCodeSlotStack.pop_back();
2318
2319 if (HaveInsertPoint())
2320 Builder.CreateBr(ContBB);
2321
2322 EmitBlock(ContBB);
2323}
2324
2326 // If this code is reachable then emit a stop point (if generating
2327 // debug info). We have to do this ourselves because we are on the
2328 // "simple" statement path.
2329 if (HaveInsertPoint())
2330 EmitStopPoint(&S);
2331
2332 // This must be a __leave from a __finally block, which we warn on and is UB.
2333 // Just emit unreachable.
2334 if (!isSEHTryScope()) {
2335 Builder.CreateUnreachable();
2336 Builder.ClearInsertionPoint();
2337 return;
2338 }
2339
2341}
#define V(N, I)
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)
Emit the dispatch block for a filter scope if necessary.
static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)
static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function.
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
Emit the structure of the dispatch block for the given catch scope.
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
static bool isNonEHScope(const EHScope &S)
Check whether this is a non-EH scope, i.e.
static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
Returns the value to inject into a selector to indicate the presence of a catch-all.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
llvm::MachO::Target Target
Definition MachO.h:51
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
CanQualType LongTy
CanQualType VoidTy
DiagnosticsEngine & getDiagnostics() const
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:29
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
const Expr * getSubExpr() const
Definition ExprCXX.h:1232
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:70
CXXCatchStmt * getHandler(unsigned i)
Definition StmtCXX.h:109
unsigned getNumHandlers() const
Definition StmtCXX.h:108
CompoundStmt * getTryBlock()
Definition StmtCXX.h:101
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition Expr.cpp:1620
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:5079
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
bool hasDWARFExceptions() const
bool hasWasmExceptions() const
bool hasSjLjExceptions() const
bool hasSEHExceptions() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition Address.h:128
llvm::Value * getBasePointer() const
Definition Address.h:198
static Address invalid()
Definition Address.h:176
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:253
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Definition Address.h:261
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Definition Address.h:276
llvm::StringRef getName() const
Return the IR name of the pointer value.
Definition Address.h:218
bool isValid() const
Definition Address.h:177
llvm::PointerType * getType() const
Return the type of the pointer value.
Definition Address.h:204
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
Definition CGBuilder.h:174
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition CGBuilder.h:146
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Definition CGBuilder.h:153
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:118
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
Definition CGBuilder.h:168
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Definition CGBuilder.h:138
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition CGCall.h:140
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
Definition CGCall.h:277
void add(RValue rvalue, QualType type)
Definition CGCall.h:305
void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn)
Enters a finally block for an implementation using zero-cost exceptions.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitCXXTryStmt(const CXXTryStmt &S)
llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)
llvm::BasicBlock * getInvokeDestImpl()
llvm::Type * ConvertType(QualType T)
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
Definition CGCall.cpp:5485
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
Definition CGCall.cpp:5512
llvm::Value * EmitSEHAbnormalTermination()
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
llvm::AllocaInst * EHSelectorSlot
The selector slot.
llvm::BasicBlock * EmitLandingPad()
Emits a landing pad for the current EH stack.
void EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
Definition CGStmt.cpp:688
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::BasicBlock * getUnreachableBlock()
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
llvm::Value * ExceptionSlot
The exception slot.
void EmitAnyExprToExn(const Expr *E, Address Addr)
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
const TargetInfo & getTarget() const
llvm::BasicBlock * getTerminateHandler()
getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...
void EnterSEHTryStmt(const SEHTryStmt &S)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
Definition CGExpr.cpp:2542
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Definition CGExpr.cpp:160
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
Arrange a function prototype that can be called by Windows exception handling personalities.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
Definition CGCall.cpp:5668
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
Definition CGExpr.cpp:232
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
Scan the outlined statement for captures from the parent function.
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
Definition CGStmt.cpp:48
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
Definition CGExpr.cpp:310
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
Definition CGStmt.cpp:58
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertTypeForMem(QualType T)
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
void ExitSEHTryStmt(const SEHTryStmt &S)
LValue EmitLValueForLambdaField(const FieldDecl *Field)
Definition CGExpr.cpp:5684
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
void WasmEmitFallthroughRethrow(llvm::BasicBlock *WasmCatchStartBlock)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
Definition CGExpr.cpp:4628
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void EmitSEHTryStmt(const SEHTryStmt &S)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)
Create a stub filter function that will ultimately hold the code of the filter expression.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
Definition CGStmt.cpp:651
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
Definition CGCall.cpp:769
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
A scope which attempts to handle some, possibly all, types of exceptions.
Definition CGCleanup.h:165
const Handler & getHandler(unsigned I) const
Definition CGCleanup.h:226
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
Definition CGCleanup.h:214
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
Definition CGCleanup.h:210
unsigned getNumHandlers() const
Definition CGCleanup.h:206
An exceptions scope which filters exceptions thrown through it.
Definition CGCleanup.h:516
llvm::Value * getFilter(unsigned i) const
Definition CGCleanup.h:546
unsigned getNumFilters() const
Definition CGCleanup.h:539
A non-stable pointer into the scope stack.
Definition CGCleanup.h:570
A saved depth on the scope stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
Definition CGCleanup.h:630
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
A protected scope for zero-cost EH handling.
Definition CGCleanup.h:45
llvm::BasicBlock * getCachedLandingPad() const
Definition CGCleanup.h:133
EHScopeStack::stable_iterator getEnclosingEHScope() const
Definition CGCleanup.h:155
llvm::BasicBlock * getCachedEHDispatchBlock() const
Definition CGCleanup.h:141
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
Definition CGCleanup.h:145
bool hasEHBranches() const
Definition CGCleanup.h:149
FunctionArgList - Type for representing both the decl and type of parameters to a function.
Definition CGCall.h:378
LValue - This represents an lvalue references.
Definition CGValue.h:183
Address getAddress() const
Definition CGValue.h:373
static RValue get(llvm::Value *V)
Definition CGValue.h:99
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Definition CGValue.h:72
body_range body()
Definition Stmt.h:1815
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Definition Expr.h:1494
ValueDecl * getDecl()
Definition Expr.h:1358
SourceLocation getLocation() const
Definition DeclBase.h:447
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
Definition Expr.h:113
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:283
QualType getType() const
Definition Expr.h:145
Represents a function declaration or definition.
Definition Decl.h:2059
bool usesSEHTry() const
Indicates the function uses __try.
Definition Decl.h:2645
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Definition Decl.cpp:4097
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5421
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5728
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5779
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5771
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:4006
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:60
const Decl * getDecl() const
Definition GlobalDecl.h:115
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Definition Decl.cpp:5663
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Definition Mangle.h:56
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
Represents Objective-C's @throw statement.
Definition StmtObjC.h:358
Kind getKind() const
Definition ObjCRuntime.h:77
const VersionTuple & getVersion() const
Definition ObjCRuntime.h:78
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
Definition ObjCRuntime.h:35
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Definition ObjCRuntime.h:40
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
Definition ObjCRuntime.h:56
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
Definition ObjCRuntime.h:59
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Definition ObjCRuntime.h:45
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
Definition ObjCRuntime.h:53
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
Definition ObjCRuntime.h:49
A (possibly-)qualified type.
Definition TypeBase.h:938
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8542
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8687
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8596
The collection of all-type qualifiers we support.
Definition TypeBase.h:332
CompoundStmt * getBlock() const
Definition Stmt.h:3805
Expr * getFilterExpr() const
Definition Stmt.h:3801
CompoundStmt * getBlock() const
Definition Stmt.h:3842
Represents a __leave statement.
Definition Stmt.h:3910
CompoundStmt * getTryBlock() const
Definition Stmt.h:3886
SEHFinallyStmt * getFinallyHandler() const
Definition Stmt.cpp:1343
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition Stmt.cpp:1339
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:85
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
child_range children()
Definition Stmt.cpp:304
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Exposes information about the current target.
Definition TargetInfo.h:226
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2296
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition TypeBase.h:2877
bool isObjCObjectPointerType() const
Definition TypeBase.h:8918
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9338
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Definition Decl.h:1286
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ NormalAndEHSEHFinallyCleanup
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
@ Address
A pointer to a ValueDecl.
Definition Primitives.h:28
bool Load(InterpState &S, CodePtr OpPC)
Definition Interp.h:2203
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
@ CPlusPlus17
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1775
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Dynamic
throw(T1, T2)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
Definition CGCleanup.h:39
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
Definition CGCleanup.h:175
llvm::BasicBlock * Block
The catch handler for this type.
Definition CGCleanup.h:178
The exceptions personality for a function.
Definition CGCleanup.h:667
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
static const EHPersonality XL_CPlusPlus
Definition CGCleanup.h:694
static const EHPersonality GNU_ObjC_SJLJ
Definition CGCleanup.h:682
static const EHPersonality ZOS_CPlusPlus
Definition CGCleanup.h:695
static const EHPersonality GNUstep_ObjC
Definition CGCleanup.h:684
static const EHPersonality MSVC_CxxFrameHandler3
Definition CGCleanup.h:692
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
Definition CGCleanup.h:699
static const EHPersonality MSVC_C_specific_handler
Definition CGCleanup.h:691
static const EHPersonality GNU_CPlusPlus_SEH
Definition CGCleanup.h:689
static const EHPersonality GNU_ObjC
Definition CGCleanup.h:681
static const EHPersonality GNU_CPlusPlus_SJLJ
Definition CGCleanup.h:688
static const EHPersonality GNU_C_SJLJ
Definition CGCleanup.h:679
static const EHPersonality GNU_C
Definition CGCleanup.h:678
static const EHPersonality NeXT_ObjC
Definition CGCleanup.h:686
static const EHPersonality GNU_CPlusPlus
Definition CGCleanup.h:687
static const EHPersonality GNU_ObjCXX
Definition CGCleanup.h:685
static const EHPersonality GNU_C_SEH
Definition CGCleanup.h:680
static const EHPersonality MSVC_except_handler
Definition CGCleanup.h:690
static const EHPersonality GNU_ObjC_SEH
Definition CGCleanup.h:683
static const EHPersonality GNU_Wasm_CPlusPlus
Definition CGCleanup.h:693