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 =
135 const llvm::Triple &
T =
Target.getTriple();
136 if (
T.isWindowsMSVCEnvironment())
149 const llvm::Triple &
T =
Target.getTriple();
150 if (
T.isWindowsMSVCEnvironment())
174 llvm_unreachable(
"bad runtime kind");
179 const llvm::Triple &
T =
Target.getTriple();
180 if (
T.isWindowsMSVCEnvironment())
201 if (
Target.getTriple().isWindowsMSVCEnvironment())
228 llvm_unreachable(
"bad runtime kind");
232 if (
T.getArch() == llvm::Triple::x86)
260 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
267 llvm::AttributeList(),
true);
273 return cast<llvm::Constant>(Fn.getCallee());
278 for (
unsigned I = 0,
E = LPI->getNumClauses(); I !=
E; ++I) {
281 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
282 if (LPI->isCatch(I)) {
284 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
287 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
291 llvm::Constant *CVal = cast<llvm::Constant>(Val);
292 for (llvm::User::op_iterator
293 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
294 if (llvm::GlobalVariable *GV =
295 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
298 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
309 for (llvm::User *
U : Fn->users()) {
311 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
312 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
319 llvm::Function *F = dyn_cast<llvm::Function>(
U);
320 if (!F)
return false;
322 for (
auto BB = F->begin(),
E = F->end(); BB !=
E; ++BB) {
323 if (BB->isLandingPad())
336void CodeGenModule::SimplifyPersonality() {
338 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
351 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
352 "Different EHPersonalities using the same personality function.");
357 if (!Fn ||
Fn->use_empty())
return;
367 if (
Fn->getType() != CXXFn.getCallee()->getType())
370 Fn->replaceAllUsesWith(CXXFn.getCallee());
371 Fn->eraseFromParent();
378 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
386 FreeException(llvm::Value *exn) : exn(exn) {}
420 cleanup, cast<llvm::Instruction>(typedAddr.
emitRawPointer(*
this)));
444 bool KeepInsertionPoint) {
449 const llvm::Triple &
T =
Target.getTriple();
450 if (
CGM.
getLangOpts().OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN())) {
454 if (
const Expr *SubExpr =
E->getSubExpr()) {
455 QualType ThrowType = SubExpr->getType();
457 const Stmt *ThrowStmt =
E->getSubExpr();
469 if (KeepInsertionPoint)
480 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(
D)) {
508 diag::warn_wasm_dynamic_exception_spec_ignored)
522 diag::warn_wasm_dynamic_exception_spec_ignored)
528 for (
unsigned I = 0; I != NumExceptions; ++I) {
533 Filter->setFilter(I, EHType);
546 if (!dispatchBlock)
return;
547 if (dispatchBlock->use_empty()) {
548 delete dispatchBlock;
561 llvm::Value *zero = CGF.
Builder.getInt32(0);
562 llvm::Value *failsFilter =
563 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
564 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
576 ->setDoesNotReturn();
577 CGF.
Builder.CreateUnreachable();
587 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(
D)) {
623 const llvm::Triple &
T =
Target.getTriple();
626 const bool IsTargetDevice =
636 unsigned NumHandlers = S.getNumHandlers();
639 for (
unsigned I = 0; I != NumHandlers; ++I) {
643 if (
C->getExceptionDecl()) {
652 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
659 CaughtType,
C->getCaughtType());
686 if (!dispatchBlock) {
716 return dispatchBlock;
731 return DispatchBlock;
741 DispatchBlock->setName(
"catch.dispatch");
745 DispatchBlock->setName(
"ehcleanup");
749 llvm_unreachable(
"exception specifications not handled yet!");
752 DispatchBlock->setName(
"terminate");
756 return DispatchBlock;
763 switch (S.getKind()) {
765 return !cast<EHCleanupScope>(S).isEHCleanup();
772 llvm_unreachable(
"Invalid EHScope Kind!");
784 if (!LO.Exceptions || LO.IgnoreExceptions) {
785 if (!LO.Borland && !LO.MicrosoftExt)
792 if (LO.CUDA && LO.CUDAIsDevice)
802 if (!
CurFn->hasPersonalityFn())
818 ir->setCachedLandingPad(LP);
828 "LandingPad should not be emitted when -fignore-exceptions are in "
831 switch (innermostEHScope.
getKind()) {
843 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
850 llvm::LandingPadInst *LPadInst =
853 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
855 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
864 bool hasCatchAll =
false;
865 bool hasCleanup =
false;
866 bool hasFilter =
false;
872 switch (I->getKind()) {
875 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
879 assert(I.next() ==
EHStack.
end() &&
"EH filter is not end of EH stack");
880 assert(!hasCatchAll &&
"EH filter reached after catch-all");
887 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
888 filterTypes.push_back(filter.
getFilter(i));
894 assert(!hasCatchAll);
903 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
906 "landingpads do not support catch handler flags");
910 assert(!hasCatchAll);
916 if (catchTypes.insert(handler.
Type.
RTTI).second)
918 LPadInst->addClause(handler.
Type.
RTTI);
924 assert(!(hasCatchAll && hasFilter));
930 }
else if (hasFilter) {
935 llvm::ArrayType *AType =
936 llvm::ArrayType::get(!filterTypes.empty() ?
940 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
941 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
942 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
943 LPadInst->addClause(FilterArray);
947 LPadInst->setCleanup(
true);
950 }
else if (hasCleanup) {
951 LPadInst->setCleanup(
true);
954 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
955 "landingpad instruction has no clauses!");
968 assert(DispatchBlock);
970 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
976 llvm::BasicBlock *UnwindBB =
980 llvm::CatchSwitchInst *CatchSwitch =
981 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
984 for (
unsigned I = 0; I < NumHandlers; ++I) {
996 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
1001 CatchSwitch->addHandler(Handler.
Block);
1003 CGF.
Builder.restoreIP(SavedIP);
1012 assert(DispatchBlock);
1014 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1020 llvm::BasicBlock *UnwindBB =
1024 llvm::CatchSwitchInst *CatchSwitch =
1025 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1029 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1030 CatchSwitch->addHandler(WasmCatchStartBlock);
1035 for (
unsigned I = 0,
E = NumHandlers; I <
E; ++I) {
1040 CatchTypes.push_back(
TypeInfo.RTTI);
1042 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1047 llvm::Function *GetExnFn =
1049 llvm::Function *GetSelectorFn =
1051 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1053 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1055 llvm::Function *TypeIDFn =
1062 CGF.
Builder.restoreIP(SavedIP);
1067 for (
unsigned I = 0,
E = NumHandlers;; ++I) {
1068 assert(I <
E &&
"ran off end of handlers!");
1075 llvm::BasicBlock *NextBlock;
1077 bool EmitNextBlock =
false, NextIsEnd =
false;
1084 EmitNextBlock =
true;
1096 EmitNextBlock =
true;
1100 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1101 TypeIndex->setDoesNotThrow();
1103 llvm::Value *MatchesTypeIndex =
1105 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1113 CGF.
Builder.restoreIP(SavedIP);
1126 assert(dispatchBlock);
1136 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1140 llvm::Function *llvm_eh_typeid_for =
1142 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1150 assert(i < e &&
"ran off end of handlers!");
1153 llvm::Value *typeValue = handler.
Type.
RTTI;
1155 "landingpads do not support catch handler flags");
1156 assert(typeValue &&
"fell into catch-all case!");
1158 if (typeValue->getType() != argTy)
1165 llvm::BasicBlock *nextBlock;
1186 llvm::CallInst *typeIndex =
1187 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1188 typeIndex->setDoesNotThrow();
1190 llvm::Value *matchesTypeIndex =
1191 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1192 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1196 CGF.
Builder.restoreIP(savedIP);
1212 unsigned NumHandlers = S.getNumHandlers();
1230 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1243 bool doImplicitRethrow =
false;
1245 doImplicitRethrow = isa<CXXDestructorDecl>(
CurCodeDecl) ||
1252 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1255 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHI());
1256 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1257 ? CatchSwitch->getSuccessor(1)
1258 : CatchSwitch->getSuccessor(0);
1259 auto *CPI = cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHI());
1270 bool HasCatchAll =
false;
1271 for (
unsigned I = NumHandlers; I != 0; --I) {
1272 HasCatchAll |= Handlers[I - 1].isCatchAll();
1273 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1281 RunCleanupsScope CatchScope(*
this);
1305 Builder.ClearInsertionPoint();
1309 CatchScope.ForceCleanup();
1321 assert(WasmCatchStartBlock);
1326 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1327 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1328 auto *BI = cast<llvm::BranchInst>(TI);
1329 assert(BI->isConditional());
1330 RethrowBlock = BI->getSuccessor(1);
1332 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1333 Builder.SetInsertPoint(RethrowBlock);
1334 llvm::Function *RethrowInCatchFn =
1345 llvm::Value *ForEHVar;
1346 llvm::FunctionCallee EndCatchFn;
1347 CallEndCatchForFinally(llvm::Value *ForEHVar,
1348 llvm::FunctionCallee EndCatchFn)
1349 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1353 llvm::BasicBlock *CleanupContBB =
1356 llvm::Value *ShouldEndCatch =
1358 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1367 llvm::Value *ForEHVar;
1368 llvm::FunctionCallee EndCatchFn;
1369 llvm::FunctionCallee RethrowFn;
1370 llvm::Value *SavedExnVar;
1372 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1373 llvm::FunctionCallee EndCatchFn,
1374 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1375 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1376 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1382 ForEHVar, EndCatchFn);
1386 llvm::Value *SavedCleanupDest =
1388 "cleanup.dest.saved");
1399 llvm::Value *ShouldRethrow =
1401 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1411 CGF.
Builder.CreateUnreachable();
1424 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1426 CGF.
Builder.restoreIP(SavedIP);
1440 llvm::FunctionCallee beginCatchFn,
1441 llvm::FunctionCallee endCatchFn,
1442 llvm::FunctionCallee rethrowFn) {
1443 assert((!!beginCatchFn) == (!!endCatchFn) &&
1444 "begin/end catch functions not paired");
1445 assert(rethrowFn &&
"rethrow function is required");
1447 BeginCatchFn = beginCatchFn;
1455 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1456 SavedExnVar =
nullptr;
1457 if (rethrowFnTy->getNumParams())
1483 ForEHVar, endCatchFn,
1484 rethrowFn, SavedExnVar);
1500 if (catchBB->use_empty()) {
1503 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1506 llvm::Value *exn =
nullptr;
1526 CGF.
Builder.restoreIP(savedIP);
1534 if (TerminateLandingPad)
1535 return TerminateLandingPad;
1537 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1541 Builder.SetInsertPoint(TerminateLandingPad);
1546 if (!
CurFn->hasPersonalityFn())
1549 llvm::LandingPadInst *LPadInst =
1553 llvm::Value *Exn =
nullptr;
1555 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1556 llvm::CallInst *terminateCall =
1558 terminateCall->setDoesNotReturn();
1564 return TerminateLandingPad;
1568 if (TerminateHandler)
1569 return TerminateHandler;
1574 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1575 Builder.SetInsertPoint(TerminateHandler);
1577 llvm::Value *Exn =
nullptr;
1580 llvm::CallInst *terminateCall =
1582 terminateCall->setDoesNotReturn();
1588 return TerminateHandler;
1593 "use getTerminateLandingPad for non-funclet EH");
1596 if (TerminateFunclet)
1597 return TerminateFunclet;
1599 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1604 Builder.SetInsertPoint(TerminateFunclet);
1615 llvm::CallInst *terminateCall =
1617 terminateCall->setDoesNotReturn();
1623 return TerminateFunclet;
1629 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1640 if (RethrowName !=
nullptr && !isCleanup) {
1652 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1653 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1654 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1655 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1657 Builder.CreateResume(LPadVal);
1669 llvm::BasicBlock *TryBB =
nullptr;
1674 TryBB =
Builder.GetInsertBlock();
1687 if (!TryExit.getBlock()->use_empty())
1690 delete TryExit.getBlock();
1700 !
V.insert(BB).second ||
1701 !BB->getParent() || BB->empty())
1704 if (!BB->isEHPad()) {
1705 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1707 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1708 LI->setVolatile(
true);
1709 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1710 SI->setVolatile(
true);
1711 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1712 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1716 const llvm::Instruction *TI = BB->getTerminator();
1718 unsigned N = TI->getNumSuccessors();
1719 for (
unsigned I = 0; I < N; I++)
1726 llvm::Function *OutlinedFinally;
1727 PerformSEHFinally(llvm::Function *OutlinedFinally)
1728 : OutlinedFinally(OutlinedFinally) {}
1738 llvm::Value *FP =
nullptr;
1741 FP = &CGF.
CurFn->arg_begin()[1];
1743 llvm::Function *LocalAddrFn =
1745 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1748 llvm::Value *IsForEH =
1749 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1756 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1759 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1760 IsForEH = CGF.
Builder.CreateICmpNE(Load, Zero);
1784 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1787 bool foundCaptures() {
1788 return !Captures.empty() || SEHCodeSlot.
isValid();
1791 void Visit(
const Stmt *S) {
1794 for (
const Stmt *Child : S->children())
1801 if (
E->refersToEnclosingVariableOrCapture())
1802 Captures.insert(ParentThis);
1804 const auto *
D = dyn_cast<VarDecl>(
E->getDecl());
1805 if (
D &&
D->isLocalVarDeclOrParm() &&
D->hasLocalStorage())
1810 Captures.insert(ParentThis);
1818 unsigned ID =
E->getBuiltinCallee();
1820 case Builtin::BI__exception_code:
1821 case Builtin::BI_exception_code:
1835 llvm::Value *ParentFP) {
1836 llvm::CallInst *RecoverCall =
nullptr;
1838 if (
auto *ParentAlloca =
1839 dyn_cast_or_null<llvm::AllocaInst>(ParentVar.
getBasePointer())) {
1842 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1843 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1844 int FrameEscapeIdx = InsertPair.first->second;
1846 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1848 RecoverCall =
Builder.CreateCall(
1850 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1856 auto *ParentRecover = cast<llvm::IntrinsicInst>(
1858 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1859 "expected alloca or localrecover in parent LocalDeclMap");
1860 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1861 RecoverCall->setArgOperand(1, ParentFP);
1866 llvm::Value *ChildVar =
1868 ChildVar->setName(ParentVar.
getName());
1873 const Stmt *OutlinedStmt,
1877 Finder.Visit(OutlinedStmt);
1881 if (!Finder.foundCaptures() &&
1888 llvm::Value *EntryFP =
nullptr;
1896 {Builder.getInt32(1)});
1900 auto AI =
CurFn->arg_begin();
1905 llvm::Value *ParentFP = EntryFP;
1910 llvm::Function *RecoverFPIntrin =
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().starts_with(
"frame_pointer"));
1930 FramePtrAddrAlloca =
1931 cast<llvm::AllocaInst>(I.second.getBasePointer());
1935 assert(FramePtrAddrAlloca);
1936 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1937 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1938 int FrameEscapeIdx = InsertPair.first->second;
1945 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1947 ParentFP =
Builder.CreateCall(
1949 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1956 for (
const VarDecl *VD : Finder.Captures) {
1962 "captured non-local variable");
1972 auto I =
ParentCGF.LocalDeclMap.find(VD);
1976 Address ParentVar = I->second;
1979 setAddrOfLocalVar(VD, Recovered);
1981 if (isa<ImplicitParamDecl>(VD)) {
1982 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
1983 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
1998 CXXThisValue = CXXABIThisValue;
2003 if (Finder.SEHCodeSlot.isValid()) {
2017 const Stmt *OutlinedStmt) {
2023 llvm::raw_svector_ostream OS(Name);
2025 assert(ParentSEHFn &&
"No CurSEHParent!");
2040 &
getContext().Idents.get(
"exception_pointers"),
2045 &
getContext().Idents.get(
"abnormal_termination"),
2060 llvm::Function *
Fn = llvm::Function::Create(
2061 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.
getModule());
2108 llvm::Value *ParentFP,
2109 llvm::Value *EntryFP) {
2135 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2136 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.
VoidPtrTy);
2140 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2148 return llvm::UndefValue::get(
Int8PtrTy);
2154 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2161 auto AI =
CurFn->arg_begin();
2166 llvm::Function *FinallyFunc) {
2167 EHStack.pushCleanup<PerformSEHFinally>(
Kind, FinallyFunc);
2172 HelperCGF.ParentCGF =
this;
2175 llvm::Function *FinallyFunc =
2176 HelperCGF.GenerateSEHFinallyFunction(*
this, *Finally);
2204 llvm::Function *FilterFunc =
2205 HelperCGF.GenerateSEHFilterFunction(*
this, *Except);
2211 if (S.getFinallyHandler()) {
2224 assert(Except &&
"__try must have __finally xor __except");
2255 llvm::CatchPadInst *CPI =
2256 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
2258 Builder.CreateCatchRet(CPI, ExceptBB);
2263 llvm::Function *SEHCodeIntrin =
2265 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2292 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
llvm::MachO::Target Target
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 ...
CanQualType UnsignedCharTy
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
CXXCatchStmt - This represents a C++ catch block.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CXXTryStmt - A C++ try block, including all handlers.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
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)
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 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...
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,...
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 ...
RawAddress getNormalCleanupDestSlot()
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
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.
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...
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
const TargetInfo & getTarget() const
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
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.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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="")
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
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() 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,...
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
A reference to a declared variable, function, enum, etc.
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
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
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)
The JSON file list parser is used to communicate input to InstallAPI.
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
@ 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,...
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