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 FixupDepth : 32 - 18 - NumCommonBits;
98 unsigned : NumCommonBits;
100 unsigned NumFilters : 32 - NumCommonBits;
114 : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
115 EnclosingEHScope(enclosingEHScope) {
122 return CachedLandingPad;
126 CachedLandingPad = block;
130 return CachedEHDispatchBlock;
134 CachedEHDispatchBlock = block;
139 return !block->use_empty();
144 return EnclosingEHScope;
175 return reinterpret_cast<Handler*
>(
this+1);
178 const Handler *getHandlers()
const {
179 return reinterpret_cast<const Handler*
>(
this+1);
204 getHandlers()[
I].
Block = Block;
210 getHandlers()[
I].
Block = Block;
215 return getHandlers()[
I];
288 unsigned cleanupSize,
unsigned fixupDepth,
291 :
EHScope(
EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal),
293 CleanupBits.IsNormalCleanup = isNormal;
294 CleanupBits.IsEHCleanup = isEH;
296 CleanupBits.IsLifetimeMarker =
false;
297 CleanupBits.TestFlagInNormalCleanup =
false;
298 CleanupBits.TestFlagInEHCleanup =
false;
299 CleanupBits.CleanupSize = cleanupSize;
300 CleanupBits.FixupDepth = fixupDepth;
302 assert(CleanupBits.CleanupSize == cleanupSize &&
"cleanup size overflow");
317 bool isActive()
const {
return CleanupBits.IsActive; }
333 CleanupBits.TestFlagInNormalCleanup =
true;
336 return CleanupBits.TestFlagInNormalCleanup;
340 CleanupBits.TestFlagInEHCleanup =
true;
343 return CleanupBits.TestFlagInEHCleanup;
348 return EnclosingNormal;
373 llvm::BasicBlock *Block) {
375 if (ExtInfo.
Branches.insert(Block).second)
376 ExtInfo.
BranchAfters.push_back(std::make_pair(Block, Index));
420 return (Scope->
getKind() == Cleanup);
429 static_assert(llvm::AlignOf<EHCleanupScope>::Alignment ==
431 "EHCleanupScope expected alignment");
447 return reinterpret_cast<llvm::Value*
const *
>(
this+1);
464 getFilters()[i] = filterValue;
469 return getFilters()[i];
506 explicit iterator(
char *Ptr) : Ptr(Ptr) {}
512 return reinterpret_cast<EHScope*
>(Ptr);
523 static_cast<const EHCatchScope *>(
get())->getNumHandlers());
528 static_cast<const EHFilterScope *>(
get())->getNumFilters());
532 Size =
static_cast<const EHCleanupScope *
>(
get())->getAllocatedSize();
575 assert(!
empty() &&
"popping exception stack when not empty");
583 assert(!
empty() &&
"popping exception stack when not empty");
591 assert(sp.
isValid() &&
"finding invalid savepoint");
592 assert(sp.Size <=
stable_begin().Size &&
"finding savepoint after pop");
593 return iterator(EndOfBuffer - sp.Size);
598 assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
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
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.
class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt
Stmt - This represents one statement.
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