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