[clang] [CIR][NFC] EHScope & Cleanups Iterators and operators overloading (PR #165317)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 27 13:58:23 PDT 2025
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/165317
Upstream EHScope & Cleanup iterators, helpers and operator overloading as a prerequisite for #165158
Issue https://github.com/llvm/llvm-project/issues/154992
>From e696f073a39da0f315e35ae609d5809f95973922 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Mon, 27 Oct 2025 21:55:41 +0100
Subject: [PATCH] [CIR][NFC] EHScope & Cleanups Iterators and operators
overloading
---
clang/lib/CIR/CodeGen/CIRGenCleanup.cpp | 8 +--
clang/lib/CIR/CodeGen/CIRGenCleanup.h | 71 ++++++++++++++++++++++---
clang/lib/CIR/CodeGen/EHScopeStack.h | 8 +++
3 files changed, 78 insertions(+), 9 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
index 851328a7db680..437db306f3369 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
@@ -147,8 +147,8 @@ void *EHScopeStack::pushCleanup(CleanupKind kind, size_t size) {
assert(!cir::MissingFeatures::innermostEHScope());
- EHCleanupScope *scope = new (buffer)
- EHCleanupScope(size, branchFixups.size(), innermostNormalCleanup);
+ EHCleanupScope *scope = new (buffer) EHCleanupScope(
+ size, branchFixups.size(), innermostNormalCleanup, innermostEHScope);
if (isNormalCleanup)
innermostNormalCleanup = stable_begin();
@@ -191,7 +191,9 @@ void EHScopeStack::popCleanup() {
EHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
assert(!cir::MissingFeatures::innermostEHScope());
- EHCatchScope *scope = new (buffer) EHCatchScope(numHandlers);
+ EHCatchScope *scope =
+ new (buffer) EHCatchScope(numHandlers, innermostEHScope);
+ innermostEHScope = stable_begin();
return scope;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
index 61a09a59b05c0..a035d792ef6d1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
@@ -30,6 +30,8 @@ struct CatchTypeInfo {
/// A protected scope for zero-cost EH handling.
class EHScope {
+ EHScopeStack::stable_iterator enclosingEHScope;
+
class CommonBitFields {
friend class EHScope;
unsigned kind : 3;
@@ -79,7 +81,10 @@ class EHScope {
public:
enum Kind { Cleanup, Catch, Terminate, Filter };
- EHScope(Kind kind) { commonBits.kind = kind; }
+ EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
+ : enclosingEHScope(enclosingEHScope) {
+ commonBits.kind = kind;
+ }
Kind getKind() const { return static_cast<Kind>(commonBits.kind); }
@@ -90,6 +95,10 @@ class EHScope {
assert(!cir::MissingFeatures::ehstackBranches());
return false;
}
+
+ EHScopeStack::stable_iterator getEnclosingEHScope() const {
+ return enclosingEHScope;
+ }
};
/// A scope which attempts to handle some, possibly all, types of
@@ -111,6 +120,8 @@ class EHCatchScope : public EHScope {
/// The catch handler for this type.
mlir::Region *region;
+
+ bool isCatchAll() const { return type.rtti == nullptr; }
};
private:
@@ -118,12 +129,18 @@ class EHCatchScope : public EHScope {
Handler *getHandlers() { return reinterpret_cast<Handler *>(this + 1); }
+ const Handler *getHandlers() const {
+ return reinterpret_cast<const Handler *>(this + 1);
+ }
+
public:
static size_t getSizeForNumHandlers(unsigned n) {
return sizeof(EHCatchScope) + n * sizeof(Handler);
}
- EHCatchScope(unsigned numHandlers) : EHScope(Catch) {
+ EHCatchScope(unsigned numHandlers,
+ EHScopeStack::stable_iterator enclosingEHScope)
+ : EHScope(Catch, enclosingEHScope) {
catchBits.numHandlers = numHandlers;
assert(catchBits.numHandlers == numHandlers && "NumHandlers overflow?");
}
@@ -136,6 +153,11 @@ class EHCatchScope : public EHScope {
getHandlers()[i].region = region;
}
+ const Handler &getHandler(unsigned i) const {
+ assert(i < getNumHandlers());
+ return getHandlers()[i];
+ }
+
// Clear all handler blocks.
// FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
// 'takeHandler' or some such function which removes ownership from the
@@ -144,6 +166,10 @@ class EHCatchScope : public EHScope {
// The blocks are owned by TryOp, nothing to delete.
}
+ using iterator = const Handler *;
+ iterator begin() const { return getHandlers(); }
+ iterator end() const { return getHandlers() + getNumHandlers(); }
+
static bool classof(const EHScope *scope) {
return scope->getKind() == Catch;
}
@@ -176,9 +202,10 @@ class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
}
EHCleanupScope(unsigned cleanupSize, unsigned fixupDepth,
- EHScopeStack::stable_iterator enclosingNormal)
- : EHScope(EHScope::Cleanup), enclosingNormal(enclosingNormal),
- fixupDepth(fixupDepth) {
+ EHScopeStack::stable_iterator enclosingNormal,
+ EHScopeStack::stable_iterator enclosingEH)
+ : EHScope(EHScope::Cleanup, enclosingEH),
+ enclosingNormal(enclosingNormal), fixupDepth(fixupDepth) {
// TODO(cir): When exception handling is upstreamed, isNormalCleanup and
// isEHCleanup will be arguments to the constructor.
cleanupBits.isNormalCleanup = true;
@@ -235,13 +262,45 @@ class EHScopeStack::iterator {
EHScope *get() const { return reinterpret_cast<EHScope *>(ptr); }
+ EHScope *operator->() const { return get(); }
EHScope &operator*() const { return *get(); }
+
+ iterator &operator++() {
+ size_t size;
+ switch (get()->getKind()) {
+ case EHScope::Catch:
+ size = EHCatchScope::getSizeForNumHandlers(
+ static_cast<const EHCatchScope *>(get())->getNumHandlers());
+ break;
+
+ case EHScope::Filter:
+ llvm_unreachable("EHScopeStack::iterator Filter");
+ break;
+
+ case EHScope::Cleanup:
+ llvm_unreachable("EHScopeStack::iterator Cleanup");
+ break;
+
+ case EHScope::Terminate:
+ llvm_unreachable("EHScopeStack::iterator Terminate");
+ break;
+ }
+ ptr += llvm::alignTo(size, ScopeStackAlignment);
+ return *this;
+ }
+
+ bool operator==(iterator other) const { return ptr == other.ptr; }
+ bool operator!=(iterator other) const { return ptr != other.ptr; }
};
inline EHScopeStack::iterator EHScopeStack::begin() const {
return iterator(startOfData);
}
+inline EHScopeStack::iterator EHScopeStack::end() const {
+ return iterator(endOfBuffer);
+}
+
inline EHScopeStack::iterator
EHScopeStack::find(stable_iterator savePoint) const {
assert(savePoint.isValid() && "finding invalid savepoint");
@@ -254,7 +313,7 @@ inline void EHScopeStack::popCatch() {
assert(!empty() && "popping exception stack when not empty");
EHCatchScope &scope = llvm::cast<EHCatchScope>(*begin());
- assert(!cir::MissingFeatures::innermostEHScope());
+ innermostEHScope = scope.getEnclosingEHScope();
deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
}
diff --git a/clang/lib/CIR/CodeGen/EHScopeStack.h b/clang/lib/CIR/CodeGen/EHScopeStack.h
index 4198c23c9cbed..9005b0106b2a4 100644
--- a/clang/lib/CIR/CodeGen/EHScopeStack.h
+++ b/clang/lib/CIR/CodeGen/EHScopeStack.h
@@ -155,6 +155,9 @@ class EHScopeStack {
/// The innermost normal cleanup on the stack.
stable_iterator innermostNormalCleanup = stable_end();
+ /// The innermost EH scope on the stack.
+ stable_iterator innermostEHScope = stable_end();
+
/// The CGF this Stack belong to
CIRGenFunction *cgf = nullptr;
@@ -226,6 +229,8 @@ class EHScopeStack {
}
stable_iterator getInnermostActiveNormalCleanup() const;
+ stable_iterator getInnermostEHScope() const { return innermostEHScope; }
+
/// An unstable reference to a scope-stack depth. Invalidated by
/// pushes but not pops.
class iterator;
@@ -233,6 +238,9 @@ class EHScopeStack {
/// Returns an iterator pointing to the innermost EH scope.
iterator begin() const;
+ /// Returns an iterator pointing to the outermost EH scope.
+ iterator end() const;
+
/// Create a stable reference to the top of the EH stack. The
/// returned reference is valid until that scope is popped off the
/// stack.
More information about the cfe-commits
mailing list