35void EHScopeStack::Cleanup::anchor() {}
38char *EHScopeStack::allocate(
size_t size) {
41 unsigned capacity = llvm::PowerOf2Ceil(std::max(size, 1024ul));
42 startOfBuffer = std::make_unique<char[]>(capacity);
43 startOfData = endOfBuffer = startOfBuffer.get() + capacity;
44 }
else if (
static_cast<size_t>(startOfData - startOfBuffer.get()) < size) {
45 unsigned currentCapacity = endOfBuffer - startOfBuffer.get();
46 unsigned usedCapacity =
47 currentCapacity - (startOfData - startOfBuffer.get());
48 unsigned requiredCapacity = usedCapacity + size;
51 unsigned newCapacity = llvm::PowerOf2Ceil(requiredCapacity);
53 std::unique_ptr<char[]> newStartOfBuffer =
54 std::make_unique<char[]>(newCapacity);
55 char *newEndOfBuffer = newStartOfBuffer.get() + newCapacity;
56 char *newStartOfData = newEndOfBuffer - usedCapacity;
57 memcpy(newStartOfData, startOfData, usedCapacity);
58 startOfBuffer.swap(newStartOfBuffer);
59 endOfBuffer = newEndOfBuffer;
60 startOfData = newStartOfData;
63 assert(startOfBuffer.get() + size <= startOfData);
68void EHScopeStack::deallocate(
size_t size) {
72void *EHScopeStack::pushCleanup(
CleanupKind kind,
size_t size) {
79 EHCleanupScope *scope =
new (buffer) EHCleanupScope(size);
82 cgf->cgm.errorNYI(
"push lifetime marker cleanup");
85 if (cgf->getLangOpts().EHAsynch && isEHCleanup && !isLifetimeMarker &&
86 cgf->getTarget().getCXXABI().isMicrosoft())
87 cgf->cgm.errorNYI(
"push seh cleanup");
93 assert(!
empty() &&
"popping exception stack when not empty");
97 deallocate(
cleanup.getAllocatedSize());
110 assert(cgf.
haveInsertPoint() &&
"cleanup ended with no insertion point?");
117 assert(!
ehStack.empty() &&
"cleanup stack is empty!");
127 mlir::Block *fallthroughSource = builder.getInsertionBlock();
128 bool hasFallthrough = fallthroughSource !=
nullptr && isActive;
130 bool requiresNormalCleanup = scope.
isNormalCleanup() && hasFallthrough;
134 if (!requiresNormalCleanup) {
146 cleanupBufferStack[8 *
sizeof(
void *)];
147 std::unique_ptr<char[]> cleanupBufferHeap;
153 if (cleanupSize <=
sizeof(cleanupBufferStack)) {
154 memcpy(cleanupBufferStack, cleanupSource, cleanupSize);
157 cleanupBufferHeap.reset(
new char[cleanupSize]);
158 memcpy(cleanupBufferHeap.get(), cleanupSource, cleanupSize);
177 while (
ehStack.stable_begin() != oldCleanupStackDepth) {
static void emitCleanup(CIRGenFunction &cgf, EHScopeStack::Cleanup *cleanup)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
bool haveInsertPoint() const
True if an insertion point is defined.
void popCleanupBlocks(EHScopeStack::stable_iterator oldCleanupStackDepth)
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
void popCleanupBlock()
Pops a cleanup block.
A cleanup scope which generates the cleanup blocks lazily.
size_t getCleanupSize() const
static size_t getSizeForCleanupSize(size_t size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
bool isNormalCleanup() const
void * getCleanupBuffer()
Information for lazily generating a cleanup.
A saved depth on the scope stack.
void popCleanup()
Pops a cleanup scope off the stack. This is private to CIRGenCleanup.cpp.
bool empty() const
Determines whether the exception-scopes stack is empty.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
static bool ehCleanupFlags()
static bool ehCleanupScopeRequiresEHCleanup()
static bool ehstackBranches()
static bool innermostEHScope()
static bool ehCleanupBranchFixups()