25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/Intrinsics.h"
27#include "llvm/IR/IntrinsicsWebAssembly.h"
28#include "llvm/Support/SaveAndRestore.h"
31using namespace CodeGen;
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 =
133 const llvm::Triple &T =
Target.getTriple();
134 if (T.isWindowsMSVCEnvironment())
147 const llvm::Triple &T =
Target.getTriple();
148 if (T.isWindowsMSVCEnvironment())
170 llvm_unreachable(
"bad runtime kind");
175 const llvm::Triple &T =
Target.getTriple();
176 if (T.isWindowsMSVCEnvironment())
195 if (
Target.getTriple().isWindowsMSVCEnvironment())
221 llvm_unreachable(
"bad runtime kind");
225 if (T.getArch() == llvm::Triple::x86)
253 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
260 llvm::AttributeList(),
true);
266 llvm::PointerType* Int8PtrTy = llvm::PointerType::get(
270 return llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(Fn.getCallee()),
276 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
279 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
280 if (LPI->isCatch(I)) {
282 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
285 if (GV->getName().startswith(
"OBJC_EHTYPE"))
289 llvm::Constant *CVal = cast<llvm::Constant>(Val);
290 for (llvm::User::op_iterator
291 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
292 if (llvm::GlobalVariable *GV =
293 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
296 if (GV->getName().startswith(
"OBJC_EHTYPE"))
307 for (llvm::User *
U : Fn->users()) {
309 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
310 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
317 llvm::Function *F = dyn_cast<llvm::Function>(
U);
318 if (!F)
return false;
320 for (
auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
321 if (BB->isLandingPad())
334void CodeGenModule::SimplifyPersonality() {
336 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
349 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
350 "Different EHPersonalities using the same personality function.");
355 if (!Fn || Fn->use_empty())
return;
365 if (Fn->getType() != CXXFn.getCallee()->getType())
368 Fn->replaceAllUsesWith(CXXFn.getCallee());
369 Fn->eraseFromParent();
376 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
384 FreeException(llvm::Value *exn) : exn(exn) {}
418 cast<llvm::Instruction>(typedAddr.
getPointer()));
442 bool KeepInsertionPoint) {
448 if (
CGM.
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) {
453 QualType ThrowType = SubExpr->getType();
467 if (KeepInsertionPoint)
475 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
478 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
506 diag::warn_wasm_dynamic_exception_spec_ignored)
520 diag::warn_wasm_dynamic_exception_spec_ignored)
526 for (
unsigned I = 0; I != NumExceptions; ++I) {
531 Filter->setFilter(I, EHType);
544 if (!dispatchBlock)
return;
545 if (dispatchBlock->use_empty()) {
546 delete dispatchBlock;
559 llvm::Value *zero = CGF.
Builder.getInt32(0);
560 llvm::Value *failsFilter =
561 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
562 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
574 ->setDoesNotReturn();
575 CGF.
Builder.CreateUnreachable();
582 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
585 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
624 const bool IsTargetDevice =
625 (
CGM.
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()));
634 unsigned NumHandlers = S.getNumHandlers();
637 for (
unsigned I = 0; I != NumHandlers; ++I) {
641 if (
C->getExceptionDecl()) {
650 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
657 CaughtType,
C->getCaughtType());
684 if (!dispatchBlock) {
714 return dispatchBlock;
729 return DispatchBlock;
739 DispatchBlock->setName(
"catch.dispatch");
743 DispatchBlock->setName(
"ehcleanup");
747 llvm_unreachable(
"exception specifications not handled yet!");
750 DispatchBlock->setName(
"terminate");
754 return DispatchBlock;
761 switch (S.getKind()) {
763 return !cast<EHCleanupScope>(S).isEHCleanup();
770 llvm_unreachable(
"Invalid EHScope Kind!");
782 if (!LO.Exceptions || LO.IgnoreExceptions) {
783 if (!LO.Borland && !LO.MicrosoftExt)
790 if (LO.CUDA && LO.CUDAIsDevice)
800 if (!
CurFn->hasPersonalityFn())
816 ir->setCachedLandingPad(LP);
826 "LandingPad should not be emitted when -fignore-exceptions are in "
829 switch (innermostEHScope.
getKind()) {
841 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
848 llvm::LandingPadInst *LPadInst =
851 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
853 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
862 bool hasCatchAll =
false;
863 bool hasCleanup =
false;
864 bool hasFilter =
false;
870 switch (I->getKind()) {
873 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
877 assert(I.next() ==
EHStack.
end() &&
"EH filter is not end of EH stack");
878 assert(!hasCatchAll &&
"EH filter reached after catch-all");
885 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
886 filterTypes.push_back(filter.
getFilter(i));
892 assert(!hasCatchAll);
901 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
904 "landingpads do not support catch handler flags");
908 assert(!hasCatchAll);
914 if (catchTypes.insert(handler.
Type.
RTTI).second)
916 LPadInst->addClause(handler.
Type.
RTTI);
922 assert(!(hasCatchAll && hasFilter));
928 }
else if (hasFilter) {
933 llvm::ArrayType *AType =
934 llvm::ArrayType::get(!filterTypes.empty() ?
938 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
939 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
940 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
941 LPadInst->addClause(FilterArray);
945 LPadInst->setCleanup(
true);
948 }
else if (hasCleanup) {
949 LPadInst->setCleanup(
true);
952 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
953 "landingpad instruction has no clauses!");
966 assert(DispatchBlock);
968 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
974 llvm::BasicBlock *UnwindBB =
978 llvm::CatchSwitchInst *CatchSwitch =
979 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
982 for (
unsigned I = 0; I < NumHandlers; ++I) {
994 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
999 CatchSwitch->addHandler(Handler.
Block);
1001 CGF.
Builder.restoreIP(SavedIP);
1010 assert(DispatchBlock);
1012 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1018 llvm::BasicBlock *UnwindBB =
1022 llvm::CatchSwitchInst *CatchSwitch =
1023 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1027 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1028 CatchSwitch->addHandler(WasmCatchStartBlock);
1033 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1038 CatchTypes.push_back(
TypeInfo.RTTI);
1040 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1045 llvm::Function *GetExnFn =
1047 llvm::Function *GetSelectorFn =
1049 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1051 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1053 llvm::Function *TypeIDFn = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::eh_typeid_for);
1059 CGF.
Builder.restoreIP(SavedIP);
1064 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1065 assert(I < E &&
"ran off end of handlers!");
1072 llvm::BasicBlock *NextBlock;
1074 bool EmitNextBlock =
false, NextIsEnd =
false;
1081 EmitNextBlock =
true;
1093 EmitNextBlock =
true;
1097 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1098 TypeIndex->setDoesNotThrow();
1100 llvm::Value *MatchesTypeIndex =
1102 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1110 CGF.
Builder.restoreIP(SavedIP);
1123 assert(dispatchBlock);
1133 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1137 llvm::Function *llvm_eh_typeid_for =
1139 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1147 assert(i < e &&
"ran off end of handlers!");
1150 llvm::Value *typeValue = handler.
Type.
RTTI;
1152 "landingpads do not support catch handler flags");
1153 assert(typeValue &&
"fell into catch-all case!");
1155 if (typeValue->getType() != argTy)
1162 llvm::BasicBlock *nextBlock;
1183 llvm::CallInst *typeIndex =
1184 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1185 typeIndex->setDoesNotThrow();
1187 llvm::Value *matchesTypeIndex =
1188 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1189 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1193 CGF.
Builder.restoreIP(savedIP);
1209 unsigned NumHandlers = S.getNumHandlers();
1227 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1240 bool doImplicitRethrow =
false;
1242 doImplicitRethrow = isa<CXXDestructorDecl>(
CurCodeDecl) ||
1249 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1252 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHI());
1253 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1254 ? CatchSwitch->getSuccessor(1)
1255 : CatchSwitch->getSuccessor(0);
1256 auto *CPI = cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHI());
1267 bool HasCatchAll =
false;
1268 for (
unsigned I = NumHandlers; I != 0; --I) {
1269 HasCatchAll |= Handlers[I - 1].isCatchAll();
1270 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1278 RunCleanupsScope CatchScope(*
this);
1302 Builder.ClearInsertionPoint();
1306 CatchScope.ForceCleanup();
1318 assert(WasmCatchStartBlock);
1323 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1324 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1325 auto *BI = cast<llvm::BranchInst>(TI);
1326 assert(BI->isConditional());
1327 RethrowBlock = BI->getSuccessor(1);
1329 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1330 Builder.SetInsertPoint(RethrowBlock);
1331 llvm::Function *RethrowInCatchFn =
1342 llvm::Value *ForEHVar;
1343 llvm::FunctionCallee EndCatchFn;
1344 CallEndCatchForFinally(llvm::Value *ForEHVar,
1345 llvm::FunctionCallee EndCatchFn)
1346 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1350 llvm::BasicBlock *CleanupContBB =
1353 llvm::Value *ShouldEndCatch =
1355 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1364 llvm::Value *ForEHVar;
1365 llvm::FunctionCallee EndCatchFn;
1366 llvm::FunctionCallee RethrowFn;
1367 llvm::Value *SavedExnVar;
1369 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1370 llvm::FunctionCallee EndCatchFn,
1371 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1372 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1373 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1379 ForEHVar, EndCatchFn);
1383 llvm::Value *SavedCleanupDest =
1385 "cleanup.dest.saved");
1396 llvm::Value *ShouldRethrow =
1398 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1408 CGF.
Builder.CreateUnreachable();
1421 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1423 CGF.
Builder.restoreIP(SavedIP);
1437 llvm::FunctionCallee beginCatchFn,
1438 llvm::FunctionCallee endCatchFn,
1439 llvm::FunctionCallee rethrowFn) {
1440 assert((!!beginCatchFn) == (!!endCatchFn) &&
1441 "begin/end catch functions not paired");
1442 assert(rethrowFn &&
"rethrow function is required");
1444 BeginCatchFn = beginCatchFn;
1452 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1453 SavedExnVar =
nullptr;
1454 if (rethrowFnTy->getNumParams())
1480 ForEHVar, endCatchFn,
1481 rethrowFn, SavedExnVar);
1497 if (catchBB->use_empty()) {
1500 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1503 llvm::Value *exn =
nullptr;
1523 CGF.
Builder.restoreIP(savedIP);
1531 if (TerminateLandingPad)
1532 return TerminateLandingPad;
1534 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1538 Builder.SetInsertPoint(TerminateLandingPad);
1543 if (!
CurFn->hasPersonalityFn())
1546 llvm::LandingPadInst *LPadInst =
1550 llvm::Value *Exn =
nullptr;
1552 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1553 llvm::CallInst *terminateCall =
1555 terminateCall->setDoesNotReturn();
1561 return TerminateLandingPad;
1565 if (TerminateHandler)
1566 return TerminateHandler;
1571 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1572 Builder.SetInsertPoint(TerminateHandler);
1574 llvm::Value *Exn =
nullptr;
1577 llvm::CallInst *terminateCall =
1579 terminateCall->setDoesNotReturn();
1585 return TerminateHandler;
1590 "use getTerminateLandingPad for non-funclet EH");
1593 if (TerminateFunclet)
1594 return TerminateFunclet;
1596 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1601 Builder.SetInsertPoint(TerminateFunclet);
1612 llvm::CallInst *terminateCall =
1614 terminateCall->setDoesNotReturn();
1620 return TerminateFunclet;
1626 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1637 if (RethrowName !=
nullptr && !isCleanup) {
1649 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1650 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1651 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1652 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1654 Builder.CreateResume(LPadVal);
1666 llvm::BasicBlock *TryBB =
nullptr;
1671 TryBB =
Builder.GetInsertBlock();
1684 if (!TryExit.getBlock()->use_empty())
1687 delete TryExit.getBlock();
1697 !
V.insert(BB).second ||
1698 !BB->getParent() || BB->empty())
1701 if (!BB->isEHPad()) {
1702 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1704 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1705 LI->setVolatile(
true);
1706 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1707 SI->setVolatile(
true);
1708 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1709 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1713 const llvm::Instruction *TI = BB->getTerminator();
1715 unsigned N = TI->getNumSuccessors();
1716 for (
unsigned I = 0; I < N; I++)
1723 llvm::Function *OutlinedFinally;
1724 PerformSEHFinally(llvm::Function *OutlinedFinally)
1725 : OutlinedFinally(OutlinedFinally) {}
1735 llvm::Value *FP =
nullptr;
1738 FP = &CGF.
CurFn->arg_begin()[1];
1740 llvm::Function *LocalAddrFn =
1742 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1745 llvm::Value *IsForEH =
1746 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1753 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1756 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1757 IsForEH = CGF.
Builder.CreateICmpNE(Load, Zero);
1781 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1784 bool foundCaptures() {
1785 return !Captures.empty() || SEHCodeSlot.
isValid();
1788 void Visit(
const Stmt *S) {
1791 for (
const Stmt *Child : S->children())
1799 Captures.insert(ParentThis);
1801 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1802 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1807 Captures.insert(ParentThis);
1810 void VisitCallExpr(
const CallExpr *E) {
1817 case Builtin::BI__exception_code:
1818 case Builtin::BI_exception_code:
1832 llvm::Value *ParentFP) {
1833 llvm::CallInst *RecoverCall =
nullptr;
1835 if (
auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.
getPointer())) {
1838 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1839 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1840 int FrameEscapeIdx = InsertPair.first->second;
1842 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1844 llvm::Constant *ParentI8Fn =
1846 RecoverCall =
Builder.CreateCall(
1847 FrameRecoverFn, {ParentI8Fn, ParentFP,
1848 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1854 auto *ParentRecover =
1855 cast<llvm::IntrinsicInst>(ParentVar.
getPointer()->stripPointerCasts());
1856 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1857 "expected alloca or localrecover in parent LocalDeclMap");
1858 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1859 RecoverCall->setArgOperand(1, ParentFP);
1864 llvm::Value *ChildVar =
1866 ChildVar->setName(ParentVar.
getName());
1871 const Stmt *OutlinedStmt,
1875 Finder.Visit(OutlinedStmt);
1879 if (!Finder.foundCaptures() &&
1886 llvm::Value *EntryFP =
nullptr;
1894 {Builder.getInt32(1)});
1898 auto AI =
CurFn->arg_begin();
1903 llvm::Value *ParentFP = EntryFP;
1908 llvm::Function *RecoverFPIntrin =
1910 llvm::Constant *ParentI8Fn =
1912 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
1924 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1925 for (
auto &I :
ParentCGF.LocalDeclMap) {
1926 const VarDecl *D = cast<VarDecl>(I.first);
1927 if (isa<ImplicitParamDecl>(D) &&
1929 assert(D->
getName().startswith(
"frame_pointer"));
1930 FramePtrAddrAlloca = cast<llvm::AllocaInst>(I.second.getPointer());
1934 assert(FramePtrAddrAlloca);
1935 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1936 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1937 int FrameEscapeIdx = InsertPair.first->second;
1945 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1947 llvm::Constant *ParentI8Fn =
1949 ParentFP =
Builder.CreateCall(
1950 FrameRecoverFn, {ParentI8Fn, ParentFP,
1951 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1959 for (
const VarDecl *VD : Finder.Captures) {
1965 "captured non-local variable");
1975 auto I =
ParentCGF.LocalDeclMap.find(VD);
1979 Address ParentVar = I->second;
1982 setAddrOfLocalVar(VD, Recovered);
1984 if (isa<ImplicitParamDecl>(VD)) {
1985 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
1986 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
2001 CXXThisValue = CXXABIThisValue;
2006 if (Finder.SEHCodeSlot.isValid()) {
2020 const Stmt *OutlinedStmt) {
2026 llvm::raw_svector_ostream OS(Name);
2028 assert(ParentSEHFn &&
"No CurSEHParent!");
2043 &
getContext().Idents.get(
"exception_pointers"),
2048 &
getContext().Idents.get(
"abnormal_termination"),
2063 llvm::Function *Fn = llvm::Function::Create(
2064 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.
getModule());
2111 llvm::Value *ParentFP,
2112 llvm::Value *EntryFP) {
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::UndefValue::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);
2175 HelperCGF.ParentCGF =
this;
2178 llvm::Function *FinallyFunc =
2179 HelperCGF.GenerateSEHFinallyFunction(*
this, *Finally);
2207 llvm::Function *FilterFunc =
2208 HelperCGF.GenerateSEHFilterFunction(*
this, *Except);
2209 llvm::Constant *OpaqueFunc =
2210 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
2216 if (S.getFinallyHandler()) {
2229 assert(Except &&
"__try must have __finally xor __except");
2260 llvm::CatchPadInst *CPI =
2261 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
2263 Builder.CreateCatchRet(CPI, ExceptBB);
2268 llvm::Function *SEHCodeIntrin =
2270 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2297 Builder.ClearInsertionPoint();
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static const EHPersonality & getObjCPersonality(const TargetInfo &Target, const LangOptions &L)
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &T)
static const EHPersonality & getCXXPersonality(const TargetInfo &Target, 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 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 const EHPersonality & getObjCXXPersonality(const TargetInfo &Target, const LangOptions &L)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static const EHPersonality & getCPersonality(const TargetInfo &Target, const LangOptions &L)
llvm::DenseSet< const void * > Visited
Defines the Objective-C statement AST node classes.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
CanQualType UnsignedCharTy
CXXCatchStmt - This represents a C++ catch block.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
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::Value * getPointer() const
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)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
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="")
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
virtual CatchTypeInfo getCatchAllTypeInfo()
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
MangleContext & getMangleContext()
Gets the mangle context.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
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.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void EnterSEHTryStmt(const SEHTryStmt &S)
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)
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...
llvm::BasicBlock * getInvokeDestImpl()
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
FieldDecl * LambdaThisCaptureField
void EmitCXXTryStmt(const CXXTryStmt &S)
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
void EmitAnyExprToExn(const Expr *E, Address Addr)
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitSEHExceptionInfo()
const LangOptions & getLangOpts() const
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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...
llvm::AllocaInst * EHSelectorSlot
The selector slot.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
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 EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
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
llvm::Value * ExceptionSlot
The exception slot.
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
const TargetInfo & getTarget() const
Address getNormalCleanupDestSlot()
llvm::Value * EmitSEHExceptionCode()
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
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.
void EmitSehTryScopeBegin()
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
void EmitSEHTryStmt(const SEHTryStmt &S)
void ExitSEHTryStmt(const SEHTryStmt &S)
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::BasicBlock * getTerminateHandler()
getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...
const TargetCodeGenInfo & getTargetHooks() const
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
llvm::BasicBlock * EmitLandingPad()
Emits a landing pad for the current EH stack.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
const TargetInfo & Target
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
Scan the outlined statement for captures from the parent function.
llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)
llvm::Value * EmitSEHAbnormalTermination()
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
llvm::Instruction * CurrentFuncletPad
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * getSelectorFromSlot()
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
Address getEHSelectorSlot()
LValue EmitLValueForLambdaField(const FieldDecl *Field)
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
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.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
DiagnosticsEngine & getDiags() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::LLVMContext & getLLVMContext()
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
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
Information for lazily generating a cleanup.
A non-stable pointer into the scope stack.
A saved depth on the scope stack.
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
stable_iterator getInnermostEHScope() const
bool requiresLandingPad() const
bool empty() const
Determines whether the exception-scopes stack is empty.
iterator end() const
Returns an iterator pointing to the outermost EH scope.
void popFilter()
Pops an exceptions filter off the stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
void popTerminate()
Pops a terminate handler off the stack.
void pushTerminate()
Push a terminate handler 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(CodeGenFunction &CGF) const
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
Decl - This represents one declaration (or definition), e.g.
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
@ Other
Other implicit parameter.
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...
bool hasWasmExceptions() const
clang::ObjCRuntime ObjCRuntime
bool hasSjLjExceptions() const
bool hasDWARFExceptions() const
bool hasSEHExceptions() const
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.
The basic abstraction for the target Objective-C runtime.
bool hasTerminate() const
Does this runtime provide an objc_terminate function?
bool isNeXTFamily() const
Is this runtime basically of the NeXT family of runtimes?
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.
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
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isPointerType() const
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.
@ 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 Zero(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
@ C
Languages that the frontend can parse and compile.
LangAS
Defines the address space values used by the address space qualifier of QualType.
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,...
llvm::PointerType * VoidPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::PointerType * VoidPtrPtrTy
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 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