@@ -30,6 +30,8 @@ struct CatchTypeInfo {
3030
3131// / A protected scope for zero-cost EH handling.
3232class EHScope {
33+ EHScopeStack::stable_iterator enclosingEHScope;
34+
3335 class CommonBitFields {
3436 friend class EHScope ;
3537 unsigned kind : 3 ;
@@ -79,7 +81,10 @@ class EHScope {
7981public:
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
116127private:
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+
121136public:
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
241296inline EHScopeStack::iterator EHScopeStack::begin () const {
242297 return iterator (startOfData);
243298}
244299
300+ inline EHScopeStack::iterator EHScopeStack::end () const {
301+ return iterator (endOfBuffer);
302+ }
303+
245304inline EHScopeStack::iterator
246305EHScopeStack::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
0 commit comments