13#ifndef LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
14#define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/SetVector.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/IR/Instruction.h"
50 llvm::BasicBlock *CachedLandingPad;
51 llvm::BasicBlock *CachedEHDispatchBlock;
55 class CommonBitFields {
57 LLVM_PREFERRED_TYPE(
Kind)
60 enum { NumCommonBits = 3 };
67 unsigned NumHandlers : 32 - NumCommonBits;
75 LLVM_PREFERRED_TYPE(
bool)
76 unsigned IsNormalCleanup : 1;
79 LLVM_PREFERRED_TYPE(
bool)
80 unsigned IsEHCleanup : 1;
83 LLVM_PREFERRED_TYPE(
bool)
84 unsigned IsActive : 1;
87 LLVM_PREFERRED_TYPE(
bool)
88 unsigned IsLifetimeMarker : 1;
91 LLVM_PREFERRED_TYPE(
bool)
92 unsigned IsFakeUse : 1;
95 LLVM_PREFERRED_TYPE(
bool)
96 unsigned TestFlagInNormalCleanup : 1;
99 LLVM_PREFERRED_TYPE(
bool)
100 unsigned TestFlagInEHCleanup : 1;
104 unsigned CleanupSize : 12;
111 unsigned NumFilters : 32 - NumCommonBits;
123 : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
124 EnclosingEHScope(enclosingEHScope) {
131 return CachedLandingPad;
135 CachedLandingPad = block;
139 return CachedEHDispatchBlock;
143 CachedEHDispatchBlock = block;
148 return !block->use_empty();
153 return EnclosingEHScope;
184 return reinterpret_cast<Handler*
>(
this+1);
187 const Handler *getHandlers()
const {
188 return reinterpret_cast<const Handler*
>(
this+1);
200 assert(
CatchBits.NumHandlers == numHandlers &&
"NumHandlers overflow?");
225 return getHandlers()[I];
256 llvm::BasicBlock *NormalBlock;
274 mutable struct ExtInfo *ExtInfo;
279 struct AuxillaryAllocas {
284 void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); }
292 ~AuxillaryAllocas() {
295 llvm::SetVector<llvm::Instruction *> Uses;
296 for (
auto *Inst : llvm::reverse(AuxAllocas))
297 CollectUses(Inst, Uses);
299 for (
auto *I : llvm::reverse(Uses))
300 I->eraseFromParent();
304 void CollectUses(llvm::Instruction *I,
305 llvm::SetVector<llvm::Instruction *> &Uses) {
306 if (!I || !Uses.insert(I))
308 for (
auto *User : I->users())
309 CollectUses(cast<llvm::Instruction>(User), Uses);
312 mutable struct AuxillaryAllocas *AuxAllocas;
314 AuxillaryAllocas &getAuxillaryAllocas() {
316 AuxAllocas =
new struct AuxillaryAllocas();
326 struct ExtInfo &getExtInfo() {
327 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
331 const struct ExtInfo &getExtInfo()
const {
332 if (!ExtInfo) ExtInfo =
new struct ExtInfo();
352 EnclosingNormal(enclosingNormal), NormalBlock(nullptr),
353 ActiveFlag(
Address::invalid()), ExtInfo(nullptr), AuxAllocas(nullptr),
354 FixupDepth(fixupDepth) {
364 assert(
CleanupBits.CleanupSize == cleanupSize &&
"cleanup size overflow");
373 for (
auto *Alloca : Allocas)
374 getAuxillaryAllocas().Add(Alloca);
420 return EnclosingNormal;
431 bool hasBranches()
const {
return ExtInfo && !ExtInfo->Branches.empty(); }
445 llvm::BasicBlock *
Block) {
446 struct ExtInfo &ExtInfo = getExtInfo();
447 if (ExtInfo.Branches.insert(
Block).second)
448 ExtInfo.BranchAfters.push_back(std::make_pair(
Block, Index));
453 return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
458 return ExtInfo->BranchAfters[I].first;
463 return ExtInfo->BranchAfters[I].second;
482 return getExtInfo().Branches.insert(
Block).second;
487 if (!ExtInfo)
return false;
488 return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
502 "EHCleanupScope expected alignment");
513 llvm::Value **getFilters() {
514 return reinterpret_cast<llvm::Value**
>(
this+1);
517 llvm::Value *
const *getFilters()
const {
518 return reinterpret_cast<llvm::Value*
const *
>(
this+1);
525 assert(
FilterBits.NumFilters == numFilters &&
"NumFilters overflow");
529 return sizeof(
EHFilterScope) + numFilters *
sizeof(llvm::Value*);
536 getFilters()[i] = filterValue;
541 return getFilters()[i];
567 explicit iterator(
char *Ptr) : Ptr(Ptr) {}
573 return reinterpret_cast<EHScope*
>(Ptr);
632 assert(!
empty() &&
"popping exception stack when not empty");
640 assert(!
empty() &&
"popping exception stack when not empty");
648 assert(sp.
isValid() &&
"finding invalid savepoint");
649 assert(sp.Size <=
stable_begin().Size &&
"finding savepoint after pop");
650 return iterator(EndOfBuffer - sp.Size);
655 assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
bool isOne() const
isOne - 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)
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.
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 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
static bool classof(const EHScope *Scope)
llvm::BasicBlock * getNormalBlock() const
bool hasBranchThroughs() const
Determines if this cleanup scope has any branch throughs.
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)
Information for lazily generating a cleanup.
A non-stable pointer into the scope stack.
bool operator!=(iterator other) const
EHScope & operator*() const
bool encloses(iterator other) const
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.
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.
The base class of the type hierarchy.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
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.
The exceptions personality for a function.
bool isMSVCXXPersonality() const
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
static const EHPersonality XL_CPlusPlus
static const EHPersonality GNU_ObjC_SJLJ
bool isWasmPersonality() const
static const EHPersonality ZOS_CPlusPlus
static const EHPersonality GNUstep_ObjC
static const EHPersonality MSVC_CxxFrameHandler3
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
static const EHPersonality MSVC_C_specific_handler
static const EHPersonality GNU_CPlusPlus_SEH
static const EHPersonality GNU_ObjC
static const EHPersonality GNU_CPlusPlus_SJLJ
static const EHPersonality GNU_C_SJLJ
static const EHPersonality GNU_C
static const EHPersonality NeXT_ObjC
const char * CatchallRethrowFn
static const EHPersonality GNU_CPlusPlus
static const EHPersonality GNU_ObjCXX
bool isMSVCPersonality() const
static const EHPersonality GNU_C_SEH
static const EHPersonality MSVC_except_handler
static const EHPersonality GNU_ObjC_SEH
const char * PersonalityFn
static const EHPersonality GNU_Wasm_CPlusPlus