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) {
85 if (cgf->
getLangOpts().EHAsynch && isEHCleanup && !isLifetimeMarker &&
93 assert(!
empty() &&
"popping exception stack when not empty");
95 assert(isa<EHCleanupScope>(*
begin()));
97 deallocate(cleanup.getAllocatedSize());
110 assert(cgf.
haveInsertPoint() &&
"cleanup ended with no insertion point?");
117 assert(!ehStack.empty() &&
"cleanup stack is empty!");
118 assert(isa<EHCleanupScope>(*ehStack.begin()) &&
"top not a cleanup!");
127 mlir::Block *fallthroughSource = builder.getInsertionBlock();
128 bool hasFallthrough = fallthroughSource !=
nullptr && isActive;
130 bool requiresNormalCleanup = scope.
isNormalCleanup() && hasFallthrough;
134 if (!requiresNormalCleanup) {
135 ehStack.popCleanup();
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);
165 ehStack.popCleanup();
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)
const clang::LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
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.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
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.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
@ 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.
static bool ehCleanupFlags()
static bool ehCleanupScopeRequiresEHCleanup()
static bool ehstackBranches()
static bool innermostEHScope()
static bool ehCleanupBranchFixups()