24 #include "llvm/IR/CallSite.h"
25 #include "llvm/IR/Intrinsics.h"
26 #include "llvm/IR/IntrinsicInst.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 =
"\01?terminate@@YAXXZ";
70 name =
"objc_terminate";
78 llvm::FunctionType *FTy =
86 struct EHPersonality {
87 const char *PersonalityFn;
92 const char *CatchallRethrowFn;
97 return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));
100 static const EHPersonality GNU_C;
101 static const EHPersonality GNU_C_SJLJ;
102 static const EHPersonality GNU_C_SEH;
103 static const EHPersonality GNU_ObjC;
104 static const EHPersonality GNUstep_ObjC;
105 static const EHPersonality GNU_ObjCXX;
106 static const EHPersonality NeXT_ObjC;
107 static const EHPersonality GNU_CPlusPlus;
108 static const EHPersonality GNU_CPlusPlus_SJLJ;
109 static const EHPersonality GNU_CPlusPlus_SEH;
110 static const EHPersonality MSVC_except_handler;
111 static const EHPersonality MSVC_C_specific_handler;
112 static const EHPersonality MSVC_CxxFrameHandler3;
116 const EHPersonality EHPersonality::GNU_C = {
"__gcc_personality_v0",
nullptr };
118 EHPersonality::GNU_C_SJLJ = {
"__gcc_personality_sj0",
nullptr };
120 EHPersonality::GNU_C_SEH = {
"__gcc_personality_seh0",
nullptr };
122 EHPersonality::NeXT_ObjC = {
"__objc_personality_v0",
nullptr };
124 EHPersonality::GNU_CPlusPlus = {
"__gxx_personality_v0",
nullptr };
126 EHPersonality::GNU_CPlusPlus_SJLJ = {
"__gxx_personality_sj0",
nullptr };
128 EHPersonality::GNU_CPlusPlus_SEH = {
"__gxx_personality_seh0",
nullptr };
130 EHPersonality::GNU_ObjC = {
"__gnu_objc_personality_v0",
"objc_exception_throw"};
132 EHPersonality::GNU_ObjCXX = {
"__gnustep_objcxx_personality_v0",
nullptr };
134 EHPersonality::GNUstep_ObjC = {
"__gnustep_objc_personality_v0",
nullptr };
136 EHPersonality::MSVC_except_handler = {
"_except_handler3",
nullptr };
138 EHPersonality::MSVC_C_specific_handler = {
"__C_specific_handler",
nullptr };
140 EHPersonality::MSVC_CxxFrameHandler3 = {
"__CxxFrameHandler3",
nullptr };
145 return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
150 if (L.SjLjExceptions)
151 return EHPersonality::GNU_C_SJLJ;
153 return EHPersonality::GNU_C_SEH;
154 return EHPersonality::GNU_C;
164 return EHPersonality::NeXT_ObjC;
167 return EHPersonality::GNUstep_ObjC;
171 return EHPersonality::GNU_ObjC;
173 llvm_unreachable(
"bad runtime kind");
178 if (L.SjLjExceptions)
179 return EHPersonality::GNU_CPlusPlus_SJLJ;
181 return EHPersonality::GNU_CPlusPlus_SEH;
182 return EHPersonality::GNU_CPlusPlus;
195 return EHPersonality::NeXT_ObjC;
206 return EHPersonality::GNU_ObjC;
208 return EHPersonality::GNU_ObjCXX;
210 llvm_unreachable(
"bad runtime kind");
214 if (T.getArch() == llvm::Triple::x86)
215 return EHPersonality::MSVC_except_handler;
216 return EHPersonality::MSVC_C_specific_handler;
227 if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
228 if (L.SjLjExceptions)
229 return EHPersonality::GNU_CPlusPlus_SJLJ;
233 return EHPersonality::MSVC_CxxFrameHandler3;
236 if (L.CPlusPlus && L.ObjC1)
238 else if (L.CPlusPlus)
247 const EHPersonality &Personality) {
250 Personality.PersonalityFn);
255 const EHPersonality &Personality) {
257 return llvm::ConstantExpr::getBitCast(Fn, CGM.
Int8PtrTy);
263 for (llvm::User *U : Fn->users()) {
265 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
266 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
273 llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(U);
274 if (!LPI)
return false;
276 for (
unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
279 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
280 if (LPI->isCatch(I)) {
282 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
285 if (GV->getName().startswith(
"OBJC_EHTYPE"))
289 llvm::Constant *CVal = cast<llvm::Constant>(Val);
290 for (llvm::User::op_iterator
291 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
292 if (llvm::GlobalVariable *GV =
293 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
296 if (GV->getName().startswith(
"OBJC_EHTYPE"))
310 void CodeGenModule::SimplifyPersonality() {
312 if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
320 const EHPersonality &ObjCXX = EHPersonality::get(*
this,
nullptr);
321 const EHPersonality &
CXX =
326 assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
327 "Different EHPersonalities using the same personality function.");
329 llvm::Function *Fn =
getModule().getFunction(ObjCXX.PersonalityFn);
332 if (!Fn || Fn->use_empty())
return;
342 if (Fn->getType() != CXXFn->getType())
return;
344 Fn->replaceAllUsesWith(CXXFn);
345 Fn->eraseFromParent();
352 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
374 pushFullExprCleanup<FreeException>(
EHCleanup, addr);
417 bool KeepInsertionPoint) {
419 QualType ThrowType = SubExpr->getType();
433 if (KeepInsertionPoint)
441 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
444 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
463 if (
getTarget().getCXXABI().isMicrosoft())
468 for (
unsigned I = 0; I != NumExceptions; ++I) {
482 if (!dispatchBlock)
return;
483 if (dispatchBlock->use_empty()) {
484 delete dispatchBlock;
499 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
500 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
512 ->setDoesNotReturn();
513 CGF.
Builder.CreateUnreachable();
520 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
523 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
541 if (
getTarget().getCXXABI().isMicrosoft())
559 for (
unsigned I = 0; I != NumHandlers; ++I) {
599 if (!dispatchBlock) {
629 return dispatchBlock;
638 return !cast<EHCleanupScope>(
S).isEHCleanup();
645 llvm_unreachable(
"Invalid EHScope Kind!");
655 if (!LO.Exceptions) {
656 if (!LO.Borland && !LO.MicrosoftExt)
674 ir->setCachedLandingPad(LP);
685 switch (innermostEHScope.getKind()) {
692 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
697 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
700 const EHPersonality &personality = EHPersonality::get(*
this);
702 if (!
CurFn->hasPersonalityFn())
709 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
723 bool hasCatchAll =
false;
724 bool hasCleanup =
false;
725 bool hasFilter =
false;
727 llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
731 switch (I->getKind()) {
734 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
738 assert(I.next() ==
EHStack.
end() &&
"EH filter is not end of EH stack");
739 assert(!hasCatchAll &&
"EH filter reached after catch-all");
746 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
747 filterTypes.push_back(filter.
getFilter(i));
753 assert(!hasCatchAll);
762 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
767 assert(!hasCatchAll);
773 if (catchTypes.insert(handler.
Type).second)
775 LPadInst->addClause(handler.
Type);
781 assert(!(hasCatchAll && hasFilter));
787 }
else if (hasFilter) {
792 llvm::ArrayType *AType =
793 llvm::ArrayType::get(!filterTypes.empty() ?
797 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
798 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
799 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
800 LPadInst->addClause(FilterArray);
804 LPadInst->setCleanup(
true);
807 }
else if (hasCleanup) {
808 LPadInst->setCleanup(
true);
811 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
812 "landingpad instruction has no clauses!");
828 assert(dispatchBlock);
838 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
850 assert(i < e &&
"ran off end of handlers!");
854 assert(typeValue &&
"fell into catch-all case!");
859 llvm::BasicBlock *nextBlock;
880 llvm::CallInst *typeIndex =
881 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
882 typeIndex->setDoesNotThrow();
885 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
886 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
890 CGF.
Builder.restoreIP(savedIP);
923 memcpy(Handlers.data(), CatchScope.
begin(),
937 bool doImplicitRethrow =
false;
939 doImplicitRethrow = isa<CXXDestructorDecl>(
CurCodeDecl) ||
949 for (
unsigned I = NumHandlers; I != 0; --I) {
950 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1001 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1005 llvm::BasicBlock *CleanupContBB =
1009 CGF.
Builder.CreateLoad(ForEHVar,
"finally.endcatch");
1010 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1027 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1028 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1034 ForEHVar, EndCatchFn);
1040 "cleanup.dest.saved");
1052 CGF.
Builder.CreateLoad(ForEHVar,
"finally.shouldthrow");
1053 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1058 CGF.
Builder.CreateLoad(SavedExnVar));
1062 CGF.
Builder.CreateUnreachable();
1067 CGF.
Builder.CreateStore(SavedCleanupDest,
1075 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1077 CGF.
Builder.restoreIP(SavedIP);
1092 llvm::Constant *beginCatchFn,
1093 llvm::Constant *endCatchFn,
1094 llvm::Constant *rethrowFn) {
1095 assert((beginCatchFn !=
nullptr) == (endCatchFn !=
nullptr) &&
1096 "begin/end catch functions not paired");
1097 assert(rethrowFn &&
"rethrow function is required");
1099 BeginCatchFn = beginCatchFn;
1107 llvm::FunctionType *rethrowFnTy =
1108 cast<llvm::FunctionType>(
1109 cast<llvm::PointerType>(rethrowFn->getType())->
getElementType());
1110 SavedExnVar =
nullptr;
1111 if (rethrowFnTy->getNumParams())
1137 ForEHVar, endCatchFn,
1138 rethrowFn, SavedExnVar);
1154 if (catchBB->use_empty()) {
1157 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1171 CGF.
Builder.CreateStore(exn, SavedExnVar);
1180 CGF.
Builder.restoreIP(savedIP);
1188 if (TerminateLandingPad)
1189 return TerminateLandingPad;
1191 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1195 Builder.SetInsertPoint(TerminateLandingPad);
1198 const EHPersonality &Personality = EHPersonality::get(*
this);
1200 if (!
CurFn->hasPersonalityFn())
1203 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
1209 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1210 llvm::CallInst *terminateCall =
1212 terminateCall->setDoesNotReturn();
1218 return TerminateLandingPad;
1222 if (TerminateHandler)
1223 return TerminateHandler;
1225 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1230 Builder.SetInsertPoint(TerminateHandler);
1234 llvm::CallInst *terminateCall =
1236 terminateCall->setDoesNotReturn();
1242 return TerminateHandler;
1248 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1254 const EHPersonality &Personality = EHPersonality::get(*
this);
1258 const char *RethrowName = Personality.CatchallRethrowFn;
1259 if (RethrowName !=
nullptr && !isCleanup) {
1271 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1272 Sel->getType(),
nullptr);
1273 llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1274 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1275 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1277 Builder.CreateResume(LPadVal);
1291 if (!TryExit.
getBlock()->use_empty())
1301 llvm::Function *OutlinedFinally;
1302 PerformSEHFinally(llvm::Function *OutlinedFinally)
1303 : OutlinedFinally(OutlinedFinally) {}
1316 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1322 const auto *FPT = cast<FunctionProtoType>(
1341 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1344 bool foundCaptures() {
1345 return !Captures.empty() || SEHCodeSlot;
1348 void Visit(
const Stmt *
S) {
1351 for (
const Stmt *Child : S->children())
1359 Captures.push_back(ParentThis);
1364 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1365 Captures.push_back(D);
1369 Captures.push_back(ParentThis);
1372 void VisitCallExpr(
const CallExpr *E) {
1374 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1379 case Builtin::BI__exception_code:
1380 case Builtin::BI_exception_code:
1385 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1394 llvm::CallInst *RecoverCall =
nullptr;
1396 if (
auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar)) {
1399 auto InsertPair = ParentCGF.EscapedLocals.insert(
1400 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1401 int FrameEscapeIdx = InsertPair.first->second;
1403 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1404 &CGM.
getModule(), llvm::Intrinsic::localrecover);
1405 llvm::Constant *ParentI8Fn =
1407 RecoverCall = Builder.CreateCall(
1408 FrameRecoverFn, {ParentI8Fn, ParentFP,
1409 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1415 auto *ParentRecover =
1416 cast<llvm::IntrinsicInst>(ParentVar->stripPointerCasts());
1417 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1418 "expected alloca or localrecover in parent LocalDeclMap");
1419 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1420 RecoverCall->setArgOperand(1, ParentFP);
1426 Builder.CreateBitCast(RecoverCall, ParentVar->getType());
1427 ChildVar->setName(ParentVar->getName());
1432 const Stmt *OutlinedStmt,
1435 CaptureFinder
Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1436 Finder.Visit(OutlinedStmt);
1440 if (!Finder.foundCaptures() &&
1455 EntryEBP = Builder.CreateCall(
1456 CGM.
getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
1457 llvm::Function *RecoverFPIntrin =
1459 llvm::Constant *ParentI8Fn =
1461 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryEBP});
1465 auto AI =
CurFn->arg_begin();
1471 for (
const VarDecl *VD : Finder.Captures) {
1472 if (isa<ImplicitParamDecl>(VD)) {
1482 "captured non-local variable");
1486 auto I = ParentCGF.LocalDeclMap.find(VD);
1487 if (I == ParentCGF.LocalDeclMap.end())
1495 if (Finder.SEHCodeSlot) {
1509 const Stmt *OutlinedStmt) {
1515 llvm::raw_svector_ostream OS(Name);
1517 const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
1518 assert(Parent &&
"FIXME: handle unnamed decls (lambdas, blocks) with SEH");
1533 &
getContext().Idents.get(
"exception_pointers"),
1538 &
getContext().Idents.get(
"abnormal_termination"),
1548 llvm::Function *ParentFn = ParentCGF.
CurFn;
1556 if (llvm::Comdat *
C = ParentFn->getComdat()) {
1558 }
else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
1559 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(ParentFn->getName());
1560 ParentFn->setComdat(C);
1569 OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
1604 CurFn->addFnAttr(llvm::Attribute::NoUnwind);
1605 CurFn->addFnAttr(llvm::Attribute::NoInline);
1622 auto AI =
CurFn->arg_begin();
1645 llvm::Type *RecordTy = CGM.
Int32Ty->getPointerTo();
1646 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.
VoidPtrTy,
nullptr);
1649 Rec =
Builder.CreateLoad(Rec);
1651 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1659 return llvm::UndefValue::get(
Int8PtrTy);
1665 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1672 auto AI =
CurFn->arg_begin();
1680 llvm::Function *FinallyFunc =
1708 llvm::Function *FilterFunc =
1710 llvm::Constant *OpaqueFunc =
1711 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
1724 assert(Except &&
"__try must have __finally xor __except");
1784 Builder.ClearInsertionPoint();
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
void pushTerminate()
Push a terminate handler on the stack.
QualType getExceptionType(unsigned i) const
iterator end() const
Returns an iterator pointing to the outermost EH scope.
llvm::IntegerType * IntTy
int
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
llvm::Value * getExceptionSlot()
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
Represents a version number in the form major[.minor[.subminor[.build]]].
void EmitAnyExprToExn(const Expr *E, llvm::Value *Addr)
llvm::Module & getModule() const
void EmitCXXTryStmt(const CXXTryStmt &S)
CXXCatchStmt * getHandler(unsigned i)
const TargetInfo & getTarget() const
llvm::Value * getFilter(unsigned i) const
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
void clearHandlerBlocks()
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
Represents Objective-C's @throw statement.
static llvm::Constant * getUnexpectedFn(CodeGenModule &CGM)
void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)
static llvm::Constant * getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
const LangOptions & getLangOpts() const
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CompoundStmt * getBlock() const
ExtProtoInfo - Extra information about a function prototype.
llvm::BasicBlock * EmitLandingPad()
Emits a landing pad for the current EH stack.
A protected scope for zero-cost EH handling.
llvm::Value * ReturnValue
Defines the Objective-C statement AST node classes.
llvm::BasicBlock * getCachedEHDispatchBlock() const
A C++ throw-expression (C++ [except.throw]).
llvm::Constant * getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)
static bool useLibGCCSEHPersonality(const llvm::Triple &T)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
llvm::Value * getNormalCleanupDestSlot()
llvm::BasicBlock * getTerminateHandler()
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
bool hasEHBranches() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Expr * getFilterExpr() const
void setFilter(unsigned i, llvm::Value *filterValue)
class EHCatchScope * pushCatch(unsigned NumHandlers)
const Handler & getHandler(unsigned I) const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, const Decl *TargetDecl=nullptr, llvm::Instruction **callOrInvoke=nullptr)
static llvm::Constant * getFreeExceptionFn(CodeGenModule &CGM)
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)
void ExitSEHTryStmt(const SEHTryStmt &S)
Stmt * getHandlerBlock() const
llvm::PointerType * VoidPtrTy
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
llvm::BasicBlock * getInvokeDestImpl()
llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)
void EmitStmt(const Stmt *S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void popFilter()
Pops an exceptions filter off the stack.
unsigned getBuiltinCallee() const
This represents the body of a CapturedStmt, and serves as its DeclContext.
llvm::AllocaInst * EHSelectorSlot
CanQualType UnsignedCharTy
llvm::Value * EmitSEHExceptionCode()
Represents the this expression in C++.
iterator find(stable_iterator save) const
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
bool hasTerminate() const
Does this runtime provide an objc_terminate function?
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
const TargetInfo & getTarget() const
bool usesSEHTry() const
Whether this is a (C++11) constexpr function or constexpr constructor.
ID
Defines the set of possible language-specific address spaces.
llvm::Value * ExceptionSlot
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
bool isNeXTFamily() const
Is this runtime basically of the NeXT family of runtimes?
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
bool empty() const
Determines whether the exception-scopes stack is empty.
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)
void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn, llvm::Constant *rethrowFn)
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)
CGCXXABI & getCXXABI() const
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)
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
llvm::Value * EmitSEHExceptionInfo()
void EmitSEHTryStmt(const SEHTryStmt &S)
ASTContext & getContext() const
llvm::Value * getSelectorFromSlot()
llvm::BasicBlock * getBlock() const
llvm::BasicBlock * Block
The catch handler for this type.
void add(RValue rvalue, QualType type, bool needscopy=false)
llvm::Value * getExceptionFromSlot()
static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)
EHScopeStack::stable_iterator getEnclosingEHScope() const
stable_iterator stable_begin() const
llvm::BasicBlock * getCachedLandingPad() const
bool currentFunctionUsesSEHTry() const
llvm::IntegerType * Int32Ty
static const EHPersonality & getObjCXXPersonality(const llvm::Triple &T, const LangOptions &L)
clang::ObjCRuntime ObjCRuntime
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
SmallVector< llvm::Value *, 1 > SEHCodeSlotStack
'gnustep' is the modern non-fragile GNUstep runtime.
llvm::IRBuilder< PreserveNames, llvm::ConstantFolder, CGBuilderInserterTy > CGBuilderTy
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, Qualifiers Quals, bool IsInitializer)
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)
Emit the dispatch block for a filter scope if necessary.
bool HaveInsertPoint() const
ASTMatchFinder *const Finder
Enumerates target-specific builtins in their own namespaces within namespace clang.
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
static const EHPersonality & getObjCPersonality(const llvm::Triple &T, const LangOptions &L)
llvm::Constant * EmitConstantExpr(const Expr *E, QualType DestType, CodeGenFunction *CGF=nullptr)
ASTContext & getContext() const
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
'objfw' is the Objective-C runtime included in ObjFW
llvm::BasicBlock * getUnreachableBlock()
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
Deactive a cleanup that was created in an active state.
CompoundStmt * getBlock() const
The noexcept specifier evaluates to true.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
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.
const LangOptions & getLangOpts() const
llvm::BasicBlock * getEHResumeBlock(bool isCleanup)
llvm::AllocaInst * CreateMemTemp(QualType T, const Twine &Name="tmp")
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
const VersionTuple & getVersion() const
NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const
Get the meaning of the noexcept spec on this function, if any.
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
MangleContext & getMangleContext()
Gets the mangle context.
void exit(CodeGenFunction &CGF)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
unsigned getNumHandlers() const
llvm::Value * getEHSelectorSlot()
llvm::Value * recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, llvm::Value *ParentVar, llvm::Value *ParentFP)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
static const EHPersonality & getCXXPersonality(const llvm::Triple &T, const LangOptions &L)
SourceLocation getExprLoc() const LLVM_READONLY
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
const Expr * getSubExpr() const
static const Type * getElementType(const Expr *BaseExpr)
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid. Otherwise switch to an artificial debug location that has a v...
The basic abstraction for the target Objective-C runtime.
static bool isNonEHScope(const EHScope &S)
llvm::IntegerType * IntPtrTy
unsigned getNumHandlers() const
QualType getCaughtType() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
const llvm::Triple & getTriple() const
QualType getNonReferenceType() const
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
llvm::PointerType * Int8PtrTy
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
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)
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
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.
bool isObjCObjectPointerType() const
llvm::BasicBlock * getTerminateLandingPad()
getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::Type * ConvertType(QualType T)
static const EHPersonality & getCPersonality(const llvm::Triple &T, const LangOptions &L)
void popTerminate()
Pops a terminate handler off the stack.
CompoundStmt * getTryBlock()
llvm::Value * EmitSEHAbnormalTermination()
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
void EnterSEHTryStmt(const SEHTryStmt &S)
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
unsigned getNumFilters() const
stable_iterator getInnermostEHScope() const
VarDecl * getExceptionDecl() const
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static RValue get(llvm::Value *V)
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
void EmitBranchThroughCleanup(JumpDest Dest)
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
static llvm::Constant * getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
CompoundStmt * getTryBlock() const
A non-stable pointer into the scope stack.
bool isSignedIntegerType() const
void EmitBlockAfterUses(llvm::BasicBlock *BB)
virtual llvm::Constant * GetEHType(QualType T)=0
bool requiresLandingPad() const
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals...
llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack
SEHFinallyStmt * getFinallyHandler() const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
unsigned getNumExceptions() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.