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())
175 llvm_unreachable(
"bad runtime kind");
180 const llvm::Triple &
T =
Target.getTriple();
181 if (
T.isWindowsMSVCEnvironment())
203 if (
Target.getTriple().isWindowsMSVCEnvironment())
230 llvm_unreachable(
"bad runtime kind");
234 if (
T.getArch() == llvm::Triple::x86)
263 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
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.isNVPTX() ||
T.isAMDGCN())) {
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() ==
525 diag::warn_wasm_dynamic_exception_spec_ignored)
531 for (
unsigned I = 0; I != NumExceptions; ++I) {
534 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
536 Filter->setFilter(I, EHType);
549 if (!dispatchBlock)
return;
550 if (dispatchBlock->use_empty()) {
551 delete dispatchBlock;
564 llvm::Value *zero = CGF.
Builder.getInt32(0);
565 llvm::Value *failsFilter =
566 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
567 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
579 ->setDoesNotReturn();
580 CGF.
Builder.CreateUnreachable();
584 if (!
CGM.getLangOpts().CXXExceptions)
587 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
590 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
591 if (CD->isNothrow() && !
EHStack.empty())
605 if (
getTarget().getCXXABI().isMicrosoft())
610 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
626 const llvm::Triple &
T =
Target.getTriple();
629 const bool IsTargetDevice =
630 (
CGM.getLangOpts().OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN()));
642 for (
unsigned I = 0; I != NumHandlers; ++I) {
646 if (
C->getExceptionDecl()) {
654 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
655 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
659 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
661 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
662 CaughtType,
C->getCaughtType());
666 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
682 if (si ==
EHStack.stable_end())
689 if (!dispatchBlock) {
719 return dispatchBlock;
726 if (SI ==
EHStack.stable_end())
734 return DispatchBlock;
744 DispatchBlock->setName(
"catch.dispatch");
748 DispatchBlock->setName(
"ehcleanup");
752 llvm_unreachable(
"exception specifications not handled yet!");
755 DispatchBlock->setName(
"terminate");
759 return DispatchBlock;
775 llvm_unreachable(
"Invalid EHScope Kind!");
779 assert(
EHStack.requiresLandingPad());
787 if (!LO.Exceptions || LO.IgnoreExceptions) {
788 if (!LO.Borland && !LO.MicrosoftExt)
795 if (LO.CUDA && LO.CUDAIsDevice)
800 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
805 if (!
CurFn->hasPersonalityFn())
821 ir->setCachedLandingPad(LP);
829 assert(
EHStack.requiresLandingPad());
830 assert(!
CGM.getLangOpts().IgnoreExceptions &&
831 "LandingPad should not be emitted when -fignore-exceptions are in "
834 switch (innermostEHScope.
getKind()) {
846 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
853 llvm::LandingPadInst *LPadInst =
856 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
858 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
867 bool hasCatchAll =
false;
868 bool hasCleanup =
false;
869 bool hasFilter =
false;
875 switch (I->getKind()) {
882 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
883 assert(!hasCatchAll &&
"EH filter reached after catch-all");
890 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
891 filterTypes.push_back(filter.
getFilter(i));
897 assert(!hasCatchAll);
906 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
909 "landingpads do not support catch handler flags");
913 assert(!hasCatchAll);
919 if (catchTypes.insert(handler.
Type.
RTTI).second)
921 LPadInst->addClause(handler.
Type.
RTTI);
927 assert(!(hasCatchAll && hasFilter));
933 }
else if (hasFilter) {
938 llvm::ArrayType *AType =
939 llvm::ArrayType::get(!filterTypes.empty() ?
943 for (llvm::Value *filterType : filterTypes)
945 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
946 LPadInst->addClause(FilterArray);
950 LPadInst->setCleanup(
true);
953 }
else if (hasCleanup) {
954 LPadInst->setCleanup(
true);
957 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
958 "landingpad instruction has no clauses!");
971 assert(DispatchBlock);
973 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
979 llvm::BasicBlock *UnwindBB =
983 llvm::CatchSwitchInst *CatchSwitch =
984 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
987 for (
unsigned I = 0; I < NumHandlers; ++I) {
999 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
1004 CatchSwitch->addHandler(Handler.
Block);
1006 CGF.
Builder.restoreIP(SavedIP);
1015 assert(DispatchBlock);
1017 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1023 llvm::BasicBlock *UnwindBB =
1027 llvm::CatchSwitchInst *CatchSwitch =
1028 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1032 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1033 CatchSwitch->addHandler(WasmCatchStartBlock);
1038 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1043 CatchTypes.push_back(
TypeInfo.RTTI);
1045 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1050 llvm::Function *GetExnFn =
1052 llvm::Function *GetSelectorFn =
1054 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1056 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1058 llvm::Function *TypeIDFn =
1065 CGF.
Builder.restoreIP(SavedIP);
1070 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1071 assert(I < E &&
"ran off end of handlers!");
1078 llvm::BasicBlock *NextBlock;
1080 bool EmitNextBlock =
false, NextIsEnd =
false;
1087 EmitNextBlock =
true;
1099 EmitNextBlock =
true;
1103 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1104 TypeIndex->setDoesNotThrow();
1106 llvm::Value *MatchesTypeIndex =
1108 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1116 CGF.
Builder.restoreIP(SavedIP);
1129 assert(dispatchBlock);
1139 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1143 llvm::Function *llvm_eh_typeid_for =
1145 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1153 assert(i < e &&
"ran off end of handlers!");
1156 llvm::Value *typeValue = handler.
Type.
RTTI;
1158 "landingpads do not support catch handler flags");
1159 assert(typeValue &&
"fell into catch-all case!");
1161 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);
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();
1324 assert(WasmCatchStartBlock);
1329 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1330 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1332 assert(BI->isConditional());
1333 RethrowBlock = BI->getSuccessor(1);
1335 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1336 Builder.SetInsertPoint(RethrowBlock);
1337 llvm::Function *RethrowInCatchFn =
1338 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1347 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1348 llvm::Value *ForEHVar;
1349 llvm::FunctionCallee EndCatchFn;
1350 CallEndCatchForFinally(llvm::Value *ForEHVar,
1351 llvm::FunctionCallee EndCatchFn)
1352 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1356 llvm::BasicBlock *CleanupContBB =
1359 llvm::Value *ShouldEndCatch =
1361 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1368 struct PerformFinally final : EHScopeStack::Cleanup {
1370 llvm::Value *ForEHVar;
1371 llvm::FunctionCallee EndCatchFn;
1372 llvm::FunctionCallee RethrowFn;
1373 llvm::Value *SavedExnVar;
1375 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1376 llvm::FunctionCallee EndCatchFn,
1377 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1378 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1379 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1381 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1385 ForEHVar, EndCatchFn);
1389 llvm::Value *SavedCleanupDest =
1391 "cleanup.dest.saved");
1402 llvm::Value *ShouldRethrow =
1404 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1414 CGF.
Builder.CreateUnreachable();
1427 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1429 CGF.
Builder.restoreIP(SavedIP);
1443 llvm::FunctionCallee beginCatchFn,
1444 llvm::FunctionCallee endCatchFn,
1445 llvm::FunctionCallee rethrowFn) {
1446 assert((!!beginCatchFn) == (!!endCatchFn) &&
1447 "begin/end catch functions not paired");
1448 assert(rethrowFn &&
"rethrow function is required");
1450 BeginCatchFn = beginCatchFn;
1458 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1459 SavedExnVar =
nullptr;
1460 if (rethrowFnTy->getNumParams())
1486 ForEHVar, endCatchFn,
1487 rethrowFn, SavedExnVar);
1503 if (catchBB->use_empty()) {
1506 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1509 llvm::Value *exn =
nullptr;
1529 CGF.
Builder.restoreIP(savedIP);
1537 if (TerminateLandingPad)
1538 return TerminateLandingPad;
1540 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1544 Builder.SetInsertPoint(TerminateLandingPad);
1549 if (!
CurFn->hasPersonalityFn())
1552 llvm::LandingPadInst *LPadInst =
1556 llvm::Value *Exn =
nullptr;
1558 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1559 llvm::CallInst *terminateCall =
1560 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1561 terminateCall->setDoesNotReturn();
1567 return TerminateLandingPad;
1571 if (TerminateHandler)
1572 return TerminateHandler;
1577 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1578 Builder.SetInsertPoint(TerminateHandler);
1580 llvm::Value *Exn =
nullptr;
1583 llvm::CallInst *terminateCall =
1584 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1585 terminateCall->setDoesNotReturn();
1591 return TerminateHandler;
1596 "use getTerminateLandingPad for non-funclet EH");
1599 if (TerminateFunclet)
1600 return TerminateFunclet;
1602 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1607 Builder.SetInsertPoint(TerminateFunclet);
1614 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1618 llvm::CallInst *terminateCall =
1619 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1620 terminateCall->setDoesNotReturn();
1626 return TerminateFunclet;
1632 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1643 if (RethrowName !=
nullptr && !isCleanup) {
1655 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1656 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1657 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1658 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1660 Builder.CreateResume(LPadVal);
1672 llvm::BasicBlock *TryBB =
nullptr;
1677 TryBB =
Builder.GetInsertBlock();
1690 if (!TryExit.
getBlock()->use_empty())
1703 !
V.insert(BB).second ||
1704 !BB->getParent() || BB->empty())
1707 if (!BB->isEHPad()) {
1708 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1710 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1711 LI->setVolatile(
true);
1712 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1713 SI->setVolatile(
true);
1714 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1715 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1719 const llvm::Instruction *TI = BB->getTerminator();
1721 unsigned N = TI->getNumSuccessors();
1722 for (
unsigned I = 0; I < N; I++)
1728struct PerformSEHFinally final : EHScopeStack::Cleanup {
1729 llvm::Function *OutlinedFinally;
1730 PerformSEHFinally(llvm::Function *OutlinedFinally)
1731 : OutlinedFinally(OutlinedFinally) {}
1740 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1741 llvm::Value *FP =
nullptr;
1744 FP = &CGF.
CurFn->arg_begin()[1];
1746 llvm::Function *LocalAddrFn =
1748 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1751 llvm::Value *IsForEH =
1752 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1759 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1762 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1770 const CGFunctionInfo &FnInfo =
1774 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1781struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1782 CodeGenFunction &ParentCGF;
1783 const VarDecl *ParentThis;
1784 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1786 CaptureFinder(CodeGenFunction &ParentCGF,
const VarDecl *ParentThis)
1787 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1790 bool foundCaptures() {
1791 return !Captures.empty() || SEHCodeSlot.
isValid();
1794 void Visit(
const Stmt *S) {
1796 ConstStmtVisitor<CaptureFinder>::Visit(S);
1797 for (
const Stmt *Child : S->
children())
1802 void VisitDeclRefExpr(
const DeclRefExpr *E) {
1805 Captures.insert(ParentThis);
1807 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1808 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1812 void VisitCXXThisExpr(
const CXXThisExpr *E) {
1813 Captures.insert(ParentThis);
1816 void VisitCallExpr(
const CallExpr *E) {
1823 case Builtin::BI__exception_code:
1824 case Builtin::BI_exception_code:
1838 llvm::Value *ParentFP) {
1839 llvm::CallInst *RecoverCall =
nullptr;
1841 if (
auto *ParentAlloca =
1842 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.
getBasePointer())) {
1845 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1846 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1847 int FrameEscapeIdx = InsertPair.first->second;
1849 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1850 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1851 RecoverCall =
Builder.CreateCall(
1852 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1853 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1861 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1862 "expected alloca or localrecover in parent LocalDeclMap");
1864 RecoverCall->setArgOperand(1, ParentFP);
1869 llvm::Value *ChildVar =
1871 ChildVar->setName(ParentVar.
getName());
1876 const Stmt *OutlinedStmt,
1880 Finder.Visit(OutlinedStmt);
1884 if (!Finder.foundCaptures() &&
1885 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1891 llvm::Value *EntryFP =
nullptr;
1893 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1899 {Builder.getInt32(1)});
1903 auto AI =
CurFn->arg_begin();
1908 llvm::Value *ParentFP = EntryFP;
1913 llvm::Function *RecoverFPIntrin =
1914 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1915 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1927 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1928 for (
auto &I :
ParentCGF.LocalDeclMap) {
1932 assert(D->
getName().starts_with(
"frame_pointer"));
1933 FramePtrAddrAlloca =
1938 assert(FramePtrAddrAlloca);
1939 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1940 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1941 int FrameEscapeIdx = InsertPair.first->second;
1948 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1949 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1950 ParentFP =
Builder.CreateCall(
1951 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1952 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1953 ParentFP =
Builder.CreateLoad(
1959 for (
const VarDecl *VD : Finder.Captures) {
1961 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1965 "captured non-local variable");
1967 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1968 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
1975 auto I =
ParentCGF.LocalDeclMap.find(VD);
1979 Address ParentVar = I->second;
1982 setAddrOfLocalVar(VD, Recovered);
1985 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
1986 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
1987 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
2001 CXXThisValue = CXXABIThisValue;
2006 if (Finder.SEHCodeSlot.
isValid()) {
2020 const Stmt *OutlinedStmt) {
2026 llvm::raw_svector_ostream OS(Name);
2028 assert(ParentSEHFn &&
"No CurSEHParent!");
2037 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2043 &
getContext().Idents.get(
"exception_pointers"),
2048 &
getContext().Idents.get(
"abnormal_termination"),
2060 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2062 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
2063 llvm::Function *Fn = llvm::Function::Create(
2064 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2111 llvm::Value *ParentFP,
2112 llvm::Value *EntryFP) {
2115 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2138 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2139 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2143 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2151 return llvm::PoisonValue::get(
Int8PtrTy);
2157 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2164 auto AI =
CurFn->arg_begin();
2169 llvm::Function *FinallyFunc) {
2170 EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
2174 CodeGenFunction HelperCGF(
CGM,
true);
2178 llvm::Function *FinallyFunc =
2199 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2207 llvm::Function *FilterFunc =
2227 assert(Except &&
"__try must have __finally xor __except");
2258 llvm::CatchPadInst *CPI =
2261 Builder.CreateCatchRet(CPI, ExceptBB);
2265 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2266 llvm::Function *SEHCodeIntrin =
2267 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2268 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2295 Builder.ClearInsertionPoint();
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &T)
static const EHPersonality & getObjCPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts, const LangOptions &L)
static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
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 const EHPersonality & getCXXPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts)
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 const EHPersonality & getCPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts)
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 & getObjCXXPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts, const LangOptions &L)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
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 ...
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)
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,...
const TargetCodeGenInfo & getTargetHooks() const
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
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()
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={})
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
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.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
SourceLocation getLocation() const
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, 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...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
bool Load(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
LangAS
Defines the address space values used by the address space qualifier of QualType.
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
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