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 =
43 llvm::FunctionType *FTy =
44 llvm::FunctionType::get(CGM.
VoidTy,
false);
49 llvm::FunctionType *FTy =
50 llvm::FunctionType::get(CGM.
VoidTy,
false);
57 llvm::FunctionType *FTy =
66 llvm::FunctionType *FTy =
67 llvm::FunctionType::get(
VoidTy,
false);
74 name =
"_ZSt9terminatev";
78 name =
"__std_terminate";
80 name =
"?terminate@@YAXXZ";
83 name =
"objc_terminate";
91 llvm::FunctionType *FTy =
135 const llvm::Triple &
T =
Target.getTriple();
136 if (
T.isWindowsMSVCEnvironment())
150 const llvm::Triple &
T =
Target.getTriple();
151 if (
T.isWindowsMSVCEnvironment())
177 llvm_unreachable(
"bad runtime kind");
182 const llvm::Triple &
T =
Target.getTriple();
183 if (
T.isWindowsMSVCEnvironment())
205 auto Triple =
Target.getTriple();
206 if (Triple.isWindowsMSVCEnvironment())
226 if (Triple.isOSCygMing())
236 llvm_unreachable(
"bad runtime kind");
240 if (
T.getArch() == llvm::Triple::x86)
269 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
274 llvm::FunctionType *FTy;
277 FTy = llvm::FunctionType::get(CGM.
Int32Ty, {CGM.VoidPtrTy},
false);
279 FTy = llvm::FunctionType::get(CGM.
Int32Ty,
true);
282 llvm::AttributeList(),
true);
293 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
296 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
297 if (LPI->isCatch(I)) {
299 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
302 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
307 for (llvm::User::op_iterator
308 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
309 if (llvm::GlobalVariable *GV =
313 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
324 for (llvm::User *
U : Fn->users()) {
326 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
327 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
334 llvm::Function *F = dyn_cast<llvm::Function>(
U);
335 if (!F)
return false;
337 for (llvm::BasicBlock &BB : *F) {
338 if (BB.isLandingPad())
351void CodeGenModule::SimplifyPersonality() {
353 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
358 if (!LangOpts.ObjCRuntime.isNeXTFamily())
366 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
367 "Different EHPersonalities using the same personality function.");
372 if (!Fn ||
Fn->use_empty())
return;
382 if (
Fn->getType() != CXXFn.getCallee()->getType())
385 Fn->replaceAllUsesWith(CXXFn.getCallee());
386 Fn->eraseFromParent();
393 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
399 struct FreeException final : EHScopeStack::Cleanup {
401 FreeException(llvm::Value *exn) : exn(exn) {}
402 void Emit(CodeGenFunction &CGF, Flags flags)
override {
459 bool KeepInsertionPoint) {
464 const llvm::Triple &
T =
Target.getTriple();
465 if (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU()) {
470 QualType ThrowType = SubExpr->getType();
474 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
476 CGM.getCXXABI().emitThrow(*
this, E);
479 CGM.getCXXABI().emitRethrow(*
this,
true);
484 if (KeepInsertionPoint)
489 if (!
CGM.getLangOpts().CXXExceptions)
492 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
495 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
513 if (
getTarget().getCXXABI().isMicrosoft())
518 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
523 diag::warn_wasm_dynamic_exception_spec_ignored)
532 if (
getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
533 CGM.getCodeGenOpts().getExceptionHandling() ==
537 diag::warn_wasm_dynamic_exception_spec_ignored)
543 for (
unsigned I = 0; I != NumExceptions; ++I) {
546 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
548 Filter->setFilter(I, EHType);
561 if (!dispatchBlock)
return;
562 if (dispatchBlock->use_empty()) {
563 delete dispatchBlock;
576 llvm::Value *zero = CGF.
Builder.getInt32(0);
577 llvm::Value *failsFilter =
578 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
579 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
591 ->setDoesNotReturn();
592 CGF.
Builder.CreateUnreachable();
596 if (!
CGM.getLangOpts().CXXExceptions)
599 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
602 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
603 if (CD->isNothrow() && !
EHStack.empty())
617 if (
getTarget().getCXXABI().isMicrosoft())
622 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
638 const llvm::Triple &
T =
Target.getTriple();
641 const bool IsTargetDevice =
642 (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU());
654 for (
unsigned I = 0; I != NumHandlers; ++I) {
658 if (
C->getExceptionDecl()) {
666 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
667 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
671 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
673 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
674 CaughtType,
C->getCaughtType());
678 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
694 if (si ==
EHStack.stable_end())
701 if (!dispatchBlock) {
731 return dispatchBlock;
738 if (SI ==
EHStack.stable_end())
746 return DispatchBlock;
756 DispatchBlock->setName(
"catch.dispatch");
760 DispatchBlock->setName(
"ehcleanup");
764 llvm_unreachable(
"exception specifications not handled yet!");
767 DispatchBlock->setName(
"terminate");
771 return DispatchBlock;
787 llvm_unreachable(
"Invalid EHScope Kind!");
791 assert(
EHStack.requiresLandingPad());
799 if (!LO.Exceptions || LO.IgnoreExceptions) {
800 if (!LO.Borland && !LO.MicrosoftExt)
807 if (LO.CUDA && LO.CUDAIsDevice)
812 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
817 if (!
CurFn->hasPersonalityFn())
833 ir->setCachedLandingPad(LP);
841 assert(
EHStack.requiresLandingPad());
842 assert(!
CGM.getLangOpts().IgnoreExceptions &&
843 "LandingPad should not be emitted when -fignore-exceptions are in "
846 switch (innermostEHScope.
getKind()) {
858 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
865 llvm::LandingPadInst *LPadInst =
868 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
870 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
879 bool hasCatchAll =
false;
880 bool hasCleanup =
false;
881 bool hasFilter =
false;
887 switch (I->getKind()) {
894 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
895 assert(!hasCatchAll &&
"EH filter reached after catch-all");
902 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
903 filterTypes.push_back(filter.
getFilter(i));
909 assert(!hasCatchAll);
918 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
921 "landingpads do not support catch handler flags");
925 assert(!hasCatchAll);
931 if (catchTypes.insert(handler.
Type.
RTTI).second)
933 LPadInst->addClause(handler.
Type.
RTTI);
939 assert(!(hasCatchAll && hasFilter));
945 }
else if (hasFilter) {
950 llvm::ArrayType *AType =
951 llvm::ArrayType::get(!filterTypes.empty() ?
955 for (llvm::Value *filterType : filterTypes)
957 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
958 LPadInst->addClause(FilterArray);
962 LPadInst->setCleanup(
true);
965 }
else if (hasCleanup) {
966 LPadInst->setCleanup(
true);
969 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
970 "landingpad instruction has no clauses!");
983 assert(DispatchBlock);
985 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
991 llvm::BasicBlock *UnwindBB =
995 llvm::CatchSwitchInst *CatchSwitch =
996 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
999 for (
unsigned I = 0; I < NumHandlers; ++I) {
1011 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
1016 CatchSwitch->addHandler(Handler.
Block);
1018 CGF.
Builder.restoreIP(SavedIP);
1027 assert(DispatchBlock);
1029 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1035 llvm::BasicBlock *UnwindBB =
1039 llvm::CatchSwitchInst *CatchSwitch =
1040 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1044 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1045 CatchSwitch->addHandler(WasmCatchStartBlock);
1050 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1055 CatchTypes.push_back(
TypeInfo.RTTI);
1057 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1062 llvm::Function *GetExnFn =
1064 llvm::Function *GetSelectorFn =
1066 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1068 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1070 llvm::Function *TypeIDFn =
1077 CGF.
Builder.restoreIP(SavedIP);
1082 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1083 assert(I < E &&
"ran off end of handlers!");
1090 llvm::BasicBlock *NextBlock;
1092 bool EmitNextBlock =
false, NextIsEnd =
false;
1099 EmitNextBlock =
true;
1111 EmitNextBlock =
true;
1115 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1116 TypeIndex->setDoesNotThrow();
1118 llvm::Value *MatchesTypeIndex =
1120 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1128 CGF.
Builder.restoreIP(SavedIP);
1141 assert(dispatchBlock);
1151 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1155 llvm::Function *llvm_eh_typeid_for =
1157 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1164 assert(i < e &&
"ran off end of handlers!");
1167 llvm::Value *typeValue = handler.
Type.
RTTI;
1169 "landingpads do not support catch handler flags");
1170 assert(typeValue &&
"fell into catch-all case!");
1172 if (typeValue->getType() != argTy)
1177 llvm::BasicBlock *nextBlock;
1198 llvm::CallInst *typeIndex =
1199 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1200 typeIndex->setDoesNotThrow();
1202 llvm::Value *matchesTypeIndex =
1203 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1204 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1208 CGF.
Builder.restoreIP(savedIP);
1224 llvm::BasicBlock *WasmCatchStartBlock) {
1225 assert(WasmCatchStartBlock);
1230 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1231 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1233 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1234 Builder.SetInsertPoint(RethrowBlock);
1235 llvm::Function *RethrowInCatchFn =
1236 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1259 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1272 bool doImplicitRethrow =
false;
1281 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1285 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1286 ? CatchSwitch->getSuccessor(1)
1287 : CatchSwitch->getSuccessor(0);
1300 bool HasCatchAll =
false;
1301 for (
unsigned I = NumHandlers; I != 0; --I) {
1302 HasCatchAll |= Handlers[I - 1].isCatchAll();
1303 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1315 CGM.getCXXABI().emitBeginCatch(*
this,
C);
1333 CGM.getCXXABI().emitRethrow(*
this,
false);
1335 Builder.ClearInsertionPoint();
1355 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1356 llvm::Value *ForEHVar;
1357 llvm::FunctionCallee EndCatchFn;
1358 CallEndCatchForFinally(llvm::Value *ForEHVar,
1359 llvm::FunctionCallee EndCatchFn)
1360 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1364 llvm::BasicBlock *CleanupContBB =
1367 llvm::Value *ShouldEndCatch =
1369 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1376 struct PerformFinally final : EHScopeStack::Cleanup {
1378 llvm::Value *ForEHVar;
1379 llvm::FunctionCallee EndCatchFn;
1380 llvm::FunctionCallee RethrowFn;
1381 llvm::Value *SavedExnVar;
1383 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1384 llvm::FunctionCallee EndCatchFn,
1385 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1386 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1387 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1389 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1393 ForEHVar, EndCatchFn);
1397 llvm::Value *SavedCleanupDest =
1399 "cleanup.dest.saved");
1410 llvm::Value *ShouldRethrow =
1412 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1423 CGF.
Builder.CreateUnreachable();
1436 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1438 CGF.
Builder.restoreIP(SavedIP);
1452 llvm::FunctionCallee beginCatchFn,
1453 llvm::FunctionCallee endCatchFn,
1454 llvm::FunctionCallee rethrowFn) {
1455 assert((!!beginCatchFn) == (!!endCatchFn) &&
1456 "begin/end catch functions not paired");
1457 assert(rethrowFn &&
"rethrow function is required");
1459 BeginCatchFn = beginCatchFn;
1467 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1468 SavedExnVar =
nullptr;
1469 if (rethrowFnTy->getNumParams())
1495 ForEHVar, endCatchFn,
1496 rethrowFn, SavedExnVar);
1512 if (catchBB->use_empty()) {
1515 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1518 llvm::Value *exn =
nullptr;
1538 CGF.
Builder.restoreIP(savedIP);
1546 if (TerminateLandingPad)
1547 return TerminateLandingPad;
1549 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1553 Builder.SetInsertPoint(TerminateLandingPad);
1558 if (!
CurFn->hasPersonalityFn())
1561 llvm::LandingPadInst *LPadInst =
1565 llvm::Value *Exn =
nullptr;
1567 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1568 llvm::CallInst *terminateCall =
1569 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1570 terminateCall->setDoesNotReturn();
1576 return TerminateLandingPad;
1580 if (TerminateHandler)
1581 return TerminateHandler;
1586 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1587 Builder.SetInsertPoint(TerminateHandler);
1589 llvm::Value *Exn =
nullptr;
1592 llvm::CallInst *terminateCall =
1593 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1594 terminateCall->setDoesNotReturn();
1600 return TerminateHandler;
1605 "use getTerminateLandingPad for non-funclet EH");
1608 if (TerminateFunclet)
1609 return TerminateFunclet;
1611 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1616 Builder.SetInsertPoint(TerminateFunclet);
1623 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1627 llvm::CallInst *terminateCall =
1628 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1629 terminateCall->setDoesNotReturn();
1635 return TerminateFunclet;
1641 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1652 if (RethrowName !=
nullptr && !isCleanup) {
1664 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1665 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1666 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1667 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1669 Builder.CreateResume(LPadVal);
1681 llvm::BasicBlock *TryBB =
nullptr;
1686 TryBB =
Builder.GetInsertBlock();
1699 if (!TryExit.
getBlock()->use_empty())
1712 !
V.insert(BB).second ||
1713 !BB->getParent() || BB->empty())
1716 if (!BB->isEHPad()) {
1717 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1719 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1720 LI->setVolatile(
true);
1721 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1722 SI->setVolatile(
true);
1723 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1724 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1728 if (
const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1729 unsigned N = TI->getNumSuccessors();
1730 for (
unsigned I = 0; I < N; I++)
1736struct PerformSEHFinally final : EHScopeStack::Cleanup {
1737 llvm::Function *OutlinedFinally;
1738 PerformSEHFinally(llvm::Function *OutlinedFinally)
1739 : OutlinedFinally(OutlinedFinally) {}
1748 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1749 llvm::Value *FP =
nullptr;
1752 FP = &CGF.
CurFn->arg_begin()[1];
1754 llvm::Function *LocalAddrFn =
1756 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1759 llvm::Value *IsForEH =
1760 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1767 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1770 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1778 const CGFunctionInfo &FnInfo =
1782 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1789struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1790 CodeGenFunction &ParentCGF;
1791 const VarDecl *ParentThis;
1792 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1794 CaptureFinder(CodeGenFunction &ParentCGF,
const VarDecl *ParentThis)
1795 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1798 bool foundCaptures() {
1799 return !Captures.empty() || SEHCodeSlot.
isValid();
1802 void Visit(
const Stmt *S) {
1804 ConstStmtVisitor<CaptureFinder>::Visit(S);
1805 for (
const Stmt *Child : S->
children())
1810 void VisitDeclRefExpr(
const DeclRefExpr *E) {
1813 Captures.insert(ParentThis);
1815 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1816 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1820 void VisitCXXThisExpr(
const CXXThisExpr *E) {
1821 Captures.insert(ParentThis);
1824 void VisitCallExpr(
const CallExpr *E) {
1831 case Builtin::BI__exception_code:
1832 case Builtin::BI_exception_code:
1846 llvm::Value *ParentFP) {
1847 llvm::Value *RecoverCall =
nullptr;
1853 auto *ParentAlloca =
1857 if (!ParentAlloca) {
1859 llvm::BasicBlock &EntryBB =
ParentCGF.CurFn->getEntryBlock();
1860 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1861 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1862 ParentArg->getType(),
nullptr, ParentArg->getName() +
".spill");
1863 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1870 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1871 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1872 int FrameEscapeIdx = InsertPair.first->second;
1874 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1875 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1876 RecoverCall =
Builder.CreateCall(
1877 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1878 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1880 RecoverCall =
Builder.CreateLoad(
1888 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1889 "expected alloca or localrecover in parent LocalDeclMap");
1890 RecoverCall = ParentRecover->clone();
1897 llvm::Value *ChildVar =
1899 ChildVar->setName(ParentVar.
getName());
1904 const Stmt *OutlinedStmt,
1908 Finder.Visit(OutlinedStmt);
1912 if (!Finder.foundCaptures() &&
1913 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1919 llvm::Value *EntryFP =
nullptr;
1921 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1927 {Builder.getInt32(1)});
1931 auto AI =
CurFn->arg_begin();
1936 llvm::Value *ParentFP = EntryFP;
1941 llvm::Function *RecoverFPIntrin =
1942 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1943 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1955 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1956 for (
auto &I :
ParentCGF.LocalDeclMap) {
1960 assert(D->
getName().starts_with(
"frame_pointer"));
1961 FramePtrAddrAlloca =
1966 assert(FramePtrAddrAlloca);
1967 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1968 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1969 int FrameEscapeIdx = InsertPair.first->second;
1976 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1977 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1978 ParentFP =
Builder.CreateCall(
1979 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1980 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1981 ParentFP =
Builder.CreateLoad(
1987 for (
const VarDecl *VD : Finder.Captures) {
1989 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1993 "captured non-local variable");
1995 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1996 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
2003 auto I =
ParentCGF.LocalDeclMap.find(VD);
2007 Address ParentVar = I->second;
2010 setAddrOfLocalVar(VD, Recovered);
2013 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
2014 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
2015 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
2029 CXXThisValue = CXXABIThisValue;
2034 if (Finder.SEHCodeSlot.
isValid()) {
2048 const Stmt *OutlinedStmt) {
2054 llvm::raw_svector_ostream OS(Name);
2056 assert(ParentSEHFn &&
"No CurSEHParent!");
2065 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2071 &
getContext().Idents.get(
"exception_pointers"),
2076 &
getContext().Idents.get(
"abnormal_termination"),
2088 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2090 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
2091 llvm::Function *Fn = llvm::Function::Create(
2092 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2139 llvm::Value *ParentFP,
2140 llvm::Value *EntryFP) {
2143 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2166 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2167 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2171 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2179 return llvm::PoisonValue::get(
Int8PtrTy);
2185 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2192 auto AI =
CurFn->arg_begin();
2197 llvm::Function *FinallyFunc) {
2198 EHStack.pushCleanup<PerformSEHFinally>(
2203 CodeGenFunction HelperCGF(
CGM,
true);
2207 llvm::Function *FinallyFunc =
2229 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2237 llvm::Function *FilterFunc =
2257 assert(Except &&
"__try must have __finally xor __except");
2269 if (
const auto *DS = dyn_cast<DeclStmt>(S))
2270 for (
const Decl *D : DS->decls())
2271 if (
const auto *VD = dyn_cast<VarDecl>(D))
2274 VD->getLocation(), diag::err_seh_object_unwinding);
2299 llvm::CatchPadInst *CPI =
2302 Builder.CreateCatchRet(CPI, ExceptBB);
2306 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2307 llvm::Function *SEHCodeIntrin =
2308 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2309 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2336 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 llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function.
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
Emit the structure of the dispatch block for the given catch scope.
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
static bool isNonEHScope(const EHScope &S)
Check whether this is a non-EH scope, i.e.
static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
Returns the value to inject into a selector to indicate the presence of a catch-all.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
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::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.
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,...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
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