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 =
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 =
85namespace clang::CodeGen {
106 llvm::FunctionType *FTy;
109 FTy = llvm::FunctionType::get(CGM.
Int32Ty, {CGM.VoidPtrTy},
false);
111 FTy = llvm::FunctionType::get(CGM.
Int32Ty,
true);
114 llvm::AttributeList(),
true);
125 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
128 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
129 if (LPI->isCatch(I)) {
131 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
134 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
139 for (llvm::User::op_iterator
140 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
141 if (llvm::GlobalVariable *GV =
145 if (GV->getName().starts_with(
"OBJC_EHTYPE"))
156 for (llvm::User *
U : Fn->users()) {
158 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(
U)) {
159 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
166 llvm::Function *F = dyn_cast<llvm::Function>(
U);
167 if (!F)
return false;
169 for (llvm::BasicBlock &BB : *F) {
170 if (BB.isLandingPad())
183void CodeGenModule::SimplifyPersonality() {
185 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)
190 if (!LangOpts.ObjCRuntime.isNeXTFamily())
194 const EHPersonality &
CXX =
199 assert(std::strcmp(
ObjCXX.PersonalityFn,
CXX.PersonalityFn) != 0 &&
200 "Different EHPersonalities using the same personality function.");
205 if (!Fn ||
Fn->use_empty())
return;
215 if (
Fn->getType() != CXXFn.getCallee()->getType())
218 Fn->replaceAllUsesWith(CXXFn.getCallee());
219 Fn->eraseFromParent();
226 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
232 struct FreeException final : EHScopeStack::Cleanup {
234 FreeException(llvm::Value *exn) : exn(exn) {}
235 void Emit(CodeGenFunction &CGF, Flags flags)
override {
292 bool KeepInsertionPoint) {
297 const llvm::Triple &
T =
Target.getTriple();
298 if (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU()) {
303 QualType ThrowType = SubExpr->getType();
307 CGM.getObjCRuntime().EmitThrowStmt(*
this, S,
false);
309 CGM.getCXXABI().emitThrow(*
this, E);
312 CGM.getCXXABI().emitRethrow(*
this,
true);
317 if (KeepInsertionPoint)
322 if (!
CGM.getLangOpts().CXXExceptions)
325 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
328 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
346 if (
getTarget().getCXXABI().isMicrosoft())
351 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
356 diag::warn_wasm_dynamic_exception_spec_ignored)
365 if (
getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&
366 (
CGM.getCodeGenOpts().getExceptionHandling() ==
368 CGM.getCodeGenOpts().getExceptionHandling() ==
372 diag::warn_wasm_dynamic_exception_spec_ignored)
378 for (
unsigned I = 0; I != NumExceptions; ++I) {
381 llvm::Value *EHType =
CGM.GetAddrOfRTTIDescriptor(ExceptType,
383 Filter->setFilter(I, EHType);
396 if (!dispatchBlock)
return;
397 if (dispatchBlock->use_empty()) {
398 delete dispatchBlock;
411 llvm::Value *zero = CGF.
Builder.getInt32(0);
412 llvm::Value *failsFilter =
413 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
414 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
426 ->setDoesNotReturn();
427 CGF.
Builder.CreateUnreachable();
431 if (!
CGM.getLangOpts().CXXExceptions)
434 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
437 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
438 if (CD->isNothrow() && !
EHStack.empty())
452 if (
getTarget().getCXXABI().isMicrosoft())
457 if (
CGM.getCodeGenOpts().hasWasmExceptions()) {
473 const llvm::Triple &
T =
Target.getTriple();
476 const bool IsTargetDevice =
477 (
CGM.getLangOpts().OpenMPIsTargetDevice &&
T.isGPU());
491 if (
CGM.getLangOpts().HIPStdPar &&
CGM.getLangOpts().CUDAIsDevice) {
492 constexpr llvm::StringLiteral MarkerName =
493 "__CXX_EXCEPTION__hipstdpar_unsupported";
494 llvm::FunctionType *MarkerTy =
495 llvm::FunctionType::get(
VoidTy,
false);
496 llvm::FunctionCallee Marker =
497 CGM.getModule().getOrInsertFunction(MarkerName, MarkerTy);
504 for (
unsigned I = 0; I != NumHandlers; ++I) {
508 if (
C->getExceptionDecl()) {
516 QualType CaughtType =
CGM.getContext().getUnqualifiedArrayType(
517 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
521 TypeInfo.RTTI =
CGM.getObjCRuntime().GetEHType(CaughtType);
523 TypeInfo =
CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
524 CaughtType,
C->getCaughtType());
528 CatchScope->
setHandler(I,
CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
544 if (si ==
EHStack.stable_end())
551 if (!dispatchBlock) {
581 return dispatchBlock;
588 if (SI ==
EHStack.stable_end())
596 return DispatchBlock;
606 DispatchBlock->setName(
"catch.dispatch");
610 DispatchBlock->setName(
"ehcleanup");
614 llvm_unreachable(
"exception specifications not handled yet!");
617 DispatchBlock->setName(
"terminate");
621 return DispatchBlock;
637 llvm_unreachable(
"Invalid EHScope Kind!");
641 assert(
EHStack.requiresLandingPad());
649 if (!LO.Exceptions || LO.IgnoreExceptions) {
650 if (!LO.Borland && !LO.MicrosoftExt)
657 if (LO.CUDA && LO.CUDAIsDevice)
662 llvm::BasicBlock *LP =
EHStack.begin()->getCachedLandingPad();
667 if (!
CurFn->hasPersonalityFn())
683 ir->setCachedLandingPad(LP);
691 assert(
EHStack.requiresLandingPad());
692 assert(!
CGM.getLangOpts().IgnoreExceptions &&
693 "LandingPad should not be emitted when -fignore-exceptions are in "
696 switch (innermostEHScope.
getKind()) {
708 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
715 llvm::LandingPadInst *LPadInst =
718 llvm::Value *LPadExn =
Builder.CreateExtractValue(LPadInst, 0);
720 llvm::Value *LPadSel =
Builder.CreateExtractValue(LPadInst, 1);
729 bool hasCatchAll =
false;
730 bool hasCleanup =
false;
731 bool hasFilter =
false;
737 switch (I->getKind()) {
744 assert(I.next() ==
EHStack.end() &&
"EH filter is not end of EH stack");
745 assert(!hasCatchAll &&
"EH filter reached after catch-all");
752 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
753 filterTypes.push_back(filter.
getFilter(i));
759 assert(!hasCatchAll);
768 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
771 "landingpads do not support catch handler flags");
775 assert(!hasCatchAll);
781 if (catchTypes.insert(handler.
Type.
RTTI).second)
783 LPadInst->addClause(handler.
Type.
RTTI);
789 assert(!(hasCatchAll && hasFilter));
795 }
else if (hasFilter) {
800 llvm::ArrayType *AType =
801 llvm::ArrayType::get(!filterTypes.empty() ?
805 for (llvm::Value *filterType : filterTypes)
807 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
808 LPadInst->addClause(FilterArray);
812 LPadInst->setCleanup(
true);
815 }
else if (hasCleanup) {
816 LPadInst->setCleanup(
true);
819 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
820 "landingpad instruction has no clauses!");
833 assert(DispatchBlock);
835 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
841 llvm::BasicBlock *UnwindBB =
845 llvm::CatchSwitchInst *CatchSwitch =
846 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
849 for (
unsigned I = 0; I < NumHandlers; ++I) {
861 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
866 CatchSwitch->addHandler(Handler.
Block);
868 CGF.
Builder.restoreIP(SavedIP);
877 assert(DispatchBlock);
879 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
885 llvm::BasicBlock *UnwindBB =
889 llvm::CatchSwitchInst *CatchSwitch =
890 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
894 llvm::BasicBlock *WasmCatchStartBlock = CGF.
createBasicBlock(
"catch.start");
895 CatchSwitch->addHandler(WasmCatchStartBlock);
900 for (
unsigned I = 0, E = NumHandlers; I < E; ++I) {
905 CatchTypes.push_back(
TypeInfo.RTTI);
907 auto *CPI = CGF.
Builder.CreateCatchPad(CatchSwitch, CatchTypes);
912 llvm::Function *GetExnFn =
914 llvm::Function *GetSelectorFn =
916 llvm::CallInst *Exn = CGF.
Builder.CreateCall(GetExnFn, CPI);
920 llvm::Function *TypeIDFn =
927 CGF.
Builder.restoreIP(SavedIP);
932 for (
unsigned I = 0, E = NumHandlers;; ++I) {
933 assert(I < E &&
"ran off end of handlers!");
940 llvm::BasicBlock *NextBlock;
942 bool EmitNextBlock =
false, NextIsEnd =
false;
949 EmitNextBlock =
true;
961 EmitNextBlock =
true;
965 llvm::CallInst *TypeIndex = CGF.
Builder.CreateCall(TypeIDFn,
TypeInfo.RTTI);
966 TypeIndex->setDoesNotThrow();
968 llvm::Value *MatchesTypeIndex =
970 CGF.
Builder.CreateCondBr(MatchesTypeIndex, Handler.
Block, NextBlock);
978 CGF.
Builder.restoreIP(SavedIP);
991 assert(dispatchBlock);
1001 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
1005 llvm::Function *llvm_eh_typeid_for =
1007 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
1014 assert(i < e &&
"ran off end of handlers!");
1017 llvm::Value *typeValue = handler.
Type.
RTTI;
1019 "landingpads do not support catch handler flags");
1020 assert(typeValue &&
"fell into catch-all case!");
1022 if (typeValue->getType() != argTy)
1027 llvm::BasicBlock *nextBlock;
1048 llvm::CallInst *typeIndex =
1049 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
1050 typeIndex->setDoesNotThrow();
1052 llvm::Value *matchesTypeIndex =
1053 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
1054 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
1058 CGF.
Builder.restoreIP(savedIP);
1074 llvm::BasicBlock *WasmCatchStartBlock) {
1075 assert(WasmCatchStartBlock);
1080 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;
1081 while (llvm::Instruction *TI = RethrowBlock->getTerminatorOrNull())
1083 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
1084 Builder.SetInsertPoint(RethrowBlock);
1085 llvm::Function *RethrowInCatchFn =
1086 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);
1109 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1122 bool doImplicitRethrow =
false;
1131 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
1135 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
1136 ? CatchSwitch->getSuccessor(1)
1137 : CatchSwitch->getSuccessor(0);
1150 bool HasCatchAll =
false;
1151 for (
unsigned I = NumHandlers; I != 0; --I) {
1152 HasCatchAll |= Handlers[I - 1].isCatchAll();
1153 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1160 *
this,
C->getHandlerBlock()->getBeginLoc());
1168 CGM.getCXXABI().emitBeginCatch(*
this,
C);
1186 CGM.getCXXABI().emitRethrow(*
this,
false);
1188 Builder.ClearInsertionPoint();
1208 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1209 llvm::Value *ForEHVar;
1210 llvm::FunctionCallee EndCatchFn;
1211 CallEndCatchForFinally(llvm::Value *ForEHVar,
1212 llvm::FunctionCallee EndCatchFn)
1213 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1217 llvm::BasicBlock *CleanupContBB =
1220 llvm::Value *ShouldEndCatch =
1222 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1229 struct PerformFinally final : EHScopeStack::Cleanup {
1231 llvm::Value *ForEHVar;
1232 llvm::FunctionCallee EndCatchFn;
1233 llvm::FunctionCallee RethrowFn;
1234 llvm::Value *SavedExnVar;
1236 PerformFinally(
const Stmt *Body, llvm::Value *ForEHVar,
1237 llvm::FunctionCallee EndCatchFn,
1238 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
1239 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1240 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1242 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1246 ForEHVar, EndCatchFn);
1250 llvm::Value *SavedCleanupDest =
1252 "cleanup.dest.saved");
1263 llvm::Value *ShouldRethrow =
1265 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1288 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1290 CGF.
Builder.restoreIP(SavedIP);
1304 llvm::FunctionCallee beginCatchFn,
1305 llvm::FunctionCallee endCatchFn,
1306 llvm::FunctionCallee rethrowFn) {
1307 assert((!!beginCatchFn) == (!!endCatchFn) &&
1308 "begin/end catch functions not paired");
1309 assert(rethrowFn &&
"rethrow function is required");
1311 BeginCatchFn = beginCatchFn;
1319 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
1320 SavedExnVar =
nullptr;
1321 if (rethrowFnTy->getNumParams())
1347 ForEHVar, endCatchFn,
1348 rethrowFn, SavedExnVar);
1361 llvm::BasicBlock *DispatchBlock =
nullptr;
1366 llvm::CatchPadInst *CPI =
nullptr;
1369 if (catchBB->use_empty()) {
1376 llvm::BasicBlock *CatchStartBlock = CatchSwitch->hasUnwindDest()
1377 ? CatchSwitch->getSuccessor(1)
1378 : CatchSwitch->getSuccessor(0);
1383 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1389 llvm::Value *exn =
nullptr;
1414 CGF.
Builder.restoreIP(savedIP);
1422 if (TerminateLandingPad)
1423 return TerminateLandingPad;
1425 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1429 Builder.SetInsertPoint(TerminateLandingPad);
1434 if (!
CurFn->hasPersonalityFn())
1437 llvm::LandingPadInst *LPadInst =
1441 llvm::Value *Exn =
nullptr;
1443 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1444 llvm::CallInst *terminateCall =
1445 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1446 terminateCall->setDoesNotReturn();
1452 return TerminateLandingPad;
1456 if (TerminateHandler)
1457 return TerminateHandler;
1462 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1463 Builder.SetInsertPoint(TerminateHandler);
1465 llvm::Value *Exn =
nullptr;
1468 llvm::CallInst *terminateCall =
1469 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this, Exn);
1470 terminateCall->setDoesNotReturn();
1476 return TerminateHandler;
1481 "use getTerminateLandingPad for non-funclet EH");
1484 if (TerminateFunclet)
1485 return TerminateFunclet;
1487 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1492 Builder.SetInsertPoint(TerminateFunclet);
1499 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1503 llvm::CallInst *terminateCall =
1504 CGM.getCXXABI().emitTerminateForUnexpectedException(*
this,
nullptr);
1505 terminateCall->setDoesNotReturn();
1511 return TerminateFunclet;
1517 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1528 if (RethrowName !=
nullptr && !isCleanup) {
1540 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
1541 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);
1542 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1543 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1545 Builder.CreateResume(LPadVal);
1557 llvm::BasicBlock *TryBB =
nullptr;
1562 TryBB =
Builder.GetInsertBlock();
1575 if (!TryExit.
getBlock()->use_empty())
1588 !
V.insert(BB).second ||
1589 !BB->getParent() || BB->empty())
1592 if (!BB->isEHPad()) {
1593 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;
1595 if (
auto LI = dyn_cast<llvm::LoadInst>(J)) {
1596 LI->setVolatile(
true);
1597 }
else if (
auto SI = dyn_cast<llvm::StoreInst>(J)) {
1598 SI->setVolatile(
true);
1599 }
else if (
auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {
1600 MCI->setVolatile(llvm::ConstantInt::get(
Builder.getInt1Ty(), 1));
1604 if (
const llvm::Instruction *TI = BB->getTerminatorOrNull()) {
1605 unsigned N = TI->getNumSuccessors();
1606 for (
unsigned I = 0; I < N; I++)
1612struct PerformSEHFinally final : EHScopeStack::Cleanup {
1613 llvm::Function *OutlinedFinally;
1614 PerformSEHFinally(llvm::Function *OutlinedFinally)
1615 : OutlinedFinally(OutlinedFinally) {}
1624 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1625 llvm::Value *FP =
nullptr;
1628 FP = &CGF.
CurFn->arg_begin()[1];
1630 llvm::Function *LocalAddrFn =
1632 FP = CGF.
Builder.CreateCall(LocalAddrFn);
1635 llvm::Value *IsForEH =
1636 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1643 if (!F.isForEHCleanup() && F.hasExitSwitch()) {
1646 llvm::Value *
Zero = llvm::Constant::getNullValue(CGM.
Int32Ty);
1654 const CGFunctionInfo &FnInfo =
1658 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
1665struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1666 CodeGenFunction &ParentCGF;
1667 const VarDecl *ParentThis;
1668 llvm::SmallSetVector<const VarDecl *, 4> Captures;
1670 CaptureFinder(CodeGenFunction &ParentCGF,
const VarDecl *ParentThis)
1671 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1674 bool foundCaptures() {
1675 return !Captures.empty() || SEHCodeSlot.
isValid();
1678 void Visit(
const Stmt *S) {
1680 ConstStmtVisitor<CaptureFinder>::Visit(S);
1681 for (
const Stmt *Child : S->
children())
1686 void VisitDeclRefExpr(
const DeclRefExpr *E) {
1689 Captures.insert(ParentThis);
1691 const auto *D = dyn_cast<VarDecl>(E->
getDecl());
1692 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1696 void VisitCXXThisExpr(
const CXXThisExpr *E) {
1697 Captures.insert(ParentThis);
1700 void VisitCallExpr(
const CallExpr *E) {
1707 case Builtin::BI__exception_code:
1708 case Builtin::BI_exception_code:
1722 llvm::Value *ParentFP) {
1723 llvm::Value *RecoverCall =
nullptr;
1729 auto *ParentAlloca =
1733 if (!ParentAlloca) {
1735 llvm::BasicBlock &EntryBB =
ParentCGF.CurFn->getEntryBlock();
1736 llvm::IRBuilder<> ParentEntryBuilder(EntryBB.begin());
1737 ParentAlloca = ParentEntryBuilder.CreateAlloca(
1738 ParentArg->getType(),
nullptr, ParentArg->getName() +
".spill");
1739 ParentEntryBuilder.CreateStore(ParentArg, ParentAlloca);
1746 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1747 std::make_pair(ParentAlloca,
ParentCGF.EscapedLocals.size()));
1748 int FrameEscapeIdx = InsertPair.first->second;
1750 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1751 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1752 RecoverCall =
Builder.CreateCall(
1753 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1754 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1756 RecoverCall =
Builder.CreateLoad(
1764 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1765 "expected alloca or localrecover in parent LocalDeclMap");
1766 RecoverCall = ParentRecover->clone();
1773 llvm::Value *ChildVar =
1775 ChildVar->setName(ParentVar.
getName());
1780 const Stmt *OutlinedStmt,
1784 Finder.Visit(OutlinedStmt);
1788 if (!Finder.foundCaptures() &&
1789 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1795 llvm::Value *EntryFP =
nullptr;
1797 if (IsFilter &&
CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1803 {Builder.getInt32(1)});
1807 auto AI =
CurFn->arg_begin();
1812 llvm::Value *ParentFP = EntryFP;
1817 llvm::Function *RecoverFPIntrin =
1818 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);
1819 ParentFP =
Builder.CreateCall(RecoverFPIntrin, {
ParentCGF.CurFn, EntryFP});
1831 llvm::AllocaInst *FramePtrAddrAlloca =
nullptr;
1832 for (
auto &I :
ParentCGF.LocalDeclMap) {
1836 assert(D->
getName().starts_with(
"frame_pointer"));
1837 FramePtrAddrAlloca =
1842 assert(FramePtrAddrAlloca);
1843 auto InsertPair =
ParentCGF.EscapedLocals.insert(
1844 std::make_pair(FramePtrAddrAlloca,
ParentCGF.EscapedLocals.size()));
1845 int FrameEscapeIdx = InsertPair.first->second;
1852 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(
1853 &
CGM.getModule(), llvm::Intrinsic::localrecover);
1854 ParentFP =
Builder.CreateCall(
1855 FrameRecoverFn, {
ParentCGF.CurFn, ParentFP,
1856 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1857 ParentFP =
Builder.CreateLoad(
1863 for (
const VarDecl *VD : Finder.Captures) {
1865 CGM.ErrorUnsupported(VD,
"VLA captured by SEH");
1869 "captured non-local variable");
1871 auto L =
ParentCGF.LambdaCaptureFields.find(VD);
1872 if (L !=
ParentCGF.LambdaCaptureFields.end()) {
1879 auto I =
ParentCGF.LocalDeclMap.find(VD);
1883 Address ParentVar = I->second;
1886 setAddrOfLocalVar(VD, Recovered);
1889 CXXABIThisAlignment =
ParentCGF.CXXABIThisAlignment;
1890 CXXThisAlignment =
ParentCGF.CXXThisAlignment;
1891 CXXABIThisValue =
Builder.CreateLoad(Recovered,
"this");
1905 CXXThisValue = CXXABIThisValue;
1910 if (Finder.SEHCodeSlot.
isValid()) {
1924 const Stmt *OutlinedStmt) {
1930 llvm::raw_svector_ostream OS(Name);
1932 assert(ParentSEHFn &&
"No CurSEHParent!");
1941 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
1947 &
getContext().Idents.get(
"exception_pointers"),
1952 &
getContext().Idents.get(
"abnormal_termination"),
1964 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
1966 llvm::FunctionType *FnTy =
CGM.getTypes().GetFunctionType(FnInfo);
1967 llvm::Function *Fn = llvm::Function::Create(
1968 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &
CGM.getModule());
2015 llvm::Value *ParentFP,
2016 llvm::Value *EntryFP) {
2019 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2042 llvm::Type *RecordTy = llvm::PointerType::getUnqual(
getLLVMContext());
2043 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy,
CGM.VoidPtrTy);
2047 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2055 return llvm::PoisonValue::get(
Int8PtrTy);
2061 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
2068 auto AI =
CurFn->arg_begin();
2073 llvm::Function *FinallyFunc) {
2074 EHStack.pushCleanup<PerformSEHFinally>(
2079 CodeGenFunction HelperCGF(
CGM,
true);
2083 llvm::Function *FinallyFunc =
2105 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 &&
C &&
2113 llvm::Function *FilterFunc =
2132 assert(Except &&
"__try must have __finally xor __except");
2144 if (
const auto *DS = dyn_cast<DeclStmt>(S))
2145 for (
const Decl *D : DS->decls())
2146 if (
const auto *VD = dyn_cast<VarDecl>(D))
2149 VD->getLocation(), diag::err_seh_object_unwinding);
2174 llvm::CatchPadInst *CPI =
2177 Builder.CreateCatchRet(CPI, ExceptBB);
2181 if (
CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
2182 llvm::Function *SEHCodeIntrin =
2183 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
2184 llvm::Value *Code =
Builder.CreateCall(SEHCodeIntrin, {CPI});
2211 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 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::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 llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
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)
Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
llvm::PointerType * getType() const
Return the type of the pointer value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
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::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID, bool EnsureInsertPoint=true)
Emit a call to trap or debugtrap.
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.
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
Emits a call or invoke instruction to the given function, depending on the current state of the EH st...
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)
void WasmEmitFallthroughRethrow(llvm::BasicBlock *WasmCatchStartBlock)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
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.
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...
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.
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
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.
const EHPersonality & getEHPersonality(const TargetInfo &Target, const LangOptions &LangOpts, const CodeGenOptions &CGOpts, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
const EHPersonality & getCXXEHPersonality(const TargetInfo &Target, const CodeGenOptions &CGOpts)
Selects the personality function that plain C++ would use.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const EHPersonality & getEHPersonality(CodeGenModule &CGM, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
@ 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 exceptions personality for a function.
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
const char * PersonalityFn
bool isWasmPersonality() const
const char * CatchallRethrowFn
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.