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"
67template <
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>
106 class stable_iterator {
123 bool encloses(stable_iterator I)
const {
return Size <= I.Size; }
131 friend bool operator==(stable_iterator A, stable_iterator B) {
132 return A.Size == B.Size;
134 friend bool operator!=(stable_iterator A, stable_iterator B) {
135 return A.Size != B.Size;
146 class LLVM_MOVABLE_POLYMORPHIC_TYPE
alignas(uint64_t) Cleanup {
148 virtual void anchor();
151 ~Cleanup() =
default;
154 Cleanup(
const Cleanup &) =
default;
155 Cleanup(Cleanup &&) {}
159 Cleanup &
operator=(
const Cleanup &) =
delete;
164 virtual bool isRedundantBeforeReturn() {
return false; }
170 F_IsNormalCleanupKind = 0x2,
171 F_IsEHCleanupKind = 0x4,
172 F_HasExitSwitch = 0x8,
180 bool isForEHCleanup()
const {
return flags & F_IsForEH; }
181 bool isForNormalCleanup()
const {
return !isForEHCleanup(); }
182 void setIsForEHCleanup() { flags |= F_IsForEH; }
184 bool isNormalCleanupKind()
const {
return flags & F_IsNormalCleanupKind; }
185 void setIsNormalCleanupKind() { flags |= F_IsNormalCleanupKind; }
189 bool isEHCleanupKind()
const {
return flags & F_IsEHCleanupKind; }
190 void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
192 bool hasExitSwitch()
const {
return flags & F_HasExitSwitch; }
193 void setHasExitSwitch() { flags |= F_HasExitSwitch; }
207 template <
class T,
class... As>
209 typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
212 template <std::size_t... Is>
220 restore(CGF, std::index_sequence_for<As...>()).Emit(CGF, flags);
247 stable_iterator InnermostNormalCleanup;
250 stable_iterator InnermostEHScope;
274 char *allocate(
size_t Size);
275 void deallocate(
size_t Size);
292 "Cleanup's alignment is too large.");
293 void *Buffer = pushCleanup(Kind,
sizeof(
T));
294 Cleanup *Obj =
new (Buffer)
T(A...);
299 template <
class T,
class... As>
302 "Cleanup's alignment is too large.");
303 void *Buffer = pushCleanup(Kind,
sizeof(
T));
304 Cleanup *Obj =
new (Buffer)
T(std::move(A));
321 template <
class T,
class... As>
324 "Cleanup's alignment is too large.");
325 void *Buffer = pushCleanup(Kind,
sizeof(
T) + T::getExtraSize(N));
326 return new (Buffer)
T(N, A...);
330 void *Buffer = pushCleanup(Kind, Size);
331 std::memcpy(Buffer, Cleanup, Size);
364 bool empty()
const {
return StartOfData == EndOfBuffer; }
370 return InnermostNormalCleanup !=
stable_end();
376 return InnermostNormalCleanup;
381 return InnermostEHScope;
418 return BranchFixups.back();
424 return BranchFixups[I];
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
A scope which attempts to handle some, possibly all, types of exceptions.
An exceptions scope which filters exceptions thrown through it.
ConditionalCleanup(SavedTuple Tuple)
ConditionalCleanup(typename DominatingValue< As >::saved_type... A)
A saved depth on the scope stack.
bool encloses(stable_iterator I) const
Returns true if this scope encloses I.
bool strictlyEncloses(stable_iterator I) const
Returns true if this scope strictly encloses I: that is, if it encloses I and is not I.
friend class EHScopeStack
static stable_iterator invalid()
friend bool operator==(stable_iterator A, stable_iterator B)
friend bool operator!=(stable_iterator A, stable_iterator B)
void popNullFixups()
Pops lazily-removed fixups from the end of the list.
BranchFixup & getBranchFixup(unsigned I)
bool requiresLandingPad() const
stable_iterator getInnermostNormalCleanup() const
Returns the innermost normal cleanup on the stack, or stable_end() if there are no normal cleanups.
EHScopeStack & operator=(const EHScopeStack &)=delete
void setCGF(CodeGenFunction *inCGF)
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
unsigned getNumBranchFixups() const
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
stable_iterator getInnermostEHScope() const
void pushCopyOfCleanup(CleanupKind Kind, const void *Cleanup, size_t Size)
bool empty() const
Determines whether the exception-scopes stack is empty.
void pushCleanup(CleanupKind Kind, As... A)
Push a lazily-created cleanup on the stack.
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
iterator end() const
Returns an iterator pointing to the outermost EH scope.
bool containsOnlyNoopCleanups(stable_iterator Old) const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
void pushTerminate()
Push a terminate handler on the stack.
BranchFixup & addBranchFixup()
Add a branch fixup to the current cleanup scope.
void popCleanup()
Pops a cleanup scope off the stack. This is private to CGCleanup.cpp.
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 getInnermostActiveNormalCleanup() const
void popFilter()
Pops an exceptions filter off the stack.
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
stable_iterator stabilize(iterator it) const
Translates an iterator into a stable_iterator.
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
void clearFixups()
Clears the branch-fixups list.
void popTerminate()
Pops a terminate handler off the stack.
class LLVM_MOVABLE_POLYMORPHIC_TYPE alignas(uint64_t) Cleanup
Information for lazily generating a cleanup.
EHScopeStack(const EHScopeStack &)=delete
void pushCleanupTuple(CleanupKind Kind, std::tuple< As... > A)
Push a lazily-created cleanup on the stack. Tuple version.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of βparallelβ, 'serial',...
const FunctionProtoType * T
unsigned DestinationIndex
The destination index value.
llvm::BasicBlock * Destination
The ultimate destination of the branch.
llvm::BasicBlock * OptimisticBranchBlock
The block containing the terminator which needs to be modified into a switch if this fixup is resolve...
llvm::BranchInst * InitialBranch
The initial branch of the fixup.
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
static bool needsSaving(type value)
static type restore(CodeGenFunction &CGF, saved_type value)
static saved_type save(CodeGenFunction &CGF, type value)