Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}

Expand Down
71 changes: 65 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenCleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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); }

Expand All @@ -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
Expand All @@ -111,19 +120,27 @@ class EHCatchScope : public EHScope {

/// The catch handler for this type.
mlir::Region *region;

bool isCatchAll() const { return type.rtti == nullptr; }
};

private:
friend class EHScopeStack;

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?");
}
Expand All @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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()));
}

Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CIR/CodeGen/EHScopeStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -226,13 +229,18 @@ 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;

/// 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.
Expand Down
Loading