25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsWebAssembly.h"
28#include "llvm/Support/SaveAndRestore.h"
36 llvm::FunctionType *FTy =
45 llvm::FunctionType *FTy =
54 llvm::FunctionType *FTy =
55 llvm::FunctionType::get(
VoidTy,
false);
62 name =
"_ZSt9terminatev";
66 name =
"__std_terminate";
68 name =
"?terminate@@YAXXZ";
71 name =
"objc_terminate";
79 llvm::FunctionType *FTy =
123 const llvm::Triple &
T =
Target.getTriple();
124 if (
T.isWindowsMSVCEnvironment())
138 const llvm::Triple &
T =
Target.getTriple();
139 if (
T.isWindowsMSVCEnvironment())
165 llvm_unreachable(
"bad runtime kind");
170 const llvm::Triple &
T =
Target.getTriple();
171 if (
T.isWindowsMSVCEnvironment())
193 auto Triple =
Target.getTriple();
194 if (Triple.isWindowsMSVCEnvironment())
214 if (Triple.isOSCygMing())
224 llvm_unreachable(
"bad runtime kind");
228 if (
T.getArch() == llvm::Triple::x86)
257 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
262 llvm::FunctionType *FTy;
265 FTy = llvm::FunctionType::get(CGM.
Int32Ty, {CGM.VoidPtrTy},
false);
267 FTy = llvm::FunctionType::get(CGM.
Int32Ty,
true);
270 llvm::AttributeList(),
true);
281 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
284 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
285 if (LPI->isCatch(I)) {
287 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
290 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
295 for (llvm::User::op_iterator
296 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
297 if (llvm::GlobalVariable *GV =
301 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
312 for (llvm::User *
U : Fn->users()) {
314 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
315 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
322 llvm::Function *F = dyn_cast<llvm::Function>(
U);
323 if (!F)
return false;
325 for (llvm::BasicBlock &BB : *F) {
326 if (BB.isLandingPad())
339void CodeGenModule::SimplifyPersonality() {
341 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
346 if (!LangOpts.ObjCRuntime.isNeXTFamily())
354 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
355 "Different EHPersonalities using the same personality function.");
360 if (!Fn ||
Fn->use_empty())
return;
370 if (
Fn->getType() != CXXFn.getCallee()->getType())
373 Fn->replaceAllUsesWith(CXXFn.getCallee());
374 Fn->eraseFromParent();
381 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
387 struct FreeException final : EHScopeStack::Cleanup {
389 FreeException(llvm::Value *exn) : exn(exn) {}
390 void Emit(CodeGenFunction &CGF, Flags flags)
override {
447 bool KeepInsertionPoint) {
452 const llvm::Triple &
T =
Target.getTriple();
453 if (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU()) {
458 QualType ThrowType = SubExpr->getType();
462 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
464 CGM.getCXXABI().emitThrow(*
this, E);
467 CGM.getCXXABI().emitRethrow(*
this,
true);
472 if (KeepInsertionPoint)
477 if (!
CGM.getLangOpts().CXXExceptions)
480 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
483 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
501 if (
getTarget().getCXXABI().isMicrosoft())
506 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
511 diag::warn_wasm_dynamic_exception_spec_ignored)
520 if (
getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
521 (
CGM.getCodeGenOpts().getExceptionHandling() ==
523 CGM.getCodeGenOpts().getExceptionHandling() ==
527 diag::warn_wasm_dynamic_exception_spec_ignored)
533 for (
unsigned I = 0; I != NumExceptions; ++I) {
536 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
538 Filter->setFilter(I, EHType);
551 if (!dispatchBlock)
return;
552 if (dispatchBlock->use_empty()) {
553 delete dispatchBlock;
566 llvm::Value *zero = CGF.
Builder.getInt32(0);
567 llvm::Value *failsFilter =
568 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
569 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
581 ->setDoesNotReturn();
582 CGF.
Builder.CreateUnreachable();
586 if (!
CGM.getLangOpts().CXXExceptions)
589 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
592 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
593 if (CD->isNothrow() && !
EHStack.empty())
607 if (
getTarget().getCXXABI().isMicrosoft())
612 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
628 const llvm::Triple &
T =
Target.getTriple();
631 const bool IsTargetDevice =
632 (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU());
644 for (
unsigned I = 0; I != NumHandlers; ++I) {
648 if (
C->getExceptionDecl()) {
656 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
657 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
661 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
663 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
664 CaughtType,
C->getCaughtType());
668 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
684 if (si ==
EHStack.stable_end())
691 if (!dispatchBlock) {
721 return dispatchBlock;
728 if (SI ==
EHStack.stable_end())
736 return DispatchBlock;
746 DispatchBlock->setName(
"catch.dispatch");
750 DispatchBlock->setName(
"ehcleanup");
754 llvm_unreachable(
"exception specifications not handled yet!");
757 DispatchBlock->setName(
"terminate");
761 return DispatchBlock;
777 llvm_unreachable(
"Invalid EHScope Kind!");
781 assert(
EHStack.requiresLandingPad());
789 if (!LO.Exceptions || LO.IgnoreExceptions) {
790 if (!LO.Borland && !LO.MicrosoftExt)
797 if (LO.CUDA && LO.CUDAIsDevice)
802 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
807 if (!
CurFn->hasPersonalityFn())
823 ir->setCachedLandingPad(LP);
831 assert(
EHStack.requiresLandingPad());
832 assert(!
CGM.getLangOpts().IgnoreExceptions &&
833 "LandingPad should not be emitted when -fignore-exceptions are in "
836 switch (innermostEHScope.
getKind()) {
848 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
855 llvm::LandingPadInst *LPadInst =
858 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
860 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
869 bool hasCatchAll =
false;
870 bool hasCleanup =
false;
871 bool hasFilter =
false;
877 switch (I->getKind()) {
884 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
885 assert(!hasCatchAll &&
"EH filter reached after catch-all");
892 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
893 filterTypes.push_back(filter.
getFilter(i));
899 assert(!hasCatchAll);
908 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
911 "landingpads do not support catch handler flags");
915 assert(!hasCatchAll);
921 if (catchTypes.insert(handler.
Type.
RTTI).second)
923 LPadInst->addClause(handler.
Type.
RTTI);
929 assert(!(hasCatchAll && hasFilter));
935 }
else if (hasFilter) {
940 llvm::ArrayType *AType =
941 llvm::ArrayType::get(!filterTypes.empty() ?
945 for (llvm::Value *filterType : filterTypes)
947 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
948 LPadInst->addClause(FilterArray);
952 LPadInst->setCleanup(
true);
955 }
else if (hasCleanup) {
956 LPadInst->setCleanup(
true);
959 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
960 "landingpad instruction has no clauses!");
973 assert(DispatchBlock);
975 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
981 llvm::BasicBlock *UnwindBB =
985 llvm::CatchSwitchInst *CatchSwitch =
986 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
989 for (
unsigned I = 0; I < NumHandlers; ++I) {
1001 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
1006 CatchSwitch->addHandler(Handler.
Block);
1008 CGF.
Builder.restoreIP(SavedIP);
1017 assert(DispatchBlock);
1019 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1025 llvm::BasicBlock *UnwindBB =
1029 llvm::CatchSwitchInst *CatchSwitch =
1030 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1034 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1035 CatchSwitch->addHandler(WasmCatchStartBlock);
1040 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1045 CatchTypes.push_back(
TypeInfo.RTTI);
1047 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1052 llvm::Function *GetExnFn =
1054 llvm::Function *GetSelectorFn =
1056 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1058 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1060 llvm::Function *TypeIDFn =
1067 CGF.
Builder.restoreIP(SavedIP);
1072 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1073 assert(I < E &&
"ran off end of handlers!");
1080 llvm::BasicBlock *NextBlock;
1082 bool EmitNextBlock =
false, NextIsEnd =
false;
1089 EmitNextBlock =
true;
1101 EmitNextBlock =
true;
1105 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1106 TypeIndex->setDoesNotThrow();
1108 llvm::Value *MatchesTypeIndex =
1110 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1118 CGF.
Builder.restoreIP(SavedIP);
1131 assert(dispatchBlock);
1141 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1145 llvm::Function *llvm_eh_typeid_for =
1147 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1154 assert(i < e &&
"ran off end of handlers!");
1157 llvm::Value *typeValue = handler.
Type.
RTTI;
1159 "landingpads do not support catch handler flags");
1160 assert(typeValue &&
"fell into catch-all case!");
1162 if (typeValue->getType() != argTy)
1167 llvm::BasicBlock *nextBlock;
1188 llvm::CallInst *typeIndex =
1189 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1190 typeIndex->setDoesNotThrow();
1192 llvm::Value *matchesTypeIndex =
1193 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1194 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1198 CGF.
Builder.restoreIP(savedIP);
1214 llvm::BasicBlock *WasmCatchStartBlock) {
1215 assert(WasmCatchStartBlock);
1220 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1221 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1223 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1224 Builder.SetInsertPoint(RethrowBlock);
1225 llvm::Function *RethrowInCatchFn =
1226 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1249 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1262 bool doImplicitRethrow =
false;
1271 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1275 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1276 ? CatchSwitch->getSuccessor(1)
1277 : CatchSwitch->getSuccessor(0);
1290 bool HasCatchAll =
false;
1291 for (
unsigned I = NumHandlers; I != 0; --I) {
1292 HasCatchAll |= Handlers[I - 1].isCatchAll();
1293 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1305 CGM.getCXXABI().emitBeginCatch(*
this,
C);
1323 CGM.getCXXABI().emitRethrow(*
this,
false);
1325 Builder.ClearInsertionPoint();
1345 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1346 llvm::Value *ForEHVar;
1347 llvm::FunctionCallee EndCatchFn;
1348 CallEndCatchForFinally(llvm::Value *ForEHVar,
1349 llvm::FunctionCallee EndCatchFn)
1350 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1354 llvm::BasicBlock *CleanupContBB =
1357 llvm::Value *ShouldEndCatch =
1359 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1366 struct PerformFinally final : EHScopeStack::Cleanup {
1368 llvm::Value *ForEHVar;
1369 llvm::FunctionCallee EndCatchFn;
1370 llvm::FunctionCallee RethrowFn;
1371 llvm::Value *SavedExnVar;
1373 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1374 llvm::FunctionCallee EndCatchFn,
1375 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1376 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1377 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1379 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1383 ForEHVar, EndCatchFn);
1387 llvm::Value *SavedCleanupDest =
1389 "cleanup.dest.saved");
1400 llvm::Value *ShouldRethrow =
1402 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1413 CGF.
Builder.CreateUnreachable();
1426 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1428 CGF.
Builder.restoreIP(SavedIP);
1442 llvm::FunctionCallee beginCatchFn,
1443 llvm::FunctionCallee endCatchFn,
1444 llvm::FunctionCallee rethrowFn) {
1445 assert((!!beginCatchFn) == (!!endCatchFn) &&
1446 "begin/end catch functions not paired");
1447 assert(rethrowFn &&
"rethrow function is required");
1449 BeginCatchFn = beginCatchFn;
1457 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1458 SavedExnVar =
nullptr;
1459 if (rethrowFnTy->getNumParams())
1485 ForEHVar, endCatchFn,
1486 rethrowFn, SavedExnVar);
1502 if (catchBB->use_empty()) {
1505 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1508 llvm::Value *exn =
nullptr;
1528 CGF.
Builder.restoreIP(savedIP);
1536 if (TerminateLandingPad)
1537 return TerminateLandingPad;
1539 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1543 Builder.SetInsertPoint(TerminateLandingPad);
1548 if (!
CurFn->hasPersonalityFn())
1551 llvm::LandingPadInst *LPadInst =
1555 llvm::Value *Exn =
nullptr;
1557 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1558 llvm::CallInst *terminateCall =
1559 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1560 terminateCall->setDoesNotReturn();
1566 return TerminateLandingPad;
1570 if (TerminateHandler)
1571 return TerminateHandler;
1576 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1577 Builder.SetInsertPoint(TerminateHandler);
1579 llvm::Value *Exn =
nullptr;
1582 llvm::CallInst *terminateCall =
1583 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1584 terminateCall->setDoesNotReturn();
1590 return TerminateHandler;
1595 "use getTerminateLandingPad for non-funclet EH");
1598 if (TerminateFunclet)
1599 return TerminateFunclet;
1601 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1606 Builder.SetInsertPoint(TerminateFunclet);
1613 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1617 llvm::CallInst *terminateCall =
1618 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1619 terminateCall->setDoesNotReturn();
1625 return TerminateFunclet;
1631 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1642 if (RethrowName !=
nullptr && !isCleanup) {
1654 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1655 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1656 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1657 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1659 Builder.CreateResume(LPadVal);
1671 llvm::BasicBlock *TryBB =
nullptr;
1676 TryBB =
Builder.GetInsertBlock();
1689 if (!TryExit.
getBlock()->use_empty())
1702 !
V.insert(BB).second ||
1703 !BB->getParent() || BB->empty())
1706 if (!BB->isEHPad()) {
1707 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1709 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1710 LI->setVolatile(
true);
1711 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1712 SI->setVolatile(
true);
1713 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1714 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1718 if (
const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1719 unsigned N = TI->getNumSuccessors();
1720 for (
unsigned I = 0; I < N; I++)
1726struct PerformSEHFinally final : EHScopeStack::Cleanup {
1727 llvm::Function *OutlinedFinally;
1728 PerformSEHFinally(llvm::Function *OutlinedFinally)
1729 : OutlinedFinally(OutlinedFinally) {}
1738 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1739 llvm::Value *FP =
nullptr;
1742 FP = &CGF.
CurFn->arg_begin()[1];
1744 llvm::Function *LocalAddrFn =
1746 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1749 llvm::Value *IsForEH =
1750 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1757 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1760 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1768 const CGFunctionInfo &FnInfo =
1772 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1779struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1780 CodeGenFunction &ParentCGF;
1781 const VarDecl *ParentThis;
1782 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1784 CaptureFinder(CodeGenFunction &ParentCGF,
const VarDecl *ParentThis)
1785 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1788 bool foundCaptures() {
1789 return !Captures.empty() || SEHCodeSlot.
isValid();
1792 void Visit(
const Stmt *S) {
1794 ConstStmtVisitor<CaptureFinder>::Visit(S);
1795 for (
const Stmt *Child : S->
children())
1800 void VisitDeclRefExpr(
const DeclRefExpr *E) {
1803 Captures.insert(ParentThis);
1805 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1806 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1810 void VisitCXXThisExpr(
const CXXThisExpr *E) {
1811 Captures.insert(ParentThis);
1814 void VisitCallExpr(
const CallExpr *E) {
1821 case Builtin::BI__exception_code:
1822 case Builtin::BI_exception_code:
1836 llvm::Value *ParentFP) {
1837 llvm::Value *RecoverCall =
nullptr;
1843 auto *ParentAlloca =
1847 if (!ParentAlloca) {
1849 llvm::BasicBlock &EntryBB =
ParentCGF.CurFn->getEntryBlock();
1850 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1851 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1852 ParentArg->getType(),
nullptr, ParentArg->getName() +
".spill");
1853 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1860 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1861 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1862 int FrameEscapeIdx = InsertPair.first->second;
1864 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1865 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1866 RecoverCall =
Builder.CreateCall(
1867 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1868 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1870 RecoverCall =
Builder.CreateLoad(
1878 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1879 "expected alloca or localrecover in parent LocalDeclMap");
1880 RecoverCall = ParentRecover->clone();
1887 llvm::Value *ChildVar =
1889 ChildVar->setName(ParentVar.
getName());
1894 const Stmt *OutlinedStmt,
1898 Finder.Visit(OutlinedStmt);
1902 if (!Finder.foundCaptures() &&
1903 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1909 llvm::Value *EntryFP =
nullptr;
1911 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1917 {Builder.getInt32(1)});
1921 auto AI =
CurFn->arg_begin();
1926 llvm::Value *ParentFP = EntryFP;
1931 llvm::Function *RecoverFPIntrin =
1932 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1933 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1945 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1946 for (
auto &I :
ParentCGF.LocalDeclMap) {
1950 assert(D->
getName().starts_with(
"frame_pointer"));
1951 FramePtrAddrAlloca =
1956 assert(FramePtrAddrAlloca);
1957 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1958 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1959 int FrameEscapeIdx = InsertPair.first->second;
1966 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1967 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1968 ParentFP =
Builder.CreateCall(
1969 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1970 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1971 ParentFP =
Builder.CreateLoad(
1977 for (
const VarDecl *VD : Finder.Captures) {
1979 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1983 "captured non-local variable");
1985 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1986 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
1993 auto I =
ParentCGF.LocalDeclMap.find(VD);
1997 Address ParentVar = I->second;
2000 setAddrOfLocalVar(VD, Recovered);
2003 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
2004 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
2005 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
2019 CXXThisValue = CXXABIThisValue;
2024 if (Finder.SEHCodeSlot.
isValid()) {
2038 const Stmt *OutlinedStmt) {
2044 llvm::raw_svector_ostream OS(Name);
2046 assert(ParentSEHFn &&
"No CurSEHParent!");
2055 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2061 &
getContext().Idents.get(
"exception_pointers"),
2066 &
getContext().Idents.get(
"abnormal_termination"),
2078 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2080 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
2081 llvm::Function *Fn = llvm::Function::Create(
2082 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2129 llvm::Value *ParentFP,
2130 llvm::Value *EntryFP) {
2133 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2156 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2157 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2161 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2169 return llvm::PoisonValue::get(
Int8PtrTy);
2175 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2182 auto AI =
CurFn->arg_begin();
2187 llvm::Function *FinallyFunc) {
2188 EHStack.pushCleanup<PerformSEHFinally>(
2193 CodeGenFunction HelperCGF(
CGM,
true);
2197 llvm::Function *FinallyFunc =
2219 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2227 llvm::Function *FilterFunc =
2246 assert(Except &&
"__try must have __finally xor __except");
2258 if (
const auto *DS = dyn_cast<DeclStmt>(S))
2259 for (
const Decl *D : DS->decls())
2260 if (
const auto *VD = dyn_cast<VarDecl>(D))
2263 VD->getLocation(), diag::err_seh_object_unwinding);
2288 llvm::CatchPadInst *CPI =
2291 Builder.CreateCatchRet(CPI, ExceptBB);
2295 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2296 llvm::Function *SEHCodeIntrin =
2297 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2298 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2325 Builder.ClearInsertionPoint();
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
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 ...
DiagnosticsEngine & getDiagnostics() const
CXXCatchStmt - This represents a C++ catch block.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CXXCatchStmt * getHandler(unsigned i)
unsigned getNumHandlers() const
CompoundStmt * getTryBlock()
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Represents the body of a CapturedStmt, and serves as its DeclContext.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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 ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::PointerType * getType() const
Return the type of the pointer value.
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.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void exit(CodeGenFunction &CGF)
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.
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 * getSelectorFromSlot()
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)
FieldDecl * LambdaThisCaptureField
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...
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
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 ...
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...
bool currentFunctionUsesSEHTry() const
llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack
CodeGenFunction * ParentCGF
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 ...
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::Value * EmitSEHExceptionCode()
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...
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
Arrange a function prototype that can be called by Windows exception handling personalities.
void EmitSehTryScopeBegin()
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,...
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...
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="")
ASTContext & getContext() const
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
RawAddress getNormalCleanupDestSlot()
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...
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
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)
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
const TargetInfo & Target
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.
llvm::Value * EmitSEHExceptionInfo()
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.
Address getEHSelectorSlot()
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.
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
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() 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)
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.
const Handler & getHandler(unsigned I) const
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
void clearHandlerBlocks()
unsigned getNumHandlers() const
An exceptions scope which filters exceptions thrown through it.
llvm::Value * getFilter(unsigned i) const
unsigned getNumFilters() const
A non-stable pointer into the scope stack.
A saved depth on the scope stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
A protected scope for zero-cost EH handling.
llvm::BasicBlock * getCachedLandingPad() const
EHScopeStack::stable_iterator getEnclosingEHScope() const
llvm::BasicBlock * getCachedEHDispatchBlock() const
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
bool hasEHBranches() const
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
Address getAddress() const
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
bool usesSEHTry() const
Indicates the function uses __try.
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
unsigned getNumExceptions() const
Return the number of types in the exception specification.
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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...
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.
Represents Objective-C's @throw statement.
const VersionTuple & getVersion() const
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
CompoundStmt * getBlock() const
Expr * getFilterExpr() const
CompoundStmt * getBlock() const
Represents a __leave statement.
CompoundStmt * getTryBlock() const
SEHFinallyStmt * getFinallyHandler() const
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
Exposes information about the current target.
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,...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
@ 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.
bool Load(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Dynamic
throw(T1, T2)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
llvm::PointerType * VoidPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::PointerType * AllocaInt8PtrTy
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
llvm::BasicBlock * Block
The catch handler for this type.
The exceptions personality for a function.
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
static const EHPersonality XL_CPlusPlus
static const EHPersonality GNU_ObjC_SJLJ
bool isWasmPersonality() const
static const EHPersonality ZOS_CPlusPlus
static const EHPersonality GNUstep_ObjC
static const EHPersonality MSVC_CxxFrameHandler3
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
static const EHPersonality MSVC_C_specific_handler
static const EHPersonality GNU_CPlusPlus_SEH
static const EHPersonality GNU_ObjC
static const EHPersonality GNU_CPlusPlus_SJLJ
static const EHPersonality GNU_C_SJLJ
static const EHPersonality GNU_C
static const EHPersonality NeXT_ObjC
const char * CatchallRethrowFn
static const EHPersonality GNU_CPlusPlus
static const EHPersonality GNU_ObjCXX
static const EHPersonality GNU_C_SEH
static const EHPersonality MSVC_except_handler
static const EHPersonality GNU_ObjC_SEH
const char * PersonalityFn
static const EHPersonality GNU_Wasm_CPlusPlus