Skip to content

Commit 240fe7e

Browse files
authored
[CIR][NFC] EHScope & Cleanups Iterators and operators overloading (#165317)
Upstream EHScope & Cleanup iterators, helpers and operator overloading as a prerequisite for #165158 Issue #154992
1 parent 6f91f58 commit 240fe7e

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

clang/lib/CIR/CodeGen/CIRGenCleanup.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ void *EHScopeStack::pushCleanup(CleanupKind kind, size_t size) {
147147

148148
assert(!cir::MissingFeatures::innermostEHScope());
149149

150-
EHCleanupScope *scope = new (buffer)
151-
EHCleanupScope(size, branchFixups.size(), innermostNormalCleanup);
150+
EHCleanupScope *scope = new (buffer) EHCleanupScope(
151+
size, branchFixups.size(), innermostNormalCleanup, innermostEHScope);
152152

153153
if (isNormalCleanup)
154154
innermostNormalCleanup = stable_begin();
@@ -191,7 +191,9 @@ void EHScopeStack::popCleanup() {
191191
EHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
192192
char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
193193
assert(!cir::MissingFeatures::innermostEHScope());
194-
EHCatchScope *scope = new (buffer) EHCatchScope(numHandlers);
194+
EHCatchScope *scope =
195+
new (buffer) EHCatchScope(numHandlers, innermostEHScope);
196+
innermostEHScope = stable_begin();
195197
return scope;
196198
}
197199

clang/lib/CIR/CodeGen/CIRGenCleanup.h

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ struct CatchTypeInfo {
3030

3131
/// A protected scope for zero-cost EH handling.
3232
class EHScope {
33+
EHScopeStack::stable_iterator enclosingEHScope;
34+
3335
class CommonBitFields {
3436
friend class EHScope;
3537
unsigned kind : 3;
@@ -79,7 +81,10 @@ class EHScope {
7981
public:
8082
enum Kind { Cleanup, Catch, Terminate, Filter };
8183

82-
EHScope(Kind kind) { commonBits.kind = kind; }
84+
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
85+
: enclosingEHScope(enclosingEHScope) {
86+
commonBits.kind = kind;
87+
}
8388

8489
Kind getKind() const { return static_cast<Kind>(commonBits.kind); }
8590

@@ -90,6 +95,10 @@ class EHScope {
9095
assert(!cir::MissingFeatures::ehstackBranches());
9196
return false;
9297
}
98+
99+
EHScopeStack::stable_iterator getEnclosingEHScope() const {
100+
return enclosingEHScope;
101+
}
93102
};
94103

95104
/// A scope which attempts to handle some, possibly all, types of
@@ -111,19 +120,27 @@ class EHCatchScope : public EHScope {
111120

112121
/// The catch handler for this type.
113122
mlir::Region *region;
123+
124+
bool isCatchAll() const { return type.rtti == nullptr; }
114125
};
115126

116127
private:
117128
friend class EHScopeStack;
118129

119130
Handler *getHandlers() { return reinterpret_cast<Handler *>(this + 1); }
120131

132+
const Handler *getHandlers() const {
133+
return reinterpret_cast<const Handler *>(this + 1);
134+
}
135+
121136
public:
122137
static size_t getSizeForNumHandlers(unsigned n) {
123138
return sizeof(EHCatchScope) + n * sizeof(Handler);
124139
}
125140

126-
EHCatchScope(unsigned numHandlers) : EHScope(Catch) {
141+
EHCatchScope(unsigned numHandlers,
142+
EHScopeStack::stable_iterator enclosingEHScope)
143+
: EHScope(Catch, enclosingEHScope) {
127144
catchBits.numHandlers = numHandlers;
128145
assert(catchBits.numHandlers == numHandlers && "NumHandlers overflow?");
129146
}
@@ -136,6 +153,11 @@ class EHCatchScope : public EHScope {
136153
getHandlers()[i].region = region;
137154
}
138155

156+
const Handler &getHandler(unsigned i) const {
157+
assert(i < getNumHandlers());
158+
return getHandlers()[i];
159+
}
160+
139161
// Clear all handler blocks.
140162
// FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
141163
// 'takeHandler' or some such function which removes ownership from the
@@ -144,6 +166,10 @@ class EHCatchScope : public EHScope {
144166
// The blocks are owned by TryOp, nothing to delete.
145167
}
146168

169+
using iterator = const Handler *;
170+
iterator begin() const { return getHandlers(); }
171+
iterator end() const { return getHandlers() + getNumHandlers(); }
172+
147173
static bool classof(const EHScope *scope) {
148174
return scope->getKind() == Catch;
149175
}
@@ -176,9 +202,10 @@ class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
176202
}
177203

178204
EHCleanupScope(unsigned cleanupSize, unsigned fixupDepth,
179-
EHScopeStack::stable_iterator enclosingNormal)
180-
: EHScope(EHScope::Cleanup), enclosingNormal(enclosingNormal),
181-
fixupDepth(fixupDepth) {
205+
EHScopeStack::stable_iterator enclosingNormal,
206+
EHScopeStack::stable_iterator enclosingEH)
207+
: EHScope(EHScope::Cleanup, enclosingEH),
208+
enclosingNormal(enclosingNormal), fixupDepth(fixupDepth) {
182209
// TODO(cir): When exception handling is upstreamed, isNormalCleanup and
183210
// isEHCleanup will be arguments to the constructor.
184211
cleanupBits.isNormalCleanup = true;
@@ -235,13 +262,45 @@ class EHScopeStack::iterator {
235262

236263
EHScope *get() const { return reinterpret_cast<EHScope *>(ptr); }
237264

265+
EHScope *operator->() const { return get(); }
238266
EHScope &operator*() const { return *get(); }
267+
268+
iterator &operator++() {
269+
size_t size;
270+
switch (get()->getKind()) {
271+
case EHScope::Catch:
272+
size = EHCatchScope::getSizeForNumHandlers(
273+
static_cast<const EHCatchScope *>(get())->getNumHandlers());
274+
break;
275+
276+
case EHScope::Filter:
277+
llvm_unreachable("EHScopeStack::iterator Filter");
278+
break;
279+
280+
case EHScope::Cleanup:
281+
llvm_unreachable("EHScopeStack::iterator Cleanup");
282+
break;
283+
284+
case EHScope::Terminate:
285+
llvm_unreachable("EHScopeStack::iterator Terminate");
286+
break;
287+
}
288+
ptr += llvm::alignTo(size, ScopeStackAlignment);
289+
return *this;
290+
}
291+
292+
bool operator==(iterator other) const { return ptr == other.ptr; }
293+
bool operator!=(iterator other) const { return ptr != other.ptr; }
239294
};
240295

241296
inline EHScopeStack::iterator EHScopeStack::begin() const {
242297
return iterator(startOfData);
243298
}
244299

300+
inline EHScopeStack::iterator EHScopeStack::end() const {
301+
return iterator(endOfBuffer);
302+
}
303+
245304
inline EHScopeStack::iterator
246305
EHScopeStack::find(stable_iterator savePoint) const {
247306
assert(savePoint.isValid() && "finding invalid savepoint");
@@ -254,7 +313,7 @@ inline void EHScopeStack::popCatch() {
254313
assert(!empty() && "popping exception stack when not empty");
255314

256315
EHCatchScope &scope = llvm::cast<EHCatchScope>(*begin());
257-
assert(!cir::MissingFeatures::innermostEHScope());
316+
innermostEHScope = scope.getEnclosingEHScope();
258317
deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
259318
}
260319

clang/lib/CIR/CodeGen/EHScopeStack.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ class EHScopeStack {
155155
/// The innermost normal cleanup on the stack.
156156
stable_iterator innermostNormalCleanup = stable_end();
157157

158+
/// The innermost EH scope on the stack.
159+
stable_iterator innermostEHScope = stable_end();
160+
158161
/// The CGF this Stack belong to
159162
CIRGenFunction *cgf = nullptr;
160163

@@ -226,13 +229,18 @@ class EHScopeStack {
226229
}
227230
stable_iterator getInnermostActiveNormalCleanup() const;
228231

232+
stable_iterator getInnermostEHScope() const { return innermostEHScope; }
233+
229234
/// An unstable reference to a scope-stack depth. Invalidated by
230235
/// pushes but not pops.
231236
class iterator;
232237

233238
/// Returns an iterator pointing to the innermost EH scope.
234239
iterator begin() const;
235240

241+
/// Returns an iterator pointing to the outermost EH scope.
242+
iterator end() const;
243+
236244
/// Create a stable reference to the top of the EH stack. The
237245
/// returned reference is valid until that scope is popped off the
238246
/// stack.

0 commit comments

Comments
 (0)