================
@@ -70,45 +70,89 @@ void EHScopeStack::deallocate(size_t size) {
 }
 
 void *EHScopeStack::pushCleanup(CleanupKind kind, size_t size) {
-  char *buffer = allocate(size);
+  char *buffer = allocate(EHCleanupScope::getSizeForCleanupSize(size));
 
-  // When the full implementation is upstreamed, this will allocate
-  // extra memory for and construct a wrapper object that is used to
-  // manage the cleanup generation.
-  assert(!cir::MissingFeatures::ehCleanupScope());
+  EHCleanupScope *scope = new (buffer) EHCleanupScope(size);
 
-  return buffer;
+  return scope->getCleanupBuffer();
 }
 
-static mlir::Block *getCurCleanupBlock(CIRGenFunction &cgf) {
-  mlir::OpBuilder::InsertionGuard guard(cgf.getBuilder());
-  mlir::Block *cleanup =
-      cgf.curLexScope->getOrCreateCleanupBlock(cgf.getBuilder());
-  return cleanup;
+void EHScopeStack::popCleanup() {
+  assert(!empty() && "popping exception stack when not empty");
+
+  assert(isa<EHCleanupScope>(*begin()));
+  EHCleanupScope &cleanup = cast<EHCleanupScope>(*begin());
+  deallocate(cleanup.getAllocatedSize());
+
+  // Destroy the cleanup.
+  cleanup.destroy();
+
+  assert(!cir::MissingFeatures::ehCleanupBranchFixups());
+}
+
+static void emitCleanup(CIRGenFunction &cgf, EHScopeStack::Cleanup *cleanup) {
+  // Ask the cleanup to emit itself.
+  assert(cgf.haveInsertPoint() && "expected insertion point");
+  assert(!cir::MissingFeatures::ehCleanupFlags());
+  cleanup->emit(cgf);
+  assert(cgf.haveInsertPoint() && "cleanup ended with no insertion point?");
 }
 
 /// Pops a cleanup block. If the block includes a normal cleanup, the
 /// current insertion point is threaded through the cleanup, as are
 /// any branch fixups on the cleanup.
 void CIRGenFunction::popCleanupBlock() {
   assert(!ehStack.empty() && "cleanup stack is empty!");
+  assert(isa<EHCleanupScope>(*ehStack.begin()) && "top not a cleanup!");
+  EHCleanupScope &scope = cast<EHCleanupScope>(*ehStack.begin());
 
-  // The memory for the cleanup continues to be owned by the EHScopeStack
-  // allocator, so we just destroy the object rather than attempting to
-  // free it.
-  EHScopeStack::Cleanup &cleanup = *ehStack.begin();
+  // Remember activation information.
+  bool isActive = scope.isActive();
 
-  // The eventual implementation here will use the EHCleanupScope helper class.
-  assert(!cir::MissingFeatures::ehCleanupScope());
+  assert(!cir::MissingFeatures::ehCleanupBranchFixups());
 
-  mlir::OpBuilder::InsertionGuard guard(builder);
+  // - whether there's a fallthrough
+  mlir::Block *fallthroughSource = builder.getInsertionBlock();
+  bool hasFallthrough = fallthroughSource != nullptr && isActive;
+
+  bool requiresNormalCleanup = scope.isNormalCleanup() && hasFallthrough;
+
+  // If we don't need the cleanup at all, we're done.
+  assert(!cir::MissingFeatures::ehCleanupScopeRequiresEHCleanup());
+  if (!requiresNormalCleanup) {
+    ehStack.popCleanup();
+    return;
+  }
+
+  // Copy the cleanup emission data out.  This uses either a stack
+  // array or malloc'd memory, depending on the size, which is
+  // behavior that SmallVector would provide, if we could use it
+  // here. Unfortunately, if you ask for a SmallVector<char>, the
+  // alignment isn't sufficient.
----------------
mmha wrote:

We need to do an [aligned operator 
new](https://en.cppreference.com/w/cpp/memory/new/align_val_t.html) below now 
that we can use C++17.

But isn't it easier to create a `SmallVector<EHScopeStack::Cleanup>` and cast 
`vector.data()` to `char *` than the other way around? This way we get our 
alignment requrement satisfied, too.

https://github.com/llvm/llvm-project/pull/152589
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to