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));
268 llvm::FunctionType *FTy;
271 FTy = llvm::FunctionType::get(CGM.
Int32Ty, {CGM.VoidPtrTy},
false);
273 FTy = llvm::FunctionType::get(CGM.
Int32Ty,
true);
276 llvm::AttributeList(),
true);
287 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
290 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
291 if (LPI->isCatch(I)) {
293 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
296 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
301 for (llvm::User::op_iterator
302 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
303 if (llvm::GlobalVariable *GV =
307 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
318 for (llvm::User *
U : Fn->users()) {
320 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
321 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
328 llvm::Function *F = dyn_cast<llvm::Function>(
U);
329 if (!F)
return false;
331 for (llvm::BasicBlock &BB : *F) {
332 if (BB.isLandingPad())
345void CodeGenModule::SimplifyPersonality() {
347 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
352 if (!LangOpts.ObjCRuntime.isNeXTFamily())
360 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
361 "Different EHPersonalities using the same personality function.");
366 if (!Fn ||
Fn->use_empty())
return;
376 if (
Fn->getType() != CXXFn.getCallee()->getType())
379 Fn->replaceAllUsesWith(CXXFn.getCallee());
380 Fn->eraseFromParent();
387 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
393 struct FreeException final : EHScopeStack::Cleanup {
395 FreeException(llvm::Value *exn) : exn(exn) {}
396 void Emit(CodeGenFunction &CGF, Flags flags)
override {
453 bool KeepInsertionPoint) {
458 const llvm::Triple &
T =
Target.getTriple();
459 if (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU()) {
464 QualType ThrowType = SubExpr->getType();
468 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
470 CGM.getCXXABI().emitThrow(*
this, E);
473 CGM.getCXXABI().emitRethrow(*
this,
true);
478 if (KeepInsertionPoint)
483 if (!
CGM.getLangOpts().CXXExceptions)
486 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
489 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
507 if (
getTarget().getCXXABI().isMicrosoft())
512 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
517 diag::warn_wasm_dynamic_exception_spec_ignored)
526 if (
getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
527 CGM.getCodeGenOpts().getExceptionHandling() ==
531 diag::warn_wasm_dynamic_exception_spec_ignored)
537 for (
unsigned I = 0; I != NumExceptions; ++I) {
540 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
542 Filter->setFilter(I, EHType);
555 if (!dispatchBlock)
return;
556 if (dispatchBlock->use_empty()) {
557 delete dispatchBlock;
570 llvm::Value *zero = CGF.
Builder.getInt32(0);
571 llvm::Value *failsFilter =
572 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
573 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
585 ->setDoesNotReturn();
586 CGF.
Builder.CreateUnreachable();
590 if (!
CGM.getLangOpts().CXXExceptions)
593 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
596 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
597 if (CD->isNothrow() && !
EHStack.empty())
611 if (
getTarget().getCXXABI().isMicrosoft())
616 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
632 const llvm::Triple &
T =
Target.getTriple();
635 const bool IsTargetDevice =
636 (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU());
648 for (
unsigned I = 0; I != NumHandlers; ++I) {
652 if (
C->getExceptionDecl()) {
660 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
661 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
665 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
667 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
668 CaughtType,
C->getCaughtType());
672 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
688 if (si ==
EHStack.stable_end())
695 if (!dispatchBlock) {
725 return dispatchBlock;
732 if (SI ==
EHStack.stable_end())
740 return DispatchBlock;
750 DispatchBlock->setName(
"catch.dispatch");
754 DispatchBlock->setName(
"ehcleanup");
758 llvm_unreachable(
"exception specifications not handled yet!");
761 DispatchBlock->setName(
"terminate");
765 return DispatchBlock;
781 llvm_unreachable(
"Invalid EHScope Kind!");
785 assert(
EHStack.requiresLandingPad());
793 if (!LO.Exceptions || LO.IgnoreExceptions) {
794 if (!LO.Borland && !LO.MicrosoftExt)
801 if (LO.CUDA && LO.CUDAIsDevice)
806 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
811 if (!
CurFn->hasPersonalityFn())
827 ir->setCachedLandingPad(LP);
835 assert(
EHStack.requiresLandingPad());
836 assert(!
CGM.getLangOpts().IgnoreExceptions &&
837 "LandingPad should not be emitted when -fignore-exceptions are in "
840 switch (innermostEHScope.
getKind()) {
852 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
859 llvm::LandingPadInst *LPadInst =
862 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
864 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
873 bool hasCatchAll =
false;
874 bool hasCleanup =
false;
875 bool hasFilter =
false;
881 switch (I->getKind()) {
888 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
889 assert(!hasCatchAll &&
"EH filter reached after catch-all");
896 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
897 filterTypes.push_back(filter.
getFilter(i));
903 assert(!hasCatchAll);
912 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
915 "landingpads do not support catch handler flags");
919 assert(!hasCatchAll);
925 if (catchTypes.insert(handler.
Type.
RTTI).second)
927 LPadInst->addClause(handler.
Type.
RTTI);
933 assert(!(hasCatchAll && hasFilter));
939 }
else if (hasFilter) {
944 llvm::ArrayType *AType =
945 llvm::ArrayType::get(!filterTypes.empty() ?
949 for (llvm::Value *filterType : filterTypes)
951 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
952 LPadInst->addClause(FilterArray);
956 LPadInst->setCleanup(
true);
959 }
else if (hasCleanup) {
960 LPadInst->setCleanup(
true);
963 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
964 "landingpad instruction has no clauses!");
977 assert(DispatchBlock);
979 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
985 llvm::BasicBlock *UnwindBB =
989 llvm::CatchSwitchInst *CatchSwitch =
990 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
993 for (
unsigned I = 0; I < NumHandlers; ++I) {
1005 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
1010 CatchSwitch->addHandler(Handler.
Block);
1012 CGF.
Builder.restoreIP(SavedIP);
1021 assert(DispatchBlock);
1023 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
1029 llvm::BasicBlock *UnwindBB =
1033 llvm::CatchSwitchInst *CatchSwitch =
1034 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
1038 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
1039 CatchSwitch->addHandler(WasmCatchStartBlock);
1044 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
1049 CatchTypes.push_back(
TypeInfo.RTTI);
1051 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
1056 llvm::Function *GetExnFn =
1058 llvm::Function *GetSelectorFn =
1060 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
1062 llvm::CallInst *
Selector = CGF.
Builder.CreateCall(GetSelectorFn, CPI);
1064 llvm::Function *TypeIDFn =
1071 CGF.
Builder.restoreIP(SavedIP);
1076 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1077 assert(I < E &&
"ran off end of handlers!");
1084 llvm::BasicBlock *NextBlock;
1086 bool EmitNextBlock =
false, NextIsEnd =
false;
1093 EmitNextBlock =
true;
1105 EmitNextBlock =
true;
1109 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
1110 TypeIndex->setDoesNotThrow();
1112 llvm::Value *MatchesTypeIndex =
1114 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1122 CGF.
Builder.restoreIP(SavedIP);
1135 assert(dispatchBlock);
1145 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1149 llvm::Function *llvm_eh_typeid_for =
1151 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1158 assert(i < e &&
"ran off end of handlers!");
1161 llvm::Value *typeValue = handler.
Type.
RTTI;
1163 "landingpads do not support catch handler flags");
1164 assert(typeValue &&
"fell into catch-all case!");
1166 if (typeValue->getType() != argTy)
1171 llvm::BasicBlock *nextBlock;
1192 llvm::CallInst *typeIndex =
1193 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1194 typeIndex->setDoesNotThrow();
1196 llvm::Value *matchesTypeIndex =
1197 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1198 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1202 CGF.
Builder.restoreIP(savedIP);
1236 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1249 bool doImplicitRethrow =
false;
1258 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1262 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1263 ? CatchSwitch->getSuccessor(1)
1264 : CatchSwitch->getSuccessor(0);
1277 bool HasCatchAll =
false;
1278 for (
unsigned I = NumHandlers; I != 0; --I) {
1279 HasCatchAll |= Handlers[I - 1].isCatchAll();
1280 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1292 CGM.getCXXABI().emitBeginCatch(*
this,
C);
1310 CGM.getCXXABI().emitRethrow(*
this,
false);
1312 Builder.ClearInsertionPoint();
1328 assert(WasmCatchStartBlock);
1333 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1334 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1336 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1337 Builder.SetInsertPoint(RethrowBlock);
1338 llvm::Function *RethrowInCatchFn =
1339 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1348 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1349 llvm::Value *ForEHVar;
1350 llvm::FunctionCallee EndCatchFn;
1351 CallEndCatchForFinally(llvm::Value *ForEHVar,
1352 llvm::FunctionCallee EndCatchFn)
1353 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1357 llvm::BasicBlock *CleanupContBB =
1360 llvm::Value *ShouldEndCatch =
1362 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1369 struct PerformFinally final : EHScopeStack::Cleanup {
1371 llvm::Value *ForEHVar;
1372 llvm::FunctionCallee EndCatchFn;
1373 llvm::FunctionCallee RethrowFn;
1374 llvm::Value *SavedExnVar;
1376 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1377 llvm::FunctionCallee EndCatchFn,
1378 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1379 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1380 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1382 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1386 ForEHVar, EndCatchFn);
1390 llvm::Value *SavedCleanupDest =
1392 "cleanup.dest.saved");
1403 llvm::Value *ShouldRethrow =
1405 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1415 CGF.
Builder.CreateUnreachable();
1428 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1430 CGF.
Builder.restoreIP(SavedIP);
1444 llvm::FunctionCallee beginCatchFn,
1445 llvm::FunctionCallee endCatchFn,
1446 llvm::FunctionCallee rethrowFn) {
1447 assert((!!beginCatchFn) == (!!endCatchFn) &&
1448 "begin/end catch functions not paired");
1449 assert(rethrowFn &&
"rethrow function is required");
1451 BeginCatchFn = beginCatchFn;
1459 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1460 SavedExnVar =
nullptr;
1461 if (rethrowFnTy->getNumParams())
1487 ForEHVar, endCatchFn,
1488 rethrowFn, SavedExnVar);
1504 if (catchBB->use_empty()) {
1507 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1510 llvm::Value *exn =
nullptr;
1530 CGF.
Builder.restoreIP(savedIP);
1538 if (TerminateLandingPad)
1539 return TerminateLandingPad;
1541 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1545 Builder.SetInsertPoint(TerminateLandingPad);
1550 if (!
CurFn->hasPersonalityFn())
1553 llvm::LandingPadInst *LPadInst =
1557 llvm::Value *Exn =
nullptr;
1559 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1560 llvm::CallInst *terminateCall =
1561 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1562 terminateCall->setDoesNotReturn();
1568 return TerminateLandingPad;
1572 if (TerminateHandler)
1573 return TerminateHandler;
1578 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1579 Builder.SetInsertPoint(TerminateHandler);
1581 llvm::Value *Exn =
nullptr;
1584 llvm::CallInst *terminateCall =
1585 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1586 terminateCall->setDoesNotReturn();
1592 return TerminateHandler;
1597 "use getTerminateLandingPad for non-funclet EH");
1600 if (TerminateFunclet)
1601 return TerminateFunclet;
1603 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1608 Builder.SetInsertPoint(TerminateFunclet);
1615 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1619 llvm::CallInst *terminateCall =
1620 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1621 terminateCall->setDoesNotReturn();
1627 return TerminateFunclet;
1633 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1644 if (RethrowName !=
nullptr && !isCleanup) {
1656 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1657 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1658 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1659 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1661 Builder.CreateResume(LPadVal);
1673 llvm::BasicBlock *TryBB =
nullptr;
1678 TryBB =
Builder.GetInsertBlock();
1691 if (!TryExit.
getBlock()->use_empty())
1704 !
V.insert(BB).second ||
1705 !BB->getParent() || BB->empty())
1708 if (!BB->isEHPad()) {
1709 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1711 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1712 LI->setVolatile(
true);
1713 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1714 SI->setVolatile(
true);
1715 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1716 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1720 if (
const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
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::Value *RecoverCall =
nullptr;
1845 auto *ParentAlloca =
1849 if (!ParentAlloca) {
1851 llvm::BasicBlock &EntryBB =
ParentCGF.CurFn->getEntryBlock();
1852 llvm::IRBuilder<> ParentEntryBuilder(&EntryBB, EntryBB.begin());
1853 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1854 ParentArg->getType(),
nullptr, ParentArg->getName() +
".spill");
1855 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1862 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1863 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1864 int FrameEscapeIdx = InsertPair.first->second;
1866 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1867 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1868 RecoverCall =
Builder.CreateCall(
1869 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1870 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1872 RecoverCall =
Builder.CreateLoad(
1880 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1881 "expected alloca or localrecover in parent LocalDeclMap");
1882 RecoverCall = ParentRecover->clone();
1889 llvm::Value *ChildVar =
1891 ChildVar->setName(ParentVar.
getName());
1896 const Stmt *OutlinedStmt,
1900 Finder.Visit(OutlinedStmt);
1904 if (!Finder.foundCaptures() &&
1905 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1911 llvm::Value *EntryFP =
nullptr;
1913 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1919 {Builder.getInt32(1)});
1923 auto AI =
CurFn->arg_begin();
1928 llvm::Value *ParentFP = EntryFP;
1933 llvm::Function *RecoverFPIntrin =
1934 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1935 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1947 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1948 for (
auto &I :
ParentCGF.LocalDeclMap) {
1952 assert(D->
getName().starts_with(
"frame_pointer"));
1953 FramePtrAddrAlloca =
1958 assert(FramePtrAddrAlloca);
1959 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1960 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1961 int FrameEscapeIdx = InsertPair.first->second;
1968 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1969 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1970 ParentFP =
Builder.CreateCall(
1971 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1972 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1973 ParentFP =
Builder.CreateLoad(
1979 for (
const VarDecl *VD : Finder.Captures) {
1981 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1985 "captured non-local variable");
1987 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1988 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
1995 auto I =
ParentCGF.LocalDeclMap.find(VD);
1999 Address ParentVar = I->second;
2002 setAddrOfLocalVar(VD, Recovered);
2005 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
2006 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
2007 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
2021 CXXThisValue = CXXABIThisValue;
2026 if (Finder.SEHCodeSlot.
isValid()) {
2040 const Stmt *OutlinedStmt) {
2046 llvm::raw_svector_ostream OS(Name);
2048 assert(ParentSEHFn &&
"No CurSEHParent!");
2057 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
2063 &
getContext().Idents.get(
"exception_pointers"),
2068 &
getContext().Idents.get(
"abnormal_termination"),
2080 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
2082 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
2083 llvm::Function *Fn = llvm::Function::Create(
2084 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2131 llvm::Value *ParentFP,
2132 llvm::Value *EntryFP) {
2135 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2158 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2159 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2163 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2171 return llvm::PoisonValue::get(
Int8PtrTy);
2177 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2184 auto AI =
CurFn->arg_begin();
2189 llvm::Function *FinallyFunc) {
2190 EHStack.pushCleanup<PerformSEHFinally>(
2195 CodeGenFunction HelperCGF(
CGM,
true);
2199 llvm::Function *FinallyFunc =
2221 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2229 llvm::Function *FilterFunc =
2249 assert(Except &&
"__try must have __finally xor __except");
2261 if (
const auto *DS = dyn_cast<DeclStmt>(S))
2262 for (
const Decl *D : DS->decls())
2263 if (
const auto *VD = dyn_cast<VarDecl>(D))
2266 VD->getLocation(), diag::err_seh_object_unwinding);
2291 llvm::CatchPadInst *CPI =
2294 Builder.CreateCatchRet(CPI, ExceptBB);
2298 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2299 llvm::Function *SEHCodeIntrin =
2300 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2301 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2328 Builder.ClearInsertionPoint();
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)
Emit the dispatch block for a filter scope if necessary.
static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)
static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function.
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
Emit the structure of the dispatch block for the given catch scope.
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
static bool isNonEHScope(const EHScope &S)
Check whether this is a non-EH scope, i.e.
static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
Returns the value to inject into a selector to indicate the presence of a catch-all.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
llvm::MachO::Target Target
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
DiagnosticsEngine & getDiagnostics() const
CXXCatchStmt - This represents a C++ catch block.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CXXCatchStmt * getHandler(unsigned i)
unsigned getNumHandlers() const
CompoundStmt * getTryBlock()
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
Represents the body of a CapturedStmt, and serves as its DeclContext.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
bool hasDWARFExceptions() const
bool hasWasmExceptions() const
bool hasSjLjExceptions() const
bool hasSEHExceptions() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::PointerType * getType() const
Return the type of the pointer value.
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void exit(CodeGenFunction &CGF)
void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn)
Enters a finally block for an implementation using zero-cost exceptions.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitCXXTryStmt(const CXXTryStmt &S)
llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::Value * getSelectorFromSlot()
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)
llvm::BasicBlock * getInvokeDestImpl()
llvm::Type * ConvertType(QualType T)
FieldDecl * LambdaThisCaptureField
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::Value * EmitSEHAbnormalTermination()
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
llvm::AllocaInst * EHSelectorSlot
The selector slot.
llvm::BasicBlock * EmitLandingPad()
Emits a landing pad for the current EH stack.
void EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::BasicBlock * getUnreachableBlock()
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
bool currentFunctionUsesSEHTry() const
llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack
CodeGenFunction * ParentCGF
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
llvm::Value * ExceptionSlot
The exception slot.
void EmitAnyExprToExn(const Expr *E, Address Addr)
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
const TargetInfo & getTarget() const
llvm::BasicBlock * getTerminateHandler()
getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...
void EnterSEHTryStmt(const SEHTryStmt &S)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
llvm::Value * EmitSEHExceptionCode()
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
Arrange a function prototype that can be called by Windows exception handling personalities.
void EmitSehTryScopeBegin()
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
Scan the outlined statement for captures from the parent function.
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
RawAddress getNormalCleanupDestSlot()
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertTypeForMem(QualType T)
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
void ExitSEHTryStmt(const SEHTryStmt &S)
LValue EmitLValueForLambdaField(const FieldDecl *Field)
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
const TargetInfo & Target
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitSEHExceptionInfo()
void EmitSEHTryStmt(const SEHTryStmt &S)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
Address getEHSelectorSlot()
llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)
Create a stub filter function that will ultimately hold the code of the filter expression.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
CGCXXABI & getCXXABI() const
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
A scope which attempts to handle some, possibly all, types of exceptions.
const Handler & getHandler(unsigned I) const
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
void clearHandlerBlocks()
unsigned getNumHandlers() const
An exceptions scope which filters exceptions thrown through it.
llvm::Value * getFilter(unsigned i) const
unsigned getNumFilters() const
A non-stable pointer into the scope stack.
A saved depth on the scope stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
A protected scope for zero-cost EH handling.
llvm::BasicBlock * getCachedLandingPad() const
EHScopeStack::stable_iterator getEnclosingEHScope() const
llvm::BasicBlock * getCachedEHDispatchBlock() const
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
bool hasEHBranches() const
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
Address getAddress() const
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
bool usesSEHTry() const
Indicates the function uses __try.
SourceRange getExceptionSpecSourceRange() const
Attempt to compute an informative source range covering the function exception specification,...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
unsigned getNumExceptions() const
Return the number of types in the exception specification.
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents Objective-C's @throw statement.
const VersionTuple & getVersion() const
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
CompoundStmt * getBlock() const
Expr * getFilterExpr() const
CompoundStmt * getBlock() const
Represents a __leave statement.
CompoundStmt * getTryBlock() const
SEHFinallyStmt * getFinallyHandler() const
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ NormalAndEHSEHFinallyCleanup
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
@ Address
A pointer to a ValueDecl.
bool Load(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_Dynamic
throw(T1, T2)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
llvm::PointerType * VoidPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::PointerType * AllocaInt8PtrTy
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
llvm::BasicBlock * Block
The catch handler for this type.
The exceptions personality for a function.
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
static const EHPersonality XL_CPlusPlus
static const EHPersonality GNU_ObjC_SJLJ
bool isWasmPersonality() const
static const EHPersonality ZOS_CPlusPlus
static const EHPersonality GNUstep_ObjC
static const EHPersonality MSVC_CxxFrameHandler3
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
static const EHPersonality MSVC_C_specific_handler
static const EHPersonality GNU_CPlusPlus_SEH
static const EHPersonality GNU_ObjC
static const EHPersonality GNU_CPlusPlus_SJLJ
static const EHPersonality GNU_C_SJLJ
static const EHPersonality GNU_C
static const EHPersonality NeXT_ObjC
const char * CatchallRethrowFn
static const EHPersonality GNU_CPlusPlus
static const EHPersonality GNU_ObjCXX
static const EHPersonality GNU_C_SEH
static const EHPersonality MSVC_except_handler
static const EHPersonality GNU_ObjC_SEH
const char * PersonalityFn
static const EHPersonality GNU_Wasm_CPlusPlus