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!");
694 if (!LO.Exceptions) {
695 if (!LO.Borland && !LO.MicrosoftExt)
708 if (!
CurFn->hasPersonalityFn())
724 ir->setCachedLandingPad(LP);
735 switch (innermostEHScope.getKind()) {
740 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
745 if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
750 CGBuilderTy::InsertPoint savedIP =
Builder.saveAndClearIP();
757 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
771 bool hasCatchAll =
false;
772 bool hasCleanup =
false;
773 bool hasFilter =
false;
775 llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
779 switch (
I->getKind()) {
782 hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
786 assert(
I.next() ==
EHStack.
end() &&
"EH filter is not end of EH stack");
787 assert(!hasCatchAll &&
"EH filter reached after catch-all");
794 for (
unsigned i = 0, e = filter.
getNumFilters(); i != e; ++i)
795 filterTypes.push_back(filter.
getFilter(i));
801 assert(!hasCatchAll);
809 llvm_unreachable(
"PadEnd unnecessary for Itanium!");
813 for (
unsigned hi = 0, he = catchScope.
getNumHandlers(); hi != he; ++hi) {
816 "landingpads do not support catch handler flags");
820 assert(!hasCatchAll);
826 if (catchTypes.insert(handler.
Type.
RTTI).second)
828 LPadInst->addClause(handler.
Type.
RTTI);
834 assert(!(hasCatchAll && hasFilter));
840 }
else if (hasFilter) {
845 llvm::ArrayType *AType =
846 llvm::ArrayType::get(!filterTypes.empty() ?
850 for (
unsigned i = 0, e = filterTypes.size(); i != e; ++i)
851 Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
852 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
853 LPadInst->addClause(FilterArray);
857 LPadInst->setCleanup(
true);
860 }
else if (hasCleanup) {
861 LPadInst->setCleanup(
true);
864 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
865 "landingpad instruction has no clauses!");
878 assert(DispatchBlock);
880 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveIP();
886 llvm::BasicBlock *UnwindBB =
890 llvm::CatchSwitchInst *CatchSwitch =
891 CGF.
Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
894 for (
unsigned I = 0;
I < NumHandlers; ++
I) {
906 llvm::Constant::getNullValue(CGF.
VoidPtrTy)});
908 CGF.
Builder.CreateCatchPad(CatchSwitch, {TypeInfo.
RTTI});
911 CatchSwitch->addHandler(Handler.
Block);
913 CGF.
Builder.restoreIP(SavedIP);
924 assert(dispatchBlock);
934 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveIP();
946 assert(i < e &&
"ran off end of handlers!");
951 "landingpads do not support catch handler flags");
952 assert(typeValue &&
"fell into catch-all case!");
957 llvm::BasicBlock *nextBlock;
978 llvm::CallInst *typeIndex =
979 CGF.
Builder.CreateCall(llvm_eh_typeid_for, typeValue);
980 typeIndex->setDoesNotThrow();
983 CGF.
Builder.CreateICmpEQ(selector, typeIndex,
"matches");
984 CGF.
Builder.CreateCondBr(matchesTypeIndex, handler.
Block, nextBlock);
988 CGF.
Builder.restoreIP(savedIP);
1021 CatchScope.
begin(), CatchScope.
begin() + NumHandlers);
1034 bool doImplicitRethrow =
false;
1036 doImplicitRethrow = isa<CXXDestructorDecl>(
CurCodeDecl) ||
1046 for (
unsigned I = NumHandlers;
I != 0; --
I) {
1047 llvm::BasicBlock *CatchBlock = Handlers[
I-1].Block;
1080 Builder.ClearInsertionPoint();
1100 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1104 llvm::BasicBlock *CleanupContBB =
1109 CGF.
Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1126 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1127 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1133 ForEHVar, EndCatchFn);
1139 "cleanup.dest.saved");
1152 CGF.
Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1161 CGF.
Builder.CreateUnreachable();
1174 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
1176 CGF.
Builder.restoreIP(SavedIP);
1191 llvm::Constant *beginCatchFn,
1192 llvm::Constant *endCatchFn,
1193 llvm::Constant *rethrowFn) {
1194 assert((beginCatchFn !=
nullptr) == (endCatchFn !=
nullptr) &&
1195 "begin/end catch functions not paired");
1196 assert(rethrowFn &&
"rethrow function is required");
1198 BeginCatchFn = beginCatchFn;
1206 llvm::FunctionType *rethrowFnTy =
1207 cast<llvm::FunctionType>(
1208 cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
1209 SavedExnVar =
nullptr;
1210 if (rethrowFnTy->getNumParams())
1236 ForEHVar, endCatchFn,
1237 rethrowFn, SavedExnVar);
1253 if (catchBB->use_empty()) {
1256 CGBuilderTy::InsertPoint savedIP = CGF.
Builder.saveAndClearIP();
1279 CGF.
Builder.restoreIP(savedIP);
1287 if (TerminateLandingPad)
1288 return TerminateLandingPad;
1290 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1294 Builder.SetInsertPoint(TerminateLandingPad);
1299 if (!
CurFn->hasPersonalityFn())
1302 llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(
1308 Exn =
Builder.CreateExtractValue(LPadInst, 0);
1309 llvm::CallInst *terminateCall =
1311 terminateCall->setDoesNotReturn();
1317 return TerminateLandingPad;
1321 if (TerminateHandler)
1322 return TerminateHandler;
1324 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1329 Builder.SetInsertPoint(TerminateHandler);
1342 llvm::CallInst *terminateCall =
1344 terminateCall->setDoesNotReturn();
1350 return TerminateHandler;
1356 CGBuilderTy::InsertPoint SavedIP =
Builder.saveIP();
1367 if (RethrowName !=
nullptr && !isCleanup) {
1379 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1380 Sel->getType(),
nullptr);
1381 llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1382 LPadVal =
Builder.CreateInsertValue(LPadVal, Exn, 0,
"lpad.val");
1383 LPadVal =
Builder.CreateInsertValue(LPadVal, Sel, 1,
"lpad.val");
1385 Builder.CreateResume(LPadVal);
1399 if (!TryExit.
getBlock()->use_empty())
1409 llvm::Function *OutlinedFinally;
1410 PerformSEHFinally(llvm::Function *OutlinedFinally)
1411 : OutlinedFinally(OutlinedFinally) {}
1424 llvm::ConstantInt::get(CGF.
ConvertType(ArgTys[0]), F.isForEHCleanup());
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 assert(ParentSEHFn &&
"No CurSEHParent!");
1642 &
getContext().Idents.get(
"exception_pointers"),
1647 &
getContext().Idents.get(
"abnormal_termination"),
1657 llvm::Function *ParentFn = ParentCGF.
CurFn;
1665 if (llvm::Comdat *C = ParentFn->getComdat()) {
1667 }
else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
1668 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(ParentFn->getName());
1669 ParentFn->setComdat(C);
1678 OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
1754 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1762 return llvm::UndefValue::get(
Int8PtrTy);
1768 assert(!
SEHCodeSlotStack.empty() &&
"emitting EH code outside of __except");
1775 auto AI =
CurFn->arg_begin();
1783 llvm::Function *FinallyFunc =
1811 llvm::Function *FilterFunc =
1813 llvm::Constant *OpaqueFunc =
1814 llvm::ConstantExpr::getBitCast(FilterFunc,
Int8PtrTy);
1827 assert(Except &&
"__try must have __finally xor __except");
1858 llvm::CatchPadInst *CPI =
1859 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
1861 Builder.CreateCatchRet(CPI, ExceptBB);
1866 llvm::Function *SEHCodeIntrin =
1895 Builder.ClearInsertionPoint();
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, raw_ostream &Out)=0
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
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.
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
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...
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...
bool requiresLandingPad() const
'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
const FunctionDecl * CurSEHParent
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.
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
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
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
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()
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
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
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 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)
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.
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.
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)
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.