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