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->getTerminator()) {
1329 auto *BI = cast<llvm::BranchInst>(TI);
1330 assert(BI->isConditional());
1331 RethrowBlock = BI->getSuccessor(1);
1332 }
1333 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1334 Builder.SetInsertPoint(RethrowBlock);
1335 llvm::Function *RethrowInCatchFn =
1336 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1337 EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
1338 }
1339
1340 EmitBlock(ContBB);
1342}
1343
1344namespace {
1345 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1346 llvm::Value *ForEHVar;
1347 llvm::FunctionCallee EndCatchFn;
1348 CallEndCatchForFinally(llvm::Value *ForEHVar,
1349 llvm::FunctionCallee EndCatchFn)
1350 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1351
1352 void Emit(CodeGenFunction &CGF, Flags flags) override {
1353 llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1354 llvm::BasicBlock *CleanupContBB =
1355 CGF.createBasicBlock("finally.cleanup.cont");
1356
1357 llvm::Value *ShouldEndCatch =
1358 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
1359 CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1360 CGF.EmitBlock(EndCatchBB);
1361 CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1362 CGF.EmitBlock(CleanupContBB);
1363 }
1364 };
1365
1366 struct PerformFinally final : EHScopeStack::Cleanup {
1367 const Stmt *Body;
1368 llvm::Value *ForEHVar;
1369 llvm::FunctionCallee EndCatchFn;
1370 llvm::FunctionCallee RethrowFn;
1371 llvm::Value *SavedExnVar;
1372
1373 PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1374 llvm::FunctionCallee EndCatchFn,
1375 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1376 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1377 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1378
1379 void Emit(CodeGenFunction &CGF, Flags flags) override {
1380 // Enter a cleanup to call the end-catch function if one was provided.
1381 if (EndCatchFn)
1382 CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1383 ForEHVar, EndCatchFn);
1384
1385 // Save the current cleanup destination in case there are
1386 // cleanups in the finally block.
1387 llvm::Value *SavedCleanupDest =
1389 "cleanup.dest.saved");
1390
1391 // Emit the finally block.
1392 CGF.EmitStmt(Body);
1393
1394 // If the end of the finally is reachable, check whether this was
1395 // for EH. If so, rethrow.
1396 if (CGF.HaveInsertPoint()) {
1397 llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1398 llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1399
1400 llvm::Value *ShouldRethrow =
1401 CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
1402 CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1403
1404 CGF.EmitBlock(RethrowBB);
1405 if (SavedExnVar) {
1406 CGF.EmitRuntimeCallOrInvoke(RethrowFn,
1407 CGF.Builder.CreateAlignedLoad(CGF.Int8PtrTy, SavedExnVar,
1408 CGF.getPointerAlign()));
1409 } else {
1410 CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1411 }
1412 CGF.Builder.CreateUnreachable();
1413
1414 CGF.EmitBlock(ContBB);
1415
1416 // Restore the cleanup destination.
1417 CGF.Builder.CreateStore(SavedCleanupDest,
1419 }
1420
1421 // Leave the end-catch cleanup. As an optimization, pretend that
1422 // the fallthrough path was inaccessible; we've dynamically proven
1423 // that we're not in the EH case along that path.
1424 if (EndCatchFn) {
1425 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1426 CGF.PopCleanupBlock();
1427 CGF.Builder.restoreIP(SavedIP);
1428 }
1429
1430 // Now make sure we actually have an insertion point or the
1431 // cleanup gods will hate us.
1432 CGF.EnsureInsertPoint();
1433 }
1434 };
1435} // end anonymous namespace
1436
1437/// Enters a finally block for an implementation using zero-cost
1438/// exceptions. This is mostly general, but hard-codes some
1439/// language/ABI-specific behavior in the catch-all sections.
1440void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, const Stmt *body,
1441 llvm::FunctionCallee beginCatchFn,
1442 llvm::FunctionCallee endCatchFn,
1443 llvm::FunctionCallee rethrowFn) {
1444 assert((!!beginCatchFn) == (!!endCatchFn) &&
1445 "begin/end catch functions not paired");
1446 assert(rethrowFn && "rethrow function is required");
1447
1448 BeginCatchFn = beginCatchFn;
1449
1450 // The rethrow function has one of the following two types:
1451 // void (*)()
1452 // void (*)(void*)
1453 // In the latter case we need to pass it the exception object.
1454 // But we can't use the exception slot because the @finally might
1455 // have a landing pad (which would overwrite the exception slot).
1456 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1457 SavedExnVar = nullptr;
1458 if (rethrowFnTy->getNumParams())
1459 SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1460
1461 // A finally block is a statement which must be executed on any edge
1462 // out of a given scope. Unlike a cleanup, the finally block may
1463 // contain arbitrary control flow leading out of itself. In
1464 // addition, finally blocks should always be executed, even if there
1465 // are no catch handlers higher on the stack. Therefore, we
1466 // surround the protected scope with a combination of a normal
1467 // cleanup (to catch attempts to break out of the block via normal
1468 // control flow) and an EH catch-all (semantically "outside" any try
1469 // statement to which the finally block might have been attached).
1470 // The finally block itself is generated in the context of a cleanup
1471 // which conditionally leaves the catch-all.
1472
1473 // Jump destination for performing the finally block on an exception
1474 // edge. We'll never actually reach this block, so unreachable is
1475 // fine.
1476 RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1477
1478 // Whether the finally block is being executed for EH purposes.
1479 ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1480 CGF.Builder.CreateFlagStore(false, ForEHVar);
1481
1482 // Enter a normal cleanup which will perform the @finally block.
1483 CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1484 ForEHVar, endCatchFn,
1485 rethrowFn, SavedExnVar);
1486
1487 // Enter a catch-all scope.
1488 llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1489 EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1490 catchScope->setCatchAllHandler(0, catchBB);
1491}
1492
1493void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1494 // Leave the finally catch-all.
1495 EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1496 llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1497
1498 CGF.popCatchScope();
1499
1500 // If there are any references to the catch-all block, emit it.
1501 if (catchBB->use_empty()) {
1502 delete catchBB;
1503 } else {
1504 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1505 CGF.EmitBlock(catchBB);
1506
1507 llvm::Value *exn = nullptr;
1508
1509 // If there's a begin-catch function, call it.
1510 if (BeginCatchFn) {
1511 exn = CGF.getExceptionFromSlot();
1512 CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1513 }
1514
1515 // If we need to remember the exception pointer to rethrow later, do so.
1516 if (SavedExnVar) {
1517 if (!exn) exn = CGF.getExceptionFromSlot();
1518 CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1519 }
1520
1521 // Tell the cleanups in the finally block that we're do this for EH.
1522 CGF.Builder.CreateFlagStore(true, ForEHVar);
1523
1524 // Thread a jump through the finally cleanup.
1525 CGF.EmitBranchThroughCleanup(RethrowDest);
1526
1527 CGF.Builder.restoreIP(savedIP);
1528 }
1529
1530 // Finally, leave the @finally cleanup.
1531 CGF.PopCleanupBlock();
1532}
1533
1535 if (TerminateLandingPad)
1536 return TerminateLandingPad;
1537
1538 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1539
1540 // This will get inserted at the end of the function.
1541 TerminateLandingPad = createBasicBlock("terminate.lpad");
1542 Builder.SetInsertPoint(TerminateLandingPad);
1543
1544 // Tell the backend that this is a landing pad.
1545 const EHPersonality &Personality = EHPersonality::get(*this);
1546
1547 if (!CurFn->hasPersonalityFn())
1548 CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
1549
1550 llvm::LandingPadInst *LPadInst =
1551 Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
1552 LPadInst->addClause(getCatchAllValue(*this));
1553
1554 llvm::Value *Exn = nullptr;
1555 if (getLangOpts().CPlusPlus)
1556 Exn = Builder.CreateExtractValue(LPadInst, 0);
1557 llvm::CallInst *terminateCall =
1558 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1559 terminateCall->setDoesNotReturn();
1560 Builder.CreateUnreachable();
1561
1562 // Restore the saved insertion state.
1563 Builder.restoreIP(SavedIP);
1564
1565 return TerminateLandingPad;
1566}
1567
1569 if (TerminateHandler)
1570 return TerminateHandler;
1571
1572 // Set up the terminate handler. This block is inserted at the very
1573 // end of the function by FinishFunction.
1574 TerminateHandler = createBasicBlock("terminate.handler");
1575 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1576 Builder.SetInsertPoint(TerminateHandler);
1577
1578 llvm::Value *Exn = nullptr;
1579 if (getLangOpts().CPlusPlus)
1580 Exn = getExceptionFromSlot();
1581 llvm::CallInst *terminateCall =
1582 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1583 terminateCall->setDoesNotReturn();
1584 Builder.CreateUnreachable();
1585
1586 // Restore the saved insertion state.
1587 Builder.restoreIP(SavedIP);
1588
1589 return TerminateHandler;
1590}
1591
1593 assert(EHPersonality::get(*this).usesFuncletPads() &&
1594 "use getTerminateLandingPad for non-funclet EH");
1595
1596 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1597 if (TerminateFunclet)
1598 return TerminateFunclet;
1599
1600 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1601
1602 // Set up the terminate handler. This block is inserted at the very
1603 // end of the function by FinishFunction.
1604 TerminateFunclet = createBasicBlock("terminate.handler");
1605 Builder.SetInsertPoint(TerminateFunclet);
1606
1607 // Create the cleanuppad using the current parent pad as its token. Use 'none'
1608 // if this is a top-level terminate scope, which is the common case.
1609 SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
1610 llvm::Value *ParentPad = CurrentFuncletPad;
1611 if (!ParentPad)
1612 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1613 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1614
1615 // Emit the __std_terminate call.
1616 llvm::CallInst *terminateCall =
1617 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);
1618 terminateCall->setDoesNotReturn();
1619 Builder.CreateUnreachable();
1620
1621 // Restore the saved insertion state.
1622 Builder.restoreIP(SavedIP);
1623
1624 return TerminateFunclet;
1625}
1626
1627llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1628 if (EHResumeBlock) return EHResumeBlock;
1629
1630 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1631
1632 // We emit a jump to a notional label at the outermost unwind state.
1633 EHResumeBlock = createBasicBlock("eh.resume");
1634 Builder.SetInsertPoint(EHResumeBlock);
1635
1636 const EHPersonality &Personality = EHPersonality::get(*this);
1637
1638 // This can always be a call because we necessarily didn't find
1639 // anything on the EH stack which needs our help.
1640 const char *RethrowName = Personality.CatchallRethrowFn;
1641 if (RethrowName != nullptr && !isCleanup) {
1643 getExceptionFromSlot())->setDoesNotReturn();
1644 Builder.CreateUnreachable();
1645 Builder.restoreIP(SavedIP);
1646 return EHResumeBlock;
1647 }
1648
1649 // Recreate the landingpad's return value for the 'resume' instruction.
1650 llvm::Value *Exn = getExceptionFromSlot();
1651 llvm::Value *Sel = getSelectorFromSlot();
1652
1653 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1654 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1655 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1656 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1657
1658 Builder.CreateResume(LPadVal);
1659 Builder.restoreIP(SavedIP);
1660 return EHResumeBlock;
1661}
1662
1664 EnterSEHTryStmt(S);
1665 {
1666 JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
1667
1668 SEHTryEpilogueStack.push_back(&TryExit);
1669
1670 llvm::BasicBlock *TryBB = nullptr;
1671 // IsEHa: emit an invoke to _seh_try_begin() runtime for -EHa
1672 if (getLangOpts().EHAsynch) {
1674 if (SEHTryEpilogueStack.size() == 1) // outermost only
1675 TryBB = Builder.GetInsertBlock();
1676 }
1677
1678 EmitStmt(S.getTryBlock());
1679
1680 // Volatilize all blocks in Try, till current insert point
1681 if (TryBB) {
1683 VolatilizeTryBlocks(TryBB, Visited);
1684 }
1685
1686 SEHTryEpilogueStack.pop_back();
1687
1688 if (!TryExit.getBlock()->use_empty())
1689 EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
1690 else
1691 delete TryExit.getBlock();
1692 }
1693 ExitSEHTryStmt(S);
1694}
1695
1696// Recursively walk through blocks in a _try
1697// and make all memory instructions volatile
1699 llvm::BasicBlock *BB, llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V) {
1700 if (BB == SEHTryEpilogueStack.back()->getBlock() /* end of Try */ ||
1701 !V.insert(BB).second /* already visited */ ||
1702 !BB->getParent() /* not emitted */ || BB->empty())
1703 return;
1704
1705 if (!BB->isEHPad()) {
1706 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1707 ++J) {
1708 if (auto LI = dyn_cast<llvm::LoadInst>(J)) {
1709 LI->setVolatile(true);
1710 } else if (auto SI = dyn_cast<llvm::StoreInst>(J)) {
1711 SI->setVolatile(true);
1712 } else if (auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1713 MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));
1714 }
1715 }
1716 }
1717 const llvm::Instruction *TI = BB->getTerminator();
1718 if (TI) {
1719 unsigned N = TI->getNumSuccessors();
1720 for (unsigned I = 0; I < N; I++)
1721 VolatilizeTryBlocks(TI->getSuccessor(I), V);
1722 }
1723}
1724
1725namespace {
1726struct PerformSEHFinally final : EHScopeStack::Cleanup {
1727 llvm::Function *OutlinedFinally;
1728 PerformSEHFinally(llvm::Function *OutlinedFinally)
1729 : OutlinedFinally(OutlinedFinally) {}
1730
1731 void Emit(CodeGenFunction &CGF, Flags F) override {
1732 ASTContext &Context = CGF.getContext();
1733 CodeGenModule &CGM = CGF.CGM;
1734
1735 CallArgList Args;
1736
1737 // Compute the two argument values.
1738 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1739 llvm::Value *FP = nullptr;
1740 // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
1741 if (CGF.IsOutlinedSEHHelper) {
1742 FP = &CGF.CurFn->arg_begin()[1];
1743 } else {
1744 llvm::Function *LocalAddrFn =
1745 CGM.getIntrinsic(llvm::Intrinsic::localaddress);
1746 FP = CGF.Builder.CreateCall(LocalAddrFn);
1747 }
1748
1749 llvm::Value *IsForEH =
1750 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
1751
1752 // Except _leave and fall-through at the end, all other exits in a _try
1753 // (return/goto/continue/break) are considered as abnormal terminations
1754 // since _leave/fall-through is always Indexed 0,
1755 // just use NormalCleanupDestSlot (>= 1 for goto/return/..),
1756 // as 1st Arg to indicate abnormal termination
1757 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1758 Address Addr = CGF.getNormalCleanupDestSlot();
1759 llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
1760 llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
1761 IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
1762 }
1763
1764 Args.add(RValue::get(IsForEH), ArgTys[0]);
1765 Args.add(RValue::get(FP), ArgTys[1]);
1766
1767 // Arrange a two-arg function info and type.
1768 const CGFunctionInfo &FnInfo =
1769 CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
1770
1771 auto Callee = CGCallee::forDirect(OutlinedFinally);
1772 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1773 }
1774};
1775} // end anonymous namespace
1776
1777namespace {
1778/// Find all local variable captures in the statement.
1779struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1780 CodeGenFunction &ParentCGF;
1781 const VarDecl *ParentThis;
1782 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1783 Address SEHCodeSlot = Address::invalid();
1784 CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
1785 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1786
1787 // Return true if we need to do any capturing work.
1788 bool foundCaptures() {
1789 return !Captures.empty() || SEHCodeSlot.isValid();
1790 }
1791
1792 void Visit(const Stmt *S) {
1793 // See if this is a capture, then recurse.
1794 ConstStmtVisitor<CaptureFinder>::Visit(S);
1795 for (const Stmt *Child : S->children())
1796 if (Child)
1797 Visit(Child);
1798 }
1799
1800 void VisitDeclRefExpr(const DeclRefExpr *E) {
1801 // If this is already a capture, just make sure we capture 'this'.
1803 Captures.insert(ParentThis);
1804
1805 const auto *D = dyn_cast<VarDecl>(E->getDecl());
1806 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1807 Captures.insert(D);
1808 }
1809
1810 void VisitCXXThisExpr(const CXXThisExpr *E) {
1811 Captures.insert(ParentThis);
1812 }
1813
1814 void VisitCallExpr(const CallExpr *E) {
1815 // We only need to add parent frame allocations for these builtins in x86.
1816 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1817 return;
1818
1819 unsigned ID = E->getBuiltinCallee();
1820 switch (ID) {
1821 case Builtin::BI__exception_code:
1822 case Builtin::BI_exception_code:
1823 // This is the simple case where we are the outermost finally. All we
1824 // have to do here is make sure we escape this and recover it in the
1825 // outlined handler.
1826 if (!SEHCodeSlot.isValid())
1827 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1828 break;
1829 }
1830 }
1831};
1832} // end anonymous namespace
1833
1835 Address ParentVar,
1836 llvm::Value *ParentFP) {
1837 llvm::Value *RecoverCall = nullptr;
1839 // We are currently handling the following case:
1840 // ParentAlloca: An alloca for a local variable/direct argument
1841 // ParentArg: An argument pointer, pointing to an argument passed indirectly
1842 // Other case: A call to localrecover, if this is a nested __try.
1843 auto *ParentAlloca =
1844 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer());
1845 auto *ParentArg =
1846 dyn_cast_or_null<llvm::Argument>(ParentVar.getBasePointer());
1847 if (!ParentAlloca) {
1848 if (ParentArg) {
1849 llvm::BasicBlock &EntryBB = ParentCGF.CurFn->getEntryBlock();
1850 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1851 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1852 ParentArg->getType(), nullptr, ParentArg->getName() + ".spill");
1853 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1854 }
1855 }
1856
1857 if (ParentAlloca) {
1858 // Mark the variable escaped if nobody else referenced it and compute the
1859 // localescape index.
1860 auto InsertPair = ParentCGF.EscapedLocals.insert(
1861 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1862 int FrameEscapeIdx = InsertPair.first->second;
1863 // call ptr @llvm.localrecover(ptr @parentFn, ptr %fp, i32 N)
1864 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1865 &CGM.getModule(), llvm::Intrinsic::localrecover);
1866 RecoverCall = Builder.CreateCall(
1867 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1868 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1869 if (ParentArg)
1870 RecoverCall = Builder.CreateLoad(
1871 Address(RecoverCall, ParentArg->getType(), getPointerAlign()));
1872 } else {
1873 // If the parent didn't have an alloca, we're doing some nested outlining.
1874 // Just clone the existing localrecover call, but tweak the FP argument to
1875 // use our FP value. All other arguments are constants.
1876 auto *ParentRecover = cast<llvm::IntrinsicInst>(
1877 ParentVar.emitRawPointer(*this)->stripPointerCasts());
1878 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1879 "expected alloca or localrecover in parent LocalDeclMap");
1880 RecoverCall = ParentRecover->clone();
1881 cast<llvm::CallInst>(RecoverCall)->setArgOperand(1, ParentFP);
1882 cast<llvm::CallInst>(RecoverCall)
1883 ->insertBefore(AllocaInsertPt->getIterator());
1884 }
1885
1886 // Bitcast the variable, rename it, and insert it in the local decl map.
1887 llvm::Value *ChildVar =
1888 Builder.CreateBitCast(RecoverCall, ParentVar.getType());
1889 ChildVar->setName(ParentVar.getName());
1890 return ParentVar.withPointer(ChildVar, KnownNonNull);
1891}
1892
1894 const Stmt *OutlinedStmt,
1895 bool IsFilter) {
1896 // Find all captures in the Stmt.
1897 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1898 Finder.Visit(OutlinedStmt);
1899
1900 // We can exit early on x86_64 when there are no captures. We just have to
1901 // save the exception code in filters so that __exception_code() works.
1902 if (!Finder.foundCaptures() &&
1903 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1904 if (IsFilter)
1905 EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
1906 return;
1907 }
1908
1909 llvm::Value *EntryFP = nullptr;
1911 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1912 // 32-bit SEH filters need to be careful about FP recovery. The end of the
1913 // EH registration is passed in as the EBP physical register. We can
1914 // recover that with llvm.frameaddress(1).
1915 EntryFP = Builder.CreateCall(
1916 CGM.getIntrinsic(llvm::Intrinsic::frameaddress, AllocaInt8PtrTy),
1917 {Builder.getInt32(1)});
1918 } else {
1919 // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
1920 // second parameter.
1921 auto AI = CurFn->arg_begin();
1922 ++AI;
1923 EntryFP = &*AI;
1924 }
1925
1926 llvm::Value *ParentFP = EntryFP;
1927 if (IsFilter) {
1928 // Given whatever FP the runtime provided us in EntryFP, recover the true
1929 // frame pointer of the parent function. We only need to do this in filters,
1930 // since finally funclets recover the parent FP for us.
1931 llvm::Function *RecoverFPIntrin =
1932 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1933 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});
1934
1935 // if the parent is a _finally, the passed-in ParentFP is the FP
1936 // of parent _finally, not Establisher's FP (FP of outermost function).
1937 // Establkisher FP is 2nd paramenter passed into parent _finally.
1938 // Fortunately, it's always saved in parent's frame. The following
1939 // code retrieves it, and escapes it so that spill instruction won't be
1940 // optimized away.
1941 if (ParentCGF.ParentCGF != nullptr) {
1942 // Locate and escape Parent's frame_pointer.addr alloca
1943 // Depending on target, should be 1st/2nd one in LocalDeclMap.
1944 // Let's just scan for ImplicitParamDecl with VoidPtrTy.
1945 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
1946 for (auto &I : ParentCGF.LocalDeclMap) {
1947 const VarDecl *D = cast<VarDecl>(I.first);
1948 if (isa<ImplicitParamDecl>(D) &&
1949 D->getType() == getContext().VoidPtrTy) {
1950 assert(D->getName().starts_with("frame_pointer"));
1951 FramePtrAddrAlloca =
1952 cast<llvm::AllocaInst>(I.second.getBasePointer());
1953 break;
1954 }
1955 }
1956 assert(FramePtrAddrAlloca);
1957 auto InsertPair = ParentCGF.EscapedLocals.insert(
1958 std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
1959 int FrameEscapeIdx = InsertPair.first->second;
1960
1961 // an example of a filter's prolog::
1962 // %0 = call ptr @llvm.eh.recoverfp(@"?fin$0@0@main@@",..)
1963 // %1 = call ptr @llvm.localrecover(@"?fin$0@0@main@@",..)
1964 // %2 = load ptr, ptr %1, align 8
1965 // ==> %2 is the frame-pointer of outermost host function
1966 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1967 &CGM.getModule(), llvm::Intrinsic::localrecover);
1968 ParentFP = Builder.CreateCall(
1969 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,
1970 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1971 ParentFP = Builder.CreateLoad(
1972 Address(ParentFP, CGM.VoidPtrTy, getPointerAlign()));
1973 }
1974 }
1975
1976 // Create llvm.localrecover calls for all captures.
1977 for (const VarDecl *VD : Finder.Captures) {
1978 if (VD->getType()->isVariablyModifiedType()) {
1979 CGM.ErrorUnsupported(VD, "VLA captured by SEH");
1980 continue;
1981 }
1982 assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
1983 "captured non-local variable");
1984
1985 auto L = ParentCGF.LambdaCaptureFields.find(VD);
1986 if (L != ParentCGF.LambdaCaptureFields.end()) {
1987 LambdaCaptureFields[VD] = L->second;
1988 continue;
1989 }
1990
1991 // If this decl hasn't been declared yet, it will be declared in the
1992 // OutlinedStmt.
1993 auto I = ParentCGF.LocalDeclMap.find(VD);
1994 if (I == ParentCGF.LocalDeclMap.end())
1995 continue;
1996
1997 Address ParentVar = I->second;
1998 Address Recovered =
1999 recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);
2000 setAddrOfLocalVar(VD, Recovered);
2001
2002 if (isa<ImplicitParamDecl>(VD)) {
2003 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
2004 CXXThisAlignment = ParentCGF.CXXThisAlignment;
2005 CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
2006 if (ParentCGF.LambdaThisCaptureField) {
2007 LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
2008 // We are in a lambda function where "this" is captured so the
2009 // CXXThisValue need to be loaded from the lambda capture
2010 LValue ThisFieldLValue =
2012 if (!LambdaThisCaptureField->getType()->isPointerType()) {
2013 CXXThisValue = ThisFieldLValue.getAddress().emitRawPointer(*this);
2014 } else {
2015 CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
2016 .getScalarVal();
2017 }
2018 } else {
2019 CXXThisValue = CXXABIThisValue;
2020 }
2021 }
2022 }
2023
2024 if (Finder.SEHCodeSlot.isValid()) {
2025 SEHCodeSlotStack.push_back(
2026 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
2027 }
2028
2029 if (IsFilter)
2030 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
2031}
2032
2033/// Arrange a function prototype that can be called by Windows exception
2034/// handling personalities. On Win64, the prototype looks like:
2035/// RetTy func(void *EHPtrs, void *ParentFP);
2037 bool IsFilter,
2038 const Stmt *OutlinedStmt) {
2039 SourceLocation StartLoc = OutlinedStmt->getBeginLoc();
2040
2041 // Get the mangled function name.
2042 SmallString<128> Name;
2043 {
2044 llvm::raw_svector_ostream OS(Name);
2045 GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;
2046 assert(ParentSEHFn && "No CurSEHParent!");
2047 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
2048 if (IsFilter)
2049 Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
2050 else
2051 Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
2052 }
2053
2054 FunctionArgList Args;
2055 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2056 // All SEH finally functions take two parameters. Win64 filters take two
2057 // parameters. Win32 filters take no parameters.
2058 if (IsFilter) {
2059 Args.push_back(ImplicitParamDecl::Create(
2060 getContext(), /*DC=*/nullptr, StartLoc,
2061 &getContext().Idents.get("exception_pointers"),
2063 } else {
2064 Args.push_back(ImplicitParamDecl::Create(
2065 getContext(), /*DC=*/nullptr, StartLoc,
2066 &getContext().Idents.get("abnormal_termination"),
2067 getContext().UnsignedCharTy, ImplicitParamKind::Other));
2068 }
2069 Args.push_back(ImplicitParamDecl::Create(
2070 getContext(), /*DC=*/nullptr, StartLoc,
2071 &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy,
2073 }
2074
2075 QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
2076
2077 const CGFunctionInfo &FnInfo =
2078 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2079
2080 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
2081 llvm::Function *Fn = llvm::Function::Create(
2082 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
2083
2084 IsOutlinedSEHHelper = true;
2085
2086 StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
2087 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
2088 CurSEHParent = ParentCGF.CurSEHParent;
2089
2090 CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
2091 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
2092}
2093
2094/// Create a stub filter function that will ultimately hold the code of the
2095/// filter expression. The EH preparation passes in LLVM will outline the code
2096/// from the main function body into this stub.
2097llvm::Function *
2099 const SEHExceptStmt &Except) {
2100 const Expr *FilterExpr = Except.getFilterExpr();
2101 startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
2102
2103 // Emit the original filter expression, convert to i32, and return.
2104 llvm::Value *R = EmitScalarExpr(FilterExpr);
2105 R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
2106 FilterExpr->getType()->isSignedIntegerType());
2107 Builder.CreateStore(R, ReturnValue);
2108
2109 FinishFunction(FilterExpr->getEndLoc());
2110
2111 return CurFn;
2112}
2113
2114llvm::Function *
2116 const SEHFinallyStmt &Finally) {
2117 const Stmt *FinallyBlock = Finally.getBlock();
2118 startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
2119
2120 // Emit the original filter expression, convert to i32, and return.
2121 EmitStmt(FinallyBlock);
2122
2123 FinishFunction(FinallyBlock->getEndLoc());
2124
2125 return CurFn;
2126}
2127
2129 llvm::Value *ParentFP,
2130 llvm::Value *EntryFP) {
2131 // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
2132 // __exception_info intrinsic.
2133 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2134 // On Win64, the info is passed as the first parameter to the filter.
2135 SEHInfo = &*CurFn->arg_begin();
2136 SEHCodeSlotStack.push_back(
2137 CreateMemTemp(getContext().IntTy, "__exception_code"));
2138 } else {
2139 // On Win32, the EBP on entry to the filter points to the end of an
2140 // exception registration object. It contains 6 32-bit fields, and the info
2141 // pointer is stored in the second field. So, GEP 20 bytes backwards and
2142 // load the pointer.
2143 SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
2144 SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
2146 ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
2147 }
2148
2149 // Save the exception code in the exception slot to unify exception access in
2150 // the filter function and the landing pad.
2151 // struct EXCEPTION_POINTERS {
2152 // EXCEPTION_RECORD *ExceptionRecord;
2153 // CONTEXT *ContextRecord;
2154 // };
2155 // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
2156 llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());
2157 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
2158 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);
2159 Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign());
2160 llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign());
2161 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2162 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2163}
2164
2166 // Sema should diagnose calling this builtin outside of a filter context, but
2167 // don't crash if we screw up.
2168 if (!SEHInfo)
2169 return llvm::PoisonValue::get(Int8PtrTy);
2170 assert(SEHInfo->getType() == Int8PtrTy);
2171 return SEHInfo;
2172}
2173
2175 assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
2176 return Builder.CreateLoad(SEHCodeSlotStack.back());
2177}
2178
2180 // Abnormal termination is just the first parameter to the outlined finally
2181 // helper.
2182 auto AI = CurFn->arg_begin();
2183 return Builder.CreateZExt(&*AI, Int32Ty);
2184}
2185
2187 llvm::Function *FinallyFunc) {
2188 EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
2189}
2190
2192 CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
2193 HelperCGF.ParentCGF = this;
2194 if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
2195 // Outline the finally block.
2196 llvm::Function *FinallyFunc =
2197 HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
2198
2199 // Push a cleanup for __finally blocks.
2200 EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
2201 return;
2202 }
2203
2204 // Otherwise, we must have an __except block.
2205 const SEHExceptStmt *Except = S.getExceptHandler();
2206 assert(Except);
2207 EHCatchScope *CatchScope = EHStack.pushCatch(1);
2208 SEHCodeSlotStack.push_back(
2209 CreateMemTemp(getContext().IntTy, "__exception_code"));
2210
2211 // If the filter is known to evaluate to 1, then we can use the clause
2212 // "catch i8* null". We can't do this on x86 because the filter has to save
2213 // the exception code.
2214 llvm::Constant *C =
2216 getContext().IntTy);
2217 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2218 C->isOneValue()) {
2219 CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
2220 return;
2221 }
2222
2223 // In general, we have to emit an outlined filter function. Use the function
2224 // in place of the RTTI typeinfo global that C++ EH uses.
2225 llvm::Function *FilterFunc =
2226 HelperCGF.GenerateSEHFilterFunction(*this, *Except);
2227 CatchScope->setHandler(0, FilterFunc, createBasicBlock("__except.ret"));
2228}
2229
2231 // Just pop the cleanup if it's a __finally block.
2232 if (S.getFinallyHandler()) {
2234 return;
2235 }
2236
2237 // IsEHa: emit an invoke _seh_try_end() to mark end of FT flow
2238 if (getLangOpts().EHAsynch && Builder.GetInsertBlock()) {
2239 llvm::FunctionCallee SehTryEnd = getSehTryEndFn(CGM);
2240 EmitRuntimeCallOrInvoke(SehTryEnd);
2241 }
2242
2243 // Otherwise, we must have an __except block.
2244 const SEHExceptStmt *Except = S.getExceptHandler();
2245 assert(Except && "__try must have __finally xor __except");
2246 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2247
2248 // Don't emit the __except block if the __try block lacked invokes.
2249 // TODO: Model unwind edges from instructions, either with iload / istore or
2250 // a try body function.
2251 if (!CatchScope.hasEHBranches()) {
2252 CatchScope.clearHandlerBlocks();
2253 EHStack.popCatch();
2254 SEHCodeSlotStack.pop_back();
2255 return;
2256 }
2257
2258 // The fall-through block.
2259 llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
2260
2261 // We just emitted the body of the __try; jump to the continue block.
2262 if (HaveInsertPoint())
2263 Builder.CreateBr(ContBB);
2264
2265 // Check if our filter function returned true.
2266 emitCatchDispatchBlock(*this, CatchScope);
2267
2268 // Grab the block before we pop the handler.
2269 llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
2270 EHStack.popCatch();
2271
2272 EmitBlockAfterUses(CatchPadBB);
2273
2274 // __except blocks don't get outlined into funclets, so immediately do a
2275 // catchret.
2276 llvm::CatchPadInst *CPI =
2277 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
2278 llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
2279 Builder.CreateCatchRet(CPI, ExceptBB);
2280 EmitBlock(ExceptBB);
2281
2282 // On Win64, the exception code is returned in EAX. Copy it into the slot.
2283 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2284 llvm::Function *SEHCodeIntrin =
2285 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2286 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2287 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2288 }
2289
2290 // Emit the __except body.
2291 EmitStmt(Except->getBlock());
2292
2293 // End the lifetime of the exception code.
2294 SEHCodeSlotStack.pop_back();
2295
2296 if (HaveInsertPoint())
2297 Builder.CreateBr(ContBB);
2298
2299 EmitBlock(ContBB);
2300}
2301
2303 // If this code is reachable then emit a stop point (if generating
2304 // debug info). We have to do this ourselves because we are on the
2305 // "simple" statement path.
2306 if (HaveInsertPoint())
2307 EmitStopPoint(&S);
2308
2309 // This must be a __leave from a __finally block, which we warn on and is UB.
2310 // Just emit unreachable.
2311 if (!isSEHTryScope()) {
2312 Builder.CreateUnreachable();
2313 Builder.ClearInsertionPoint();
2314 return;
2315 }
2316
2318}
#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:4946
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:5157
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:5184
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:5340
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:5608
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:4566
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:439
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:2000
bool usesSEHTry() const
Indicates the function uses __try.
Definition Decl.h:2518
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Definition Decl.cpp:4057
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5315
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5622
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5673
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5665
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:3917
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:5603
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:52
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:8428
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:8573
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8482
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
CompoundStmt * getBlock() const
Definition Stmt.h:3785
Expr * getFilterExpr() const
Definition Stmt.h:3781
CompoundStmt * getBlock() const
Definition Stmt.h:3822
Represents a __leave statement.
Definition Stmt.h:3890
CompoundStmt * getTryBlock() const
Definition Stmt.h:3866
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:2230
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition TypeBase.h:2808
bool isObjCObjectPointerType() const
Definition TypeBase.h:8804
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9218
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:1262
@ 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:1986
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:1746
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