15 #ifndef LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H 16 #define LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/IR/BasicBlock.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/IR/Value.h" 28 class CodeGenFunction;
67 template <
class T,
bool mightBeInstruction =
68 std::is_base_of<llvm::Value, T>::value &&
69 !std::is_base_of<llvm::Constant, T>::value &&
70 !std::is_base_of<llvm::BasicBlock, T>::value>
102 enum { ScopeStackAlignment = 8 };
132 return A.Size == B.Size;
135 return A.Size != B.Size;
148 virtual void anchor();
162 F_IsNormalCleanupKind = 0x2,
163 F_IsEHCleanupKind = 0x4
196 template <
class T,
class... As>
198 typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
209 restore(CGF, std::index_sequence_for<As...>()).Emit(CGF, flags);
260 char *allocate(
size_t Size);
261 void deallocate(
size_t Size);
267 StartOfData(nullptr), InnermostNormalCleanup(stable_end()),
268 InnermostEHScope(stable_end()) {}
273 static_assert(
alignof(T) <= ScopeStackAlignment,
274 "Cleanup's alignment is too large.");
275 void *Buffer = pushCleanup(Kind,
sizeof(T));
276 Cleanup *Obj =
new (Buffer) T(A...);
281 template <
class T,
class... As>
283 static_assert(
alignof(T) <= ScopeStackAlignment,
284 "Cleanup's alignment is too large.");
285 void *Buffer = pushCleanup(Kind,
sizeof(T));
286 Cleanup *Obj =
new (Buffer) T(std::move(A));
303 template <
class T,
class... As>
305 static_assert(
alignof(T) <= ScopeStackAlignment,
306 "Cleanup's alignment is too large.");
307 void *Buffer = pushCleanup(Kind,
sizeof(T) + T::getExtraSize(N));
308 return new (Buffer) T(N, A...);
312 void *Buffer = pushCleanup(Kind, Size);
334 void pushTerminate();
344 bool empty()
const {
return StartOfData == EndOfBuffer; }
346 bool requiresLandingPad()
const;
350 return InnermostNormalCleanup != stable_end();
356 return InnermostNormalCleanup;
361 return InnermostEHScope;
396 assert(hasNormalCleanups() &&
"adding fixup in scope without cleanups");
398 return BranchFixups.back();
403 assert(I < getNumBranchFixups());
404 return BranchFixups[I];
410 void popNullFixups();
void setIsEHCleanupKind()
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
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.
static saved_type save(CodeGenFunction &CGF, type value)
A scope which attempts to handle some, possibly all, types of exceptions.
ConditionalCleanup stores the saved form of its parameters, then restores them and performs the clean...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function...
bool isNormalCleanupKind() const
unsigned getNumBranchFixups() const
bool isForEHCleanup() const
isForEH - true if the current emission is for an EH cleanup.
BranchFixup & getBranchFixup(unsigned I)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
bool strictlyEncloses(stable_iterator I) const
Returns true if this scope strictly encloses I: that is, if it encloses I and is not I...
void pushCleanup(CleanupKind Kind, As... A)
Push a lazily-created cleanup on the stack.
static type restore(CodeGenFunction &CGF, saved_type value)
llvm::BranchInst * InitialBranch
The initial branch of the fixup.
void clearFixups()
Clears the branch-fixups list.
stable_iterator getInnermostNormalCleanup() const
Returns the innermost normal cleanup on the stack, or stable_end() if there are no normal cleanups...
ConditionalCleanup(SavedTuple Tuple)
bool encloses(stable_iterator I) const
Returns true if this scope encloses I.
bool isForNormalCleanup() const
llvm::BasicBlock * OptimisticBranchBlock
The block containing the terminator which needs to be modified into a switch if this fixup is resolve...
llvm::BasicBlock * Destination
The ultimate destination of the branch.
A saved depth on the scope stack.
static bool needsSaving(type value)
void pushCopyOfCleanup(CleanupKind Kind, const void *Cleanup, size_t Size)
unsigned DestinationIndex
The destination index value.
void setIsNormalCleanupKind()
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
friend bool operator==(stable_iterator A, stable_iterator B)
Dataflow Directional Tag Classes.
BranchFixup & addBranchFixup()
Add a branch fixup to the current cleanup scope.
friend bool operator!=(stable_iterator A, stable_iterator B)
static stable_iterator invalid()
void pushCleanupTuple(CleanupKind Kind, std::tuple< As... > A)
Push a lazily-created cleanup on the stack. Tuple version.
ConditionalCleanup(typename DominatingValue< As >::saved_type... A)
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
bool isEHCleanupKind() const
isEHCleanupKind - true if the cleanup was pushed as an EH cleanup.
stable_iterator getInnermostEHScope() const
An exceptions scope which filters exceptions thrown through it.
Information for lazily generating a cleanup.