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 =
113 return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
118 if (L.SjLjExceptions)
142 llvm_unreachable(
"bad runtime kind");
147 if (L.SjLjExceptions)
180 llvm_unreachable(
"bad runtime kind");
184 if (T.getArch() == llvm::Triple::x86)
201 if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
202 if (L.SjLjExceptions)
208 if (L.CPlusPlus && L.ObjC1)
210 else if (L.CPlusPlus)
219 return get(CGF.
CGM, dyn_cast_or_null<FunctionDecl>(CGF.
CurCodeDecl));
233 return llvm::ConstantExpr::getBitCast(Fn, CGM.
Int8PtrTy);
238 for (
unsigned I = 0,
E = LPI->getNumClauses();
I !=
E; ++
I) {
241 llvm::Value *Val = LPI->getClause(
I)->stripPointerCasts();
242 if (LPI->isCatch(
I)) {
244 if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
247 if (GV->getName().startswith(
"OBJC_EHTYPE"))
251 llvm::Constant *CVal = cast<llvm::Constant>(Val);
252 for (llvm::User::op_iterator
253 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
254 if (llvm::GlobalVariable *GV =
255 cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
258 if (GV->getName().startswith(
"OBJC_EHTYPE"))
269 for (llvm::User *U : Fn->users()) {
271 if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
272 if (CE->getOpcode() != llvm::Instruction::BitCast)
return false;
279 llvm::Function *F = dyn_cast<llvm::Function>(U);
280 if (!F)
return false;
282 for (
auto BB = F->begin(),
E = F->end(); BB !=
E; ++BB) {
283 if (BB->isLandingPad())
296 void CodeGenModule::SimplifyPersonality() {
298 if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
313 "Different EHPersonalities using the same personality function.");
318 if (!Fn || Fn->use_empty())
return;
328 if (Fn->getType() != CXXFn->getType())
return;
330 Fn->replaceAllUsesWith(CXXFn);
331 Fn->eraseFromParent();
338 return llvm::ConstantPointerNull::get(CGF.
Int8PtrTy);
380 cast<llvm::Instruction>(typedAddr.
getPointer()));
404 bool KeepInsertionPoint) {
406 QualType ThrowType = SubExpr->getType();
420 if (KeepInsertionPoint)
428 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
431 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
450 if (
getTarget().getCXXABI().isMicrosoft())
455 for (
unsigned I = 0;
I != NumExceptions; ++
I) {
469 if (!dispatchBlock)
return;
470 if (dispatchBlock->use_empty()) {
471 delete dispatchBlock;
486 CGF.
Builder.CreateICmpSLT(selector, zero,
"ehspec.fails");
487 CGF.
Builder.CreateCondBr(failsFilter, unexpectedBB,
499 ->setDoesNotReturn();
500 CGF.
Builder.CreateUnreachable();
507 const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
510 if (
const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
528 if (
getTarget().getCXXABI().isMicrosoft())
546 for (
unsigned I = 0;
I != NumHandlers; ++
I) {
589 if (!dispatchBlock) {
618 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
622 return dispatchBlock;
637 return DispatchBlock;
647 DispatchBlock->setName(
"catch.dispatch");
651 DispatchBlock->setName(
"ehcleanup");
655 llvm_unreachable(
"exception specifications not handled yet!");
658 DispatchBlock->setName(
"terminate");
662 llvm_unreachable(
"PadEnd dispatch block missing!");
665 return DispatchBlock;
682 llvm_unreachable(
"Invalid EHScope Kind!");
692 if (!LO.Exceptions) {
693 if (!LO.Borland && !LO.MicrosoftExt)
706 if (!
CurFn->hasPersonalityFn())
722 ir->setCachedLandingPad(LP);
733 switch (innermostEHScope.getKind()) {
738 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
743 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
748 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
755 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
769 bool hasCatchAll =
false;
770 bool hasCleanup =
false;
771 bool hasFilter =
false;
773 llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
777 switch (
I->getKind()) {
780 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
784 assert(
I.next() ==
EHStack.
end() &&
"EH filter is not end of EH stack");
785 assert(!hasCatchAll &&
"EH filter reached after catch-all");
792 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
793 filterTypes.push_back(filter.
getFilter(i));
799 assert(!hasCatchAll);
807 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
811 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
814 "landingpads do not support catch handler flags");
818 assert(!hasCatchAll);
824 if (catchTypes.insert(handler.
Type.
RTTI).second)
826 LPadInst->addClause(handler.
Type.
RTTI);
832 assert(!(hasCatchAll && hasFilter));
838 }
else if (hasFilter) {
843 llvm::ArrayType *AType =
844 llvm::ArrayType::get(!filterTypes.empty() ?
848 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
849 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
850 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
851 LPadInst->addClause(FilterArray);
855 LPadInst->setCleanup(
true);
858 }
else if (hasCleanup) {
859 LPadInst->setCleanup(
true);
862 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
863 "landingpad instruction has no clauses!");
876 assert(DispatchBlock);
878 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
884 llvm::BasicBlock *UnwindBB =
888 llvm::CatchSwitchInst *CatchSwitch =
889 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
892 for (
unsigned I = 0;
I < NumHandlers; ++
I) {
904 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
906 CGF.
Builder.CreateCatchPad(CatchSwitch, {TypeInfo.
RTTI});
909 CatchSwitch->addHandler(Handler.
Block);
911 CGF.
Builder.restoreIP(SavedIP);
922 assert(dispatchBlock);
932 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
944 assert(i < e &&
"ran off end of handlers!");
949 "landingpads do not support catch handler flags");
950 assert(typeValue &&
"fell into catch-all case!");
955 llvm::BasicBlock *nextBlock;
976 llvm::CallInst *typeIndex =
977 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
978 typeIndex->setDoesNotThrow();
981 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
982 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
986 CGF.
Builder.restoreIP(savedIP);
1019 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1032 bool doImplicitRethrow =
false;
1034 doImplicitRethrow = isa<CXXDestructorDecl>(
CurCodeDecl) ||
1044 for (
unsigned I = NumHandlers;
I != 0; --
I) {
1045 llvm::BasicBlock *CatchBlock = Handlers[
I-1].Block;
1078 Builder.ClearInsertionPoint();
1098 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1102 llvm::BasicBlock *CleanupContBB =
1107 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1124 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1125 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1131 ForEHVar, EndCatchFn);
1137 "cleanup.dest.saved");
1150 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1159 CGF.
Builder.CreateUnreachable();
1172 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1174 CGF.
Builder.restoreIP(SavedIP);
1189 llvm::Constant *beginCatchFn,
1190 llvm::Constant *endCatchFn,
1191 llvm::Constant *rethrowFn) {
1192 assert((beginCatchFn !=
nullptr) == (endCatchFn !=
nullptr) &&
1193 "begin/end catch functions not paired");
1194 assert(rethrowFn &&
"rethrow function is required");
1196 BeginCatchFn = beginCatchFn;
1204 llvm::FunctionType *rethrowFnTy =
1205 cast<llvm::FunctionType>(
1206 cast<llvm::PointerType>(rethrowFn->getType())->
getElementType());
1207 SavedExnVar =
nullptr;
1208 if (rethrowFnTy->getNumParams())
1234 ForEHVar, endCatchFn,
1235 rethrowFn, SavedExnVar);
1251 if (catchBB->use_empty()) {
1254 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1277 CGF.
Builder.restoreIP(savedIP);
1285 if (TerminateLandingPad)
1286 return TerminateLandingPad;
1288 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1292 Builder.SetInsertPoint(TerminateLandingPad);
1297 if (!
CurFn->hasPersonalityFn())
1300 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
1306 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1307 llvm::CallInst *terminateCall =
1309 terminateCall->setDoesNotReturn();
1315 return TerminateLandingPad;
1319 if (TerminateHandler)
1320 return TerminateHandler;
1322 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1327 Builder.SetInsertPoint(TerminateHandler);
1333 Builder.CreateCleanupPad(ParentPad);
1338 llvm::CallInst *terminateCall =
1340 terminateCall->setDoesNotReturn();
1346 return TerminateHandler;
1352 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1363 if (RethrowName !=
nullptr && !isCleanup) {
1375 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1376 Sel->getType(),
nullptr);
1377 llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1378 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1379 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1381 Builder.CreateResume(LPadVal);
1395 if (!TryExit.
getBlock()->use_empty())
1405 llvm::Function *OutlinedFinally;
1406 PerformSEHFinally(llvm::Function *OutlinedFinally)
1407 : OutlinedFinally(OutlinedFinally) {}
1420 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
1426 const auto *FPT = cast<FunctionProtoType>(
1445 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1448 bool foundCaptures() {
1449 return !Captures.empty() || SEHCodeSlot.isValid();
1452 void Visit(
const Stmt *
S) {
1455 for (
const Stmt *Child : S->children())
1463 Captures.insert(ParentThis);
1468 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1473 Captures.insert(ParentThis);
1476 void VisitCallExpr(
const CallExpr *E) {
1478 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1483 case Builtin::BI__exception_code:
1484 case Builtin::BI_exception_code:
1488 if (!SEHCodeSlot.isValid())
1489 SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1499 llvm::CallInst *RecoverCall =
nullptr;
1501 if (
auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.
getPointer())) {
1504 auto InsertPair = ParentCGF.EscapedLocals.insert(
1505 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1506 int FrameEscapeIdx = InsertPair.first->second;
1508 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1509 &CGM.
getModule(), llvm::Intrinsic::localrecover);
1510 llvm::Constant *ParentI8Fn =
1512 RecoverCall = Builder.CreateCall(
1513 FrameRecoverFn, {ParentI8Fn, ParentFP,
1514 llvm::ConstantInt::get(
Int32Ty, FrameEscapeIdx)});
1520 auto *ParentRecover =
1521 cast<llvm::IntrinsicInst>(ParentVar.
getPointer()->stripPointerCasts());
1522 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1523 "expected alloca or localrecover in parent LocalDeclMap");
1524 RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1525 RecoverCall->setArgOperand(1, ParentFP);
1532 ChildVar->setName(ParentVar.
getName());
1537 const Stmt *OutlinedStmt,
1540 CaptureFinder
Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1541 Finder.Visit(OutlinedStmt);
1545 if (!Finder.foundCaptures() &&
1558 EntryFP = Builder.CreateCall(
1559 CGM.
getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
1563 auto AI =
CurFn->arg_begin();
1573 llvm::Function *RecoverFPIntrin =
1575 llvm::Constant *ParentI8Fn =
1577 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
1581 for (
const VarDecl *VD : Finder.Captures) {
1582 if (isa<ImplicitParamDecl>(VD)) {
1592 "captured non-local variable");
1596 auto I = ParentCGF.LocalDeclMap.find(VD);
1597 if (
I == ParentCGF.LocalDeclMap.end())
1605 if (Finder.SEHCodeSlot.isValid()) {
1619 const Stmt *OutlinedStmt) {
1625 llvm::raw_svector_ostream OS(Name);
1627 const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
1628 assert(Parent &&
"FIXME: handle unnamed decls (lambdas, blocks) with SEH");
1643 &
getContext().Idents.get(
"exception_pointers"),
1648 &
getContext().Idents.get(
"abnormal_termination"),
1658 llvm::Function *ParentFn = ParentCGF.
CurFn;
1666 if (llvm::Comdat *
C = ParentFn->getComdat()) {
1668 }
else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
1669 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(ParentFn->getName());
1670 ParentFn->setComdat(C);
1679 OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
1714 CurFn->addFnAttr(llvm::Attribute::NoUnwind);
1715 CurFn->addFnAttr(llvm::Attribute::NoInline);
1760 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1768 return llvm::UndefValue::get(
Int8PtrTy);
1774 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1781 auto AI =
CurFn->arg_begin();
1789 llvm::Function *FinallyFunc =
1817 llvm::Function *FilterFunc =
1819 llvm::Constant *OpaqueFunc =
1820 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
1833 assert(Except &&
"__try must have __finally xor __except");
1864 llvm::CatchPadInst *CPI =
1865 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
1867 Builder.CreateCatchRet(CPI, ExceptBB);
1872 llvm::Function *SEHCodeIntrin =
1901 Builder.ClearInsertionPoint();
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
void pushTerminate()
Push a terminate handler on the stack.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
QualType getExceptionType(unsigned i) const
iterator end() const
Returns an iterator pointing to the outermost EH scope.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
llvm::IntegerType * IntTy
int
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
A (possibly-)qualified type.
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
Represents a version number in the form major[.minor[.subminor[.build]]].
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
static const EHPersonality GNU_C_SJLJ
void EmitCXXTryStmt(const CXXTryStmt &S)
CXXCatchStmt * getHandler(unsigned i)
static const EHPersonality MSVC_C_specific_handler
const TargetInfo & getTarget() const
llvm::Value * getFilter(unsigned i) const
static const EHPersonality MSVC_CxxFrameHandler3
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")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
Decl - This represents one declaration (or definition), e.g.
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
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
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI ...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
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.
Defines the Objective-C statement AST node classes.
llvm::BasicBlock * getCachedEHDispatchBlock() const
A C++ throw-expression (C++ [except.throw]).
static bool useLibGCCSEHPersonality(const llvm::Triple &T)
On Win64, use libgcc's SEH personality function.
A scope which attempts to handle some, possibly all, types of exceptions.
The collection of all-type qualifiers we support.
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...
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
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
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 ...
SmallVector< Address, 1 > SEHCodeSlotStack
A stack of exception code slots.
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...
llvm::Value * SEHInfo
Value returned by __exception_info intrinsic.
bool hasEHBranches() const
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
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.
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...
Expr * getFilterExpr() const
void setFilter(unsigned i, llvm::Value *filterValue)
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
const Handler & getHandler(unsigned I) const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
static llvm::Constant * getFreeExceptionFn(CodeGenModule &CGM)
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
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)
Stmt * getHandlerBlock() const
llvm::PointerType * VoidPtrTy
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.
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)
EmitStmt - Emit the code for the statement.
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 popFilter()
Pops an exceptions filter off the stack.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
This represents the body of a CapturedStmt, and serves as its DeclContext.
detail::InMemoryDirectory::const_iterator I
llvm::AllocaInst * EHSelectorSlot
The selector slot.
CanQualType UnsignedCharTy
llvm::Value * EmitSEHExceptionCode()
Represents the this expression in C++.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack. ...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
'watchos' is a variant of iOS for Apple's watchOS.
bool hasTerminate() const
Does this runtime provide an objc_terminate function?
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
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...
static const EHPersonality MSVC_except_handler
static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)
const TargetInfo & getTarget() const
bool usesSEHTry() const
Indicates the function uses __try.
ID
Defines the set of possible language-specific address spaces.
llvm::Value * ExceptionSlot
The exception slot.
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::Value * getPointer() const
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
bool empty() const
Determines whether the exception-scopes stack is empty.
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.
Expr - 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...
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)
Create a stub filter function that will ultimately hold the code of the filter expression.
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.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CXXTryStmt - A C++ try block, including all handlers.
void add(RValue rvalue, QualType type, bool needscopy=false)
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.
EHScopeStack::stable_iterator getEnclosingEHScope() const
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
llvm::BasicBlock * getCachedLandingPad() const
llvm::LLVMContext & getLLVMContext()
bool currentFunctionUsesSEHTry() const
llvm::IntegerType * Int32Ty
static const EHPersonality & getObjCXXPersonality(const llvm::Triple &T, const LangOptions &L)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught...
static const EHPersonality GNU_ObjCXX
clang::ObjCRuntime ObjCRuntime
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)
Creates clause with a list of variables VL and a linear step Step.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets...
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
'gnustep' is the modern non-fragile GNUstep runtime.
llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)
Emit a store to an i1 flag variable.
GlobalDecl - represents a global declaration.
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
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.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)
Recovers the address of a local in a parent function.
ASTMatchFinder *const Finder
Enumerates target-specific builtins in their own namespaces within namespace clang.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
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)
Try to emit the given expression as a constant; returns 0 if the expression cannot be emitted as a co...
ASTContext & getContext() const
Encodes a location in the source.
CharUnits getPointerAlign() const
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.
const char * PersonalityFn
'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)
DeactivateCleanupBlock - Deactivates the given cleanup block.
CompoundStmt * getBlock() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
virtual CatchTypeInfo getCatchAllTypeInfo()
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)
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.
llvm::Instruction * CurrentFuncletPad
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...
llvm::StringRef getName() const
Return the IR name of the pointer value.
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
unsigned getNumHandlers() const
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
static const EHPersonality & getCXXPersonality(const llvm::Triple &T, const LangOptions &L)
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
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)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::BasicBlock * getMSVCDispatchBlock(EHScopeStack::stable_iterator scope)
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
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.
static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)
Check whether a landingpad instruction only uses C++ features.
static const EHPersonality GNU_CPlusPlus_SEH
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
The basic abstraction for the target Objective-C runtime.
static const EHPersonality GNU_ObjC
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
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="")
unsigned getNumHandlers() const
QualType getCaughtType() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
bool isSEHTryScope() const
Returns true inside SEH __try blocks.
const llvm::Triple & getTriple() const
Address getNormalCleanupDestSlot()
Represents a __leave statement.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
llvm::PointerType * getType() const
Return the type of the pointer value.
const T * getAs() const
Member-template getAs<specific type>'.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
CharUnits getIntAlign() const
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::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
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)
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.
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
static const EHPersonality GNU_C_SEH
static const EHPersonality & getCPersonality(const llvm::Triple &T, const LangOptions &L)
The exceptions personality for a function.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
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.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
unsigned getNumFilters() const
stable_iterator getInnermostEHScope() const
An exceptions scope which filters exceptions thrown through it.
VarDecl * getExceptionDecl() const
A reference to a declared variable, function, enum, etc.
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)
Figure out the rules for calling a function with the given formal type using the given arguments...
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.
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
static llvm::Constant * getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
Information for lazily generating a cleanup.
NamedDecl - This represents a decl with a name.
CompoundStmt * getTryBlock() const
A non-stable pointer into the scope stack.
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.
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)
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
CallArgList - Type for representing both the value and type of arguments in a call.
bool requiresLandingPad() const
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)
A class which abstracts out some details necessary for making a call.
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.