clang 22.0.0git
CGException.cpp
Go to the documentation of this file.
1//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with C++ exception related code generation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGCXXABI.h"
14#include "CGCleanup.h"
15#include "CGDebugInfo.h"
16#include "CGObjCRuntime.h"
17#include "CodeGenFunction.h"
18#include "ConstantEmitter.h"
19#include "TargetInfo.h"
20#include "clang/AST/Mangle.h"
21#include "clang/AST/StmtCXX.h"
22#include "clang/AST/StmtObjC.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsWebAssembly.h"
28#include "llvm/Support/SaveAndRestore.h"
29
30using namespace clang;
31using namespace CodeGen;
32
33static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM) {
34 // void __cxa_free_exception(void *thrown_exception);
35
36 llvm::FunctionType *FTy =
37 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
38
39 return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
40}
41
42static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM) {
43 llvm::FunctionType *FTy =
44 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
45 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");
46}
47
48static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM) {
49 llvm::FunctionType *FTy =
50 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
51 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");
52}
53
54static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {
55 // void __cxa_call_unexpected(void *thrown_exception);
56
57 llvm::FunctionType *FTy =
58 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
59
60 return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
61}
62
63llvm::FunctionCallee CodeGenModule::getTerminateFn() {
64 // void __terminate();
65
66 llvm::FunctionType *FTy =
67 llvm::FunctionType::get(VoidTy, /*isVarArg=*/false);
68
69 StringRef name;
70
71 // In C++, use std::terminate().
72 if (getLangOpts().CPlusPlus &&
73 getTarget().getCXXABI().isItaniumFamily()) {
74 name = "_ZSt9terminatev";
75 } else if (getLangOpts().CPlusPlus &&
76 getTarget().getCXXABI().isMicrosoft()) {
77 if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
78 name = "__std_terminate";
79 else
80 name = "?terminate@@YAXXZ";
81 } else if (getLangOpts().ObjC &&
83 name = "objc_terminate";
84 else
85 name = "abort";
86 return CreateRuntimeFunction(FTy, name);
87}
88
89static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,
90 StringRef Name) {
91 llvm::FunctionType *FTy =
92 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
93
94 return CGM.CreateRuntimeFunction(FTy, Name);
95}
96
97const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
98const EHPersonality
99EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
100const EHPersonality
101EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
102const EHPersonality
103EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
104const EHPersonality
105EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
106const EHPersonality
107EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
108const EHPersonality
109EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
110const EHPersonality
111EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
112const EHPersonality
113EHPersonality::GNU_ObjC_SJLJ = {"__gnu_objc_personality_sj0", "objc_exception_throw"};
114const EHPersonality
115EHPersonality::GNU_ObjC_SEH = {"__gnu_objc_personality_seh0", "objc_exception_throw"};
116const EHPersonality
117EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
118const EHPersonality
119EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
120const EHPersonality
121EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
122const EHPersonality
123EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
124const EHPersonality
125EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
126const EHPersonality
127EHPersonality::GNU_Wasm_CPlusPlus = { "__gxx_wasm_personality_v0", nullptr };
128const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
129 nullptr};
130const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
131 nullptr};
132
134 const CodeGenOptions &CGOpts) {
135 const llvm::Triple &T = Target.getTriple();
136 if (T.isWindowsMSVCEnvironment())
138 if (CGOpts.hasSjLjExceptions())
140 if (CGOpts.hasDWARFExceptions())
142 if (CGOpts.hasSEHExceptions())
145}
146
148 const CodeGenOptions &CGOpts,
149 const LangOptions &L) {
150 const llvm::Triple &T = Target.getTriple();
151 if (T.isWindowsMSVCEnvironment())
153
154 switch (L.ObjCRuntime.getKind()) {
156 return getCPersonality(Target, CGOpts);
158 case ObjCRuntime::iOS:
162 if (T.isOSCygMing())
164 else if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
166 [[fallthrough]];
167 case ObjCRuntime::GCC:
169 if (CGOpts.hasSjLjExceptions())
171 if (CGOpts.hasSEHExceptions())
174 }
175 llvm_unreachable("bad runtime kind");
176}
177
179 const CodeGenOptions &CGOpts) {
180 const llvm::Triple &T = Target.getTriple();
181 if (T.isWindowsMSVCEnvironment())
183 if (T.isOSAIX())
185 if (CGOpts.hasSjLjExceptions())
187 if (CGOpts.hasDWARFExceptions())
189 if (CGOpts.hasSEHExceptions())
191 if (CGOpts.hasWasmExceptions())
193 if (T.isOSzOS())
196}
197
198/// Determines the personality function to use when both C++
199/// and Objective-C exceptions are being caught.
201 const CodeGenOptions &CGOpts,
202 const LangOptions &L) {
203 if (Target.getTriple().isWindowsMSVCEnvironment())
205
206 switch (L.ObjCRuntime.getKind()) {
207 // In the fragile ABI, just use C++ exception handling and hope
208 // they're not doing crazy exception mixing.
210 return getCXXPersonality(Target, CGOpts);
211
212 // The ObjC personality defers to the C++ personality for non-ObjC
213 // handlers. Unlike the C++ case, we use the same personality
214 // function on targets using (backend-driven) SJLJ EH.
216 case ObjCRuntime::iOS:
218 return getObjCPersonality(Target, CGOpts, L);
219
221 return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
223
224 // The GCC runtime's personality function inherently doesn't support
225 // mixed EH. Use the ObjC personality just to avoid returning null.
226 case ObjCRuntime::GCC:
228 return getObjCPersonality(Target, CGOpts, L);
229 }
230 llvm_unreachable("bad runtime kind");
231}
232
233static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
234 if (T.getArch() == llvm::Triple::x86)
237}
238
240 const FunctionDecl *FD) {
241 const llvm::Triple &T = CGM.getTarget().getTriple();
242 const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();
243 const LangOptions &L = CGM.getLangOpts();
244 const TargetInfo &Target = CGM.getTarget();
245
246 // Functions using SEH get an SEH personality.
247 if (FD && FD->usesSEHTry())
248 return getSEHPersonalityMSVC(T);
249
250 if (L.ObjC)
251 return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)
252 : getObjCPersonality(Target, CGOpts, L);
253 return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)
254 : getCPersonality(Target, CGOpts);
255}
256
258 const auto *FD = CGF.CurCodeDecl;
259 // For outlined finallys and filters, use the SEH personality in case they
260 // contain more SEH. This mostly only affects finallys. Filters could
261 // hypothetically use gnu statement expressions to sneak in nested SEH.
262 FD = FD ? FD : CGF.CurSEHParent.getDecl();
263 return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
264}
265
266static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,
267 const EHPersonality &Personality) {
268 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
269 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.
403 pushFullExprCleanup<FreeException>(EHCleanup, addr.emitRawPointer(*this));
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
427 if (!ExceptionSlot)
430}
431
433 if (!EHSelectorSlot)
434 EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
436}
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.isNVPTX() || T.isAMDGCN())) {
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())
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.
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
507 if (EST == EST_DynamicNone)
509 else
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 EST == EST_Dynamic)
525 diag::warn_wasm_dynamic_exception_spec_ignored)
527
528 unsigned NumExceptions = Proto->getNumExceptions();
529 EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
530
531 for (unsigned I = 0; I != NumExceptions; ++I) {
532 QualType Ty = Proto->getExceptionType(I);
534 llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
535 /*ForEH=*/true);
536 Filter->setFilter(I, EHType);
537 }
538 } else if (Proto->canThrow() == CT_Cannot) {
539 // noexcept functions are simple terminate scopes.
540 if (!getLangOpts().EHAsynch) // -EHa: HW exception still can occur
542 }
543}
544
545/// Emit the dispatch block for a filter scope if necessary.
547 EHFilterScope &filterScope) {
548 llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
549 if (!dispatchBlock) return;
550 if (dispatchBlock->use_empty()) {
551 delete dispatchBlock;
552 return;
553 }
554
555 CGF.EmitBlockAfterUses(dispatchBlock);
556
557 // If this isn't a catch-all filter, we need to check whether we got
558 // here because the filter triggered.
559 if (filterScope.getNumFilters()) {
560 // Load the selector value.
561 llvm::Value *selector = CGF.getSelectorFromSlot();
562 llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
563
564 llvm::Value *zero = CGF.Builder.getInt32(0);
565 llvm::Value *failsFilter =
566 CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
567 CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,
568 CGF.getEHResumeBlock(false));
569
570 CGF.EmitBlock(unexpectedBB);
571 }
572
573 // Call __cxa_call_unexpected. This doesn't need to be an invoke
574 // because __cxa_call_unexpected magically filters exceptions
575 // according to the last landing pad the exception was thrown
576 // into. Seriously.
577 llvm::Value *exn = CGF.getExceptionFromSlot();
578 CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)
579 ->setDoesNotReturn();
580 CGF.Builder.CreateUnreachable();
581}
582
584 if (!CGM.getLangOpts().CXXExceptions)
585 return;
586
587 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
588 if (!FD) {
589 // Check if CapturedDecl is nothrow and pop terminate scope for it.
590 if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
591 if (CD->isNothrow() && !EHStack.empty())
593 }
594 return;
595 }
596 const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
597 if (!Proto)
598 return;
599
601 if (EST == EST_Dynamic ||
602 (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {
603 // TODO: Revisit exception specifications for the MS ABI. There is a way to
604 // encode these in an object file but MSVC doesn't do anything with it.
606 return;
607 // In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
608 // case of throw with types, we ignore it and print a warning for now.
609 // TODO Correctly handle exception specification in wasm
611 if (EST == EST_DynamicNone)
613 return;
614 }
615 EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
616 emitFilterDispatchBlock(*this, filterScope);
618 } else if (Proto->canThrow() == CT_Cannot &&
619 /* possible empty when under async exceptions */
620 !EHStack.empty()) {
622 }
623}
624
626 const llvm::Triple &T = Target.getTriple();
627 // If we encounter a try statement on in an OpenMP target region offloaded to
628 // a GPU, we treat it as a basic block.
629 const bool IsTargetDevice =
630 (CGM.getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()));
631 if (!IsTargetDevice)
633 EmitStmt(S.getTryBlock());
634 if (!IsTargetDevice)
636}
637
638void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
639 unsigned NumHandlers = S.getNumHandlers();
640 EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
641
642 for (unsigned I = 0; I != NumHandlers; ++I) {
643 const CXXCatchStmt *C = S.getHandler(I);
644
645 llvm::BasicBlock *Handler = createBasicBlock("catch");
646 if (C->getExceptionDecl()) {
647 // FIXME: Dropping the reference type on the type into makes it
648 // impossible to correctly implement catch-by-reference
649 // semantics for pointers. Unfortunately, this is what all
650 // existing compilers do, and it's not clear that the standard
651 // personality routine is capable of doing this right. See C++ DR 388:
652 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
653 Qualifiers CaughtTypeQuals;
655 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
656
657 CatchTypeInfo TypeInfo{nullptr, 0};
658 if (CaughtType->isObjCObjectPointerType())
659 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
660 else
662 CaughtType, C->getCaughtType());
663 CatchScope->setHandler(I, TypeInfo, Handler);
664 } else {
665 // No exception decl indicates '...', a catch-all.
666 CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
667 // Under async exceptions, catch(...) need to catch HW exception too
668 // Mark scope with SehTryBegin as a SEH __try scope
669 if (getLangOpts().EHAsynch)
671 }
672 }
673}
674
675llvm::BasicBlock *
678 return getFuncletEHDispatchBlock(si);
679
680 // The dispatch block for the end of the scope chain is a block that
681 // just resumes unwinding.
682 if (si == EHStack.stable_end())
683 return getEHResumeBlock(true);
684
685 // Otherwise, we should look at the actual scope.
686 EHScope &scope = *EHStack.find(si);
687
688 llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
689 if (!dispatchBlock) {
690 switch (scope.getKind()) {
691 case EHScope::Catch: {
692 // Apply a special case to a single catch-all.
693 EHCatchScope &catchScope = cast<EHCatchScope>(scope);
694 if (catchScope.getNumHandlers() == 1 &&
695 catchScope.getHandler(0).isCatchAll()) {
696 dispatchBlock = catchScope.getHandler(0).Block;
697
698 // Otherwise, make a dispatch block.
699 } else {
700 dispatchBlock = createBasicBlock("catch.dispatch");
701 }
702 break;
703 }
704
705 case EHScope::Cleanup:
706 dispatchBlock = createBasicBlock("ehcleanup");
707 break;
708
709 case EHScope::Filter:
710 dispatchBlock = createBasicBlock("filter.dispatch");
711 break;
712
714 dispatchBlock = getTerminateHandler();
715 break;
716 }
717 scope.setCachedEHDispatchBlock(dispatchBlock);
718 }
719 return dispatchBlock;
720}
721
722llvm::BasicBlock *
724 // Returning nullptr indicates that the previous dispatch block should unwind
725 // to caller.
726 if (SI == EHStack.stable_end())
727 return nullptr;
728
729 // Otherwise, we should look at the actual scope.
730 EHScope &EHS = *EHStack.find(SI);
731
732 llvm::BasicBlock *DispatchBlock = EHS.getCachedEHDispatchBlock();
733 if (DispatchBlock)
734 return DispatchBlock;
735
736 if (EHS.getKind() == EHScope::Terminate)
737 DispatchBlock = getTerminateFunclet();
738 else
739 DispatchBlock = createBasicBlock();
740 CGBuilderTy Builder(*this, DispatchBlock);
741
742 switch (EHS.getKind()) {
743 case EHScope::Catch:
744 DispatchBlock->setName("catch.dispatch");
745 break;
746
747 case EHScope::Cleanup:
748 DispatchBlock->setName("ehcleanup");
749 break;
750
751 case EHScope::Filter:
752 llvm_unreachable("exception specifications not handled yet!");
753
755 DispatchBlock->setName("terminate");
756 break;
757 }
758 EHS.setCachedEHDispatchBlock(DispatchBlock);
759 return DispatchBlock;
760}
761
762/// Check whether this is a non-EH scope, i.e. a scope which doesn't
763/// affect exception handling. Currently, the only non-EH scopes are
764/// normal-only cleanup scopes.
765static bool isNonEHScope(const EHScope &S) {
766 switch (S.getKind()) {
767 case EHScope::Cleanup:
768 return !cast<EHCleanupScope>(S).isEHCleanup();
769 case EHScope::Filter:
770 case EHScope::Catch:
772 return false;
773 }
774
775 llvm_unreachable("Invalid EHScope Kind!");
776}
777
779 assert(EHStack.requiresLandingPad());
780 assert(!EHStack.empty());
781
782 // If exceptions are disabled/ignored and SEH is not in use, then there is no
783 // invoke destination. SEH "works" even if exceptions are off. In practice,
784 // this means that C++ destructors and other EH cleanups don't run, which is
785 // consistent with MSVC's behavior, except in the presence of -EHa
786 const LangOptions &LO = CGM.getLangOpts();
787 if (!LO.Exceptions || LO.IgnoreExceptions) {
788 if (!LO.Borland && !LO.MicrosoftExt)
789 return nullptr;
791 return nullptr;
792 }
793
794 // CUDA device code doesn't have exceptions.
795 if (LO.CUDA && LO.CUDAIsDevice)
796 return nullptr;
797
798 // Check the innermost scope for a cached landing pad. If this is
799 // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
800 llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
801 if (LP) return LP;
802
803 const EHPersonality &Personality = EHPersonality::get(*this);
804
805 if (!CurFn->hasPersonalityFn())
806 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
807
808 if (Personality.usesFuncletPads()) {
809 // We don't need separate landing pads in the funclet model.
811 } else {
812 // Build the landing pad for this scope.
813 LP = EmitLandingPad();
814 }
815
816 assert(LP);
817
818 // Cache the landing pad on the innermost scope. If this is a
819 // non-EH scope, cache the landing pad on the enclosing scope, too.
820 for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
821 ir->setCachedLandingPad(LP);
822 if (!isNonEHScope(*ir)) break;
823 }
824
825 return LP;
826}
827
829 assert(EHStack.requiresLandingPad());
830 assert(!CGM.getLangOpts().IgnoreExceptions &&
831 "LandingPad should not be emitted when -fignore-exceptions are in "
832 "effect.");
833 EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
834 switch (innermostEHScope.getKind()) {
836 return getTerminateLandingPad();
837
838 case EHScope::Catch:
839 case EHScope::Cleanup:
840 case EHScope::Filter:
841 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
842 return lpad;
843 }
844
845 // Save the current IR generation state.
846 CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
847 auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
848
849 // Create and configure the landing pad.
850 llvm::BasicBlock *lpad = createBasicBlock("lpad");
851 EmitBlock(lpad);
852
853 llvm::LandingPadInst *LPadInst =
854 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
855
856 llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
858 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
860
861 // Save the exception pointer. It's safe to use a single exception
862 // pointer per function because EH cleanups can never have nested
863 // try/catches.
864 // Build the landingpad instruction.
865
866 // Accumulate all the handlers in scope.
867 bool hasCatchAll = false;
868 bool hasCleanup = false;
869 bool hasFilter = false;
872 for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E;
873 ++I) {
874
875 switch (I->getKind()) {
876 case EHScope::Cleanup:
877 // If we have a cleanup, remember that.
878 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
879 continue;
880
881 case EHScope::Filter: {
882 assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
883 assert(!hasCatchAll && "EH filter reached after catch-all");
884
885 // Filter scopes get added to the landingpad in weird ways.
886 EHFilterScope &filter = cast<EHFilterScope>(*I);
887 hasFilter = true;
888
889 // Add all the filter values.
890 for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
891 filterTypes.push_back(filter.getFilter(i));
892 goto done;
893 }
894
896 // Terminate scopes are basically catch-alls.
897 assert(!hasCatchAll);
898 hasCatchAll = true;
899 goto done;
900
901 case EHScope::Catch:
902 break;
903 }
904
905 EHCatchScope &catchScope = cast<EHCatchScope>(*I);
906 for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
907 EHCatchScope::Handler handler = catchScope.getHandler(hi);
908 assert(handler.Type.Flags == 0 &&
909 "landingpads do not support catch handler flags");
910
911 // If this is a catch-all, register that and abort.
912 if (!handler.Type.RTTI) {
913 assert(!hasCatchAll);
914 hasCatchAll = true;
915 goto done;
916 }
917
918 // Check whether we already have a handler for this type.
919 if (catchTypes.insert(handler.Type.RTTI).second)
920 // If not, add it directly to the landingpad.
921 LPadInst->addClause(handler.Type.RTTI);
922 }
923 }
924
925 done:
926 // If we have a catch-all, add null to the landingpad.
927 assert(!(hasCatchAll && hasFilter));
928 if (hasCatchAll) {
929 LPadInst->addClause(getCatchAllValue(*this));
930
931 // If we have an EH filter, we need to add those handlers in the
932 // right place in the landingpad, which is to say, at the end.
933 } else if (hasFilter) {
934 // Create a filter expression: a constant array indicating which filter
935 // types there are. The personality routine only lands here if the filter
936 // doesn't match.
938 llvm::ArrayType *AType =
939 llvm::ArrayType::get(!filterTypes.empty() ?
940 filterTypes[0]->getType() : Int8PtrTy,
941 filterTypes.size());
942
943 for (llvm::Value *filterType : filterTypes)
944 Filters.push_back(cast<llvm::Constant>(filterType));
945 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
946 LPadInst->addClause(FilterArray);
947
948 // Also check whether we need a cleanup.
949 if (hasCleanup)
950 LPadInst->setCleanup(true);
951
952 // Otherwise, signal that we at least have cleanups.
953 } else if (hasCleanup) {
954 LPadInst->setCleanup(true);
955 }
956
957 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
958 "landingpad instruction has no clauses!");
959
960 // Tell the backend how to generate the landing pad.
962
963 // Restore the old IR generation state.
964 Builder.restoreIP(savedIP);
965
966 return lpad;
967}
968
969static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {
970 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
971 assert(DispatchBlock);
972
973 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
974 CGF.EmitBlockAfterUses(DispatchBlock);
975
976 llvm::Value *ParentPad = CGF.CurrentFuncletPad;
977 if (!ParentPad)
978 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
979 llvm::BasicBlock *UnwindBB =
980 CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
981
982 unsigned NumHandlers = CatchScope.getNumHandlers();
983 llvm::CatchSwitchInst *CatchSwitch =
984 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
985
986 // Test against each of the exception types we claim to catch.
987 for (unsigned I = 0; I < NumHandlers; ++I) {
988 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
989
990 CatchTypeInfo TypeInfo = Handler.Type;
991 if (!TypeInfo.RTTI)
992 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
993
994 CGF.Builder.SetInsertPoint(Handler.Block);
995
996 if (EHPersonality::get(CGF).isMSVCXXPersonality()) {
997 CGF.Builder.CreateCatchPad(
998 CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),
999 llvm::Constant::getNullValue(CGF.VoidPtrTy)});
1000 } else {
1001 CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});
1002 }
1003
1004 CatchSwitch->addHandler(Handler.Block);
1005 }
1006 CGF.Builder.restoreIP(SavedIP);
1007}
1008
1009// Wasm uses Windows-style EH instructions, but it merges all catch clauses into
1010// one big catchpad, within which we use Itanium's landingpad-style selector
1011// comparison instructions.
1013 EHCatchScope &CatchScope) {
1014 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
1015 assert(DispatchBlock);
1016
1017 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
1018 CGF.EmitBlockAfterUses(DispatchBlock);
1019
1020 llvm::Value *ParentPad = CGF.CurrentFuncletPad;
1021 if (!ParentPad)
1022 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
1023 llvm::BasicBlock *UnwindBB =
1024 CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
1025
1026 unsigned NumHandlers = CatchScope.getNumHandlers();
1027 llvm::CatchSwitchInst *CatchSwitch =
1028 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1029
1030 // We don't use a landingpad instruction, so generate intrinsic calls to
1031 // provide exception and selector values.
1032 llvm::BasicBlock *WasmCatchStartBlock = CGF.createBasicBlock("catch.start");
1033 CatchSwitch->addHandler(WasmCatchStartBlock);
1034 CGF.EmitBlockAfterUses(WasmCatchStartBlock);
1035
1036 // Create a catchpad instruction.
1038 for (unsigned I = 0, E = NumHandlers; I < E; ++I) {
1039 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
1040 CatchTypeInfo TypeInfo = Handler.Type;
1041 if (!TypeInfo.RTTI)
1042 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
1043 CatchTypes.push_back(TypeInfo.RTTI);
1044 }
1045 auto *CPI = CGF.Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1046
1047 // Create calls to wasm.get.exception and wasm.get.ehselector intrinsics.
1048 // Before they are lowered appropriately later, they provide values for the
1049 // exception and selector.
1050 llvm::Function *GetExnFn =
1051 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
1052 llvm::Function *GetSelectorFn =
1053 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_ehselector);
1054 llvm::CallInst *Exn = CGF.Builder.CreateCall(GetExnFn, CPI);
1055 CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());
1056 llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
1057
1058 llvm::Function *TypeIDFn =
1059 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
1060
1061 // If there's only a single catch-all, branch directly to its handler.
1062 if (CatchScope.getNumHandlers() == 1 &&
1063 CatchScope.getHandler(0).isCatchAll()) {
1064 CGF.Builder.CreateBr(CatchScope.getHandler(0).Block);
1065 CGF.Builder.restoreIP(SavedIP);
1066 return;
1067 }
1068
1069 // Test against each of the exception types we claim to catch.
1070 for (unsigned I = 0, E = NumHandlers;; ++I) {
1071 assert(I < E && "ran off end of handlers!");
1072 const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
1073 CatchTypeInfo TypeInfo = Handler.Type;
1074 if (!TypeInfo.RTTI)
1075 TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
1076
1077 // Figure out the next block.
1078 llvm::BasicBlock *NextBlock;
1079
1080 bool EmitNextBlock = false, NextIsEnd = false;
1081
1082 // If this is the last handler, we're at the end, and the next block is a
1083 // block that contains a call to the rethrow function, so we can unwind to
1084 // the enclosing EH scope. The call itself will be generated later.
1085 if (I + 1 == E) {
1086 NextBlock = CGF.createBasicBlock("rethrow");
1087 EmitNextBlock = true;
1088 NextIsEnd = true;
1089
1090 // If the next handler is a catch-all, we're at the end, and the
1091 // next block is that handler.
1092 } else if (CatchScope.getHandler(I + 1).isCatchAll()) {
1093 NextBlock = CatchScope.getHandler(I + 1).Block;
1094 NextIsEnd = true;
1095
1096 // Otherwise, we're not at the end and we need a new block.
1097 } else {
1098 NextBlock = CGF.createBasicBlock("catch.fallthrough");
1099 EmitNextBlock = true;
1100 }
1101
1102 // Figure out the catch type's index in the LSDA's type table.
1103 llvm::CallInst *TypeIndex = CGF.Builder.CreateCall(TypeIDFn, TypeInfo.RTTI);
1104 TypeIndex->setDoesNotThrow();
1105
1106 llvm::Value *MatchesTypeIndex =
1107 CGF.Builder.CreateICmpEQ(Selector, TypeIndex, "matches");
1108 CGF.Builder.CreateCondBr(MatchesTypeIndex, Handler.Block, NextBlock);
1109
1110 if (EmitNextBlock)
1111 CGF.EmitBlock(NextBlock);
1112 if (NextIsEnd)
1113 break;
1114 }
1115
1116 CGF.Builder.restoreIP(SavedIP);
1117}
1118
1119/// Emit the structure of the dispatch block for the given catch scope.
1120/// It is an invariant that the dispatch block already exists.
1122 EHCatchScope &catchScope) {
1123 if (EHPersonality::get(CGF).isWasmPersonality())
1124 return emitWasmCatchPadBlock(CGF, catchScope);
1125 if (EHPersonality::get(CGF).usesFuncletPads())
1126 return emitCatchPadBlock(CGF, catchScope);
1127
1128 llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
1129 assert(dispatchBlock);
1130
1131 // If there's only a single catch-all, getEHDispatchBlock returned
1132 // that catch-all as the dispatch block.
1133 if (catchScope.getNumHandlers() == 1 &&
1134 catchScope.getHandler(0).isCatchAll()) {
1135 assert(dispatchBlock == catchScope.getHandler(0).Block);
1136 return;
1137 }
1138
1139 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
1140 CGF.EmitBlockAfterUses(dispatchBlock);
1141
1142 // Select the right handler.
1143 llvm::Function *llvm_eh_typeid_for =
1144 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
1145 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1146 LangAS globAS = CGF.CGM.GetGlobalVarAddressSpace(nullptr);
1147
1148 // Load the selector value.
1149 llvm::Value *selector = CGF.getSelectorFromSlot();
1150
1151 // Test against each of the exception types we claim to catch.
1152 for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
1153 assert(i < e && "ran off end of handlers!");
1154 const EHCatchScope::Handler &handler = catchScope.getHandler(i);
1155
1156 llvm::Value *typeValue = handler.Type.RTTI;
1157 assert(handler.Type.Flags == 0 &&
1158 "landingpads do not support catch handler flags");
1159 assert(typeValue && "fell into catch-all case!");
1160 // With opaque ptrs, only the address space can be a mismatch.
1161 if (typeValue->getType() != argTy)
1162 typeValue = CGF.getTargetHooks().performAddrSpaceCast(CGF, typeValue,
1163 globAS, 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
1213void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1214 unsigned NumHandlers = S.getNumHandlers();
1215 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1216 assert(CatchScope.getNumHandlers() == NumHandlers);
1217 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
1218
1219 // If the catch was not required, bail out now.
1220 if (!CatchScope.hasEHBranches()) {
1221 CatchScope.clearHandlerBlocks();
1222 EHStack.popCatch();
1223 return;
1224 }
1225
1226 // Emit the structure of the EH dispatch for this catch.
1227 emitCatchDispatchBlock(*this, CatchScope);
1228
1229 // Copy the handler blocks off before we pop the EH stack. Emitting
1230 // the handlers might scribble on this memory.
1232 CatchScope.begin(), CatchScope.begin() + NumHandlers);
1233
1234 EHStack.popCatch();
1235
1236 // The fall-through block.
1237 llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1238
1239 // We just emitted the body of the try; jump to the continue block.
1240 if (HaveInsertPoint())
1241 Builder.CreateBr(ContBB);
1242
1243 // Determine if we need an implicit rethrow for all these catch handlers;
1244 // see the comment below.
1245 bool doImplicitRethrow = false;
1246 if (IsFnTryBlock)
1247 doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1248 isa<CXXConstructorDecl>(CurCodeDecl);
1249
1250 // Wasm uses Windows-style EH instructions, but merges all catch clauses into
1251 // one big catchpad. So we save the old funclet pad here before we traverse
1252 // each catch handler.
1253 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1254 llvm::BasicBlock *WasmCatchStartBlock = nullptr;
1256 auto *CatchSwitch =
1257 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHIIt());
1258 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1259 ? CatchSwitch->getSuccessor(1)
1260 : CatchSwitch->getSuccessor(0);
1261 auto *CPI =
1262 cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHIIt());
1263 CurrentFuncletPad = CPI;
1264 }
1265
1266 // Perversely, we emit the handlers backwards precisely because we
1267 // want them to appear in source order. In all of these cases, the
1268 // catch block will have exactly one predecessor, which will be a
1269 // particular block in the catch dispatch. However, in the case of
1270 // a catch-all, one of the dispatch blocks will branch to two
1271 // different handlers, and EmitBlockAfterUses will cause the second
1272 // handler to be moved before the first.
1273 bool HasCatchAll = false;
1274 for (unsigned I = NumHandlers; I != 0; --I) {
1275 HasCatchAll |= Handlers[I - 1].isCatchAll();
1276 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1277 EmitBlockAfterUses(CatchBlock);
1278
1279 // Catch the exception if this isn't a catch-all.
1280 const CXXCatchStmt *C = S.getHandler(I-1);
1281
1282 // Enter a cleanup scope, including the catch variable and the
1283 // end-catch.
1284 RunCleanupsScope CatchScope(*this);
1285
1286 // Initialize the catch variable and set up the cleanups.
1287 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1288 CGM.getCXXABI().emitBeginCatch(*this, C);
1289
1290 // Emit the PGO counter increment.
1292
1293 // Perform the body of the catch.
1294 EmitStmt(C->getHandlerBlock());
1295
1296 // [except.handle]p11:
1297 // The currently handled exception is rethrown if control
1298 // reaches the end of a handler of the function-try-block of a
1299 // constructor or destructor.
1300
1301 // It is important that we only do this on fallthrough and not on
1302 // return. Note that it's illegal to put a return in a
1303 // constructor function-try-block's catch handler (p14), so this
1304 // really only applies to destructors.
1305 if (doImplicitRethrow && HaveInsertPoint()) {
1306 CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1307 Builder.CreateUnreachable();
1308 Builder.ClearInsertionPoint();
1309 }
1310
1311 // Fall out through the catch cleanups.
1312 CatchScope.ForceCleanup();
1313
1314 // Branch out of the try.
1315 if (HaveInsertPoint())
1316 Builder.CreateBr(ContBB);
1317 }
1318
1319 // Because in wasm we merge all catch clauses into one big catchpad, in case
1320 // none of the types in catch handlers matches after we test against each of
1321 // them, we should unwind to the next EH enclosing scope. We generate a call
1322 // to rethrow function here to do that.
1323 if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {
1324 assert(WasmCatchStartBlock);
1325 // Navigate for the "rethrow" block we created in emitWasmCatchPadBlock().
1326 // Wasm uses landingpad-style conditional branches to compare selectors, so
1327 // we follow the false destination for each of the cond branches to reach
1328 // the rethrow block.
1329 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1330 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1331 auto *BI = cast<llvm::BranchInst>(TI);
1332 assert(BI->isConditional());
1333 RethrowBlock = BI->getSuccessor(1);
1334 }
1335 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1336 Builder.SetInsertPoint(RethrowBlock);
1337 llvm::Function *RethrowInCatchFn =
1338 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1339 EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
1340 }
1341
1342 EmitBlock(ContBB);
1344}
1345
1346namespace {
1347 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1348 llvm::Value *ForEHVar;
1349 llvm::FunctionCallee EndCatchFn;
1350 CallEndCatchForFinally(llvm::Value *ForEHVar,
1351 llvm::FunctionCallee EndCatchFn)
1352 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1353
1354 void Emit(CodeGenFunction &CGF, Flags flags) override {
1355 llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1356 llvm::BasicBlock *CleanupContBB =
1357 CGF.createBasicBlock("finally.cleanup.cont");
1358
1359 llvm::Value *ShouldEndCatch =
1360 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
1361 CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1362 CGF.EmitBlock(EndCatchBB);
1363 CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1364 CGF.EmitBlock(CleanupContBB);
1365 }
1366 };
1367
1368 struct PerformFinally final : EHScopeStack::Cleanup {
1369 const Stmt *Body;
1370 llvm::Value *ForEHVar;
1371 llvm::FunctionCallee EndCatchFn;
1372 llvm::FunctionCallee RethrowFn;
1373 llvm::Value *SavedExnVar;
1374
1375 PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1376 llvm::FunctionCallee EndCatchFn,
1377 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1378 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1379 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1380
1381 void Emit(CodeGenFunction &CGF, Flags flags) override {
1382 // Enter a cleanup to call the end-catch function if one was provided.
1383 if (EndCatchFn)
1384 CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1385 ForEHVar, EndCatchFn);
1386
1387 // Save the current cleanup destination in case there are
1388 // cleanups in the finally block.
1389 llvm::Value *SavedCleanupDest =
1391 "cleanup.dest.saved");
1392
1393 // Emit the finally block.
1394 CGF.EmitStmt(Body);
1395
1396 // If the end of the finally is reachable, check whether this was
1397 // for EH. If so, rethrow.
1398 if (CGF.HaveInsertPoint()) {
1399 llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1400 llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1401
1402 llvm::Value *ShouldRethrow =
1403 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
1404 CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1405
1406 CGF.EmitBlock(RethrowBB);
1407 if (SavedExnVar) {
1408 CGF.EmitRuntimeCallOrInvoke(RethrowFn,
1409 CGF.Builder.CreateAlignedLoad(CGF.Int8PtrTy, SavedExnVar,
1410 CGF.getPointerAlign()));
1411 } else {
1412 CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1413 }
1414 CGF.Builder.CreateUnreachable();
1415
1416 CGF.EmitBlock(ContBB);
1417
1418 // Restore the cleanup destination.
1419 CGF.Builder.CreateStore(SavedCleanupDest,
1421 }
1422
1423 // Leave the end-catch cleanup. As an optimization, pretend that
1424 // the fallthrough path was inaccessible; we've dynamically proven
1425 // that we're not in the EH case along that path.
1426 if (EndCatchFn) {
1427 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1428 CGF.PopCleanupBlock();
1429 CGF.Builder.restoreIP(SavedIP);
1430 }
1431
1432 // Now make sure we actually have an insertion point or the
1433 // cleanup gods will hate us.
1434 CGF.EnsureInsertPoint();
1435 }
1436 };
1437} // end anonymous namespace
1438
1439/// Enters a finally block for an implementation using zero-cost
1440/// exceptions. This is mostly general, but hard-codes some
1441/// language/ABI-specific behavior in the catch-all sections.
1443 llvm::FunctionCallee beginCatchFn,
1444 llvm::FunctionCallee endCatchFn,
1445 llvm::FunctionCallee rethrowFn) {
1446 assert((!!beginCatchFn) == (!!endCatchFn) &&
1447 "begin/end catch functions not paired");
1448 assert(rethrowFn && "rethrow function is required");
1449
1450 BeginCatchFn = beginCatchFn;
1451
1452 // The rethrow function has one of the following two types:
1453 // void (*)()
1454 // void (*)(void*)
1455 // In the latter case we need to pass it the exception object.
1456 // But we can't use the exception slot because the @finally might
1457 // have a landing pad (which would overwrite the exception slot).
1458 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1459 SavedExnVar = nullptr;
1460 if (rethrowFnTy->getNumParams())
1461 SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1462
1463 // A finally block is a statement which must be executed on any edge
1464 // out of a given scope. Unlike a cleanup, the finally block may
1465 // contain arbitrary control flow leading out of itself. In
1466 // addition, finally blocks should always be executed, even if there
1467 // are no catch handlers higher on the stack. Therefore, we
1468 // surround the protected scope with a combination of a normal
1469 // cleanup (to catch attempts to break out of the block via normal
1470 // control flow) and an EH catch-all (semantically "outside" any try
1471 // statement to which the finally block might have been attached).
1472 // The finally block itself is generated in the context of a cleanup
1473 // which conditionally leaves the catch-all.
1474
1475 // Jump destination for performing the finally block on an exception
1476 // edge. We'll never actually reach this block, so unreachable is
1477 // fine.
1478 RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1479
1480 // Whether the finally block is being executed for EH purposes.
1481 ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1482 CGF.Builder.CreateFlagStore(false, ForEHVar);
1483
1484 // Enter a normal cleanup which will perform the @finally block.
1485 CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1486 ForEHVar, endCatchFn,
1487 rethrowFn, SavedExnVar);
1488
1489 // Enter a catch-all scope.
1490 llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1491 EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1492 catchScope->setCatchAllHandler(0, catchBB);
1493}
1494
1496 // Leave the finally catch-all.
1497 EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1498 llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1499
1500 CGF.popCatchScope();
1501
1502 // If there are any references to the catch-all block, emit it.
1503 if (catchBB->use_empty()) {
1504 delete catchBB;
1505 } else {
1506 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1507 CGF.EmitBlock(catchBB);
1508
1509 llvm::Value *exn = nullptr;
1510
1511 // If there's a begin-catch function, call it.
1512 if (BeginCatchFn) {
1513 exn = CGF.getExceptionFromSlot();
1514 CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1515 }
1516
1517 // If we need to remember the exception pointer to rethrow later, do so.
1518 if (SavedExnVar) {
1519 if (!exn) exn = CGF.getExceptionFromSlot();
1520 CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1521 }
1522
1523 // Tell the cleanups in the finally block that we're do this for EH.
1524 CGF.Builder.CreateFlagStore(true, ForEHVar);
1525
1526 // Thread a jump through the finally cleanup.
1527 CGF.EmitBranchThroughCleanup(RethrowDest);
1528
1529 CGF.Builder.restoreIP(savedIP);
1530 }
1531
1532 // Finally, leave the @finally cleanup.
1533 CGF.PopCleanupBlock();
1534}
1535
1537 if (TerminateLandingPad)
1538 return TerminateLandingPad;
1539
1540 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1541
1542 // This will get inserted at the end of the function.
1543 TerminateLandingPad = createBasicBlock("terminate.lpad");
1544 Builder.SetInsertPoint(TerminateLandingPad);
1545
1546 // Tell the backend that this is a landing pad.
1547 const EHPersonality &Personality = EHPersonality::get(*this);
1548
1549 if (!CurFn->hasPersonalityFn())
1550 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
1551
1552 llvm::LandingPadInst *LPadInst =
1553 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
1554 LPadInst->addClause(getCatchAllValue(*this));
1555
1556 llvm::Value *Exn = nullptr;
1557 if (getLangOpts().CPlusPlus)
1558 Exn = Builder.CreateExtractValue(LPadInst, 0);
1559 llvm::CallInst *terminateCall =
1561 terminateCall->setDoesNotReturn();
1562 Builder.CreateUnreachable();
1563
1564 // Restore the saved insertion state.
1565 Builder.restoreIP(SavedIP);
1566
1567 return TerminateLandingPad;
1568}
1569
1571 if (TerminateHandler)
1572 return TerminateHandler;
1573
1574 // Set up the terminate handler. This block is inserted at the very
1575 // end of the function by FinishFunction.
1576 TerminateHandler = createBasicBlock("terminate.handler");
1577 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1578 Builder.SetInsertPoint(TerminateHandler);
1579
1580 llvm::Value *Exn = nullptr;
1581 if (getLangOpts().CPlusPlus)
1582 Exn = getExceptionFromSlot();
1583 llvm::CallInst *terminateCall =
1585 terminateCall->setDoesNotReturn();
1586 Builder.CreateUnreachable();
1587
1588 // Restore the saved insertion state.
1589 Builder.restoreIP(SavedIP);
1590
1591 return TerminateHandler;
1592}
1593
1595 assert(EHPersonality::get(*this).usesFuncletPads() &&
1596 "use getTerminateLandingPad for non-funclet EH");
1597
1598 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1599 if (TerminateFunclet)
1600 return TerminateFunclet;
1601
1602 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1603
1604 // Set up the terminate handler. This block is inserted at the very
1605 // end of the function by FinishFunction.
1606 TerminateFunclet = createBasicBlock("terminate.handler");
1607 Builder.SetInsertPoint(TerminateFunclet);
1608
1609 // Create the cleanuppad using the current parent pad as its token. Use 'none'
1610 // if this is a top-level terminate scope, which is the common case.
1611 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1612 llvm::Value *ParentPad = CurrentFuncletPad;
1613 if (!ParentPad)
1614 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1615 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1616
1617 // Emit the __std_terminate call.
1618 llvm::CallInst *terminateCall =
1620 terminateCall->setDoesNotReturn();
1621 Builder.CreateUnreachable();
1622
1623 // Restore the saved insertion state.
1624 Builder.restoreIP(SavedIP);
1625
1626 return TerminateFunclet;
1627}
1628
1629llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1630 if (EHResumeBlock) return EHResumeBlock;
1631
1632 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1633
1634 // We emit a jump to a notional label at the outermost unwind state.
1635 EHResumeBlock = createBasicBlock("eh.resume");
1636 Builder.SetInsertPoint(EHResumeBlock);
1637
1638 const EHPersonality &Personality = EHPersonality::get(*this);
1639
1640 // This can always be a call because we necessarily didn't find
1641 // anything on the EH stack which needs our help.
1642 const char *RethrowName = Personality.CatchallRethrowFn;
1643 if (RethrowName != nullptr && !isCleanup) {
1645 getExceptionFromSlot())->setDoesNotReturn();
1646 Builder.CreateUnreachable();
1647 Builder.restoreIP(SavedIP);
1648 return EHResumeBlock;
1649 }
1650
1651 // Recreate the landingpad's return value for the 'resume' instruction.
1652 llvm::Value *Exn = getExceptionFromSlot();
1653 llvm::Value *Sel = getSelectorFromSlot();
1654
1655 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1656 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1657 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1658 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1659
1660 Builder.CreateResume(LPadVal);
1661 Builder.restoreIP(SavedIP);
1662 return EHResumeBlock;
1663}
1664
1666 EnterSEHTryStmt(S);
1667 {
1668 JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
1669
1670 SEHTryEpilogueStack.push_back(&TryExit);
1671
1672 llvm::BasicBlock *TryBB = nullptr;
1673 // IsEHa: emit an invoke to _seh_try_begin() runtime for -EHa
1674 if (getLangOpts().EHAsynch) {
1676 if (SEHTryEpilogueStack.size() == 1) // outermost only
1677 TryBB = Builder.GetInsertBlock();
1678 }
1679
1680 EmitStmt(S.getTryBlock());
1681
1682 // Volatilize all blocks in Try, till current insert point
1683 if (TryBB) {
1686 }
1687
1688 SEHTryEpilogueStack.pop_back();
1689
1690 if (!TryExit.getBlock()->use_empty())
1691 EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
1692 else
1693 delete TryExit.getBlock();
1694 }
1695 ExitSEHTryStmt(S);
1696}
1697
1698// Recursively walk through blocks in a _try
1699// and make all memory instructions volatile
1701 llvm::BasicBlock *BB, llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V) {
1702 if (BB == SEHTryEpilogueStack.back()->getBlock() /* end of Try */ ||
1703 !V.insert(BB).second /* already visited */ ||
1704 !BB->getParent() /* not emitted */ || BB->empty())
1705 return;
1706
1707 if (!BB->isEHPad()) {
1708 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1709 ++J) {
1710 if (auto LI = dyn_cast<llvm::LoadInst>(J)) {
1711 LI->setVolatile(true);
1712 } else if (auto SI = dyn_cast<llvm::StoreInst>(J)) {
1713 SI->setVolatile(true);
1714 } else if (auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1715 MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));
1716 }
1717 }
1718 }
1719 const llvm::Instruction *TI = BB->getTerminator();
1720 if (TI) {
1721 unsigned N = TI->getNumSuccessors();
1722 for (unsigned I = 0; I < N; I++)
1723 VolatilizeTryBlocks(TI->getSuccessor(I), V);
1724 }
1725}
1726
1727namespace {
1728struct PerformSEHFinally final : EHScopeStack::Cleanup {
1729 llvm::Function *OutlinedFinally;
1730 PerformSEHFinally(llvm::Function *OutlinedFinally)
1731 : OutlinedFinally(OutlinedFinally) {}
1732
1733 void Emit(CodeGenFunction &CGF, Flags F) override {
1734 ASTContext &Context = CGF.getContext();
1735 CodeGenModule &CGM = CGF.CGM;
1736
1737 CallArgList Args;
1738
1739 // Compute the two argument values.
1740 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1741 llvm::Value *FP = nullptr;
1742 // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
1743 if (CGF.IsOutlinedSEHHelper) {
1744 FP = &CGF.CurFn->arg_begin()[1];
1745 } else {
1746 llvm::Function *LocalAddrFn =
1747 CGM.getIntrinsic(llvm::Intrinsic::localaddress);
1748 FP = CGF.Builder.CreateCall(LocalAddrFn);
1749 }
1750
1751 llvm::Value *IsForEH =
1752 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
1753
1754 // Except _leave and fall-through at the end, all other exits in a _try
1755 // (return/goto/continue/break) are considered as abnormal terminations
1756 // since _leave/fall-through is always Indexed 0,
1757 // just use NormalCleanupDestSlot (>= 1 for goto/return/..),
1758 // as 1st Arg to indicate abnormal termination
1759 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1761 llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
1762 llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
1763 IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
1764 }
1765
1766 Args.add(RValue::get(IsForEH), ArgTys[0]);
1767 Args.add(RValue::get(FP), ArgTys[1]);
1768
1769 // Arrange a two-arg function info and type.
1770 const CGFunctionInfo &FnInfo =
1771 CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
1772
1773 auto Callee = CGCallee::forDirect(OutlinedFinally);
1774 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1775 }
1776};
1777} // end anonymous namespace
1778
1779namespace {
1780/// Find all local variable captures in the statement.
1781struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1782 CodeGenFunction &ParentCGF;
1783 const VarDecl *ParentThis;
1785 Address SEHCodeSlot = Address::invalid();
1786 CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
1787 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1788
1789 // Return true if we need to do any capturing work.
1790 bool foundCaptures() {
1791 return !Captures.empty() || SEHCodeSlot.isValid();
1792 }
1793
1794 void Visit(const Stmt *S) {
1795 // See if this is a capture, then recurse.
1797 for (const Stmt *Child : S->children())
1798 if (Child)
1799 Visit(Child);
1800 }
1801
1802 void VisitDeclRefExpr(const DeclRefExpr *E) {
1803 // If this is already a capture, just make sure we capture 'this'.
1804 if (E->refersToEnclosingVariableOrCapture())
1805 Captures.insert(ParentThis);
1806
1807 const auto *D = dyn_cast<VarDecl>(E->getDecl());
1808 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1809 Captures.insert(D);
1810 }
1811
1812 void VisitCXXThisExpr(const CXXThisExpr *E) {
1813 Captures.insert(ParentThis);
1814 }
1815
1816 void VisitCallExpr(const CallExpr *E) {
1817 // We only need to add parent frame allocations for these builtins in x86.
1818 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1819 return;
1820
1821 unsigned ID = E->getBuiltinCallee();
1822 switch (ID) {
1823 case Builtin::BI__exception_code:
1824 case Builtin::BI_exception_code:
1825 // This is the simple case where we are the outermost finally. All we
1826 // have to do here is make sure we escape this and recover it in the
1827 // outlined handler.
1828 if (!SEHCodeSlot.isValid())
1829 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1830 break;
1831 }
1832 }
1833};
1834} // end anonymous namespace
1835
1837 Address ParentVar,
1838 llvm::Value *ParentFP) {
1839 llvm::CallInst *RecoverCall = nullptr;
1841 if (auto *ParentAlloca =
1842 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {
1843 // Mark the variable escaped if nobody else referenced it and compute the
1844 // localescape index.
1845 auto InsertPair = ParentCGF.EscapedLocals.insert(
1846 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1847 int FrameEscapeIdx = InsertPair.first->second;
1848 // call ptr @llvm.localrecover(ptr @parentFn, ptr %fp, i32 N)
1849 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1850 &CGM.getModule(), llvm::Intrinsic::localrecover);
1851 RecoverCall = Builder.CreateCall(
1852 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1853 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1854
1855 } else {
1856 // If the parent didn't have an alloca, we're doing some nested outlining.
1857 // Just clone the existing localrecover call, but tweak the FP argument to
1858 // use our FP value. All other arguments are constants.
1859 auto *ParentRecover = cast<llvm::IntrinsicInst>(
1860 ParentVar.emitRawPointer(*this)->stripPointerCasts());
1861 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1862 "expected alloca or localrecover in parent LocalDeclMap");
1863 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1864 RecoverCall->setArgOperand(1, ParentFP);
1865 RecoverCall->insertBefore(AllocaInsertPt->getIterator());
1866 }
1867
1868 // Bitcast the variable, rename it, and insert it in the local decl map.
1869 llvm::Value *ChildVar =
1870 Builder.CreateBitCast(RecoverCall, ParentVar.getType());
1871 ChildVar->setName(ParentVar.getName());
1872 return ParentVar.withPointer(ChildVar, KnownNonNull);
1873}
1874
1876 const Stmt *OutlinedStmt,
1877 bool IsFilter) {
1878 // Find all captures in the Stmt.
1879 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1880 Finder.Visit(OutlinedStmt);
1881
1882 // We can exit early on x86_64 when there are no captures. We just have to
1883 // save the exception code in filters so that __exception_code() works.
1884 if (!Finder.foundCaptures() &&
1885 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1886 if (IsFilter)
1887 EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
1888 return;
1889 }
1890
1891 llvm::Value *EntryFP = nullptr;
1893 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1894 // 32-bit SEH filters need to be careful about FP recovery. The end of the
1895 // EH registration is passed in as the EBP physical register. We can
1896 // recover that with llvm.frameaddress(1).
1897 EntryFP = Builder.CreateCall(
1898 CGM.getIntrinsic(llvm::Intrinsic::frameaddress, AllocaInt8PtrTy),
1899 {Builder.getInt32(1)});
1900 } else {
1901 // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
1902 // second parameter.
1903 auto AI = CurFn->arg_begin();
1904 ++AI;
1905 EntryFP = &*AI;
1906 }
1907
1908 llvm::Value *ParentFP = EntryFP;
1909 if (IsFilter) {
1910 // Given whatever FP the runtime provided us in EntryFP, recover the true
1911 // frame pointer of the parent function. We only need to do this in filters,
1912 // since finally funclets recover the parent FP for us.
1913 llvm::Function *RecoverFPIntrin =
1914 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1915 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});
1916
1917 // if the parent is a _finally, the passed-in ParentFP is the FP
1918 // of parent _finally, not Establisher's FP (FP of outermost function).
1919 // Establkisher FP is 2nd paramenter passed into parent _finally.
1920 // Fortunately, it's always saved in parent's frame. The following
1921 // code retrieves it, and escapes it so that spill instruction won't be
1922 // optimized away.
1923 if (ParentCGF.ParentCGF != nullptr) {
1924 // Locate and escape Parent's frame_pointer.addr alloca
1925 // Depending on target, should be 1st/2nd one in LocalDeclMap.
1926 // Let's just scan for ImplicitParamDecl with VoidPtrTy.
1927 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
1928 for (auto &I : ParentCGF.LocalDeclMap) {
1929 const VarDecl *D = cast<VarDecl>(I.first);
1930 if (isa<ImplicitParamDecl>(D) &&
1931 D->getType() == getContext().VoidPtrTy) {
1932 assert(D->getName().starts_with("frame_pointer"));
1933 FramePtrAddrAlloca =
1934 cast<llvm::AllocaInst>(I.second.getBasePointer());
1935 break;
1936 }
1937 }
1938 assert(FramePtrAddrAlloca);
1939 auto InsertPair = ParentCGF.EscapedLocals.insert(
1940 std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
1941 int FrameEscapeIdx = InsertPair.first->second;
1942
1943 // an example of a filter's prolog::
1944 // %0 = call ptr @llvm.eh.recoverfp(@"?fin$0@0@main@@",..)
1945 // %1 = call ptr @llvm.localrecover(@"?fin$0@0@main@@",..)
1946 // %2 = load ptr, ptr %1, align 8
1947 // ==> %2 is the frame-pointer of outermost host function
1948 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1949 &CGM.getModule(), llvm::Intrinsic::localrecover);
1950 ParentFP = Builder.CreateCall(
1951 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1952 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1953 ParentFP = Builder.CreateLoad(
1954 Address(ParentFP, CGM.VoidPtrTy, getPointerAlign()));
1955 }
1956 }
1957
1958 // Create llvm.localrecover calls for all captures.
1959 for (const VarDecl *VD : Finder.Captures) {
1960 if (VD->getType()->isVariablyModifiedType()) {
1961 CGM.ErrorUnsupported(VD, "VLA captured by SEH");
1962 continue;
1963 }
1964 assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
1965 "captured non-local variable");
1966
1967 auto L = ParentCGF.LambdaCaptureFields.find(VD);
1968 if (L != ParentCGF.LambdaCaptureFields.end()) {
1969 LambdaCaptureFields[VD] = L->second;
1970 continue;
1971 }
1972
1973 // If this decl hasn't been declared yet, it will be declared in the
1974 // OutlinedStmt.
1975 auto I = ParentCGF.LocalDeclMap.find(VD);
1976 if (I == ParentCGF.LocalDeclMap.end())
1977 continue;
1978
1979 Address ParentVar = I->second;
1980 Address Recovered =
1981 recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);
1982 setAddrOfLocalVar(VD, Recovered);
1983
1984 if (isa<ImplicitParamDecl>(VD)) {
1985 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
1986 CXXThisAlignment = ParentCGF.CXXThisAlignment;
1987 CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
1990 // We are in a lambda function where "this" is captured so the
1991 // CXXThisValue need to be loaded from the lambda capture
1992 LValue ThisFieldLValue =
1995 CXXThisValue = ThisFieldLValue.getAddress().emitRawPointer(*this);
1996 } else {
1997 CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
1998 .getScalarVal();
1999 }
2000 } else {
2001 CXXThisValue = CXXABIThisValue;
2002 }
2003 }
2004 }
2005
2006 if (Finder.SEHCodeSlot.isValid()) {
2007 SEHCodeSlotStack.push_back(
2008 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
2009 }
2010
2011 if (IsFilter)
2012 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
2013}
2014
2015/// Arrange a function prototype that can be called by Windows exception
2016/// handling personalities. On Win64, the prototype looks like:
2017/// RetTy func(void *EHPtrs, void *ParentFP);
2019 bool IsFilter,
2020 const Stmt *OutlinedStmt) {
2021 SourceLocation StartLoc = OutlinedStmt->getBeginLoc();
2022
2023 // Get the mangled function name.
2024 SmallString<128> Name;
2025 {
2026 llvm::raw_svector_ostream OS(Name);
2027 GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;
2028 assert(ParentSEHFn && "No CurSEHParent!");
2030 if (IsFilter)
2031 Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
2032 else
2033 Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
2034 }
2035
2036 FunctionArgList Args;
2037 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2038 // All SEH finally functions take two parameters. Win64 filters take two
2039 // parameters. Win32 filters take no parameters.
2040 if (IsFilter) {
2041 Args.push_back(ImplicitParamDecl::Create(
2042 getContext(), /*DC=*/nullptr, StartLoc,
2043 &getContext().Idents.get("exception_pointers"),
2045 } else {
2046 Args.push_back(ImplicitParamDecl::Create(
2047 getContext(), /*DC=*/nullptr, StartLoc,
2048 &getContext().Idents.get("abnormal_termination"),
2049 getContext().UnsignedCharTy, ImplicitParamKind::Other));
2050 }
2051 Args.push_back(ImplicitParamDecl::Create(
2052 getContext(), /*DC=*/nullptr, StartLoc,
2053 &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy,
2055 }
2056
2057 QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
2058
2059 const CGFunctionInfo &FnInfo =
2061
2062 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
2063 llvm::Function *Fn = llvm::Function::Create(
2064 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
2065
2066 IsOutlinedSEHHelper = true;
2067
2068 StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
2069 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
2071
2073 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
2074}
2075
2076/// Create a stub filter function that will ultimately hold the code of the
2077/// filter expression. The EH preparation passes in LLVM will outline the code
2078/// from the main function body into this stub.
2079llvm::Function *
2081 const SEHExceptStmt &Except) {
2082 const Expr *FilterExpr = Except.getFilterExpr();
2083 startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
2084
2085 // Emit the original filter expression, convert to i32, and return.
2086 llvm::Value *R = EmitScalarExpr(FilterExpr);
2087 R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
2088 FilterExpr->getType()->isSignedIntegerType());
2090
2091 FinishFunction(FilterExpr->getEndLoc());
2092
2093 return CurFn;
2094}
2095
2096llvm::Function *
2098 const SEHFinallyStmt &Finally) {
2099 const Stmt *FinallyBlock = Finally.getBlock();
2100 startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
2101
2102 // Emit the original filter expression, convert to i32, and return.
2103 EmitStmt(FinallyBlock);
2104
2105 FinishFunction(FinallyBlock->getEndLoc());
2106
2107 return CurFn;
2108}
2109
2111 llvm::Value *ParentFP,
2112 llvm::Value *EntryFP) {
2113 // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
2114 // __exception_info intrinsic.
2115 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2116 // On Win64, the info is passed as the first parameter to the filter.
2117 SEHInfo = &*CurFn->arg_begin();
2118 SEHCodeSlotStack.push_back(
2119 CreateMemTemp(getContext().IntTy, "__exception_code"));
2120 } else {
2121 // On Win32, the EBP on entry to the filter points to the end of an
2122 // exception registration object. It contains 6 32-bit fields, and the info
2123 // pointer is stored in the second field. So, GEP 20 bytes backwards and
2124 // load the pointer.
2125 SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
2128 ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
2129 }
2130
2131 // Save the exception code in the exception slot to unify exception access in
2132 // the filter function and the landing pad.
2133 // struct EXCEPTION_POINTERS {
2134 // EXCEPTION_RECORD *ExceptionRecord;
2135 // CONTEXT *ContextRecord;
2136 // };
2137 // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
2138 llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());
2139 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
2140 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);
2141 Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign());
2142 llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign());
2143 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2144 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2145}
2146
2148 // Sema should diagnose calling this builtin outside of a filter context, but
2149 // don't crash if we screw up.
2150 if (!SEHInfo)
2151 return llvm::PoisonValue::get(Int8PtrTy);
2152 assert(SEHInfo->getType() == Int8PtrTy);
2153 return SEHInfo;
2154}
2155
2157 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2158 return Builder.CreateLoad(SEHCodeSlotStack.back());
2159}
2160
2162 // Abnormal termination is just the first parameter to the outlined finally
2163 // helper.
2164 auto AI = CurFn->arg_begin();
2165 return Builder.CreateZExt(&*AI, Int32Ty);
2166}
2167
2169 llvm::Function *FinallyFunc) {
2170 EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
2171}
2172
2174 CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
2175 HelperCGF.ParentCGF = this;
2176 if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
2177 // Outline the finally block.
2178 llvm::Function *FinallyFunc =
2179 HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
2180
2181 // Push a cleanup for __finally blocks.
2182 EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
2183 return;
2184 }
2185
2186 // Otherwise, we must have an __except block.
2187 const SEHExceptStmt *Except = S.getExceptHandler();
2188 assert(Except);
2189 EHCatchScope *CatchScope = EHStack.pushCatch(1);
2190 SEHCodeSlotStack.push_back(
2191 CreateMemTemp(getContext().IntTy, "__exception_code"));
2192
2193 // If the filter is known to evaluate to 1, then we can use the clause
2194 // "catch i8* null". We can't do this on x86 because the filter has to save
2195 // the exception code.
2196 llvm::Constant *C =
2198 getContext().IntTy);
2199 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2200 C->isOneValue()) {
2201 CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
2202 return;
2203 }
2204
2205 // In general, we have to emit an outlined filter function. Use the function
2206 // in place of the RTTI typeinfo global that C++ EH uses.
2207 llvm::Function *FilterFunc =
2208 HelperCGF.GenerateSEHFilterFunction(*this, *Except);
2209 CatchScope->setHandler(0, FilterFunc, createBasicBlock("__except.ret"));
2210}
2211
2213 // Just pop the cleanup if it's a __finally block.
2214 if (S.getFinallyHandler()) {
2216 return;
2217 }
2218
2219 // IsEHa: emit an invoke _seh_try_end() to mark end of FT flow
2220 if (getLangOpts().EHAsynch && Builder.GetInsertBlock()) {
2221 llvm::FunctionCallee SehTryEnd = getSehTryEndFn(CGM);
2222 EmitRuntimeCallOrInvoke(SehTryEnd);
2223 }
2224
2225 // Otherwise, we must have an __except block.
2226 const SEHExceptStmt *Except = S.getExceptHandler();
2227 assert(Except && "__try must have __finally xor __except");
2228 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2229
2230 // Don't emit the __except block if the __try block lacked invokes.
2231 // TODO: Model unwind edges from instructions, either with iload / istore or
2232 // a try body function.
2233 if (!CatchScope.hasEHBranches()) {
2234 CatchScope.clearHandlerBlocks();
2235 EHStack.popCatch();
2236 SEHCodeSlotStack.pop_back();
2237 return;
2238 }
2239
2240 // The fall-through block.
2241 llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
2242
2243 // We just emitted the body of the __try; jump to the continue block.
2244 if (HaveInsertPoint())
2245 Builder.CreateBr(ContBB);
2246
2247 // Check if our filter function returned true.
2248 emitCatchDispatchBlock(*this, CatchScope);
2249
2250 // Grab the block before we pop the handler.
2251 llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
2252 EHStack.popCatch();
2253
2254 EmitBlockAfterUses(CatchPadBB);
2255
2256 // __except blocks don't get outlined into funclets, so immediately do a
2257 // catchret.
2258 llvm::CatchPadInst *CPI =
2259 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
2260 llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
2261 Builder.CreateCatchRet(CPI, ExceptBB);
2262 EmitBlock(ExceptBB);
2263
2264 // On Win64, the exception code is returned in EAX. Copy it into the slot.
2265 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2266 llvm::Function *SEHCodeIntrin =
2267 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2268 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2269 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2270 }
2271
2272 // Emit the __except body.
2273 EmitStmt(Except->getBlock());
2274
2275 // End the lifetime of the exception code.
2276 SEHCodeSlotStack.pop_back();
2277
2278 if (HaveInsertPoint())
2279 Builder.CreateBr(ContBB);
2280
2281 EmitBlock(ContBB);
2282}
2283
2285 // If this code is reachable then emit a stop point (if generating
2286 // debug info). We have to do this ourselves because we are on the
2287 // "simple" statement path.
2288 if (HaveInsertPoint())
2289 EmitStopPoint(&S);
2290
2291 // This must be a __leave from a __finally block, which we warn on and is UB.
2292 // Just emit unreachable.
2293 if (!isSEHTryScope()) {
2294 Builder.CreateUnreachable();
2295 Builder.ClearInsertionPoint();
2296 return;
2297 }
2298
2300}
#define V(N, I)
Definition: ASTContext.h:3597
static char ID
Definition: Arena.cpp:183
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
Definition: CGException.cpp:54
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &T)
static const EHPersonality & getObjCPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts, const LangOptions &L)
static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
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)
Definition: CGException.cpp:33
static const EHPersonality & getCXXPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts)
static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)
Definition: CGException.cpp:48
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 const EHPersonality & getCPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts)
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)
Definition: CGException.cpp:89
static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)
Definition: CGException.cpp:42
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 & getObjCXXPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts, const LangOptions &L)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
const Decl * D
Expr * E
llvm::DenseSet< const void * > Visited
Definition: HTMLLogger.cpp:145
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:188
CanQualType LongTy
Definition: ASTContext.h:1231
CanQualType VoidPtrTy
Definition: ASTContext.h:1249
CanQualType VoidTy
Definition: ASTContext.h:1222
CanQualType UnsignedCharTy
Definition: ASTContext.h:1232
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
Represents the this expression in C++.
Definition: ExprCXX.h:1155
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1209
CXXTryStmt - A C++ try block, including all handlers.
Definition: StmtCXX.h:69
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4906
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.
Definition: CGDebugInfo.h:953
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
Definition: CGBuilder.h:168
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition: CGBuilder.h:140
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Definition: CGBuilder.h:147
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition: CGBuilder.h:223
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition: CGBuilder.h:112
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
Definition: CGBuilder.h:162
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Definition: CGBuilder.h:132
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
Definition: CGCXXABI.cpp:327
virtual CatchTypeInfo getCatchAllTypeInfo()
Definition: CGCXXABI.cpp:333
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
MangleContext & getMangleContext()
Gets the mangle context.
Definition: CGCXXABI.h:113
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition: CGCall.h:137
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
CallArgList - Type for representing both the value and type of arguments in a call.
Definition: CGCall.h:274
void add(RValue rvalue, QualType type)
Definition: CGCall.h:302
void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn)
Enters a finally block for an implementation using zero-cost exceptions.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitCXXTryStmt(const CXXTryStmt &S)
llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)
llvm::BasicBlock * getInvokeDestImpl()
llvm::Type * ConvertType(QualType T)
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
Definition: CGCall.cpp:5033
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:5060
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:689
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
Definition: CGCleanup.cpp:1112
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:2336
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
Definition: CGCleanup.cpp:1293
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:151
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:5216
const TargetCodeGenInfo & getTargetHooks() const
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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:51
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:293
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
Definition: CGStmt.cpp:61
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:5165
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
Definition: CGExpr.cpp:186
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
Definition: CGExpr.cpp:4214
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 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.
Definition: CGCleanup.cpp:652
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:652
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
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.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
DiagnosticsEngine & getDiags() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
Definition: CGException.cpp:63
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
Definition: CGCall.cpp:1702
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
Definition: CGCall.cpp:739
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
Definition: CGCall.cpp:728
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:162
iterator begin() const
Definition: CGCleanup.h:238
const Handler & getHandler(unsigned I) const
Definition: CGCleanup.h:223
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
Definition: CGCleanup.h:211
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
Definition: CGCleanup.h:207
unsigned getNumHandlers() const
Definition: CGCleanup.h:203
An exceptions scope which filters exceptions thrown through it.
Definition: CGCleanup.h:509
llvm::Value * getFilter(unsigned i) const
Definition: CGCleanup.h:539
unsigned getNumFilters() const
Definition: CGCleanup.h:532
Information for lazily generating a cleanup.
Definition: EHScopeStack.h:146
A non-stable pointer into the scope stack.
Definition: CGCleanup.h:563
A saved depth on the scope stack.
Definition: EHScopeStack.h:106
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
Definition: CGCleanup.cpp:225
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
Definition: EHScopeStack.h:398
stable_iterator getInnermostEHScope() const
Definition: EHScopeStack.h:380
bool empty() const
Determines whether the exception-scopes stack is empty.
Definition: EHScopeStack.h:364
iterator end() const
Returns an iterator pointing to the outermost EH scope.
Definition: CGCleanup.h:627
void popFilter()
Pops an exceptions filter off the stack.
Definition: CGCleanup.cpp:233
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
Definition: CGCleanup.h:623
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
Definition: CGCleanup.h:631
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
Definition: CGCleanup.cpp:242
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
Definition: CGCleanup.h:647
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
Definition: EHScopeStack.h:403
void popTerminate()
Pops a terminate handler off the stack.
Definition: CGCleanup.h:639
void pushTerminate()
Push a terminate handler on the stack.
Definition: CGCleanup.cpp:250
A protected scope for zero-cost EH handling.
Definition: CGCleanup.h:45
llvm::BasicBlock * getCachedLandingPad() const
Definition: CGCleanup.h:130
Kind getKind() const
Definition: CGCleanup.h:128
EHScopeStack::stable_iterator getEnclosingEHScope() const
Definition: CGCleanup.h:152
llvm::BasicBlock * getCachedEHDispatchBlock() const
Definition: CGCleanup.h:138
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
Definition: CGCleanup.h:142
bool hasEHBranches() const
Definition: CGCleanup.h:146
FunctionArgList - Type for representing both the decl and type of parameters to a function.
Definition: CGCall.h:375
LValue - This represents an lvalue references.
Definition: CGValue.h:182
Address getAddress() const
Definition: CGValue.h:361
static RValue get(llvm::Value *V)
Definition: CGValue.h:98
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Definition: CGValue.h:71
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Definition: CGCall.h:379
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:196
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getLocation() const
Definition: DeclBase.h:439
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1529
This represents one expression.
Definition: Expr.h:112
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:273
QualType getType() const
Definition: Expr.h:144
Represents a function declaration or definition.
Definition: Decl.h:1999
bool usesSEHTry() const
Indicates the function uses __try.
Definition: Decl.h:2517
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Definition: Decl.cpp:3997
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: TypeBase.h:5589
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: TypeBase.h:5640
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: TypeBase.h:5632
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition: Type.cpp:3881
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
const Decl * getDecl() const
Definition: GlobalDecl.h:106
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Definition: Decl.cpp:5470
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:469
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Definition: Mangle.h:52
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:358
The basic abstraction for the target Objective-C runtime.
Definition: ObjCRuntime.h:28
bool hasTerminate() const
Does this runtime provide an objc_terminate function?
Definition: ObjCRuntime.h:364
Kind getKind() const
Definition: ObjCRuntime.h:77
bool isNeXTFamily() const
Is this runtime basically of the NeXT family of runtimes?
Definition: ObjCRuntime.h:143
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:937
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
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:8528
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: TypeBase.h:8437
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
CompoundStmt * getBlock() const
Definition: Stmt.h:3742
Expr * getFilterExpr() const
Definition: Stmt.h:3738
CompoundStmt * getBlock() const
Definition: Stmt.h:3779
Represents a __leave statement.
Definition: Stmt.h:3847
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:358
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Definition: TargetCXXABI.h:136
Exposes information about the current target.
Definition: TargetInfo.h:226
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1288
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Definition: TargetInfo.h:1360
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition: Type.cpp:2209
bool isPointerType() const
Definition: TypeBase.h:8580
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: TypeBase.h:2818
bool isObjCObjectPointerType() const
Definition: TypeBase.h:8749
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Definition: Decl.h:1261
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
Definition: EHScopeStack.h:84
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
Definition: EHScopeStack.h:80
bool Load(InterpState &S, CodePtr OpPC)
Definition: Interp.h:1948
The JSON file list parser is used to communicate input to InstallAPI.
@ CPlusPlus
Definition: LangStandard.h:55
@ CPlusPlus17
Definition: LangStandard.h:58
LangAS
Defines the address space values used by the address space qualifier of QualType.
Definition: AddressSpaces.h:25
const FunctionProtoType * T
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DynamicNone
throw()
@ 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
llvm::Constant * RTTI
Definition: CGCleanup.h:40
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
llvm::IntegerType * IntTy
int
llvm::PointerType * AllocaInt8PtrTy
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
Definition: CGCleanup.h:172
llvm::BasicBlock * Block
The catch handler for this type.
Definition: CGCleanup.h:175
The exceptions personality for a function.
Definition: CGCleanup.h:660
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
static const EHPersonality XL_CPlusPlus
Definition: CGCleanup.h:687
static const EHPersonality GNU_ObjC_SJLJ
Definition: CGCleanup.h:675
bool isWasmPersonality() const
Definition: CGCleanup.h:701
static const EHPersonality ZOS_CPlusPlus
Definition: CGCleanup.h:688
static const EHPersonality GNUstep_ObjC
Definition: CGCleanup.h:677
static const EHPersonality MSVC_CxxFrameHandler3
Definition: CGCleanup.h:685
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
Definition: CGCleanup.h:692
static const EHPersonality MSVC_C_specific_handler
Definition: CGCleanup.h:684
static const EHPersonality GNU_CPlusPlus_SEH
Definition: CGCleanup.h:682
static const EHPersonality GNU_ObjC
Definition: CGCleanup.h:674
static const EHPersonality GNU_CPlusPlus_SJLJ
Definition: CGCleanup.h:681
static const EHPersonality GNU_C_SJLJ
Definition: CGCleanup.h:672
static const EHPersonality GNU_C
Definition: CGCleanup.h:671
static const EHPersonality NeXT_ObjC
Definition: CGCleanup.h:679
const char * CatchallRethrowFn
Definition: CGCleanup.h:666
static const EHPersonality GNU_CPlusPlus
Definition: CGCleanup.h:680
static const EHPersonality GNU_ObjCXX
Definition: CGCleanup.h:678
static const EHPersonality GNU_C_SEH
Definition: CGCleanup.h:673
static const EHPersonality MSVC_except_handler
Definition: CGCleanup.h:683
static const EHPersonality GNU_ObjC_SEH
Definition: CGCleanup.h:676
static const EHPersonality GNU_Wasm_CPlusPlus
Definition: CGCleanup.h:686