clang 23.0.0git
CGException.cpp
Go to the documentation of this file.
1//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with C++ exception related code generation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGCXXABI.h"
14#include "CGCleanup.h"
15#include "CGDebugInfo.h"
16#include "CGObjCRuntime.h"
17#include "CodeGenFunction.h"
18#include "ConstantEmitter.h"
19#include "TargetInfo.h"
20#include "clang/AST/Mangle.h"
21#include "clang/AST/StmtCXX.h"
22#include "clang/AST/StmtObjC.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsWebAssembly.h"
28#include "llvm/Support/SaveAndRestore.h"
29
30using namespace clang;
31using namespace CodeGen;
32
33static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM) {
34 // void __cxa_free_exception(void *thrown_exception);
35
36 llvm::FunctionType *FTy =
37 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
38
39 return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
40}
41
42static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM) {
43 llvm::FunctionType *FTy =
44 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
45 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");
46}
47
48static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM) {
49 llvm::FunctionType *FTy =
50 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
51 return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");
52}
53
54static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {
55 // void __cxa_call_unexpected(void *thrown_exception);
56
57 llvm::FunctionType *FTy =
58 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
59
60 return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
61}
62
63llvm::FunctionCallee CodeGenModule::getTerminateFn() {
64 // void __terminate();
65
66 llvm::FunctionType *FTy =
67 llvm::FunctionType::get(VoidTy, /*isVarArg=*/false);
68
69 StringRef name;
70
71 // In C++, use std::terminate().
72 if (getLangOpts().CPlusPlus &&
73 getTarget().getCXXABI().isItaniumFamily()) {
74 name = "_ZSt9terminatev";
75 } else if (getLangOpts().CPlusPlus &&
76 getTarget().getCXXABI().isMicrosoft()) {
77 if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
78 name = "__std_terminate";
79 else
80 name = "?terminate@@YAXXZ";
81 } else if (getLangOpts().ObjC &&
82 getLangOpts().ObjCRuntime.hasTerminate())
83 name = "objc_terminate";
84 else
85 name = "abort";
86 return CreateRuntimeFunction(FTy, name);
87}
88
89static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,
90 StringRef Name) {
91 llvm::FunctionType *FTy =
92 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
93
94 return CGM.CreateRuntimeFunction(FTy, Name);
95}
96
97const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
98const EHPersonality
99EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
100const EHPersonality
101EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
102const EHPersonality
103EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
104const EHPersonality
105EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
106const EHPersonality
107EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
108const EHPersonality
109EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
110const EHPersonality
111EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
112const EHPersonality
113EHPersonality::GNU_ObjC_SJLJ = {"__gnu_objc_personality_sj0", "objc_exception_throw"};
114const EHPersonality
115EHPersonality::GNU_ObjC_SEH = {"__gnu_objc_personality_seh0", "objc_exception_throw"};
116const EHPersonality
117EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
118const EHPersonality
119EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
120const EHPersonality
121EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
122const EHPersonality
123EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
124const EHPersonality
125EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
126const EHPersonality
127EHPersonality::GNU_Wasm_CPlusPlus = { "__gxx_wasm_personality_v0", nullptr };
128const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
129 nullptr};
130const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
131 nullptr};
132
134 const CodeGenOptions &CGOpts) {
135 const llvm::Triple &T = Target.getTriple();
136 if (T.isWindowsMSVCEnvironment())
138 if (CGOpts.hasSjLjExceptions())
140 if (CGOpts.hasDWARFExceptions())
142 if (CGOpts.hasSEHExceptions())
145}
146
148 const CodeGenOptions &CGOpts,
149 const LangOptions &L) {
150 const llvm::Triple &T = Target.getTriple();
151 if (T.isWindowsMSVCEnvironment())
153
154 switch (L.ObjCRuntime.getKind()) {
156 return getCPersonality(Target, CGOpts);
158 case ObjCRuntime::iOS:
162 if (T.isOSCygMing())
164 else if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
166 [[fallthrough]];
167 case ObjCRuntime::GCC:
169 if (CGOpts.hasSjLjExceptions())
171 if (CGOpts.hasSEHExceptions())
174 }
175 llvm_unreachable("bad runtime kind");
176}
177
179 const CodeGenOptions &CGOpts) {
180 const llvm::Triple &T = Target.getTriple();
181 if (T.isWindowsMSVCEnvironment())
183 if (T.isOSAIX())
185 if (CGOpts.hasSjLjExceptions())
187 if (CGOpts.hasDWARFExceptions())
189 if (CGOpts.hasSEHExceptions())
191 if (CGOpts.hasWasmExceptions())
193 if (T.isOSzOS())
196}
197
198/// Determines the personality function to use when both C++
199/// and Objective-C exceptions are being caught.
201 const CodeGenOptions &CGOpts,
202 const LangOptions &L) {
203 if (Target.getTriple().isWindowsMSVCEnvironment())
205
206 switch (L.ObjCRuntime.getKind()) {
207 // In the fragile ABI, just use C++ exception handling and hope
208 // they're not doing crazy exception mixing.
210 return getCXXPersonality(Target, CGOpts);
211
212 // The ObjC personality defers to the C++ personality for non-ObjC
213 // handlers. Unlike the C++ case, we use the same personality
214 // function on targets using (backend-driven) SJLJ EH.
216 case ObjCRuntime::iOS:
218 return getObjCPersonality(Target, CGOpts, L);
219
221 return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
223
224 // The GCC runtime's personality function inherently doesn't support
225 // mixed EH. Use the ObjC personality just to avoid returning null.
226 case ObjCRuntime::GCC:
228 return getObjCPersonality(Target, CGOpts, L);
229 }
230 llvm_unreachable("bad runtime kind");
231}
232
233static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
234 if (T.getArch() == llvm::Triple::x86)
237}
238
240 const FunctionDecl *FD) {
241 const llvm::Triple &T = CGM.getTarget().getTriple();
242 const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();
243 const LangOptions &L = CGM.getLangOpts();
244 const TargetInfo &Target = CGM.getTarget();
245
246 // Functions using SEH get an SEH personality.
247 if (FD && FD->usesSEHTry())
248 return getSEHPersonalityMSVC(T);
249
250 if (L.ObjC)
251 return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)
252 : getObjCPersonality(Target, CGOpts, L);
253 return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)
254 : getCPersonality(Target, CGOpts);
255}
256
258 const auto *FD = CGF.CurCodeDecl;
259 // For outlined finallys and filters, use the SEH personality in case they
260 // contain more SEH. This mostly only affects finallys. Filters could
261 // hypothetically use gnu statement expressions to sneak in nested SEH.
262 FD = FD ? FD : CGF.CurSEHParent.getDecl();
263 return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
264}
265
266static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,
267 const EHPersonality &Personality) {
268 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.
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.
424}
425
431
437
439 return Builder.CreateLoad(getExceptionSlot(), "exn");
440}
441
443 return Builder.CreateLoad(getEHSelectorSlot(), "sel");
444}
445
447 bool KeepInsertionPoint) {
448 // If the exception is being emitted in an OpenMP target region,
449 // and the target is a GPU, we do not support exception handling.
450 // Therefore, we emit a trap which will abort the program, and
451 // prompt a warning indicating that a trap will be emitted.
452 const llvm::Triple &T = Target.getTriple();
453 if (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU()) {
454 EmitTrapCall(llvm::Intrinsic::trap);
455 return;
456 }
457 if (const Expr *SubExpr = E->getSubExpr()) {
458 QualType ThrowType = SubExpr->getType();
459 if (ThrowType->isObjCObjectPointerType()) {
460 const Stmt *ThrowStmt = E->getSubExpr();
461 const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt));
462 CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
463 } else {
464 CGM.getCXXABI().emitThrow(*this, E);
465 }
466 } else {
467 CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
468 }
469
470 // throw is an expression, and the expression emitters expect us
471 // to leave ourselves at a valid insertion point.
472 if (KeepInsertionPoint)
473 EmitBlock(createBasicBlock("throw.cont"));
474}
475
477 if (!CGM.getLangOpts().CXXExceptions)
478 return;
479
480 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
481 if (!FD) {
482 // Check if CapturedDecl is nothrow and create terminate scope for it.
483 if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
484 if (CD->isNothrow())
485 EHStack.pushTerminate();
486 }
487 return;
488 }
489 const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
490 if (!Proto)
491 return;
492
494 // In C++17 and later, 'throw()' aka EST_DynamicNone is treated the same way
495 // as noexcept. In earlier standards, it is handled in this block, along with
496 // 'throw(X...)'.
497 if (EST == EST_Dynamic ||
498 (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {
499 // TODO: Revisit exception specifications for the MS ABI. There is a way to
500 // encode these in an object file but MSVC doesn't do anything with it.
501 if (getTarget().getCXXABI().isMicrosoft())
502 return;
503 // In Wasm EH we currently treat 'throw()' in the same way as 'noexcept'. In
504 // case of throw with types, we ignore it and print a warning for now.
505 // TODO Correctly handle exception specification in Wasm EH
506 if (CGM.getCodeGenOpts().hasWasmExceptions()) {
507 if (EST == EST_DynamicNone)
508 EHStack.pushTerminate();
509 else
510 CGM.getDiags().Report(D->getLocation(),
511 diag::warn_wasm_dynamic_exception_spec_ignored)
513 return;
514 }
515 // Currently Emscripten EH only handles 'throw()' but not 'throw' with
516 // types. 'throw()' handling will be done in JS glue code so we don't need
517 // to do anything in that case. Just print a warning message in case of
518 // throw with types.
519 // TODO Correctly handle exception specification in Emscripten EH
520 if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
521 CGM.getCodeGenOpts().getExceptionHandling() ==
523 EST == EST_Dynamic)
524 CGM.getDiags().Report(D->getLocation(),
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
541 EHStack.pushTerminate();
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())
592 EHStack.popTerminate();
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.
605 if (getTarget().getCXXABI().isMicrosoft())
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
610 if (CGM.getCodeGenOpts().hasWasmExceptions()) {
611 if (EST == EST_DynamicNone)
612 EHStack.popTerminate();
613 return;
614 }
615 EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
616 emitFilterDispatchBlock(*this, filterScope);
617 EHStack.popFilter();
618 } else if (Proto->canThrow() == CT_Cannot &&
619 /* possible empty when under async exceptions */
620 !EHStack.empty()) {
621 EHStack.popTerminate();
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.isGPU());
631 if (!IsTargetDevice)
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;
654 QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
655 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
656
657 CatchTypeInfo TypeInfo{nullptr, 0};
658 if (CaughtType->isObjCObjectPointerType())
659 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
660 else
661 TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
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 *
677 if (EHPersonality::get(*this).usesFuncletPads())
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(CGM, 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.
810 LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
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);
857 Builder.CreateStore(LPadExn, getExceptionSlot());
858 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
859 Builder.CreateStore(LPadSel, getEHSelectorSlot());
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.
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.
961 Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
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
1147 // Load the selector value.
1148 llvm::Value *selector = CGF.getSelectorFromSlot();
1149
1150 // Test against each of the exception types we claim to catch.
1151 for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
1152 assert(i < e && "ran off end of handlers!");
1153 const EHCatchScope::Handler &handler = catchScope.getHandler(i);
1154
1155 llvm::Value *typeValue = handler.Type.RTTI;
1156 assert(handler.Type.Flags == 0 &&
1157 "landingpads do not support catch handler flags");
1158 assert(typeValue && "fell into catch-all case!");
1159 // With opaque ptrs, only the address space can be a mismatch.
1160 if (typeValue->getType() != argTy)
1161 typeValue = CGF.performAddrSpaceCast(typeValue, argTy);
1162
1163 // Figure out the next block.
1164 bool nextIsEnd;
1165 llvm::BasicBlock *nextBlock;
1166
1167 // If this is the last handler, we're at the end, and the next
1168 // block is the block for the enclosing EH scope.
1169 if (i + 1 == e) {
1170 nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
1171 nextIsEnd = true;
1172
1173 // If the next handler is a catch-all, we're at the end, and the
1174 // next block is that handler.
1175 } else if (catchScope.getHandler(i+1).isCatchAll()) {
1176 nextBlock = catchScope.getHandler(i+1).Block;
1177 nextIsEnd = true;
1178
1179 // Otherwise, we're not at the end and we need a new block.
1180 } else {
1181 nextBlock = CGF.createBasicBlock("catch.fallthrough");
1182 nextIsEnd = false;
1183 }
1184
1185 // Figure out the catch type's index in the LSDA's type table.
1186 llvm::CallInst *typeIndex =
1187 CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1188 typeIndex->setDoesNotThrow();
1189
1190 llvm::Value *matchesTypeIndex =
1191 CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
1192 CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
1193
1194 // If the next handler is a catch-all, we're completely done.
1195 if (nextIsEnd) {
1196 CGF.Builder.restoreIP(savedIP);
1197 return;
1198 }
1199 // Otherwise we need to emit and continue at that block.
1200 CGF.EmitBlock(nextBlock);
1201 }
1202}
1203
1205 EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1206 if (catchScope.hasEHBranches())
1207 emitCatchDispatchBlock(*this, catchScope);
1208 EHStack.popCatch();
1209}
1210
1211void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1212 unsigned NumHandlers = S.getNumHandlers();
1213 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1214 assert(CatchScope.getNumHandlers() == NumHandlers);
1215 llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
1216
1217 // If the catch was not required, bail out now.
1218 if (!CatchScope.hasEHBranches()) {
1219 CatchScope.clearHandlerBlocks();
1220 EHStack.popCatch();
1221 return;
1222 }
1223
1224 // Emit the structure of the EH dispatch for this catch.
1225 emitCatchDispatchBlock(*this, CatchScope);
1226
1227 // Copy the handler blocks off before we pop the EH stack. Emitting
1228 // the handlers might scribble on this memory.
1230 CatchScope.begin(), CatchScope.begin() + NumHandlers);
1231
1232 EHStack.popCatch();
1233
1234 // The fall-through block.
1235 llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1236
1237 // We just emitted the body of the try; jump to the continue block.
1238 if (HaveInsertPoint())
1239 Builder.CreateBr(ContBB);
1240
1241 // Determine if we need an implicit rethrow for all these catch handlers;
1242 // see the comment below.
1243 bool doImplicitRethrow = false;
1244 if (IsFnTryBlock)
1245 doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1247
1248 // Wasm uses Windows-style EH instructions, but merges all catch clauses into
1249 // one big catchpad. So we save the old funclet pad here before we traverse
1250 // each catch handler.
1251 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1252 llvm::BasicBlock *WasmCatchStartBlock = nullptr;
1253 if (EHPersonality::get(*this).isWasmPersonality()) {
1254 auto *CatchSwitch =
1255 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHIIt());
1256 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1257 ? CatchSwitch->getSuccessor(1)
1258 : CatchSwitch->getSuccessor(0);
1259 auto *CPI =
1260 cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHIIt());
1261 CurrentFuncletPad = CPI;
1262 }
1263
1264 // Perversely, we emit the handlers backwards precisely because we
1265 // want them to appear in source order. In all of these cases, the
1266 // catch block will have exactly one predecessor, which will be a
1267 // particular block in the catch dispatch. However, in the case of
1268 // a catch-all, one of the dispatch blocks will branch to two
1269 // different handlers, and EmitBlockAfterUses will cause the second
1270 // handler to be moved before the first.
1271 bool HasCatchAll = false;
1272 for (unsigned I = NumHandlers; I != 0; --I) {
1273 HasCatchAll |= Handlers[I - 1].isCatchAll();
1274 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1275 EmitBlockAfterUses(CatchBlock);
1276
1277 // Catch the exception if this isn't a catch-all.
1278 const CXXCatchStmt *C = S.getHandler(I-1);
1279
1280 // Enter a cleanup scope, including the catch variable and the
1281 // end-catch.
1282 RunCleanupsScope CatchScope(*this);
1283
1284 // Initialize the catch variable and set up the cleanups.
1285 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1286 CGM.getCXXABI().emitBeginCatch(*this, C);
1287
1288 // Emit the PGO counter increment.
1290
1291 // Perform the body of the catch.
1292 EmitStmt(C->getHandlerBlock());
1293
1294 // [except.handle]p11:
1295 // The currently handled exception is rethrown if control
1296 // reaches the end of a handler of the function-try-block of a
1297 // constructor or destructor.
1298
1299 // It is important that we only do this on fallthrough and not on
1300 // return. Note that it's illegal to put a return in a
1301 // constructor function-try-block's catch handler (p14), so this
1302 // really only applies to destructors.
1303 if (doImplicitRethrow && HaveInsertPoint()) {
1304 CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1305 Builder.CreateUnreachable();
1306 Builder.ClearInsertionPoint();
1307 }
1308
1309 // Fall out through the catch cleanups.
1310 CatchScope.ForceCleanup();
1311
1312 // Branch out of the try.
1313 if (HaveInsertPoint())
1314 Builder.CreateBr(ContBB);
1315 }
1316
1317 // Because in wasm we merge all catch clauses into one big catchpad, in case
1318 // none of the types in catch handlers matches after we test against each of
1319 // them, we should unwind to the next EH enclosing scope. We generate a call
1320 // to rethrow function here to do that.
1321 if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {
1322 assert(WasmCatchStartBlock);
1323 // Navigate for the "rethrow" block we created in emitWasmCatchPadBlock().
1324 // Wasm uses landingpad-style conditional branches to compare selectors, so
1325 // we follow the false destination for each of the cond branches to reach
1326 // the rethrow block.
1327 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1328 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1329 RethrowBlock = cast<llvm::CondBrInst>(TI)->getSuccessor(1);
1330 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1331 Builder.SetInsertPoint(RethrowBlock);
1332 llvm::Function *RethrowInCatchFn =
1333 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1334 EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
1335 }
1336
1337 EmitBlock(ContBB);
1339}
1340
1341namespace {
1342 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1343 llvm::Value *ForEHVar;
1344 llvm::FunctionCallee EndCatchFn;
1345 CallEndCatchForFinally(llvm::Value *ForEHVar,
1346 llvm::FunctionCallee EndCatchFn)
1347 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1348
1349 void Emit(CodeGenFunction &CGF, Flags flags) override {
1350 llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1351 llvm::BasicBlock *CleanupContBB =
1352 CGF.createBasicBlock("finally.cleanup.cont");
1353
1354 llvm::Value *ShouldEndCatch =
1355 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
1356 CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1357 CGF.EmitBlock(EndCatchBB);
1358 CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1359 CGF.EmitBlock(CleanupContBB);
1360 }
1361 };
1362
1363 struct PerformFinally final : EHScopeStack::Cleanup {
1364 const Stmt *Body;
1365 llvm::Value *ForEHVar;
1366 llvm::FunctionCallee EndCatchFn;
1367 llvm::FunctionCallee RethrowFn;
1368 llvm::Value *SavedExnVar;
1369
1370 PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1371 llvm::FunctionCallee EndCatchFn,
1372 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1373 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1374 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1375
1376 void Emit(CodeGenFunction &CGF, Flags flags) override {
1377 // Enter a cleanup to call the end-catch function if one was provided.
1378 if (EndCatchFn)
1379 CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1380 ForEHVar, EndCatchFn);
1381
1382 // Save the current cleanup destination in case there are
1383 // cleanups in the finally block.
1384 llvm::Value *SavedCleanupDest =
1386 "cleanup.dest.saved");
1387
1388 // Emit the finally block.
1389 CGF.EmitStmt(Body);
1390
1391 // If the end of the finally is reachable, check whether this was
1392 // for EH. If so, rethrow.
1393 if (CGF.HaveInsertPoint()) {
1394 llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1395 llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1396
1397 llvm::Value *ShouldRethrow =
1398 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
1399 CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1400
1401 CGF.EmitBlock(RethrowBB);
1402 if (SavedExnVar) {
1403 CGF.EmitRuntimeCallOrInvoke(RethrowFn,
1404 CGF.Builder.CreateAlignedLoad(CGF.Int8PtrTy, SavedExnVar,
1405 CGF.getPointerAlign()));
1406 } else {
1407 CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1408 }
1409 CGF.Builder.CreateUnreachable();
1410
1411 CGF.EmitBlock(ContBB);
1412
1413 // Restore the cleanup destination.
1414 CGF.Builder.CreateStore(SavedCleanupDest,
1416 }
1417
1418 // Leave the end-catch cleanup. As an optimization, pretend that
1419 // the fallthrough path was inaccessible; we've dynamically proven
1420 // that we're not in the EH case along that path.
1421 if (EndCatchFn) {
1422 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1423 CGF.PopCleanupBlock();
1424 CGF.Builder.restoreIP(SavedIP);
1425 }
1426
1427 // Now make sure we actually have an insertion point or the
1428 // cleanup gods will hate us.
1429 CGF.EnsureInsertPoint();
1430 }
1431 };
1432} // end anonymous namespace
1433
1434/// Enters a finally block for an implementation using zero-cost
1435/// exceptions. This is mostly general, but hard-codes some
1436/// language/ABI-specific behavior in the catch-all sections.
1437void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, const Stmt *body,
1438 llvm::FunctionCallee beginCatchFn,
1439 llvm::FunctionCallee endCatchFn,
1440 llvm::FunctionCallee rethrowFn) {
1441 assert((!!beginCatchFn) == (!!endCatchFn) &&
1442 "begin/end catch functions not paired");
1443 assert(rethrowFn && "rethrow function is required");
1444
1445 BeginCatchFn = beginCatchFn;
1446
1447 // The rethrow function has one of the following two types:
1448 // void (*)()
1449 // void (*)(void*)
1450 // In the latter case we need to pass it the exception object.
1451 // But we can't use the exception slot because the @finally might
1452 // have a landing pad (which would overwrite the exception slot).
1453 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1454 SavedExnVar = nullptr;
1455 if (rethrowFnTy->getNumParams())
1456 SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1457
1458 // A finally block is a statement which must be executed on any edge
1459 // out of a given scope. Unlike a cleanup, the finally block may
1460 // contain arbitrary control flow leading out of itself. In
1461 // addition, finally blocks should always be executed, even if there
1462 // are no catch handlers higher on the stack. Therefore, we
1463 // surround the protected scope with a combination of a normal
1464 // cleanup (to catch attempts to break out of the block via normal
1465 // control flow) and an EH catch-all (semantically "outside" any try
1466 // statement to which the finally block might have been attached).
1467 // The finally block itself is generated in the context of a cleanup
1468 // which conditionally leaves the catch-all.
1469
1470 // Jump destination for performing the finally block on an exception
1471 // edge. We'll never actually reach this block, so unreachable is
1472 // fine.
1473 RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1474
1475 // Whether the finally block is being executed for EH purposes.
1476 ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1477 CGF.Builder.CreateFlagStore(false, ForEHVar);
1478
1479 // Enter a normal cleanup which will perform the @finally block.
1480 CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1481 ForEHVar, endCatchFn,
1482 rethrowFn, SavedExnVar);
1483
1484 // Enter a catch-all scope.
1485 llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1486 EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1487 catchScope->setCatchAllHandler(0, catchBB);
1488}
1489
1490void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1491 // Leave the finally catch-all.
1492 EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1493 llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1494
1495 CGF.popCatchScope();
1496
1497 // If there are any references to the catch-all block, emit it.
1498 if (catchBB->use_empty()) {
1499 delete catchBB;
1500 } else {
1501 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1502 CGF.EmitBlock(catchBB);
1503
1504 llvm::Value *exn = nullptr;
1505
1506 // If there's a begin-catch function, call it.
1507 if (BeginCatchFn) {
1508 exn = CGF.getExceptionFromSlot();
1509 CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1510 }
1511
1512 // If we need to remember the exception pointer to rethrow later, do so.
1513 if (SavedExnVar) {
1514 if (!exn) exn = CGF.getExceptionFromSlot();
1515 CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1516 }
1517
1518 // Tell the cleanups in the finally block that we're do this for EH.
1519 CGF.Builder.CreateFlagStore(true, ForEHVar);
1520
1521 // Thread a jump through the finally cleanup.
1522 CGF.EmitBranchThroughCleanup(RethrowDest);
1523
1524 CGF.Builder.restoreIP(savedIP);
1525 }
1526
1527 // Finally, leave the @finally cleanup.
1528 CGF.PopCleanupBlock();
1529}
1530
1532 if (TerminateLandingPad)
1533 return TerminateLandingPad;
1534
1535 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1536
1537 // This will get inserted at the end of the function.
1538 TerminateLandingPad = createBasicBlock("terminate.lpad");
1539 Builder.SetInsertPoint(TerminateLandingPad);
1540
1541 // Tell the backend that this is a landing pad.
1542 const EHPersonality &Personality = EHPersonality::get(*this);
1543
1544 if (!CurFn->hasPersonalityFn())
1545 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
1546
1547 llvm::LandingPadInst *LPadInst =
1548 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
1549 LPadInst->addClause(getCatchAllValue(*this));
1550
1551 llvm::Value *Exn = nullptr;
1552 if (getLangOpts().CPlusPlus)
1553 Exn = Builder.CreateExtractValue(LPadInst, 0);
1554 llvm::CallInst *terminateCall =
1555 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1556 terminateCall->setDoesNotReturn();
1557 Builder.CreateUnreachable();
1558
1559 // Restore the saved insertion state.
1560 Builder.restoreIP(SavedIP);
1561
1562 return TerminateLandingPad;
1563}
1564
1566 if (TerminateHandler)
1567 return TerminateHandler;
1568
1569 // Set up the terminate handler. This block is inserted at the very
1570 // end of the function by FinishFunction.
1571 TerminateHandler = createBasicBlock("terminate.handler");
1572 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1573 Builder.SetInsertPoint(TerminateHandler);
1574
1575 llvm::Value *Exn = nullptr;
1576 if (getLangOpts().CPlusPlus)
1577 Exn = getExceptionFromSlot();
1578 llvm::CallInst *terminateCall =
1579 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1580 terminateCall->setDoesNotReturn();
1581 Builder.CreateUnreachable();
1582
1583 // Restore the saved insertion state.
1584 Builder.restoreIP(SavedIP);
1585
1586 return TerminateHandler;
1587}
1588
1590 assert(EHPersonality::get(*this).usesFuncletPads() &&
1591 "use getTerminateLandingPad for non-funclet EH");
1592
1593 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1594 if (TerminateFunclet)
1595 return TerminateFunclet;
1596
1597 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1598
1599 // Set up the terminate handler. This block is inserted at the very
1600 // end of the function by FinishFunction.
1601 TerminateFunclet = createBasicBlock("terminate.handler");
1602 Builder.SetInsertPoint(TerminateFunclet);
1603
1604 // Create the cleanuppad using the current parent pad as its token. Use 'none'
1605 // if this is a top-level terminate scope, which is the common case.
1606 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1607 llvm::Value *ParentPad = CurrentFuncletPad;
1608 if (!ParentPad)
1609 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1610 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1611
1612 // Emit the __std_terminate call.
1613 llvm::CallInst *terminateCall =
1614 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);
1615 terminateCall->setDoesNotReturn();
1616 Builder.CreateUnreachable();
1617
1618 // Restore the saved insertion state.
1619 Builder.restoreIP(SavedIP);
1620
1621 return TerminateFunclet;
1622}
1623
1624llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1625 if (EHResumeBlock) return EHResumeBlock;
1626
1627 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1628
1629 // We emit a jump to a notional label at the outermost unwind state.
1630 EHResumeBlock = createBasicBlock("eh.resume");
1631 Builder.SetInsertPoint(EHResumeBlock);
1632
1633 const EHPersonality &Personality = EHPersonality::get(*this);
1634
1635 // This can always be a call because we necessarily didn't find
1636 // anything on the EH stack which needs our help.
1637 const char *RethrowName = Personality.CatchallRethrowFn;
1638 if (RethrowName != nullptr && !isCleanup) {
1640 getExceptionFromSlot())->setDoesNotReturn();
1641 Builder.CreateUnreachable();
1642 Builder.restoreIP(SavedIP);
1643 return EHResumeBlock;
1644 }
1645
1646 // Recreate the landingpad's return value for the 'resume' instruction.
1647 llvm::Value *Exn = getExceptionFromSlot();
1648 llvm::Value *Sel = getSelectorFromSlot();
1649
1650 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1651 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1652 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1653 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1654
1655 Builder.CreateResume(LPadVal);
1656 Builder.restoreIP(SavedIP);
1657 return EHResumeBlock;
1658}
1659
1661 EnterSEHTryStmt(S);
1662 {
1663 JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
1664
1665 SEHTryEpilogueStack.push_back(&TryExit);
1666
1667 llvm::BasicBlock *TryBB = nullptr;
1668 // IsEHa: emit an invoke to _seh_try_begin() runtime for -EHa
1669 if (getLangOpts().EHAsynch) {
1671 if (SEHTryEpilogueStack.size() == 1) // outermost only
1672 TryBB = Builder.GetInsertBlock();
1673 }
1674
1675 EmitStmt(S.getTryBlock());
1676
1677 // Volatilize all blocks in Try, till current insert point
1678 if (TryBB) {
1680 VolatilizeTryBlocks(TryBB, Visited);
1681 }
1682
1683 SEHTryEpilogueStack.pop_back();
1684
1685 if (!TryExit.getBlock()->use_empty())
1686 EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
1687 else
1688 delete TryExit.getBlock();
1689 }
1690 ExitSEHTryStmt(S);
1691}
1692
1693// Recursively walk through blocks in a _try
1694// and make all memory instructions volatile
1696 llvm::BasicBlock *BB, llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V) {
1697 if (BB == SEHTryEpilogueStack.back()->getBlock() /* end of Try */ ||
1698 !V.insert(BB).second /* already visited */ ||
1699 !BB->getParent() /* not emitted */ || BB->empty())
1700 return;
1701
1702 if (!BB->isEHPad()) {
1703 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1704 ++J) {
1705 if (auto LI = dyn_cast<llvm::LoadInst>(J)) {
1706 LI->setVolatile(true);
1707 } else if (auto SI = dyn_cast<llvm::StoreInst>(J)) {
1708 SI->setVolatile(true);
1709 } else if (auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1710 MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));
1711 }
1712 }
1713 }
1714 if (const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1715 unsigned N = TI->getNumSuccessors();
1716 for (unsigned I = 0; I < N; I++)
1717 VolatilizeTryBlocks(TI->getSuccessor(I), V);
1718 }
1719}
1720
1721namespace {
1722struct PerformSEHFinally final : EHScopeStack::Cleanup {
1723 llvm::Function *OutlinedFinally;
1724 PerformSEHFinally(llvm::Function *OutlinedFinally)
1725 : OutlinedFinally(OutlinedFinally) {}
1726
1727 void Emit(CodeGenFunction &CGF, Flags F) override {
1728 ASTContext &Context = CGF.getContext();
1729 CodeGenModule &CGM = CGF.CGM;
1730
1731 CallArgList Args;
1732
1733 // Compute the two argument values.
1734 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1735 llvm::Value *FP = nullptr;
1736 // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
1737 if (CGF.IsOutlinedSEHHelper) {
1738 FP = &CGF.CurFn->arg_begin()[1];
1739 } else {
1740 llvm::Function *LocalAddrFn =
1741 CGM.getIntrinsic(llvm::Intrinsic::localaddress);
1742 FP = CGF.Builder.CreateCall(LocalAddrFn);
1743 }
1744
1745 llvm::Value *IsForEH =
1746 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
1747
1748 // Except _leave and fall-through at the end, all other exits in a _try
1749 // (return/goto/continue/break) are considered as abnormal terminations
1750 // since _leave/fall-through is always Indexed 0,
1751 // just use NormalCleanupDestSlot (>= 1 for goto/return/..),
1752 // as 1st Arg to indicate abnormal termination
1753 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1754 Address Addr = CGF.getNormalCleanupDestSlot();
1755 llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
1756 llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
1757 IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
1758 }
1759
1760 Args.add(RValue::get(IsForEH), ArgTys[0]);
1761 Args.add(RValue::get(FP), ArgTys[1]);
1762
1763 // Arrange a two-arg function info and type.
1764 const CGFunctionInfo &FnInfo =
1765 CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
1766
1767 auto Callee = CGCallee::forDirect(OutlinedFinally);
1768 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1769 }
1770};
1771} // end anonymous namespace
1772
1773namespace {
1774/// Find all local variable captures in the statement.
1775struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1776 CodeGenFunction &ParentCGF;
1777 const VarDecl *ParentThis;
1778 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1779 Address SEHCodeSlot = Address::invalid();
1780 CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
1781 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1782
1783 // Return true if we need to do any capturing work.
1784 bool foundCaptures() {
1785 return !Captures.empty() || SEHCodeSlot.isValid();
1786 }
1787
1788 void Visit(const Stmt *S) {
1789 // See if this is a capture, then recurse.
1790 ConstStmtVisitor<CaptureFinder>::Visit(S);
1791 for (const Stmt *Child : S->children())
1792 if (Child)
1793 Visit(Child);
1794 }
1795
1796 void VisitDeclRefExpr(const DeclRefExpr *E) {
1797 // If this is already a capture, just make sure we capture 'this'.
1799 Captures.insert(ParentThis);
1800
1801 const auto *D = dyn_cast<VarDecl>(E->getDecl());
1802 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1803 Captures.insert(D);
1804 }
1805
1806 void VisitCXXThisExpr(const CXXThisExpr *E) {
1807 Captures.insert(ParentThis);
1808 }
1809
1810 void VisitCallExpr(const CallExpr *E) {
1811 // We only need to add parent frame allocations for these builtins in x86.
1812 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1813 return;
1814
1815 unsigned ID = E->getBuiltinCallee();
1816 switch (ID) {
1817 case Builtin::BI__exception_code:
1818 case Builtin::BI_exception_code:
1819 // This is the simple case where we are the outermost finally. All we
1820 // have to do here is make sure we escape this and recover it in the
1821 // outlined handler.
1822 if (!SEHCodeSlot.isValid())
1823 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1824 break;
1825 }
1826 }
1827};
1828} // end anonymous namespace
1829
1831 Address ParentVar,
1832 llvm::Value *ParentFP) {
1833 llvm::Value *RecoverCall = nullptr;
1835 // We are currently handling the following case:
1836 // ParentAlloca: An alloca for a local variable/direct argument
1837 // ParentArg: An argument pointer, pointing to an argument passed indirectly
1838 // Other case: A call to localrecover, if this is a nested __try.
1839 auto *ParentAlloca =
1840 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer());
1841 auto *ParentArg =
1842 dyn_cast_or_null<llvm::Argument>(ParentVar.getBasePointer());
1843 if (!ParentAlloca) {
1844 if (ParentArg) {
1845 llvm::BasicBlock &EntryBB = ParentCGF.CurFn->getEntryBlock();
1846 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1847 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1848 ParentArg->getType(), nullptr, ParentArg->getName() + ".spill");
1849 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1850 }
1851 }
1852
1853 if (ParentAlloca) {
1854 // Mark the variable escaped if nobody else referenced it and compute the
1855 // localescape index.
1856 auto InsertPair = ParentCGF.EscapedLocals.insert(
1857 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1858 int FrameEscapeIdx = InsertPair.first->second;
1859 // call ptr @llvm.localrecover(ptr @parentFn, ptr %fp, i32 N)
1860 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1861 &CGM.getModule(), llvm::Intrinsic::localrecover);
1862 RecoverCall = Builder.CreateCall(
1863 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1864 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1865 if (ParentArg)
1866 RecoverCall = Builder.CreateLoad(
1867 Address(RecoverCall, ParentArg->getType(), getPointerAlign()));
1868 } else {
1869 // If the parent didn't have an alloca, we're doing some nested outlining.
1870 // Just clone the existing localrecover call, but tweak the FP argument to
1871 // use our FP value. All other arguments are constants.
1872 auto *ParentRecover = cast<llvm::IntrinsicInst>(
1873 ParentVar.emitRawPointer(*this)->stripPointerCasts());
1874 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1875 "expected alloca or localrecover in parent LocalDeclMap");
1876 RecoverCall = ParentRecover->clone();
1877 cast<llvm::CallInst>(RecoverCall)->setArgOperand(1, ParentFP);
1878 cast<llvm::CallInst>(RecoverCall)
1879 ->insertBefore(AllocaInsertPt->getIterator());
1880 }
1881
1882 // Bitcast the variable, rename it, and insert it in the local decl map.
1883 llvm::Value *ChildVar =
1884 Builder.CreateBitCast(RecoverCall, ParentVar.getType());
1885 ChildVar->setName(ParentVar.getName());
1886 return ParentVar.withPointer(ChildVar, KnownNonNull);
1887}
1888
1890 const Stmt *OutlinedStmt,
1891 bool IsFilter) {
1892 // Find all captures in the Stmt.
1893 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1894 Finder.Visit(OutlinedStmt);
1895
1896 // We can exit early on x86_64 when there are no captures. We just have to
1897 // save the exception code in filters so that __exception_code() works.
1898 if (!Finder.foundCaptures() &&
1899 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1900 if (IsFilter)
1901 EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
1902 return;
1903 }
1904
1905 llvm::Value *EntryFP = nullptr;
1907 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1908 // 32-bit SEH filters need to be careful about FP recovery. The end of the
1909 // EH registration is passed in as the EBP physical register. We can
1910 // recover that with llvm.frameaddress(1).
1911 EntryFP = Builder.CreateCall(
1912 CGM.getIntrinsic(llvm::Intrinsic::frameaddress, AllocaInt8PtrTy),
1913 {Builder.getInt32(1)});
1914 } else {
1915 // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
1916 // second parameter.
1917 auto AI = CurFn->arg_begin();
1918 ++AI;
1919 EntryFP = &*AI;
1920 }
1921
1922 llvm::Value *ParentFP = EntryFP;
1923 if (IsFilter) {
1924 // Given whatever FP the runtime provided us in EntryFP, recover the true
1925 // frame pointer of the parent function. We only need to do this in filters,
1926 // since finally funclets recover the parent FP for us.
1927 llvm::Function *RecoverFPIntrin =
1928 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1929 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});
1930
1931 // if the parent is a _finally, the passed-in ParentFP is the FP
1932 // of parent _finally, not Establisher's FP (FP of outermost function).
1933 // Establkisher FP is 2nd paramenter passed into parent _finally.
1934 // Fortunately, it's always saved in parent's frame. The following
1935 // code retrieves it, and escapes it so that spill instruction won't be
1936 // optimized away.
1937 if (ParentCGF.ParentCGF != nullptr) {
1938 // Locate and escape Parent's frame_pointer.addr alloca
1939 // Depending on target, should be 1st/2nd one in LocalDeclMap.
1940 // Let's just scan for ImplicitParamDecl with VoidPtrTy.
1941 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
1942 for (auto &I : ParentCGF.LocalDeclMap) {
1943 const VarDecl *D = cast<VarDecl>(I.first);
1944 if (isa<ImplicitParamDecl>(D) &&
1945 D->getType() == getContext().VoidPtrTy) {
1946 assert(D->getName().starts_with("frame_pointer"));
1947 FramePtrAddrAlloca =
1948 cast<llvm::AllocaInst>(I.second.getBasePointer());
1949 break;
1950 }
1951 }
1952 assert(FramePtrAddrAlloca);
1953 auto InsertPair = ParentCGF.EscapedLocals.insert(
1954 std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
1955 int FrameEscapeIdx = InsertPair.first->second;
1956
1957 // an example of a filter's prolog::
1958 // %0 = call ptr @llvm.eh.recoverfp(@"?fin$0@0@main@@",..)
1959 // %1 = call ptr @llvm.localrecover(@"?fin$0@0@main@@",..)
1960 // %2 = load ptr, ptr %1, align 8
1961 // ==> %2 is the frame-pointer of outermost host function
1962 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1963 &CGM.getModule(), llvm::Intrinsic::localrecover);
1964 ParentFP = Builder.CreateCall(
1965 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1966 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1967 ParentFP = Builder.CreateLoad(
1968 Address(ParentFP, CGM.VoidPtrTy, getPointerAlign()));
1969 }
1970 }
1971
1972 // Create llvm.localrecover calls for all captures.
1973 for (const VarDecl *VD : Finder.Captures) {
1974 if (VD->getType()->isVariablyModifiedType()) {
1975 CGM.ErrorUnsupported(VD, "VLA captured by SEH");
1976 continue;
1977 }
1978 assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
1979 "captured non-local variable");
1980
1981 auto L = ParentCGF.LambdaCaptureFields.find(VD);
1982 if (L != ParentCGF.LambdaCaptureFields.end()) {
1983 LambdaCaptureFields[VD] = L->second;
1984 continue;
1985 }
1986
1987 // If this decl hasn't been declared yet, it will be declared in the
1988 // OutlinedStmt.
1989 auto I = ParentCGF.LocalDeclMap.find(VD);
1990 if (I == ParentCGF.LocalDeclMap.end())
1991 continue;
1992
1993 Address ParentVar = I->second;
1994 Address Recovered =
1995 recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);
1996 setAddrOfLocalVar(VD, Recovered);
1997
1998 if (isa<ImplicitParamDecl>(VD)) {
1999 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
2000 CXXThisAlignment = ParentCGF.CXXThisAlignment;
2001 CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
2002 if (ParentCGF.LambdaThisCaptureField) {
2003 LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
2004 // We are in a lambda function where "this" is captured so the
2005 // CXXThisValue need to be loaded from the lambda capture
2006 LValue ThisFieldLValue =
2008 if (!LambdaThisCaptureField->getType()->isPointerType()) {
2009 CXXThisValue = ThisFieldLValue.getAddress().emitRawPointer(*this);
2010 } else {
2011 CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
2012 .getScalarVal();
2013 }
2014 } else {
2015 CXXThisValue = CXXABIThisValue;
2016 }
2017 }
2018 }
2019
2020 if (Finder.SEHCodeSlot.isValid()) {
2021 SEHCodeSlotStack.push_back(
2022 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
2023 }
2024
2025 if (IsFilter)
2026 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
2027}
2028
2029/// Arrange a function prototype that can be called by Windows exception
2030/// handling personalities. On Win64, the prototype looks like:
2031/// RetTy func(void *EHPtrs, void *ParentFP);
2033 bool IsFilter,
2034 const Stmt *OutlinedStmt) {
2035 SourceLocation StartLoc = OutlinedStmt->getBeginLoc();
2036
2037 // Get the mangled function name.
2038 SmallString<128> Name;
2039 {
2040 llvm::raw_svector_ostream OS(Name);
2041 GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;
2042 assert(ParentSEHFn && "No CurSEHParent!");
2043 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
2044 if (IsFilter)
2045 Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
2046 else
2047 Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
2048 }
2049
2050 FunctionArgList Args;
2051 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2052 // All SEH finally functions take two parameters. Win64 filters take two
2053 // parameters. Win32 filters take no parameters.
2054 if (IsFilter) {
2055 Args.push_back(ImplicitParamDecl::Create(
2056 getContext(), /*DC=*/nullptr, StartLoc,
2057 &getContext().Idents.get("exception_pointers"),
2059 } else {
2060 Args.push_back(ImplicitParamDecl::Create(
2061 getContext(), /*DC=*/nullptr, StartLoc,
2062 &getContext().Idents.get("abnormal_termination"),
2063 getContext().UnsignedCharTy, ImplicitParamKind::Other));
2064 }
2065 Args.push_back(ImplicitParamDecl::Create(
2066 getContext(), /*DC=*/nullptr, StartLoc,
2067 &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy,
2069 }
2070
2071 QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
2072
2073 const CGFunctionInfo &FnInfo =
2074 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2075
2076 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
2077 llvm::Function *Fn = llvm::Function::Create(
2078 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
2079
2080 IsOutlinedSEHHelper = true;
2081
2082 StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
2083 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
2084 CurSEHParent = ParentCGF.CurSEHParent;
2085
2086 CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
2087 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
2088}
2089
2090/// Create a stub filter function that will ultimately hold the code of the
2091/// filter expression. The EH preparation passes in LLVM will outline the code
2092/// from the main function body into this stub.
2093llvm::Function *
2095 const SEHExceptStmt &Except) {
2096 const Expr *FilterExpr = Except.getFilterExpr();
2097 startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
2098
2099 // Emit the original filter expression, convert to i32, and return.
2100 llvm::Value *R = EmitScalarExpr(FilterExpr);
2101 R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
2102 FilterExpr->getType()->isSignedIntegerType());
2103 Builder.CreateStore(R, ReturnValue);
2104
2105 FinishFunction(FilterExpr->getEndLoc());
2106
2107 return CurFn;
2108}
2109
2110llvm::Function *
2112 const SEHFinallyStmt &Finally) {
2113 const Stmt *FinallyBlock = Finally.getBlock();
2114 startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
2115
2116 // Emit the original filter expression, convert to i32, and return.
2117 EmitStmt(FinallyBlock);
2118
2119 FinishFunction(FinallyBlock->getEndLoc());
2120
2121 return CurFn;
2122}
2123
2125 llvm::Value *ParentFP,
2126 llvm::Value *EntryFP) {
2127 // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
2128 // __exception_info intrinsic.
2129 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2130 // On Win64, the info is passed as the first parameter to the filter.
2131 SEHInfo = &*CurFn->arg_begin();
2132 SEHCodeSlotStack.push_back(
2133 CreateMemTemp(getContext().IntTy, "__exception_code"));
2134 } else {
2135 // On Win32, the EBP on entry to the filter points to the end of an
2136 // exception registration object. It contains 6 32-bit fields, and the info
2137 // pointer is stored in the second field. So, GEP 20 bytes backwards and
2138 // load the pointer.
2139 SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
2140 SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
2142 ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
2143 }
2144
2145 // Save the exception code in the exception slot to unify exception access in
2146 // the filter function and the landing pad.
2147 // struct EXCEPTION_POINTERS {
2148 // EXCEPTION_RECORD *ExceptionRecord;
2149 // CONTEXT *ContextRecord;
2150 // };
2151 // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
2152 llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());
2153 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
2154 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);
2155 Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign());
2156 llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign());
2157 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2158 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2159}
2160
2162 // Sema should diagnose calling this builtin outside of a filter context, but
2163 // don't crash if we screw up.
2164 if (!SEHInfo)
2165 return llvm::PoisonValue::get(Int8PtrTy);
2166 assert(SEHInfo->getType() == Int8PtrTy);
2167 return SEHInfo;
2168}
2169
2171 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2172 return Builder.CreateLoad(SEHCodeSlotStack.back());
2173}
2174
2176 // Abnormal termination is just the first parameter to the outlined finally
2177 // helper.
2178 auto AI = CurFn->arg_begin();
2179 return Builder.CreateZExt(&*AI, Int32Ty);
2180}
2181
2183 llvm::Function *FinallyFunc) {
2184 EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
2185}
2186
2188 CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
2189 HelperCGF.ParentCGF = this;
2190 if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
2191 // Outline the finally block.
2192 llvm::Function *FinallyFunc =
2193 HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
2194
2195 // Push a cleanup for __finally blocks.
2196 EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
2197 return;
2198 }
2199
2200 // Otherwise, we must have an __except block.
2201 const SEHExceptStmt *Except = S.getExceptHandler();
2202 assert(Except);
2203 EHCatchScope *CatchScope = EHStack.pushCatch(1);
2204 SEHCodeSlotStack.push_back(
2205 CreateMemTemp(getContext().IntTy, "__exception_code"));
2206
2207 // If the filter is known to evaluate to 1, then we can use the clause
2208 // "catch i8* null". We can't do this on x86 because the filter has to save
2209 // the exception code.
2210 llvm::Constant *C =
2212 getContext().IntTy);
2213 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2214 C->isOneValue()) {
2215 CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
2216 return;
2217 }
2218
2219 // In general, we have to emit an outlined filter function. Use the function
2220 // in place of the RTTI typeinfo global that C++ EH uses.
2221 llvm::Function *FilterFunc =
2222 HelperCGF.GenerateSEHFilterFunction(*this, *Except);
2223 CatchScope->setHandler(0, FilterFunc, createBasicBlock("__except.ret"));
2224}
2225
2227 // Just pop the cleanup if it's a __finally block.
2228 if (S.getFinallyHandler()) {
2230 return;
2231 }
2232
2233 // IsEHa: emit an invoke _seh_try_end() to mark end of FT flow
2234 if (getLangOpts().EHAsynch && Builder.GetInsertBlock()) {
2235 llvm::FunctionCallee SehTryEnd = getSehTryEndFn(CGM);
2236 EmitRuntimeCallOrInvoke(SehTryEnd);
2237 }
2238
2239 // Otherwise, we must have an __except block.
2240 const SEHExceptStmt *Except = S.getExceptHandler();
2241 assert(Except && "__try must have __finally xor __except");
2242 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2243
2244 // Don't emit the __except block if the __try block lacked invokes.
2245 // TODO: Model unwind edges from instructions, either with iload / istore or
2246 // a try body function.
2247 if (!CatchScope.hasEHBranches()) {
2248 CatchScope.clearHandlerBlocks();
2249 EHStack.popCatch();
2250 SEHCodeSlotStack.pop_back();
2251 return;
2252 }
2253
2254 // The fall-through block.
2255 llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
2256
2257 // We just emitted the body of the __try; jump to the continue block.
2258 if (HaveInsertPoint())
2259 Builder.CreateBr(ContBB);
2260
2261 // Check if our filter function returned true.
2262 emitCatchDispatchBlock(*this, CatchScope);
2263
2264 // Grab the block before we pop the handler.
2265 llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
2266 EHStack.popCatch();
2267
2268 EmitBlockAfterUses(CatchPadBB);
2269
2270 // __except blocks don't get outlined into funclets, so immediately do a
2271 // catchret.
2272 llvm::CatchPadInst *CPI =
2273 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
2274 llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
2275 Builder.CreateCatchRet(CPI, ExceptBB);
2276 EmitBlock(ExceptBB);
2277
2278 // On Win64, the exception code is returned in EAX. Copy it into the slot.
2279 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2280 llvm::Function *SEHCodeIntrin =
2281 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2282 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2283 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2284 }
2285
2286 // Emit the __except body.
2287 EmitStmt(Except->getBlock());
2288
2289 // End the lifetime of the exception code.
2290 SEHCodeSlotStack.pop_back();
2291
2292 if (HaveInsertPoint())
2293 Builder.CreateBr(ContBB);
2294
2295 EmitBlock(ContBB);
2296}
2297
2299 // If this code is reachable then emit a stop point (if generating
2300 // debug info). We have to do this ourselves because we are on the
2301 // "simple" statement path.
2302 if (HaveInsertPoint())
2303 EmitStopPoint(&S);
2304
2305 // This must be a __leave from a __finally block, which we warn on and is UB.
2306 // Just emit unreachable.
2307 if (!isSEHTryScope()) {
2308 Builder.CreateUnreachable();
2309 Builder.ClearInsertionPoint();
2310 return;
2311 }
2312
2314}
#define V(N, I)
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)
Emit the dispatch block for a filter scope if necessary.
static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)
static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function.
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
Emit the structure of the dispatch block for the given catch scope.
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
static bool isNonEHScope(const EHScope &S)
Check whether this is a non-EH scope, i.e.
static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
Returns the value to inject into a selector to indicate the presence of a catch-all.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="<stdin>")
Clean up any erroneous/redundant code in the given Ranges in Code.
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:226
CanQualType LongTy
CanQualType VoidTy
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1209
const Expr * getSubExpr() const
Definition ExprCXX.h:1229
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:69
CXXCatchStmt * getHandler(unsigned i)
Definition StmtCXX.h:108
unsigned getNumHandlers() const
Definition StmtCXX.h:107
CompoundStmt * getTryBlock()
Definition StmtCXX.h:100
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Definition Expr.cpp:1592
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:4961
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
bool hasDWARFExceptions() const
bool hasWasmExceptions() const
bool hasSjLjExceptions() const
bool hasSEHExceptions() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition Address.h:128
llvm::Value * getBasePointer() const
Definition Address.h:198
static Address invalid()
Definition Address.h:176
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:253
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Definition Address.h:261
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Definition Address.h:276
llvm::StringRef getName() const
Return the IR name of the pointer value.
Definition Address.h:218
bool isValid() const
Definition Address.h:177
llvm::PointerType * getType() const
Return the type of the pointer value.
Definition Address.h:204
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
Definition CGBuilder.h:174
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition CGBuilder.h:146
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Definition CGBuilder.h:153
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:118
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
Definition CGBuilder.h:168
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Definition CGBuilder.h:138
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition CGCall.h:137
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
Definition CGCall.h: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)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)
llvm::BasicBlock * getInvokeDestImpl()
llvm::Type * ConvertType(QualType T)
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
Definition CGCall.cpp:5172
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:5199
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:677
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::BasicBlock * getUnreachableBlock()
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
llvm::Value * ExceptionSlot
The exception slot.
void EmitAnyExprToExn(const Expr *E, Address Addr)
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
const TargetInfo & getTarget() const
llvm::BasicBlock * getTerminateHandler()
getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...
void EnterSEHTryStmt(const SEHTryStmt &S)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
Definition CGExpr.cpp:2497
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Definition CGExpr.cpp:153
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:5355
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
Scan the outlined statement for captures from the parent function.
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
Definition CGStmt.cpp:48
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
Definition CGExpr.cpp:302
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
Definition CGStmt.cpp:58
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertTypeForMem(QualType T)
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
void ExitSEHTryStmt(const SEHTryStmt &S)
LValue EmitLValueForLambdaField(const FieldDecl *Field)
Definition CGExpr.cpp:5611
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:189
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:4569
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void EmitSEHTryStmt(const SEHTryStmt &S)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)
Create a stub filter function that will ultimately hold the code of the filter expression.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
Definition CGStmt.cpp:640
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
Definition CGCall.cpp:731
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
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
A non-stable pointer into the scope stack.
Definition CGCleanup.h:563
A saved depth on the scope stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
Definition CGCleanup.h:623
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
A protected scope for zero-cost EH handling.
Definition CGCleanup.h:45
llvm::BasicBlock * getCachedLandingPad() const
Definition CGCleanup.h:130
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:183
Address getAddress() const
Definition CGValue.h:373
static RValue get(llvm::Value *V)
Definition CGValue.h:99
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Definition CGValue.h:72
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Definition Expr.h:1477
ValueDecl * getDecl()
Definition Expr.h:1341
SourceLocation getLocation() const
Definition DeclBase.h:447
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:277
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2015
bool usesSEHTry() const
Indicates the function uses __try.
Definition Decl.h:2533
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Definition Decl.cpp:4058
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5357
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5664
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5715
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5707
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:3920
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:5604
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Definition Mangle.h:56
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
Represents Objective-C's @throw statement.
Definition StmtObjC.h:358
Kind getKind() const
Definition ObjCRuntime.h:77
const VersionTuple & getVersion() const
Definition ObjCRuntime.h:78
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
Definition ObjCRuntime.h:35
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Definition ObjCRuntime.h:40
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
Definition ObjCRuntime.h:56
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
Definition ObjCRuntime.h:59
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Definition ObjCRuntime.h:45
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
Definition ObjCRuntime.h:53
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
Definition ObjCRuntime.h:49
A (possibly-)qualified type.
Definition TypeBase.h:937
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8471
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:8616
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8525
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
CompoundStmt * getBlock() const
Definition Stmt.h:3794
Expr * getFilterExpr() const
Definition Stmt.h:3790
CompoundStmt * getBlock() const
Definition Stmt.h:3831
Represents a __leave statement.
Definition Stmt.h:3899
CompoundStmt * getTryBlock() const
Definition Stmt.h:3875
SEHFinallyStmt * getFinallyHandler() const
Definition Stmt.cpp:1343
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Definition Stmt.cpp:1339
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
Stmt - This represents one statement.
Definition Stmt.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
child_range children()
Definition Stmt.cpp:304
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Exposes information about the current target.
Definition TargetInfo.h:227
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2231
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition TypeBase.h:2850
bool isObjCObjectPointerType() const
Definition TypeBase.h:8847
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
Definition Decl.h:1277
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
bool Load(InterpState &S, CodePtr OpPC)
Definition Interp.h:1999
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
@ CPlusPlus17
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1761
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Dynamic
throw(T1, T2)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
Definition CGCleanup.h:39
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
Definition CGCleanup.h: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
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
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