25 #include "llvm/IR/CallSite.h" 26 #include "llvm/IR/Intrinsics.h" 27 #include "llvm/IR/IntrinsicInst.h" 28 #include "llvm/Support/SaveAndRestore.h" 30 using namespace clang;
31 using namespace CodeGen;
36 llvm::FunctionType *FTy =
45 llvm::FunctionType *FTy =
54 llvm::FunctionType *FTy =
55 llvm::FunctionType::get(
VoidTy,
false);
62 name =
"_ZSt9terminatev";
66 name =
"__std_terminate";
68 name =
"?terminate@@YAXXZ";
71 name =
"objc_terminate";
79 llvm::FunctionType *FTy =
119 const llvm::Triple &T = Target.
getTriple();
120 if (T.isWindowsMSVCEnvironment())
121 return EHPersonality::MSVC_CxxFrameHandler3;
122 if (L.SjLjExceptions)
124 if (L.DWARFExceptions)
133 const llvm::Triple &T = Target.
getTriple();
134 if (T.isWindowsMSVCEnvironment())
135 return EHPersonality::MSVC_CxxFrameHandler3;
146 return EHPersonality::GNUstep_ObjC;
150 if (L.SjLjExceptions)
156 llvm_unreachable(
"bad runtime kind");
161 const llvm::Triple &T = Target.
getTriple();
162 if (T.isWindowsMSVCEnvironment())
163 return EHPersonality::MSVC_CxxFrameHandler3;
164 if (L.SjLjExceptions)
166 if (L.DWARFExceptions)
171 if (Target.
hasFeature(
"exception-handling") &&
172 (T.getArch() == llvm::Triple::wasm32 ||
173 T.getArch() == llvm::Triple::wasm64))
182 if (Target.
getTriple().isWindowsMSVCEnvironment())
183 return EHPersonality::MSVC_CxxFrameHandler3;
208 llvm_unreachable(
"bad runtime kind");
212 if (T.getArch() == llvm::Triple::x86)
213 return EHPersonality::MSVC_except_handler;
240 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(FD));
247 llvm::AttributeList(),
true);
253 llvm::PointerType*
Int8PtrTy = llvm::PointerType::get(
257 return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy);
262 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
265 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
266 if (LPI->isCatch(I)) {
268 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
271 if (GV->getName().startswith(
"OBJC_EHTYPE"))
275 llvm::Constant *CVal = cast<llvm::Constant>(Val);
276 for (llvm::User::op_iterator
277 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
278 if (llvm::GlobalVariable *GV =
279 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
282 if (GV->getName().startswith(
"OBJC_EHTYPE"))
293 for (llvm::User *U : Fn->users()) {
295 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
296 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
303 llvm::Function *F = dyn_cast<llvm::Function>(U);
304 if (!F)
return false;
306 for (
auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
307 if (BB->isLandingPad())
320 void CodeGenModule::SimplifyPersonality() {
322 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
336 "Different EHPersonalities using the same personality function.");
341 if (!Fn || Fn->use_empty())
return;
351 if (Fn->getType() != CXXFn->getType())
return;
353 Fn->replaceAllUsesWith(CXXFn);
354 Fn->eraseFromParent();
361 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
389 Address typedAddr = Builder.CreateBitCast(addr, ty);
402 DeactivateCleanupBlock(cleanup,
403 cast<llvm::Instruction>(typedAddr.
getPointer()));
408 ExceptionSlot = CreateTempAlloca(
Int8PtrTy,
"exn.slot");
414 EHSelectorSlot = CreateTempAlloca(
Int32Ty,
"ehselector.slot");
419 return Builder.CreateLoad(getExceptionSlot(),
"exn");
423 return Builder.CreateLoad(getEHSelectorSlot(),
"sel");
427 bool KeepInsertionPoint) {
429 QualType ThrowType = SubExpr->getType();
433 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
435 CGM.getCXXABI().emitThrow(*
this, E);
438 CGM.getCXXABI().emitRethrow(*
this,
true);
443 if (KeepInsertionPoint)
444 EmitBlock(createBasicBlock(
"throw.cont"));
448 if (!CGM.getLangOpts().CXXExceptions)
451 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
454 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
456 EHStack.pushTerminate();
467 EHStack.pushTerminate();
476 for (
unsigned I = 0; I != NumExceptions; ++I) {
479 llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
490 if (!dispatchBlock)
return;
491 if (dispatchBlock->use_empty()) {
492 delete dispatchBlock;
507 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
508 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
520 ->setDoesNotReturn();
521 CGF.
Builder.CreateUnreachable();
525 if (!CGM.getLangOpts().CXXExceptions)
528 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
531 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
533 EHStack.popTerminate();
543 EHStack.popTerminate();
549 EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
563 EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
565 for (
unsigned I = 0; I != NumHandlers; ++I) {
568 llvm::BasicBlock *Handler = createBasicBlock(
"catch");
577 QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
582 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
584 TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
589 CatchScope->
setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
597 return getFuncletEHDispatchBlock(si);
601 if (si == EHStack.stable_end())
602 return getEHResumeBlock(
true);
605 EHScope &scope = *EHStack.find(si);
608 if (!dispatchBlock) {
619 dispatchBlock = createBasicBlock(
"catch.dispatch");
625 dispatchBlock = createBasicBlock(
"ehcleanup");
629 dispatchBlock = createBasicBlock(
"filter.dispatch");
633 dispatchBlock = getTerminateHandler();
637 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
641 return dispatchBlock;
648 if (SI == EHStack.stable_end())
652 EHScope &EHS = *EHStack.find(SI);
656 return DispatchBlock;
659 DispatchBlock = getTerminateFunclet();
661 DispatchBlock = createBasicBlock();
666 DispatchBlock->setName(
"catch.dispatch");
670 DispatchBlock->setName(
"ehcleanup");
674 llvm_unreachable(
"exception specifications not handled yet!");
677 DispatchBlock->setName(
"terminate");
681 llvm_unreachable(
"PadEnd dispatch block missing!");
684 return DispatchBlock;
693 return !cast<EHCleanupScope>(S).isEHCleanup();
701 llvm_unreachable(
"Invalid EHScope Kind!");
705 assert(EHStack.requiresLandingPad());
706 assert(!EHStack.empty());
713 if (!LO.Exceptions) {
714 if (!LO.Borland && !LO.MicrosoftExt)
716 if (!currentFunctionUsesSEHTry())
721 if (LO.CUDA && LO.CUDAIsDevice)
726 llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
731 if (!CurFn->hasPersonalityFn())
736 LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
739 LP = EmitLandingPad();
747 ir->setCachedLandingPad(LP);
755 assert(EHStack.requiresLandingPad());
757 EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
758 switch (innermostEHScope.getKind()) {
760 return getTerminateLandingPad();
763 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
768 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
773 CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
777 llvm::BasicBlock *lpad = createBasicBlock(
"lpad");
780 llvm::LandingPadInst *LPadInst =
783 llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
784 Builder.CreateStore(LPadExn, getExceptionSlot());
785 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
786 Builder.CreateStore(LPadSel, getEHSelectorSlot());
794 bool hasCatchAll =
false;
795 bool hasCleanup =
false;
796 bool hasFilter =
false;
798 llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
802 switch (I->getKind()) {
805 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
809 assert(I.next() == EHStack.end() &&
"EH filter is not end of EH stack");
810 assert(!hasCatchAll &&
"EH filter reached after catch-all");
817 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
818 filterTypes.push_back(filter.
getFilter(i));
824 assert(!hasCatchAll);
832 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
836 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
839 "landingpads do not support catch handler flags");
843 assert(!hasCatchAll);
849 if (catchTypes.insert(handler.
Type.
RTTI).second)
851 LPadInst->addClause(handler.
Type.
RTTI);
857 assert(!(hasCatchAll && hasFilter));
863 }
else if (hasFilter) {
868 llvm::ArrayType *AType =
869 llvm::ArrayType::get(!filterTypes.empty() ?
873 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
874 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
875 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
876 LPadInst->addClause(FilterArray);
880 LPadInst->setCleanup(
true);
883 }
else if (hasCleanup) {
884 LPadInst->setCleanup(
true);
887 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
888 "landingpad instruction has no clauses!");
891 Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
894 Builder.restoreIP(savedIP);
901 assert(DispatchBlock);
903 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
909 llvm::BasicBlock *UnwindBB =
913 llvm::CatchSwitchInst *CatchSwitch =
914 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
917 for (
unsigned I = 0; I < NumHandlers; ++I) {
929 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
931 CGF.
Builder.CreateCatchPad(CatchSwitch, {TypeInfo.
RTTI});
934 CatchSwitch->addHandler(Handler.
Block);
936 CGF.
Builder.restoreIP(SavedIP);
945 assert(DispatchBlock);
947 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
953 llvm::BasicBlock *UnwindBB =
957 llvm::CatchSwitchInst *CatchSwitch =
958 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
962 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
963 CatchSwitch->addHandler(WasmCatchStartBlock);
968 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
973 CatchTypes.push_back(TypeInfo.
RTTI);
975 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
984 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
994 CGF.
Builder.restoreIP(SavedIP);
999 for (
unsigned I = 0, E = NumHandlers;; ++I) {
1000 assert(I < E &&
"ran off end of handlers!");
1004 TypeInfo.
RTTI = llvm::Constant::getNullValue(CGF.
VoidPtrTy);
1007 llvm::BasicBlock *NextBlock;
1009 bool EmitNextBlock =
false, NextIsEnd =
false;
1016 EmitNextBlock =
true;
1028 EmitNextBlock =
true;
1032 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn, TypeInfo.
RTTI);
1033 TypeIndex->setDoesNotThrow();
1036 CGF.
Builder.CreateICmpEQ(Selector, TypeIndex,
"matches");
1037 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
1045 CGF.
Builder.restoreIP(SavedIP);
1058 assert(dispatchBlock);
1068 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1080 assert(i < e &&
"ran off end of handlers!");
1085 "landingpads do not support catch handler flags");
1086 assert(typeValue &&
"fell into catch-all case!");
1091 llvm::BasicBlock *nextBlock;
1112 llvm::CallInst *typeIndex =
1113 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1114 typeIndex->setDoesNotThrow();
1117 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1118 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1122 CGF.
Builder.restoreIP(savedIP);
1131 EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
1139 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1156 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1161 llvm::BasicBlock *ContBB = createBasicBlock(
"try.cont");
1164 if (HaveInsertPoint())
1165 Builder.CreateBr(ContBB);
1169 bool doImplicitRethrow =
false;
1171 doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1172 isa<CXXConstructorDecl>(CurCodeDecl);
1179 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1182 cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHI());
1183 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1184 ? CatchSwitch->getSuccessor(1)
1185 : CatchSwitch->getSuccessor(0);
1186 auto *CPI = cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHI());
1187 CurrentFuncletPad = CPI;
1197 bool HasCatchAll =
false;
1198 for (
unsigned I = NumHandlers; I != 0; --I) {
1199 HasCatchAll |= Handlers[I - 1].isCatchAll();
1200 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1201 EmitBlockAfterUses(CatchBlock);
1213 CGM.getCXXABI().emitBeginCatch(*
this, C);
1216 incrementProfileCounter(C);
1230 if (doImplicitRethrow && HaveInsertPoint()) {
1231 CGM.getCXXABI().emitRethrow(*
this,
false);
1232 Builder.CreateUnreachable();
1233 Builder.ClearInsertionPoint();
1240 if (HaveInsertPoint())
1241 Builder.CreateBr(ContBB);
1249 assert(WasmCatchStartBlock);
1254 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1255 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {
1256 auto *BI = cast<llvm::BranchInst>(TI);
1257 assert(BI->isConditional());
1258 RethrowBlock = BI->getSuccessor(1);
1260 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1261 Builder.SetInsertPoint(RethrowBlock);
1262 CGM.getCXXABI().emitRethrow(*
this,
true);
1266 incrementProfileCounter(&S);
1274 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1278 llvm::BasicBlock *CleanupContBB =
1283 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1300 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1301 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1307 ForEHVar, EndCatchFn);
1313 "cleanup.dest.saved");
1326 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1335 CGF.
Builder.CreateUnreachable();
1348 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1350 CGF.
Builder.restoreIP(SavedIP);
1365 llvm::Constant *beginCatchFn,
1366 llvm::Constant *endCatchFn,
1367 llvm::Constant *rethrowFn) {
1368 assert((beginCatchFn !=
nullptr) == (endCatchFn !=
nullptr) &&
1369 "begin/end catch functions not paired");
1370 assert(rethrowFn &&
"rethrow function is required");
1372 BeginCatchFn = beginCatchFn;
1380 llvm::FunctionType *rethrowFnTy =
1381 cast<llvm::FunctionType>(
1382 cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
1383 SavedExnVar =
nullptr;
1384 if (rethrowFnTy->getNumParams())
1410 ForEHVar, endCatchFn,
1411 rethrowFn, SavedExnVar);
1427 if (catchBB->use_empty()) {
1430 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1453 CGF.
Builder.restoreIP(savedIP);
1461 if (TerminateLandingPad)
1462 return TerminateLandingPad;
1464 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1467 TerminateLandingPad = createBasicBlock(
"terminate.lpad");
1468 Builder.SetInsertPoint(TerminateLandingPad);
1473 if (!CurFn->hasPersonalityFn())
1476 llvm::LandingPadInst *LPadInst =
1482 Exn = Builder.CreateExtractValue(LPadInst, 0);
1483 llvm::CallInst *terminateCall =
1484 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1485 terminateCall->setDoesNotReturn();
1486 Builder.CreateUnreachable();
1489 Builder.restoreIP(SavedIP);
1491 return TerminateLandingPad;
1495 if (TerminateHandler)
1496 return TerminateHandler;
1500 TerminateHandler = createBasicBlock(
"terminate.handler");
1501 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1502 Builder.SetInsertPoint(TerminateHandler);
1506 Exn = getExceptionFromSlot();
1507 llvm::CallInst *terminateCall =
1508 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1509 terminateCall->setDoesNotReturn();
1510 Builder.CreateUnreachable();
1513 Builder.restoreIP(SavedIP);
1515 return TerminateHandler;
1520 "use getTerminateLandingPad for non-funclet EH");
1522 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
1523 if (TerminateFunclet)
1524 return TerminateFunclet;
1526 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1530 TerminateFunclet = createBasicBlock(
"terminate.handler");
1531 Builder.SetInsertPoint(TerminateFunclet);
1539 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1540 CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1549 CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
1550 Exn = Builder.CreateCall(GetExnFn, CurrentFuncletPad);
1552 llvm::CallInst *terminateCall =
1553 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1554 terminateCall->setDoesNotReturn();
1555 Builder.CreateUnreachable();
1558 Builder.restoreIP(SavedIP);
1560 return TerminateFunclet;
1564 if (EHResumeBlock)
return EHResumeBlock;
1566 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1569 EHResumeBlock = createBasicBlock(
"eh.resume");
1570 Builder.SetInsertPoint(EHResumeBlock);
1577 if (RethrowName !=
nullptr && !isCleanup) {
1579 getExceptionFromSlot())->setDoesNotReturn();
1580 Builder.CreateUnreachable();
1581 Builder.restoreIP(SavedIP);
1582 return EHResumeBlock;
1589 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1590 llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1591 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1592 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1594 Builder.CreateResume(LPadVal);
1595 Builder.restoreIP(SavedIP);
1596 return EHResumeBlock;
1602 JumpDest TryExit = getJumpDestInCurrentScope(
"__try.__leave");
1604 SEHTryEpilogueStack.push_back(&TryExit);
1606 SEHTryEpilogueStack.pop_back();
1608 if (!TryExit.
getBlock()->use_empty())
1609 EmitBlock(TryExit.
getBlock(),
true);
1618 llvm::Function *OutlinedFinally;
1619 PerformSEHFinally(llvm::Function *OutlinedFinally)
1620 : OutlinedFinally(OutlinedFinally) {}
1633 FP = &CGF.
CurFn->arg_begin()[1];
1637 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1641 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1663 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1666 bool foundCaptures() {
1667 return !Captures.empty() || SEHCodeSlot.
isValid();
1670 void Visit(
const Stmt *S) {
1681 Captures.insert(ParentThis);
1686 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1691 Captures.insert(ParentThis);
1694 void VisitCallExpr(
const CallExpr *E) {
1701 case Builtin::BI__exception_code:
1702 case Builtin::BI_exception_code:
1717 llvm::CallInst *RecoverCall =
nullptr;
1719 if (
auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.
getPointer())) {
1722 auto InsertPair = ParentCGF.EscapedLocals.insert(
1723 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1724 int FrameEscapeIdx = InsertPair.first->second;
1726 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1727 &CGM.getModule(), llvm::Intrinsic::localrecover);
1728 llvm::Constant *ParentI8Fn =
1730 RecoverCall = Builder.CreateCall(
1731 FrameRecoverFn, {ParentI8Fn, ParentFP,
1732 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1738 auto *ParentRecover =
1739 cast<llvm::IntrinsicInst>(ParentVar.
getPointer()->stripPointerCasts());
1740 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1741 "expected alloca or localrecover in parent LocalDeclMap");
1742 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1743 RecoverCall->setArgOperand(1, ParentFP);
1744 RecoverCall->insertBefore(AllocaInsertPt);
1750 ChildVar->setName(ParentVar.
getName());
1755 const Stmt *OutlinedStmt,
1758 CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1759 Finder.Visit(OutlinedStmt);
1763 if (!Finder.foundCaptures() &&
1764 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1766 EmitSEHExceptionCodeSave(ParentCGF,
nullptr,
nullptr);
1772 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1776 EntryFP = Builder.CreateCall(
1777 CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
1781 auto AI = CurFn->arg_begin();
1791 llvm::Function *RecoverFPIntrin =
1792 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1793 llvm::Constant *ParentI8Fn =
1795 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
1799 for (
const VarDecl *VD : Finder.Captures) {
1800 if (isa<ImplicitParamDecl>(VD)) {
1801 CGM.ErrorUnsupported(VD,
"'this' captured by SEH");
1802 CXXThisValue = llvm::UndefValue::get(ConvertTypeForMem(VD->
getType()));
1806 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1810 "captured non-local variable");
1814 auto I = ParentCGF.LocalDeclMap.find(VD);
1815 if (I == ParentCGF.LocalDeclMap.end())
1818 Address ParentVar = I->second;
1820 VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
1823 if (Finder.SEHCodeSlot.isValid()) {
1824 SEHCodeSlotStack.push_back(
1825 recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
1829 EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
1837 const Stmt *OutlinedStmt) {
1843 llvm::raw_svector_ostream OS(Name);
1845 assert(ParentSEHFn &&
"No CurSEHParent!");
1846 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
1854 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
1860 &
getContext().Idents.get(
"exception_pointers"),
1865 &
getContext().Idents.get(
"abnormal_termination"),
1877 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
1879 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
1883 IsOutlinedSEHHelper =
true;
1885 StartFunction(
GlobalDecl(), RetTy, Fn, FnInfo, Args,
1889 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FnInfo, CurFn);
1890 EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
1900 startOutlinedSEHHelper(ParentCGF,
true, FilterExpr);
1904 R = Builder.CreateIntCast(R, ConvertType(
getContext().LongTy),
1906 Builder.CreateStore(R, ReturnValue);
1908 FinishFunction(FilterExpr->
getEndLoc());
1917 startOutlinedSEHHelper(ParentCGF,
false, FinallyBlock);
1920 EmitStmt(FinallyBlock);
1922 FinishFunction(FinallyBlock->
getEndLoc());
1932 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1934 SEHInfo = &*CurFn->arg_begin();
1935 SEHCodeSlotStack.push_back(
1942 SEHInfo = Builder.CreateConstInBoundsGEP1_32(
Int8Ty, EntryFP, -20);
1943 SEHInfo = Builder.CreateBitCast(SEHInfo,
Int8PtrTy->getPointerTo());
1945 SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
1956 llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
1957 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
1958 llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
1959 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
1962 assert(!SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1963 Builder.CreateStore(Code, SEHCodeSlotStack.back());
1970 return llvm::UndefValue::get(
Int8PtrTy);
1971 assert(SEHInfo->getType() ==
Int8PtrTy);
1976 assert(!SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1977 return Builder.CreateLoad(SEHCodeSlotStack.back());
1983 auto AI = CurFn->arg_begin();
1984 return Builder.CreateZExt(&*AI,
Int32Ty);
1988 llvm::Function *FinallyFunc) {
1989 EHStack.pushCleanup<PerformSEHFinally>(
Kind, FinallyFunc);
1996 llvm::Function *FinallyFunc =
2008 SEHCodeSlotStack.push_back(
2017 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
2025 llvm::Function *FilterFunc =
2027 llvm::Constant *OpaqueFunc =
2028 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
2029 CatchScope->
setHandler(0, OpaqueFunc, createBasicBlock(
"__except.ret"));
2041 assert(Except &&
"__try must have __finally xor __except");
2042 EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
2050 SEHCodeSlotStack.pop_back();
2055 llvm::BasicBlock *ContBB = createBasicBlock(
"__try.cont");
2058 if (HaveInsertPoint())
2059 Builder.CreateBr(ContBB);
2068 EmitBlockAfterUses(CatchPadBB);
2072 llvm::CatchPadInst *CPI =
2073 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
2074 llvm::BasicBlock *ExceptBB = createBasicBlock(
"__except");
2075 Builder.CreateCatchRet(CPI, ExceptBB);
2076 EmitBlock(ExceptBB);
2079 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2080 llvm::Function *SEHCodeIntrin =
2081 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2082 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
2083 Builder.CreateStore(Code, SEHCodeSlotStack.back());
2090 SEHCodeSlotStack.pop_back();
2092 if (HaveInsertPoint())
2093 Builder.CreateBr(ContBB);
2102 if (HaveInsertPoint())
2107 if (!isSEHTryScope()) {
2108 Builder.CreateUnreachable();
2109 Builder.ClearInsertionPoint();
2113 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...
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 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.
static llvm::Constant * getUnexpectedFn(CodeGenModule &CGM)
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...
static llvm::Constant * getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
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 ...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **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.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
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
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
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 * getFreeExceptionFn(CodeGenModule &CGM)
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)
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 const EHPersonality GNUstep_ObjC
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
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++.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
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.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
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.
void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn, llvm::Constant *rethrowFn)
Enters a finally block for an implementation using zero-cost exceptions.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
Check whether a personality function could reasonably be swapped for a C++ personality function...
'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
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.
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()
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
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::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
Address getNormalCleanupDestSlot()
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
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.
static llvm::Constant * getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
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)
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)