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];
289 unsigned cleanupSize,
unsigned fixupDepth,
293 EnclosingNormal(enclosingNormal),
NormalBlock(nullptr),
295 CleanupBits.IsNormalCleanup = isNormal;
296 CleanupBits.IsEHCleanup = isEH;
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; }
334 CleanupBits.TestFlagInNormalCleanup =
true;
337 return CleanupBits.TestFlagInNormalCleanup;
341 CleanupBits.TestFlagInEHCleanup =
true;
344 return CleanupBits.TestFlagInEHCleanup;
349 return EnclosingNormal;
374 llvm::BasicBlock *Block) {
376 if (ExtInfo.
Branches.insert(Block).second)
377 ExtInfo.
BranchAfters.push_back(std::make_pair(Block, Index));
421 return (Scope->
getKind() == Cleanup);
430 static_assert(llvm::AlignOf<EHCleanupScope>::Alignment ==
432 "EHCleanupScope expected alignment");
448 return reinterpret_cast<llvm::Value*
const *
>(
this+1);
455 assert(
FilterBits.NumFilters == numFilters &&
"NumFilters overflow");
466 getFilters()[i] = filterValue;
471 return getFilters()[i];
508 explicit iterator(
char *Ptr) : Ptr(Ptr) {}
514 return reinterpret_cast<EHScope*
>(Ptr);
525 static_cast<const EHCatchScope *>(
get())->getNumHandlers());
530 static_cast<const EHFilterScope *>(
get())->getNumFilters());
534 Size =
static_cast<const EHCleanupScope *
>(
get())->getAllocatedSize();
577 assert(!
empty() &&
"popping exception stack when not empty");
585 assert(!
empty() &&
"popping exception stack when not empty");
593 assert(sp.
isValid() &&
"finding invalid savepoint");
594 assert(sp.Size <=
stable_begin().Size &&
"finding savepoint after pop");
595 return iterator(EndOfBuffer - sp.Size);
600 assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
class LLVM_ALIGNAS(8) Decl
Decl - This represents one declaration (or definition), e.g.
iterator end() const
Returns an iterator pointing to the outermost EH scope.
unsigned getFixupDepth() const
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
void * getCleanupBuffer()
llvm::SmallPtrSet< llvm::BasicBlock *, 4 > Branches
The destinations of normal branch-afters and branch-throughs.
static const EHPersonality GNU_C_SJLJ
bool isOne() const
isOne - Test whether the quantity equals one.
llvm::BasicBlock * NormalBlock
The dual entry/exit block along the normal edge.
static const EHPersonality MSVC_C_specific_handler
llvm::Value * getFilter(unsigned i) const
static const EHPersonality MSVC_CxxFrameHandler3
bool hasBranches() const
True if this cleanup scope has any branch-afters or branch-throughs.
void clearHandlerBlocks()
static const EHPersonality GNU_C
size_t getCleanupSize() const
EHCatchScope(unsigned numHandlers, EHScopeStack::stable_iterator enclosingEHScope)
The base class of the type hierarchy.
bool hasBranchThroughs() const
Determines if this cleanup scope has any branch throughs.
friend class EHCleanupScope
bool hasActiveFlag() const
class LLVM_ALIGNAS(8) EHCleanupScope EHScopeStack::stable_iterator EnclosingEH
A cleanup scope which generates the cleanup blocks lazily.
bool isLifetimeMarker() const
void addBranchAfter(llvm::ConstantInt *Index, llvm::BasicBlock *Block)
Add a branch-after to this cleanup scope.
A protected scope for zero-cost EH handling.
llvm::BasicBlock * getCachedEHDispatchBlock() const
A scope which attempts to handle some, possibly all, types of exceptions.
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
struct ExtInfo & getExtInfo()
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
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
bool isNormalCleanup() const
unsigned FixupDepth
The number of fixups required by enclosing scopes (not including this one).
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.
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 CharUnits One()
One - Construct a CharUnits quantity of one.
bool encloses(iterator other) const
static const EHPersonality MSVC_except_handler
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.
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
bool operator!=(iterator other) const
llvm::ConstantInt * getBranchAfterIndex(unsigned I) const
Address getActiveFlag() const
void setActiveFlag(Address Var)
bool isMSVCXXPersonality() const
static bool classof(const EHScope *Scope)
SmallVector< std::pair< llvm::BasicBlock *, llvm::ConstantInt * >, 4 > BranchAfters
Normal branch-afters.
llvm::BasicBlock * Block
The catch handler for this type.
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::AllocaInst * ActiveFlag
An optional i1 variable indicating whether this cleanup has been activated yet.
static const EHPersonality GNU_ObjCXX
CommonBitFields CommonBits
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets...
EHCleanupScope(bool isNormal, bool isEH, bool isActive, unsigned cleanupSize, unsigned fixupDepth, EHScopeStack::stable_iterator enclosingNormal, EHScopeStack::stable_iterator enclosingEH)
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.
void setTestFlagInNormalCleanup()
CleanupBitFields CleanupBits
const TemplateArgument * iterator
A saved depth on the scope stack.
const char * PersonalityFn
size_t getAllocatedSize() const
static bool classof(const EHScope *Scope)
EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope)
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
bool shouldTestFlagInNormalCleanup() const
EHScopeStack::Cleanup * getCleanup()
unsigned getNumBranchAfters() const
Return the number of unique branch-afters on this scope.
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
bool addBranchThrough(llvm::BasicBlock *Block)
Add a branch-through to this cleanup scope.
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
static const EHPersonality GNU_ObjC
static bool classof(const EHScope *scope)
bool shouldTestFlagInEHCleanup() const
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const
void setNormalBlock(llvm::BasicBlock *BB)
static const EHPersonality GNU_CPlusPlus
llvm::BasicBlock * getNormalBlock() const
bool operator==(iterator other) const
static const EHPersonality GNU_C_SEH
The exceptions personality for a function.
void popTerminate()
Pops a terminate handler off the stack.
void setTestFlagInEHCleanup()
unsigned kind
All of the diagnostics that can be emitted by the frontend.
unsigned getNumFilters() const
static Decl::Kind getKind(const Decl *D)
An exceptions scope which filters exceptions thrown through it.
Extra information required for cleanups that have resolved branches through them. ...
Information for lazily generating a cleanup.
A non-stable pointer into the scope stack.
void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block)
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
FilterBitFields FilterBits
static bool classof(const EHScope *scope)
llvm::BasicBlock * getBranchAfterBlock(unsigned I) const