16 #ifndef LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H 17 #define LLVM_CLANG_LIB_CODEGEN_EHSCOPESTACK_H 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/IR/BasicBlock.h" 23 #include "llvm/IR/Instructions.h" 24 #include "llvm/IR/Value.h" 29 class CodeGenFunction;
68 template <
class T,
bool mightBeInstruction =
69 std::is_base_of<llvm::Value, T>::value &&
70 !std::is_base_of<llvm::Constant, T>::value &&
71 !std::is_base_of<llvm::BasicBlock, T>::value>
103 enum { ScopeStackAlignment = 8 };
133 return A.Size == B.Size;
136 return A.Size != B.Size;
149 virtual void anchor();
163 F_IsNormalCleanupKind = 0x2,
164 F_IsEHCleanupKind = 0x4
197 template <
class T,
class... As>
199 typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
210 restore(CGF, llvm::index_sequence_for<As...>()).Emit(CGF, flags);
261 char *allocate(
size_t Size);
262 void deallocate(
size_t Size);
268 StartOfData(nullptr), InnermostNormalCleanup(stable_end()),
269 InnermostEHScope(stable_end()) {}
274 static_assert(
alignof(T) <= ScopeStackAlignment,
275 "Cleanup's alignment is too large.");
276 void *Buffer = pushCleanup(Kind,
sizeof(T));
277 Cleanup *Obj =
new (Buffer) T(A...);
282 template <
class T,
class... As>
284 static_assert(
alignof(T) <= ScopeStackAlignment,
285 "Cleanup's alignment is too large.");
286 void *Buffer = pushCleanup(Kind,
sizeof(T));
287 Cleanup *Obj =
new (Buffer) T(std::move(A));
304 template <
class T,
class... As>
306 static_assert(
alignof(T) <= ScopeStackAlignment,
307 "Cleanup's alignment is too large.");
308 void *Buffer = pushCleanup(Kind,
sizeof(T) + T::getExtraSize(N));
309 return new (Buffer) T(N, A...);
313 void *Buffer = pushCleanup(Kind, Size);
335 void pushTerminate();
345 bool empty()
const {
return StartOfData == EndOfBuffer; }
347 bool requiresLandingPad()
const;
351 return InnermostNormalCleanup != stable_end();
357 return InnermostNormalCleanup;
362 return InnermostEHScope;
397 assert(hasNormalCleanups() &&
"adding fixup in scope without cleanups");
399 return BranchFixups.back();
404 assert(I < getNumBranchFixups());
405 return BranchFixups[I];
411 void popNullFixups();
void setIsEHCleanupKind()
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
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...
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)
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
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)
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.
A non-stable pointer into the scope stack.