24 #include "llvm/IR/IntrinsicInst.h" 25 #include "llvm/IR/Intrinsics.h" 26 #include "llvm/IR/IntrinsicsWebAssembly.h" 27 #include "llvm/Support/SaveAndRestore.h" 29 using namespace clang;
30 using namespace CodeGen;
35 llvm::FunctionType *FTy =
44 llvm::FunctionType *FTy =
53 llvm::FunctionType *FTy =
54 llvm::FunctionType::get(
VoidTy,
false);
61 name =
"_ZSt9terminatev";
65 name =
"__std_terminate";
67 name =
"?terminate@@YAXXZ";
70 name =
"objc_terminate";
78 llvm::FunctionType *FTy =
118 const llvm::Triple &T = Target.
getTriple();
119 if (T.isWindowsMSVCEnvironment())
120 return EHPersonality::MSVC_CxxFrameHandler3;
121 if (L.SjLjExceptions)
123 if (L.DWARFExceptions)
132 const llvm::Triple &T = Target.
getTriple();
133 if (T.isWindowsMSVCEnvironment())
134 return EHPersonality::MSVC_CxxFrameHandler3;
145 return EHPersonality::GNUstep_ObjC;
149 if (L.SjLjExceptions)
155 llvm_unreachable(
"bad runtime kind");
160 const llvm::Triple &T = Target.
getTriple();
161 if (T.isWindowsMSVCEnvironment())
162 return EHPersonality::MSVC_CxxFrameHandler3;
163 if (L.SjLjExceptions)
165 if (L.DWARFExceptions)
169 if (L.WasmExceptions)
178 if (Target.
getTriple().isWindowsMSVCEnvironment())
179 return EHPersonality::MSVC_CxxFrameHandler3;
204 llvm_unreachable(
"bad runtime kind");
208 if (T.getArch() == llvm::Triple::x86)
209 return EHPersonality::MSVC_except_handler;
236 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
243 llvm::AttributeList(),
true);
249 llvm::PointerType*
Int8PtrTy = llvm::PointerType::get(
253 return llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(Fn.getCallee()),
259 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
262 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
263 if (LPI->isCatch(I)) {
265 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
268 if (GV->getName().startswith(
"OBJC_EHTYPE"))
272 llvm::Constant *CVal = cast<llvm::Constant>(Val);
273 for (llvm::User::op_iterator
274 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
275 if (llvm::GlobalVariable *GV =
276 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
279 if (GV->getName().startswith(
"OBJC_EHTYPE"))
290 for (llvm::User *U : Fn->users()) {
292 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
293 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
300 llvm::Function *F = dyn_cast<llvm::Function>(U);
301 if (!F)
return false;
303 for (
auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
304 if (BB->isLandingPad())
317 void CodeGenModule::SimplifyPersonality() {
319 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
333 "Different EHPersonalities using the same personality function.");
338 if (!Fn || Fn->use_empty())
return;
348 if (Fn->getType() != CXXFn.getCallee()->getType())
351 Fn->replaceAllUsesWith(CXXFn.getCallee());
352 Fn->eraseFromParent();
359 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
387 Address typedAddr = Builder.CreateBitCast(addr, ty);
400 DeactivateCleanupBlock(cleanup,
401 cast<llvm::Instruction>(typedAddr.
getPointer()));
406 ExceptionSlot = CreateTempAlloca(
Int8PtrTy,
"exn.slot");
412 EHSelectorSlot = CreateTempAlloca(
Int32Ty,
"ehselector.slot");
417 return Builder.CreateLoad(getExceptionSlot(),
"exn");
421 return Builder.CreateLoad(getEHSelectorSlot(),
"sel");
425 bool KeepInsertionPoint) {
427 QualType ThrowType = SubExpr->getType();
431 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
433 CGM.getCXXABI().emitThrow(*
this, E);
436 CGM.getCXXABI().emitRethrow(*
this,
true);
441 if (KeepInsertionPoint)
442 EmitBlock(createBasicBlock(
"throw.cont"));
446 if (!CGM.getLangOpts().CXXExceptions)
449 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
452 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
454 EHStack.pushTerminate();
465 EHStack.pushTerminate();
474 for (
unsigned I = 0; I != NumExceptions; ++I) {
477 llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
488 if (!dispatchBlock)
return;
489 if (dispatchBlock->use_empty()) {
490 delete dispatchBlock;
505 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
506 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
518 ->setDoesNotReturn();
519 CGF.
Builder.CreateUnreachable();
523 if (!CGM.getLangOpts().CXXExceptions)
526 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
529 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
531 EHStack.popTerminate();
541 EHStack.popTerminate();
547 EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
561 EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
563 for (
unsigned I = 0; I != NumHandlers; ++I) {
566 llvm::BasicBlock *Handler = createBasicBlock(
"catch");
575 QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
580 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
582 TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
587 CatchScope->
setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
595 return getFuncletEHDispatchBlock(si);
599 if (si == EHStack.stable_end())
600 return getEHResumeBlock(
true);
603 EHScope &scope = *EHStack.find(si);
606 if (!dispatchBlock) {
617 dispatchBlock = createBasicBlock(
"catch.dispatch");
623 dispatchBlock = createBasicBlock(
"ehcleanup");
627 dispatchBlock = createBasicBlock(
"filter.dispatch");
631 dispatchBlock = getTerminateHandler();
635 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
639 return dispatchBlock;
646 if (SI == EHStack.stable_end())
650 EHScope &EHS = *EHStack.find(SI);
654 return DispatchBlock;
657 DispatchBlock = getTerminateFunclet();
659 DispatchBlock = createBasicBlock();
664 DispatchBlock->setName(
"catch.dispatch");
668 DispatchBlock->setName(
"ehcleanup");
672 llvm_unreachable(
"exception specifications not handled yet!");
675 DispatchBlock->setName(
"terminate");
679 llvm_unreachable(
"PadEnd dispatch block missing!");
682 return DispatchBlock;
691 return !cast<EHCleanupScope>(S).isEHCleanup();
699 llvm_unreachable(
"Invalid EHScope Kind!");
703 assert(EHStack.requiresLandingPad());
704 assert(!EHStack.empty());
711 if (!LO.Exceptions) {
712 if (!LO.Borland && !LO.MicrosoftExt)
714 if (!currentFunctionUsesSEHTry())
719 if (LO.CUDA && LO.CUDAIsDevice)
724 llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
729 if (!CurFn->hasPersonalityFn())
734 LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
737 LP = EmitLandingPad();
745 ir->setCachedLandingPad(LP);
753 assert(EHStack.requiresLandingPad());
755 EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
756 switch (innermostEHScope.getKind()) {
758 return getTerminateLandingPad();
761 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
766 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
771 CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
775 llvm::BasicBlock *lpad = createBasicBlock(
"lpad");
778 llvm::LandingPadInst *LPadInst =
781 llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
782 Builder.CreateStore(LPadExn, getExceptionSlot());
783 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
784 Builder.CreateStore(LPadSel, getEHSelectorSlot());
792 bool hasCatchAll =
false;
793 bool hasCleanup =
false;
794 bool hasFilter =
false;
796 llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
800 switch (I->getKind()) {
803 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
807 assert(I.next() == EHStack.end() &&
"EH filter is not end of EH stack");
808 assert(!hasCatchAll &&
"EH filter reached after catch-all");
815 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
816 filterTypes.push_back(filter.
getFilter(i));
822 assert(!hasCatchAll);
830 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
834 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
837 "landingpads do not support catch handler flags");
841 assert(!hasCatchAll);
847 if (catchTypes.insert(handler.
Type.
RTTI).second)
849 LPadInst->addClause(handler.
Type.
RTTI);
855 assert(!(hasCatchAll && hasFilter));
861 }
else if (hasFilter) {
866 llvm::ArrayType *AType =
867 llvm::ArrayType::get(!filterTypes.empty() ?
871 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
872 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
873 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
874 LPadInst->addClause(FilterArray);
878 LPadInst->setCleanup(
true);
881 }
else if (hasCleanup) {
882 LPadInst->setCleanup(
true);
885 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
886 "landingpad instruction has no clauses!");
889 Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
892 Builder.restoreIP(savedIP);
899 assert(DispatchBlock);
901 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
907 llvm::BasicBlock *UnwindBB =
911 llvm::CatchSwitchInst *CatchSwitch =
912 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
915 for (
unsigned I = 0; I < NumHandlers; ++I) {
927 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
929 CGF.
Builder.CreateCatchPad(CatchSwitch, {TypeInfo.
RTTI});
932 CatchSwitch->addHandler(Handler.
Block);
934 CGF.
Builder.restoreIP(SavedIP);
943 assert(DispatchBlock);
945 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
951 llvm::BasicBlock *UnwindBB =
955 llvm::CatchSwitchInst *CatchSwitch =
956 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
960 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
961 CatchSwitch->addHandler(WasmCatchStartBlock);
966 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
971 CatchTypes.push_back(TypeInfo.
RTTI);
973 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
978 llvm::Function *GetExnFn =
980 llvm::Function *GetSelectorFn =
982 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
986 llvm::Function *TypeIDFn = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::eh_typeid_for);
992 CGF.
Builder.restoreIP(SavedIP);
997 for (
unsigned I = 0, E = NumHandlers;; ++I) {
998 assert(I < E &&
"ran off end of handlers!");
1002 TypeInfo.
RTTI = llvm::Constant::getNullValue(CGF.
VoidPtrTy);
1005 llvm::BasicBlock *NextBlock;
1007 bool EmitNextBlock =
false, NextIsEnd =
false;
1014 EmitNextBlock =
true;
1026 EmitNextBlock =
true;
1030 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn, TypeInfo.
RTTI);
1031 TypeIndex->setDoesNotThrow();
1034 CGF.
Builder.CreateICmpEQ(Selector, TypeIndex,
"matches");
1035 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1043 CGF.
Builder.restoreIP(SavedIP);
1056 assert(dispatchBlock);
1066 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1070 llvm::Function *llvm_eh_typeid_for =
1078 assert(i < e &&
"ran off end of handlers!");
1083 "landingpads do not support catch handler flags");
1084 assert(typeValue &&
"fell into catch-all case!");
1089 llvm::BasicBlock *nextBlock;
1110 llvm::CallInst *typeIndex =
1111 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1112 typeIndex->setDoesNotThrow();
1115 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1116 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1120 CGF.
Builder.restoreIP(savedIP);
1129 EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1137 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1154 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1159 llvm::BasicBlock *ContBB = createBasicBlock(
"try.cont");
1162 if (HaveInsertPoint())
1163 Builder.CreateBr(ContBB);
1167 bool doImplicitRethrow =
false;
1169 doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1170 isa<CXXConstructorDecl>(CurCodeDecl);
1177 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1180 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHI());
1181 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1182 ? CatchSwitch->getSuccessor(1)
1183 : CatchSwitch->getSuccessor(0);
1184 auto *CPI = cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHI());
1185 CurrentFuncletPad = CPI;
1195 bool HasCatchAll =
false;
1196 for (
unsigned I = NumHandlers; I != 0; --I) {
1197 HasCatchAll |= Handlers[I - 1].isCatchAll();
1198 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1199 EmitBlockAfterUses(CatchBlock);
1211 CGM.getCXXABI().emitBeginCatch(*
this, C);
1214 incrementProfileCounter(C);
1228 if (doImplicitRethrow && HaveInsertPoint()) {
1229 CGM.getCXXABI().emitRethrow(*
this,
false);
1230 Builder.CreateUnreachable();
1231 Builder.ClearInsertionPoint();
1238 if (HaveInsertPoint())
1239 Builder.CreateBr(ContBB);
1247 assert(WasmCatchStartBlock);
1252 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1253 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1254 auto *BI = cast<llvm::BranchInst>(TI);
1255 assert(BI->isConditional());
1256 RethrowBlock = BI->getSuccessor(1);
1258 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1259 Builder.SetInsertPoint(RethrowBlock);
1260 llvm::Function *RethrowInCatchFn =
1261 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow_in_catch);
1262 EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
1266 incrementProfileCounter(&S);
1272 llvm::FunctionCallee EndCatchFn;
1274 llvm::FunctionCallee EndCatchFn)
1275 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1279 llvm::BasicBlock *CleanupContBB =
1284 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1294 llvm::FunctionCallee EndCatchFn;
1295 llvm::FunctionCallee RethrowFn;
1299 llvm::FunctionCallee EndCatchFn,
1300 llvm::FunctionCallee RethrowFn,
llvm::Value *SavedExnVar)
1301 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1302 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1308 ForEHVar, EndCatchFn);
1314 "cleanup.dest.saved");
1327 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1336 CGF.
Builder.CreateUnreachable();
1349 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1351 CGF.
Builder.restoreIP(SavedIP);
1365 llvm::FunctionCallee beginCatchFn,
1366 llvm::FunctionCallee endCatchFn,
1367 llvm::FunctionCallee rethrowFn) {
1368 assert((!!beginCatchFn) == (!!endCatchFn) &&
1369 "begin/end catch functions not paired");
1370 assert(rethrowFn &&
"rethrow function is required");
1372 BeginCatchFn = beginCatchFn;
1380 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1381 SavedExnVar =
nullptr;
1382 if (rethrowFnTy->getNumParams())
1408 ForEHVar, endCatchFn,
1409 rethrowFn, SavedExnVar);
1425 if (catchBB->use_empty()) {
1428 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1451 CGF.
Builder.restoreIP(savedIP);
1459 if (TerminateLandingPad)
1460 return TerminateLandingPad;
1462 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1465 TerminateLandingPad = createBasicBlock(
"terminate.lpad");
1466 Builder.SetInsertPoint(TerminateLandingPad);
1471 if (!CurFn->hasPersonalityFn())
1474 llvm::LandingPadInst *LPadInst =
1480 Exn = Builder.CreateExtractValue(LPadInst, 0);
1481 llvm::CallInst *terminateCall =
1482 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1483 terminateCall->setDoesNotReturn();
1484 Builder.CreateUnreachable();
1487 Builder.restoreIP(SavedIP);
1489 return TerminateLandingPad;
1493 if (TerminateHandler)
1494 return TerminateHandler;
1498 TerminateHandler = createBasicBlock(
"terminate.handler");
1499 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1500 Builder.SetInsertPoint(TerminateHandler);
1504 Exn = getExceptionFromSlot();
1505 llvm::CallInst *terminateCall =
1506 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1507 terminateCall->setDoesNotReturn();
1508 Builder.CreateUnreachable();
1511 Builder.restoreIP(SavedIP);
1513 return TerminateHandler;
1518 "use getTerminateLandingPad for non-funclet EH");
1520 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1521 if (TerminateFunclet)
1522 return TerminateFunclet;
1524 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1528 TerminateFunclet = createBasicBlock(
"terminate.handler");
1529 Builder.SetInsertPoint(TerminateFunclet);
1537 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1538 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1546 llvm::Function *GetExnFn =
1547 CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
1548 Exn = Builder.CreateCall(GetExnFn, CurrentFuncletPad);
1550 llvm::CallInst *terminateCall =
1551 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1552 terminateCall->setDoesNotReturn();
1553 Builder.CreateUnreachable();
1556 Builder.restoreIP(SavedIP);
1558 return TerminateFunclet;
1562 if (EHResumeBlock)
return EHResumeBlock;
1564 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1567 EHResumeBlock = createBasicBlock(
"eh.resume");
1568 Builder.SetInsertPoint(EHResumeBlock);
1575 if (RethrowName !=
nullptr && !isCleanup) {
1577 getExceptionFromSlot())->setDoesNotReturn();
1578 Builder.CreateUnreachable();
1579 Builder.restoreIP(SavedIP);
1580 return EHResumeBlock;
1587 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1588 llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1589 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1590 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1592 Builder.CreateResume(LPadVal);
1593 Builder.restoreIP(SavedIP);
1594 return EHResumeBlock;
1600 JumpDest TryExit = getJumpDestInCurrentScope(
"__try.__leave");
1602 SEHTryEpilogueStack.push_back(&TryExit);
1604 SEHTryEpilogueStack.pop_back();
1606 if (!TryExit.
getBlock()->use_empty())
1607 EmitBlock(TryExit.
getBlock(),
true);
1616 llvm::Function *OutlinedFinally;
1617 PerformSEHFinally(llvm::Function *OutlinedFinally)
1618 : OutlinedFinally(OutlinedFinally) {}
1631 FP = &CGF.
CurFn->arg_begin()[1];
1633 llvm::Function *LocalAddrFn =
1635 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1639 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1661 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1664 bool foundCaptures() {
1665 return !Captures.empty() || SEHCodeSlot.
isValid();
1668 void Visit(
const Stmt *S) {
1679 Captures.insert(ParentThis);
1684 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1689 Captures.insert(ParentThis);
1692 void VisitCallExpr(
const CallExpr *E) {
1699 case Builtin::BI__exception_code:
1700 case Builtin::BI_exception_code:
1715 llvm::CallInst *RecoverCall =
nullptr;
1717 if (
auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.
getPointer())) {
1720 auto InsertPair = ParentCGF.EscapedLocals.insert(
1721 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1722 int FrameEscapeIdx = InsertPair.first->second;
1724 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1725 &CGM.getModule(), llvm::Intrinsic::localrecover);
1726 llvm::Constant *ParentI8Fn =
1728 RecoverCall = Builder.CreateCall(
1729 FrameRecoverFn, {ParentI8Fn, ParentFP,
1730 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1736 auto *ParentRecover =
1737 cast<llvm::IntrinsicInst>(ParentVar.
getPointer()->stripPointerCasts());
1738 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1739 "expected alloca or localrecover in parent LocalDeclMap");
1740 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1741 RecoverCall->setArgOperand(1, ParentFP);
1742 RecoverCall->insertBefore(AllocaInsertPt);
1748 ChildVar->setName(ParentVar.
getName());
1753 const Stmt *OutlinedStmt,
1756 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1757 Finder.Visit(OutlinedStmt);
1761 if (!Finder.foundCaptures() &&
1762 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1764 EmitSEHExceptionCodeSave(ParentCGF,
nullptr,
nullptr);
1770 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1774 EntryFP = Builder.CreateCall(
1776 {Builder.getInt32(1)});
1780 auto AI = CurFn->arg_begin();
1790 llvm::Function *RecoverFPIntrin =
1791 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1792 llvm::Constant *ParentI8Fn =
1794 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
1798 for (
const VarDecl *VD : Finder.Captures) {
1799 if (isa<ImplicitParamDecl>(VD)) {
1800 CGM.ErrorUnsupported(VD,
"'this' captured by SEH");
1801 CXXThisValue = llvm::UndefValue::get(ConvertTypeForMem(VD->
getType()));
1805 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1809 "captured non-local variable");
1813 auto I = ParentCGF.LocalDeclMap.find(VD);
1814 if (I == ParentCGF.LocalDeclMap.end())
1817 Address ParentVar = I->second;
1819 VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
1822 if (Finder.SEHCodeSlot.isValid()) {
1823 SEHCodeSlotStack.push_back(
1824 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
1828 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
1836 const Stmt *OutlinedStmt) {
1842 llvm::raw_svector_ostream OS(Name);
1844 assert(ParentSEHFn &&
"No CurSEHParent!");
1845 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
1853 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
1859 &
getContext().Idents.get(
"exception_pointers"),
1864 &
getContext().Idents.get(
"abnormal_termination"),
1876 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
1878 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
1882 IsOutlinedSEHHelper =
true;
1884 StartFunction(
GlobalDecl(), RetTy, Fn, FnInfo, Args,
1888 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FnInfo, CurFn);
1889 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
1899 startOutlinedSEHHelper(ParentCGF,
true, FilterExpr);
1903 R = Builder.CreateIntCast(R, ConvertType(
getContext().LongTy),
1907 FinishFunction(FilterExpr->
getEndLoc());
1916 startOutlinedSEHHelper(ParentCGF,
false, FinallyBlock);
1919 EmitStmt(FinallyBlock);
1921 FinishFunction(FinallyBlock->
getEndLoc());
1931 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1933 SEHInfo = &*CurFn->arg_begin();
1934 SEHCodeSlotStack.push_back(
1941 SEHInfo = Builder.CreateConstInBoundsGEP1_32(
Int8Ty, EntryFP, -20);
1942 SEHInfo = Builder.CreateBitCast(SEHInfo,
Int8PtrTy->getPointerTo());
1944 SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
1955 llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
1956 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
1957 llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
1958 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
1961 assert(!SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1962 Builder.CreateStore(Code, SEHCodeSlotStack.back());
1969 return llvm::UndefValue::get(
Int8PtrTy);
1970 assert(SEHInfo->getType() ==
Int8PtrTy);
1975 assert(!SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1976 return Builder.CreateLoad(SEHCodeSlotStack.back());
1982 auto AI = CurFn->arg_begin();
1983 return Builder.CreateZExt(&*AI,
Int32Ty);
1987 llvm::Function *FinallyFunc) {
1988 EHStack.pushCleanup<PerformSEHFinally>(
Kind, FinallyFunc);
1995 llvm::Function *FinallyFunc =
2007 SEHCodeSlotStack.push_back(
2016 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2024 llvm::Function *FilterFunc =
2026 llvm::Constant *OpaqueFunc =
2027 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
2028 CatchScope->
setHandler(0, OpaqueFunc, createBasicBlock(
"__except.ret"));
2040 assert(Except &&
"__try must have __finally xor __except");
2041 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2049 SEHCodeSlotStack.pop_back();
2054 llvm::BasicBlock *ContBB = createBasicBlock(
"__try.cont");
2057 if (HaveInsertPoint())
2058 Builder.CreateBr(ContBB);
2067 EmitBlockAfterUses(CatchPadBB);
2071 llvm::CatchPadInst *CPI =
2072 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
2073 llvm::BasicBlock *ExceptBB = createBasicBlock(
"__except");
2074 Builder.CreateCatchRet(CPI, ExceptBB);
2075 EmitBlock(ExceptBB);
2078 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2079 llvm::Function *SEHCodeIntrin =
2080 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2081 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2082 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2089 SEHCodeSlotStack.pop_back();
2091 if (HaveInsertPoint())
2092 Builder.CreateBr(ContBB);
2101 if (HaveInsertPoint())
2106 if (!isSEHTryScope()) {
2107 Builder.CreateUnreachable();
2108 Builder.ClearInsertionPoint();
2112 EmitBranchThroughCleanup(*SEHTryEpilogueStack.back());
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)
Represents a function declaration or definition.
llvm::IntegerType * IntTy
int
EHScopeStack::stable_iterator getEnclosingEHScope() const
CharUnits getIntAlign() const
Other implicit parameter.
CompoundStmt * getBlock() const
Smart pointer class that efficiently represents Objective-C method names.
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
A (possibly-)qualified type.
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
CodeGenTypes & getTypes()
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets...
unsigned getNumExceptions() const
Return the number of types in the exception specification.
const Expr * getSubExpr() const
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
llvm::BasicBlock * getCachedEHDispatchBlock() const
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::LLVMContext & getLLVMContext()
static const EHPersonality GNU_C_SJLJ
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.
void EmitCXXTryStmt(const CXXTryStmt &S)
Stmt - This represents one statement.
CXXCatchStmt * getHandler(unsigned i)
static const EHPersonality MSVC_C_specific_handler
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
static const EHPersonality MSVC_CxxFrameHandler3
bool hasEHBranches() const
Decl - This represents one declaration (or definition), e.g.
Stmt * getHandlerBlock() const
void clearHandlerBlocks()
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Address getEHSelectorSlot()
static const EHPersonality GNU_C
virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents Objective-C's @throw statement.
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
bool usesSEHTry() const
Indicates the function uses __try.
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...
unsigned getNumFilters() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI ...
bool ReturnValue(const T &V, APValue &R)
Convers a value to an APValue.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
unsigned getNumHandlers() const
llvm::Value * getPointer() const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
llvm::BasicBlock * EmitLandingPad()
Emits a landing pad for the current EH stack.
A protected scope for zero-cost EH handling.
Defines the Objective-C statement AST node classes.
A C++ throw-expression (C++ [except.throw]).
static const EHPersonality & getObjCPersonality(const TargetInfo &Target, const LangOptions &L)
A scope which attempts to handle some, possibly all, types of exceptions.
The collection of all-type qualifiers we support.
void add(RValue rvalue, QualType type)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
const TargetInfo & getTarget() const
llvm::BasicBlock * getTerminateHandler()
getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
const char * CatchallRethrowFn
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
const NamedDecl * CurSEHParent
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getCaughtType() const
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
SourceLocation getBeginLoc() const LLVM_READONLY
static const EHPersonality GNU_CPlusPlus_SJLJ
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
void setFilter(unsigned i, llvm::Value *filterValue)
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
bool isNeXTFamily() const
Is this runtime basically of the NeXT family of runtimes?
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
Returns the value to inject into a selector to indicate the presence of a catch-all.
void ExitSEHTryStmt(const SEHTryStmt &S)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::PointerType * VoidPtrTy
const Handler & getHandler(unsigned I) const
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)
static const EHPersonality GNUstep_ObjC
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::BasicBlock * getInvokeDestImpl()
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CharUnits getPointerAlign() const
Represents the body of a CapturedStmt, and serves as its DeclContext.
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...
CanQualType UnsignedCharTy
llvm::Value * EmitSEHExceptionCode()
Represents the this expression in C++.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
'watchos' is a variant of iOS for Apple's watchOS.
static const EHPersonality & getCPersonality(const TargetInfo &Target, const LangOptions &L)
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
static const EHPersonality MSVC_except_handler
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
Exposes information about the current target.
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
Scan the outlined statement for captures from the parent function.
This represents one expression.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function...
static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)
Create a stub filter function that will ultimately hold the code of the filter expression.
llvm::BasicBlock * getBlock() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
llvm::Value * EmitSEHExceptionInfo()
VarDecl * getExceptionDecl() const
llvm::PointerType * getType() const
Return the type of the pointer value.
void EmitSEHTryStmt(const SEHTryStmt &S)
llvm::Value * getSelectorFromSlot()
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
llvm::BasicBlock * Block
The catch handler for this type.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CXXTryStmt - A C++ try block, including all handlers.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
Emit the structure of the dispatch block for the given catch scope.
llvm::LLVMContext & getLLVMContext()
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
llvm::IntegerType * Int32Ty
static const EHPersonality GNU_ObjCXX
bool hasTerminate() const
Does this runtime provide an objc_terminate function?
clang::ObjCRuntime ObjCRuntime
llvm::PointerType * AllocaInt8PtrTy
static const EHPersonality GNU_ObjC_SEH
const TargetInfo & getTarget() const
'gnustep' is the modern non-fragile GNUstep runtime.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
GlobalDecl - represents a global declaration.
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
The l-value was considered opaque, so the alignment was determined from a type.
static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)
Emit the dispatch block for a filter scope if necessary.
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Encodes a location in the source.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
A saved depth on the scope stack.
unsigned getNumHandlers() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
const char * PersonalityFn
'objfw' is the Objective-C runtime included in ObjFW
llvm::BasicBlock * getUnreachableBlock()
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
static const EHPersonality & getCXXPersonality(const TargetInfo &Target, const LangOptions &L)
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
bool isObjCObjectPointerType() const
bool isWasmPersonality() const
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
llvm::Instruction * CurrentFuncletPad
llvm::Value * getFilter(unsigned i) const
void exit(CodeGenFunction &CGF)
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...
const VersionTuple & getVersion() const
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
static const EHPersonality NeXT_ObjC
llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)
FunctionArgList - Type for representing both the decl and type of parameters to a function...
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static const EHPersonality GNU_CPlusPlus_SEH
The basic abstraction for the target Objective-C runtime.
static const EHPersonality GNU_ObjC
static bool isNonEHScope(const EHScope &S)
Check whether this is a non-EH scope, i.e.
void EmitAnyExprToExn(const Expr *E, Address Addr)
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
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::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
Address getNormalCleanupDestSlot()
Represents a __leave statement.
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
llvm::BasicBlock * getTerminateFunclet()
getTerminateLandingPad - Return a cleanup funclet that just calls terminate.
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
static const EHPersonality GNU_CPlusPlus
llvm::PointerType * Int8PtrTy
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::StringRef getName() const
Return the IR name of the pointer value.
static const EHPersonality GNU_ObjC_SJLJ
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
SEHFinallyStmt * getFinallyHandler() const
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &T)
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Expr * getFilterExpr() const
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static const EHPersonality GNU_C_SEH
The exceptions personality for a function.
CompoundStmt * getTryBlock()
llvm::Value * EmitSEHAbnormalTermination()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
void EnterSEHTryStmt(const SEHTryStmt &S)
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
Arrange a function prototype that can be called by Windows exception handling personalities.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
CGCXXABI & getCXXABI() const
An exceptions scope which filters exceptions thrown through it.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
static const EHPersonality GNU_Wasm_CPlusPlus
Information for lazily generating a cleanup.
This represents a decl that may have a name.
A non-stable pointer into the scope stack.
void EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
CallArgList - Type for representing both the value and type of arguments in a call.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
CompoundStmt * getTryBlock() const
CompoundStmt * getBlock() const
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)