41void EHScopeStack::Cleanup::anchor() {}
44char *EHScopeStack::allocate(
size_t size) {
47 unsigned capacity = llvm::PowerOf2Ceil(std::max(size, 1024ul));
48 startOfBuffer = std::make_unique<char[]>(capacity);
49 startOfData = endOfBuffer = startOfBuffer.get() + capacity;
50 }
else if (
static_cast<size_t>(startOfData - startOfBuffer.get()) < size) {
51 unsigned currentCapacity = endOfBuffer - startOfBuffer.get();
52 unsigned usedCapacity =
53 currentCapacity - (startOfData - startOfBuffer.get());
54 unsigned requiredCapacity = usedCapacity + size;
57 unsigned newCapacity = llvm::PowerOf2Ceil(requiredCapacity);
59 std::unique_ptr<char[]> newStartOfBuffer =
60 std::make_unique<char[]>(newCapacity);
61 char *newEndOfBuffer = newStartOfBuffer.get() + newCapacity;
62 char *newStartOfData = newEndOfBuffer - usedCapacity;
63 memcpy(newStartOfData, startOfData, usedCapacity);
64 startOfBuffer.swap(newStartOfBuffer);
65 endOfBuffer = newEndOfBuffer;
66 startOfData = newStartOfData;
69 assert(startOfBuffer.get() + size <= startOfData);
74void EHScopeStack::deallocate(
size_t size) {
78void *EHScopeStack::pushCleanup(
CleanupKind kind,
size_t size) {
85 EHCleanupScope *scope =
new (buffer) EHCleanupScope(size);
88 cgf->cgm.errorNYI(
"push lifetime marker cleanup");
91 if (cgf->getLangOpts().EHAsynch && isEHCleanup && !isLifetimeMarker &&
92 cgf->getTarget().getCXXABI().isMicrosoft())
93 cgf->cgm.errorNYI(
"push seh cleanup");
99 assert(!
empty() &&
"popping exception stack when not empty");
103 deallocate(
cleanup.getAllocatedSize());
116 assert(cgf.
haveInsertPoint() &&
"cleanup ended with no insertion point?");
123 assert(!
ehStack.empty() &&
"cleanup stack is empty!");
133 mlir::Block *fallthroughSource = builder.getInsertionBlock();
134 bool hasFallthrough = fallthroughSource !=
nullptr && isActive;
136 bool requiresNormalCleanup = scope.
isNormalCleanup() && hasFallthrough;
140 if (!requiresNormalCleanup) {
152 cleanupBufferStack[8 *
sizeof(
void *)];
153 std::unique_ptr<char[]> cleanupBufferHeap;
159 if (cleanupSize <=
sizeof(cleanupBufferStack)) {
160 memcpy(cleanupBufferStack, cleanupSource, cleanupSize);
163 cleanupBufferHeap.reset(
new char[cleanupSize]);
164 memcpy(cleanupBufferHeap.get(), cleanupSource, cleanupSize);
183 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.
static Destroyer destroyCXXObject
bool haveInsertPoint() const
True if an insertion point is defined.
void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType, Address ptr)
Emits all the code to cause the given temporary to be cleaned up.
void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer)
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.
Represents a C++ temporary.
A (possibly-)qualified type.
@ 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()