14 #ifndef LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
15 #define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallVector.h"
34 class CodeGenFunction;
45 llvm::BasicBlock *CachedLandingPad;
46 llvm::BasicBlock *CachedEHDispatchBlock;
50 class CommonBitFields {
54 enum { NumCommonBits = 3 };
59 unsigned : NumCommonBits;
61 unsigned NumHandlers : 32 - NumCommonBits;
66 unsigned : NumCommonBits;
69 unsigned IsNormalCleanup : 1;
72 unsigned IsEHCleanup : 1;
75 unsigned IsActive : 1;
78 unsigned IsLifetimeMarker : 1;
81 unsigned TestFlagInNormalCleanup : 1;
84 unsigned TestFlagInEHCleanup : 1;
88 unsigned CleanupSize : 12;
93 unsigned : NumCommonBits;
95 unsigned NumFilters : 32 - NumCommonBits;
109 : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
110 EnclosingEHScope(enclosingEHScope) {
117 return CachedLandingPad;
121 CachedLandingPad = block;
125 return CachedEHDispatchBlock;
129 CachedEHDispatchBlock = block;
134 return !block->use_empty();
139 return EnclosingEHScope;
170 return reinterpret_cast<Handler*
>(
this+1);
173 const Handler *getHandlers()
const {
174 return reinterpret_cast<const Handler*
>(
this+1);
186 assert(
CatchBits.NumHandlers == numHandlers &&
"NumHandlers overflow?");
200 getHandlers()[
I].
Block = Block;
206 getHandlers()[
I].
Block = Block;
211 return getHandlers()[
I];
242 llvm::BasicBlock *NormalBlock;
246 llvm::AllocaInst *ActiveFlag;
254 llvm::SmallPtrSet<llvm::BasicBlock*, 4> Branches;
260 mutable struct ExtInfo *ExtInfo;
267 struct ExtInfo &getExtInfo() {
268 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
272 const struct ExtInfo &getExtInfo()
const {
273 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
289 unsigned cleanupSize,
unsigned fixupDepth,
293 EnclosingNormal(enclosingNormal), NormalBlock(nullptr),
294 ActiveFlag(nullptr), ExtInfo(nullptr), FixupDepth(fixupDepth) {
295 CleanupBits.IsNormalCleanup = isNormal;
296 CleanupBits.IsEHCleanup = isEH;
297 CleanupBits.IsActive = isActive;
298 CleanupBits.IsLifetimeMarker =
false;
299 CleanupBits.TestFlagInNormalCleanup =
false;
300 CleanupBits.TestFlagInEHCleanup =
false;
301 CleanupBits.CleanupSize = cleanupSize;
303 assert(CleanupBits.CleanupSize == cleanupSize &&
"cleanup size overflow");
318 bool isActive()
const {
return CleanupBits.IsActive; }
330 ActiveFlag = cast<llvm::AllocaInst>(Var.
getPointer());
334 CleanupBits.TestFlagInNormalCleanup =
true;
337 return CleanupBits.TestFlagInNormalCleanup;
341 CleanupBits.TestFlagInEHCleanup =
true;
344 return CleanupBits.TestFlagInEHCleanup;
349 return EnclosingNormal;
360 bool hasBranches()
const {
return ExtInfo && !ExtInfo->Branches.empty(); }
374 llvm::BasicBlock *Block) {
375 struct ExtInfo &ExtInfo = getExtInfo();
376 if (ExtInfo.Branches.insert(Block).second)
377 ExtInfo.BranchAfters.push_back(std::make_pair(Block, Index));
382 return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
386 assert(I < getNumBranchAfters());
387 return ExtInfo->BranchAfters[
I].first;
391 assert(I < getNumBranchAfters());
392 return ExtInfo->BranchAfters[
I].second;
411 return getExtInfo().Branches.insert(Block).second;
416 if (!ExtInfo)
return false;
417 return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
421 return (Scope->
getKind() == Cleanup);
431 "EHCleanupScope expected alignment");
447 return reinterpret_cast<llvm::Value*
const *
>(
this+1);
454 assert(
FilterBits.NumFilters == numFilters &&
"NumFilters overflow");
465 getFilters()[i] = filterValue;
470 return getFilters()[i];
507 explicit iterator(
char *Ptr) : Ptr(Ptr) {}
513 return reinterpret_cast<EHScope*
>(Ptr);
524 static_cast<const EHCatchScope *>(
get())->getNumHandlers());
529 static_cast<const EHFilterScope *>(
get())->getNumFilters());
576 assert(!
empty() &&
"popping exception stack when not empty");
584 assert(!
empty() &&
"popping exception stack when not empty");
592 assert(sp.
isValid() &&
"finding invalid savepoint");
593 assert(sp.Size <=
stable_begin().Size &&
"finding savepoint after pop");
594 return iterator(EndOfBuffer - sp.Size);
599 assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
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...
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
static const EHPersonality GNU_C_SJLJ
bool isOne() const
isOne - Test whether the quantity equals one.
static const EHPersonality MSVC_C_specific_handler
llvm::Value * getFilter(unsigned i) const
static const EHPersonality MSVC_CxxFrameHandler3
void clearHandlerBlocks()
static const EHPersonality GNU_C
EHCatchScope(unsigned numHandlers, EHScopeStack::stable_iterator enclosingEHScope)
The base class of the type hierarchy.
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const
bool hasActiveFlag() const
A protected scope for zero-cost EH handling.
llvm::BasicBlock * getCachedEHDispatchBlock() const
A scope which attempts to handle some, possibly all, types of exceptions.
bool addBranchThrough(llvm::BasicBlock *Block)
Add a branch-through to this cleanup scope.
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
An exceptions scope which calls std::terminate if any exception reaches it.
stable_iterator stabilize(iterator it) const
Translates an iterator into a stable_iterator.
const char * CatchallRethrowFn
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
static const EHPersonality GNU_CPlusPlus_SJLJ
EHScope * operator->() const
bool hasEHBranches() const
void setFilter(unsigned i, llvm::Value *filterValue)
void setCachedLandingPad(llvm::BasicBlock *block)
const Handler & getHandler(unsigned I) const
bool isLifetimeMarker() const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
void setNormalBlock(llvm::BasicBlock *BB)
bool strictlyEncloses(iterator other) const
static bool classof(const EHScope *scope)
static const EHPersonality GNUstep_ObjC
bool isMSVCPersonality() const
Scope - A scope is a transient data structure that is used while parsing the program.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
size_t getCleanupSize() const
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
detail::InMemoryDirectory::const_iterator I
static size_t getSizeForNumHandlers(unsigned N)
EHFilterScope(unsigned numFilters)
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack. ...
static bool classof(const EHScope *Scope)
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool encloses(iterator other) const
static const EHPersonality MSVC_except_handler
EHScopeStack::Cleanup * getCleanup()
llvm::Value * getPointer() const
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.
bool operator!=(iterator other) const
void * getCleanupBuffer()
bool isMSVCXXPersonality() const
static bool classof(const EHScope *Scope)
llvm::BasicBlock * getBranchAfterBlock(unsigned I) const
llvm::BasicBlock * Block
The catch handler for this type.
EHScopeStack::stable_iterator getEnclosingEHScope() const
bool hasBranchThroughs() const
Determines if this cleanup scope has any branch throughs.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
llvm::BasicBlock * getCachedLandingPad() const
size_t getAllocatedSize() const
static const EHPersonality GNU_ObjCXX
bool isNormalCleanup() const
static const EHPersonality GNU_ObjC_SEH
void setActiveFlag(Address Var)
bool shouldTestFlagInNormalCleanup() const
CommonBitFields CommonBits
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets...
void setTestFlagInNormalCleanup()
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
The l-value was considered opaque, so the alignment was determined from a type.
CleanupBitFields CleanupBits
A saved depth on the scope stack.
const char * PersonalityFn
llvm::BasicBlock * getNormalBlock() const
EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope)
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
unsigned getNumHandlers() const
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
static size_t getSizeForNumFilters(unsigned numFilters)
static const EHPersonality NeXT_ObjC
EHScope & operator*() const
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
EHTerminateScope(EHScopeStack::stable_iterator enclosingEHScope)
static const EHPersonality GNU_CPlusPlus_SEH
bool hasBranches() const
True if this cleanup scope has any branch-afters or branch-throughs.
void addBranchAfter(llvm::ConstantInt *Index, llvm::BasicBlock *Block)
Add a branch-after to this cleanup scope.
static const EHPersonality GNU_ObjC
static bool classof(const EHScope *scope)
unsigned getFixupDepth() const
static const EHPersonality GNU_CPlusPlus
static const EHPersonality GNU_ObjC_SJLJ
bool operator==(iterator other) const
static const EHPersonality GNU_C_SEH
unsigned getNumBranchAfters() const
Return the number of unique branch-afters on this scope.
Address getActiveFlag() const
The exceptions personality for a function.
void popTerminate()
Pops a terminate handler off the stack.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
A cleanup scope which generates the cleanup blocks lazily.
llvm::ConstantInt * getBranchAfterIndex(unsigned I) const
unsigned getNumFilters() const
EHCleanupScope(bool isNormal, bool isEH, bool isActive, unsigned cleanupSize, unsigned fixupDepth, EHScopeStack::stable_iterator enclosingNormal, EHScopeStack::stable_iterator enclosingEH)
static Decl::Kind getKind(const Decl *D)
An exceptions scope which filters exceptions thrown through it.
Information for lazily generating a cleanup.
A non-stable pointer into the scope stack.
void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block)
void setTestFlagInEHCleanup()
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
FilterBitFields FilterBits
static bool classof(const EHScope *scope)
bool shouldTestFlagInEHCleanup() const