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