13#ifndef LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
14#define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SetVector.h"
22#include "llvm/ADT/SmallPtrSet.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/IR/Instruction.h"
51 llvm::BasicBlock *CachedLandingPad;
52 llvm::BasicBlock *CachedEHDispatchBlock;
56 class CommonBitFields {
58 LLVM_PREFERRED_TYPE(Kind)
61 enum { NumCommonBits = 3 };
68 unsigned NumHandlers : 32 - NumCommonBits;
76 LLVM_PREFERRED_TYPE(
bool)
77 unsigned IsNormalCleanup : 1;
80 LLVM_PREFERRED_TYPE(
bool)
81 unsigned IsEHCleanup : 1;
84 LLVM_PREFERRED_TYPE(
bool)
85 unsigned IsActive : 1;
88 LLVM_PREFERRED_TYPE(
bool)
89 unsigned IsLifetimeMarker : 1;
92 LLVM_PREFERRED_TYPE(
bool)
93 unsigned IsFakeUse : 1;
96 LLVM_PREFERRED_TYPE(
bool)
97 unsigned TestFlagInNormalCleanup : 1;
100 LLVM_PREFERRED_TYPE(
bool)
101 unsigned TestFlagInEHCleanup : 1;
103 LLVM_PREFERRED_TYPE(
bool)
104 unsigned IsSEHFinallyCleanup : 1;
106 LLVM_PREFERRED_TYPE(
bool)
107 unsigned IsStackRestore : 1;
111 unsigned CleanupSize : 12;
118 unsigned NumFilters : 32 - NumCommonBits;
131 EnclosingEHScope(enclosingEHScope) {
138 return CachedLandingPad;
142 CachedLandingPad = block;
146 return CachedEHDispatchBlock;
150 CachedEHDispatchBlock = block;
155 return !block->use_empty();
160 return EnclosingEHScope;
191 return reinterpret_cast<Handler*
>(
this+1);
194 const Handler *getHandlers()
const {
195 return reinterpret_cast<const Handler*
>(
this+1);
207 assert(
CatchBits.NumHandlers == numHandlers &&
"NumHandlers overflow?");
221 getHandlers()[I].Block =
Block;
226 getHandlers()[I].Type =
Type;
227 getHandlers()[I].Block =
Block;
232 return getHandlers()[I];
263 llvm::BasicBlock *NormalBlock;
281 mutable struct ExtInfo *ExtInfo;
286 struct AuxillaryAllocas {
291 void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); }
299 ~AuxillaryAllocas() {
302 llvm::SetVector<llvm::Instruction *> Uses;
303 for (
auto *Inst : llvm::reverse(AuxAllocas))
304 CollectUses(Inst, Uses);
306 for (
auto *I : llvm::reverse(Uses))
307 I->eraseFromParent();
311 void CollectUses(llvm::Instruction *I,
312 llvm::SetVector<llvm::Instruction *> &Uses) {
313 if (!I || !Uses.insert(I))
315 for (
auto *User : I->users())
319 mutable struct AuxillaryAllocas *AuxAllocas;
321 AuxillaryAllocas &getAuxillaryAllocas() {
323 AuxAllocas =
new struct AuxillaryAllocas();
333 struct ExtInfo &getExtInfo() {
334 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
338 const struct ExtInfo &getExtInfo()
const {
339 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
359 EnclosingNormal(enclosingNormal), NormalBlock(
nullptr),
361 FixupDepth(fixupDepth) {
373 assert(
CleanupBits.CleanupSize == cleanupSize &&
"cleanup size overflow");
382 for (
auto *Alloca : Allocas)
383 getAuxillaryAllocas().Add(Alloca);
439 return EnclosingNormal;
450 bool hasBranches()
const {
return ExtInfo && !ExtInfo->Branches.empty(); }
464 llvm::BasicBlock *
Block) {
465 struct ExtInfo &ExtInfo = getExtInfo();
466 if (ExtInfo.Branches.insert(
Block).second)
467 ExtInfo.BranchAfters.push_back(std::make_pair(
Block, Index));
472 return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
477 return ExtInfo->BranchAfters[I].first;
482 return ExtInfo->BranchAfters[I].second;
501 return getExtInfo().Branches.insert(
Block).second;
506 if (!ExtInfo)
return false;
507 return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
521 "EHCleanupScope expected alignment");
532 llvm::Value **getFilters() {
533 return reinterpret_cast<llvm::Value**
>(
this+1);
536 llvm::Value *
const *getFilters()
const {
537 return reinterpret_cast<llvm::Value*
const *
>(
this+1);
544 assert(
FilterBits.NumFilters == numFilters &&
"NumFilters overflow");
548 return sizeof(
EHFilterScope) + numFilters *
sizeof(llvm::Value*);
555 getFilters()[i] = filterValue;
560 return getFilters()[i];
586 explicit iterator(
char *Ptr) : Ptr(Ptr) {}
592 return reinterpret_cast<EHScope*
>(Ptr);
624 iterator copy = *
this;
630 iterator copy = *
this;
635 bool encloses(iterator other)
const {
return Ptr >= other.Ptr; }
638 bool operator==(iterator other)
const {
return Ptr == other.Ptr; }
639 bool operator!=(iterator other)
const {
return Ptr != other.Ptr; }
651 assert(!
empty() &&
"popping exception stack when not empty");
659 assert(!
empty() &&
"popping exception stack when not empty");
667 assert(sp.
isValid() &&
"finding invalid savepoint");
668 assert(sp.Size <=
stable_begin().Size &&
"finding savepoint after pop");
669 return iterator(EndOfBuffer - sp.Size);
674 assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
static Decl::Kind getKind(const Decl *D)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
bool isOne() const
Test whether the quantity equals one.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
This class organizes the cross-function state that is used while generating LLVM code.
A scope which attempts to handle some, possibly all, types of exceptions.
EHCatchScope(unsigned numHandlers, EHScopeStack::stable_iterator enclosingEHScope)
const Handler & getHandler(unsigned I) const
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
friend class EHScopeStack
static size_t getSizeForNumHandlers(unsigned N)
void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block)
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
void clearHandlerBlocks()
static bool classof(const EHScope *Scope)
unsigned getNumHandlers() const
A cleanup scope which generates the cleanup blocks lazily.
void setSEHFinallyCleanup()
bool shouldTestFlagInEHCleanup() const
bool isLifetimeMarker() const
Address getActiveFlag() const
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const
size_t getAllocatedSize() const
bool hasActiveFlag() const
void setNormalBlock(llvm::BasicBlock *BB)
llvm::ConstantInt * getBranchAfterIndex(unsigned I) const
bool shouldTestFlagInNormalCleanup() const
bool isRedundantBeforeReturn() const
bool addBranchThrough(llvm::BasicBlock *Block)
Add a branch-through to this cleanup scope.
llvm::BasicBlock * getBranchAfterBlock(unsigned I) const
void AddAuxAllocas(llvm::SmallVector< llvm::AllocaInst * > Allocas)
void setTestFlagInNormalCleanup()
void setTestFlagInEHCleanup()
void * getCleanupBuffer()
unsigned getNumBranchAfters() const
Return the number of unique branch-afters on this scope.
bool isNormalCleanup() const
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
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.
void setActiveFlag(RawAddress Var)
EHCleanupScope(bool isNormal, bool isEH, unsigned cleanupSize, unsigned fixupDepth, EHScopeStack::stable_iterator enclosingNormal, EHScopeStack::stable_iterator enclosingEH)
EHScopeStack::Cleanup * getCleanup()
unsigned getFixupDepth() const
size_t getCleanupSize() const
bool isSEHFinallyCleanup() const
static bool classof(const EHScope *Scope)
llvm::BasicBlock * getNormalBlock() const
bool hasBranchThroughs() const
Determines if this cleanup scope has any branch throughs.
bool isStackRestore() const
An exceptions scope which filters exceptions thrown through it.
void setFilter(unsigned i, llvm::Value *filterValue)
static size_t getSizeForNumFilters(unsigned numFilters)
EHFilterScope(unsigned numFilters)
llvm::Value * getFilter(unsigned i) const
unsigned getNumFilters() const
static bool classof(const EHScope *scope)
A non-stable pointer into the scope stack.
bool operator!=(iterator other) const
EHScope & operator*() const
bool encloses(iterator other) const
friend class EHScopeStack
bool strictlyEncloses(iterator other) const
EHScope * operator->() const
bool operator==(iterator other) const
A saved depth on the scope stack.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
bool empty() const
Determines whether the exception-scopes stack is empty.
iterator end() const
Returns an iterator pointing to the outermost EH scope.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
void popCatch()
Pops a catch scope off the stack. This is private to CGException.cpp.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
stable_iterator stabilize(iterator it) const
Translates an iterator into a stable_iterator.
void popTerminate()
Pops a terminate handler off the stack.
friend class EHCatchScope
friend class EHCleanupScope
friend class EHFilterScope
A protected scope for zero-cost EH handling.
llvm::BasicBlock * getCachedLandingPad() const
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
void setCachedLandingPad(llvm::BasicBlock *block)
CleanupBitFields CleanupBits
FilterBitFields FilterBits
EHScopeStack::stable_iterator getEnclosingEHScope() const
llvm::BasicBlock * getCachedEHDispatchBlock() const
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
bool hasEHBranches() const
CommonBitFields CommonBits
An exceptions scope which calls std::terminate if any exception reaches it.
EHTerminateScope(EHScopeStack::stable_iterator enclosingEHScope)
static bool classof(const EHScope *scope)
An abstract representation of an aligned address.
CharUnits getAlignment() const
Return the alignment of this pointer.
Represents a function declaration or definition.
Scope - A scope is a transient data structure that is used while parsing the program.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const EHPersonality & getEHPersonality(CodeGenModule &CGM, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
Top level wrappers for InstallAPI frontend operations.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
The exceptions personality for a function.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
llvm::BasicBlock * Block
The catch handler for this type.