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 =
87 const llvm::Triple &
T =
Target.getTriple();
88 if (
T.isWindowsMSVCEnvironment())
102 const llvm::Triple &
T =
Target.getTriple();
103 if (
T.isWindowsMSVCEnvironment())
129 llvm_unreachable(
"bad runtime kind");
134 const llvm::Triple &
T =
Target.getTriple();
135 if (
T.isWindowsMSVCEnvironment())
157 auto Triple =
Target.getTriple();
158 if (Triple.isWindowsMSVCEnvironment())
178 if (Triple.isOSCygMing())
188 llvm_unreachable(
"bad runtime kind");
192 if (
T.getArch() == llvm::Triple::x86)
197namespace clang::CodeGen {
230 llvm::FunctionType *FTy;
233 FTy = llvm::FunctionType::get(CGM.
Int32Ty, {CGM.VoidPtrTy},
false);
235 FTy = llvm::FunctionType::get(CGM.
Int32Ty,
true);
238 llvm::AttributeList(),
true);
249 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
252 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
253 if (LPI->isCatch(I)) {
255 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
258 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
263 for (llvm::User::op_iterator
264 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
265 if (llvm::GlobalVariable *GV =
269 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
280 for (llvm::User *
U : Fn->users()) {
282 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
283 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
290 llvm::Function *F = dyn_cast<llvm::Function>(
U);
291 if (!F)
return false;
293 for (llvm::BasicBlock &BB : *F) {
294 if (BB.isLandingPad())
307void CodeGenModule::SimplifyPersonality() {
309 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
314 if (!LangOpts.ObjCRuntime.isNeXTFamily())
322 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
323 "Different EHPersonalities using the same personality function.");
328 if (!Fn ||
Fn->use_empty())
return;
338 if (
Fn->getType() != CXXFn.getCallee()->getType())
341 Fn->replaceAllUsesWith(CXXFn.getCallee());
342 Fn->eraseFromParent();
349 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
355 struct FreeException final : EHScopeStack::Cleanup {
357 FreeException(llvm::Value *exn) : exn(exn) {}
358 void Emit(CodeGenFunction &CGF, Flags flags)
override {
415 bool KeepInsertionPoint) {
420 const llvm::Triple &
T =
Target.getTriple();
421 if (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU()) {
426 QualType ThrowType = SubExpr->getType();
430 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
432 CGM.getCXXABI().emitThrow(*
this, E);
435 CGM.getCXXABI().emitRethrow(*
this,
true);
440 if (KeepInsertionPoint)
445 if (!
CGM.getLangOpts().CXXExceptions)
448 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
451 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
469 if (
getTarget().getCXXABI().isMicrosoft())
474 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
479 diag::warn_wasm_dynamic_exception_spec_ignored)
488 if (
getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
489 (
CGM.getCodeGenOpts().getExceptionHandling() ==
491 CGM.getCodeGenOpts().getExceptionHandling() ==
495 diag::warn_wasm_dynamic_exception_spec_ignored)
501 for (
unsigned I = 0; I != NumExceptions; ++I) {
504 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
506 Filter->setFilter(I, EHType);
519 if (!dispatchBlock)
return;
520 if (dispatchBlock->use_empty()) {
521 delete dispatchBlock;
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,
549 ->setDoesNotReturn();
550 CGF.
Builder.CreateUnreachable();
554 if (!
CGM.getLangOpts().CXXExceptions)
557 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
560 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
561 if (CD->isNothrow() && !
EHStack.empty())
575 if (
getTarget().getCXXABI().isMicrosoft())
580 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
596 const llvm::Triple &
T =
Target.getTriple();
599 const bool IsTargetDevice =
600 (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU());
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,
false);
619 llvm::FunctionCallee Marker =
620 CGM.getModule().getOrInsertFunction(MarkerName, MarkerTy);
627 for (
unsigned I = 0; I != NumHandlers; ++I) {
631 if (
C->getExceptionDecl()) {
639 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
640 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
644 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
646 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
647 CaughtType,
C->getCaughtType());
651 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
667 if (si ==
EHStack.stable_end())
674 if (!dispatchBlock) {
704 return dispatchBlock;
711 if (SI ==
EHStack.stable_end())
719 return DispatchBlock;
729 DispatchBlock->setName(
"catch.dispatch");
733 DispatchBlock->setName(
"ehcleanup");
737 llvm_unreachable(
"exception specifications not handled yet!");
740 DispatchBlock->setName(
"terminate");
744 return DispatchBlock;
760 llvm_unreachable(
"Invalid EHScope Kind!");
764 assert(
EHStack.requiresLandingPad());
772 if (!LO.Exceptions || LO.IgnoreExceptions) {
773 if (!LO.Borland && !LO.MicrosoftExt)
780 if (LO.CUDA && LO.CUDAIsDevice)
785 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
790 if (!
CurFn->hasPersonalityFn())
806 ir->setCachedLandingPad(LP);
814 assert(
EHStack.requiresLandingPad());
815 assert(!
CGM.getLangOpts().IgnoreExceptions &&
816 "LandingPad should not be emitted when -fignore-exceptions are in "
819 switch (innermostEHScope.
getKind()) {
831 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
838 llvm::LandingPadInst *LPadInst =
841 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
843 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
852 bool hasCatchAll =
false;
853 bool hasCleanup =
false;
854 bool hasFilter =
false;
860 switch (I->getKind()) {
867 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
868 assert(!hasCatchAll &&
"EH filter reached after catch-all");
875 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
876 filterTypes.push_back(filter.
getFilter(i));
882 assert(!hasCatchAll);
891 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
894 "landingpads do not support catch handler flags");
898 assert(!hasCatchAll);
904 if (catchTypes.insert(handler.
Type.
RTTI).second)
906 LPadInst->addClause(handler.
Type.
RTTI);
912 assert(!(hasCatchAll && hasFilter));
918 }
else if (hasFilter) {
923 llvm::ArrayType *AType =
924 llvm::ArrayType::get(!filterTypes.empty() ?
928 for (llvm::Value *filterType : filterTypes)
930 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
931 LPadInst->addClause(FilterArray);
935 LPadInst->setCleanup(
true);
938 }
else if (hasCleanup) {
939 LPadInst->setCleanup(
true);
942 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
943 "landingpad instruction has no clauses!");
956 assert(DispatchBlock);
958 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
964 llvm::BasicBlock *UnwindBB =
968 llvm::CatchSwitchInst *CatchSwitch =
969 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
972 for (
unsigned I = 0; I < NumHandlers; ++I) {
984 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
989 CatchSwitch->addHandler(Handler.
Block);
991 CGF.
Builder.restoreIP(SavedIP);
1000 assert(DispatchBlock);
1002 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1008 llvm::BasicBlock *UnwindBB =
1012 llvm::CatchSwitchInst *CatchSwitch =
1013 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1017 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1018 CatchSwitch->addHandler(WasmCatchStartBlock);
1023 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1028 CatchTypes.push_back(
TypeInfo.RTTI);
1030 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1035 llvm::Function *GetExnFn =
1037 llvm::Function *GetSelectorFn =
1039 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1041 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1043 llvm::Function *TypeIDFn =
1050 CGF.
Builder.restoreIP(SavedIP);
1055 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1056 assert(I < E &&
"ran off end of handlers!");
1063 llvm::BasicBlock *NextBlock;
1065 bool EmitNextBlock =
false, NextIsEnd =
false;
1072 EmitNextBlock =
true;
1084 EmitNextBlock =
true;
1088 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1089 TypeIndex->setDoesNotThrow();
1091 llvm::Value *MatchesTypeIndex =
1093 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1101 CGF.
Builder.restoreIP(SavedIP);
1114 assert(dispatchBlock);
1124 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1128 llvm::Function *llvm_eh_typeid_for =
1130 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1137 assert(i < e &&
"ran off end of handlers!");
1140 llvm::Value *typeValue = handler.
Type.
RTTI;
1142 "landingpads do not support catch handler flags");
1143 assert(typeValue &&
"fell into catch-all case!");
1145 if (typeValue->getType() != argTy)
1150 llvm::BasicBlock *nextBlock;
1171 llvm::CallInst *typeIndex =
1172 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1173 typeIndex->setDoesNotThrow();
1175 llvm::Value *matchesTypeIndex =
1176 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1177 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1181 CGF.
Builder.restoreIP(savedIP);
1197 llvm::BasicBlock *WasmCatchStartBlock) {
1198 assert(WasmCatchStartBlock);
1203 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1204 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1206 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1207 Builder.SetInsertPoint(RethrowBlock);
1208 llvm::Function *RethrowInCatchFn =
1209 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1232 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1245 bool doImplicitRethrow =
false;
1254 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1258 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1259 ? CatchSwitch->getSuccessor(1)
1260 : CatchSwitch->getSuccessor(0);
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;
1288 CGM.getCXXABI().emitBeginCatch(*
this,
C);
1306 CGM.getCXXABI().emitRethrow(*
this,
false);
1308 Builder.ClearInsertionPoint();
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) {}
1337 llvm::BasicBlock *CleanupContBB =
1340 llvm::Value *ShouldEndCatch =
1342 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1349 struct PerformFinally final : EHScopeStack::Cleanup {
1351 llvm::Value *ForEHVar;
1352 llvm::FunctionCallee EndCatchFn;
1353 llvm::FunctionCallee RethrowFn;
1354 llvm::Value *SavedExnVar;
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) {}
1362 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1366 ForEHVar, EndCatchFn);
1370 llvm::Value *SavedCleanupDest =
1372 "cleanup.dest.saved");
1383 llvm::Value *ShouldRethrow =
1385 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1396 CGF.
Builder.CreateUnreachable();
1409 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1411 CGF.
Builder.restoreIP(SavedIP);
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");
1432 BeginCatchFn = beginCatchFn;
1440 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1441 SavedExnVar =
nullptr;
1442 if (rethrowFnTy->getNumParams())
1468 ForEHVar, endCatchFn,
1469 rethrowFn, SavedExnVar);
1485 if (catchBB->use_empty()) {
1488 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1491 llvm::Value *exn =
nullptr;
1511 CGF.
Builder.restoreIP(savedIP);
1519 if (TerminateLandingPad)
1520 return TerminateLandingPad;
1522 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1526 Builder.SetInsertPoint(TerminateLandingPad);
1531 if (!
CurFn->hasPersonalityFn())
1534 llvm::LandingPadInst *LPadInst =
1538 llvm::Value *Exn =
nullptr;
1540 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1541 llvm::CallInst *terminateCall =
1542 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1543 terminateCall->setDoesNotReturn();
1549 return TerminateLandingPad;
1553 if (TerminateHandler)
1554 return TerminateHandler;
1559 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1560 Builder.SetInsertPoint(TerminateHandler);
1562 llvm::Value *Exn =
nullptr;
1565 llvm::CallInst *terminateCall =
1566 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1567 terminateCall->setDoesNotReturn();
1573 return TerminateHandler;
1578 "use getTerminateLandingPad for non-funclet EH");
1581 if (TerminateFunclet)
1582 return TerminateFunclet;
1584 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1589 Builder.SetInsertPoint(TerminateFunclet);
1596 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1600 llvm::CallInst *terminateCall =
1601 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1602 terminateCall->setDoesNotReturn();
1608 return TerminateFunclet;
1614 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1625 if (RethrowName !=
nullptr && !isCleanup) {
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");
1642 Builder.CreateResume(LPadVal);
1654 llvm::BasicBlock *TryBB =
nullptr;
1659 TryBB =
Builder.GetInsertBlock();
1672 if (!TryExit.
getBlock()->use_empty())
1685 !
V.insert(BB).second ||
1686 !BB->getParent() || BB->empty())
1689 if (!BB->isEHPad()) {
1690 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
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));
1701 if (
const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1702 unsigned N = TI->getNumSuccessors();
1703 for (
unsigned I = 0; I < N; I++)
1709struct PerformSEHFinally final : EHScopeStack::Cleanup {
1710 llvm::Function *OutlinedFinally;
1711 PerformSEHFinally(llvm::Function *OutlinedFinally)
1712 : OutlinedFinally(OutlinedFinally) {}
1721 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1722 llvm::Value *FP =
nullptr;
1725 FP = &CGF.
CurFn->arg_begin()[1];
1727 llvm::Function *LocalAddrFn =
1729 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1732 llvm::Value *IsForEH =
1733 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1740 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1743 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1751 const CGFunctionInfo &FnInfo =
1755 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1762struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1763 CodeGenFunction &ParentCGF;
1764 const VarDecl *ParentThis;
1765 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1767 CaptureFinder(CodeGenFunction &ParentCGF,
const VarDecl *ParentThis)
1768 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1771 bool foundCaptures() {
1772 return !Captures.empty() || SEHCodeSlot.
isValid();
1775 void Visit(
const Stmt *S) {
1777 ConstStmtVisitor<CaptureFinder>::Visit(S);
1778 for (
const Stmt *Child : S->
children())
1783 void VisitDeclRefExpr(
const DeclRefExpr *E) {
1786 Captures.insert(ParentThis);
1788 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1789 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1793 void VisitCXXThisExpr(
const CXXThisExpr *E) {
1794 Captures.insert(ParentThis);
1797 void VisitCallExpr(
const CallExpr *E) {
1804 case Builtin::BI__exception_code:
1805 case Builtin::BI_exception_code:
1819 llvm::Value *ParentFP) {
1820 llvm::Value *RecoverCall =
nullptr;
1826 auto *ParentAlloca =
1830 if (!ParentAlloca) {
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);
1843 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1844 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1845 int FrameEscapeIdx = InsertPair.first->second;
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)});
1853 RecoverCall =
Builder.CreateLoad(
1861 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1862 "expected alloca or localrecover in parent LocalDeclMap");
1863 RecoverCall = ParentRecover->clone();
1870 llvm::Value *ChildVar =
1872 ChildVar->setName(ParentVar.
getName());
1877 const Stmt *OutlinedStmt,
1881 Finder.Visit(OutlinedStmt);
1885 if (!Finder.foundCaptures() &&
1886 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1892 llvm::Value *EntryFP =
nullptr;
1894 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1900 {Builder.getInt32(1)});
1904 auto AI =
CurFn->arg_begin();
1909 llvm::Value *ParentFP = EntryFP;
1914 llvm::Function *RecoverFPIntrin =
1915 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1916 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1928 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1929 for (
auto &I :
ParentCGF.LocalDeclMap) {
1933 assert(D->
getName().starts_with(
"frame_pointer"));
1934 FramePtrAddrAlloca =
1939 assert(FramePtrAddrAlloca);
1940 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1941 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1942 int FrameEscapeIdx = InsertPair.first->second;
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(
1960 for (
const VarDecl *VD : Finder.Captures) {
1962 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1966 "captured non-local variable");
1968 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1969 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
1976 auto I =
ParentCGF.LocalDeclMap.find(VD);
1980 Address ParentVar = I->second;
1983 setAddrOfLocalVar(VD, Recovered);
1986 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
1987 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
1988 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
2002 CXXThisValue = CXXABIThisValue;
2007 if (Finder.SEHCodeSlot.
isValid()) {
2021 const Stmt *OutlinedStmt) {
2027 llvm::raw_svector_ostream OS(Name);
2029 assert(ParentSEHFn &&
"No CurSEHParent!");
2038 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2044 &
getContext().Idents.get(
"exception_pointers"),
2049 &
getContext().Idents.get(
"abnormal_termination"),
2061 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2063 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
2064 llvm::Function *Fn = llvm::Function::Create(
2065 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2112 llvm::Value *ParentFP,
2113 llvm::Value *EntryFP) {
2116 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2139 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2140 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2144 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2152 return llvm::PoisonValue::get(
Int8PtrTy);
2158 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2165 auto AI =
CurFn->arg_begin();
2170 llvm::Function *FinallyFunc) {
2171 EHStack.pushCleanup<PerformSEHFinally>(
2176 CodeGenFunction HelperCGF(
CGM,
true);
2180 llvm::Function *FinallyFunc =
2202 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2210 llvm::Function *FilterFunc =
2229 assert(Except &&
"__try must have __finally xor __except");
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))
2246 VD->getLocation(), diag::err_seh_object_unwinding);
2271 llvm::CatchPadInst *CPI =
2274 Builder.CreateCatchRet(CPI, ExceptBB);
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});
2308 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)
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 ...
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.
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 exceptions personality for a function.
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
const char * PersonalityFn
bool isWasmPersonality() const
const char * CatchallRethrowFn
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.
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