[MS ABI] Hook clang up to the new EH instructions
The new EH instructions make it possible for LLVM to generate .xdata
tables that the MSVC personality routines will be happy about. Because
this is experimental, hide it behind a -cc1 flag (-fnew-ms-eh).
Differential Revision: http://reviews.llvm.org/D11405
llvm-svn: 243767
diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index 8338691..dcbc40d 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/lib/CodeGen/CGCleanup.h
@@ -40,9 +40,9 @@
class CommonBitFields {
friend class EHScope;
- unsigned Kind : 2;
+ unsigned Kind : 3;
};
- enum { NumCommonBits = 2 };
+ enum { NumCommonBits = 3 };
protected:
class CatchBitFields {
@@ -81,7 +81,7 @@
/// The number of fixups required by enclosing scopes (not including
/// this one). If this is the top cleanup scope, all the fixups
/// from this index onwards belong to this scope.
- unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 13
+ unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 12
};
class FilterBitFields {
@@ -99,7 +99,7 @@
};
public:
- enum Kind { Cleanup, Catch, Terminate, Filter };
+ enum Kind { Cleanup, Catch, Terminate, Filter, CatchEnd };
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
: CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
@@ -466,6 +466,17 @@
}
};
+class EHCatchEndScope : public EHScope {
+public:
+ EHCatchEndScope(EHScopeStack::stable_iterator enclosingEHScope)
+ : EHScope(CatchEnd, enclosingEHScope) {}
+ static size_t getSize() { return sizeof(EHCatchEndScope); }
+
+ static bool classof(const EHScope *scope) {
+ return scope->getKind() == CatchEnd;
+ }
+};
+
/// A non-stable pointer into the scope stack.
class EHScopeStack::iterator {
char *Ptr;
@@ -503,6 +514,10 @@
case EHScope::Terminate:
Size = EHTerminateScope::getSize();
break;
+
+ case EHScope::CatchEnd:
+ Size = EHCatchEndScope::getSize();
+ break;
}
Ptr += llvm::RoundUpToAlignment(Size, ScopeStackAlignment);
return *this;
@@ -551,6 +566,14 @@
deallocate(EHTerminateScope::getSize());
}
+inline void EHScopeStack::popCatchEnd() {
+ assert(!empty() && "popping exception stack when not empty");
+
+ EHCatchEndScope &scope = cast<EHCatchEndScope>(*begin());
+ InnermostEHScope = scope.getEnclosingEHScope();
+ deallocate(EHCatchEndScope::getSize());
+}
+
inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
assert(sp.isValid() && "finding invalid savepoint");
assert(sp.Size <= stable_begin().Size && "finding savepoint after pop");
@@ -588,6 +611,13 @@
static const EHPersonality MSVC_except_handler;
static const EHPersonality MSVC_C_specific_handler;
static const EHPersonality MSVC_CxxFrameHandler3;
+
+ bool isMSVCPersonality() const {
+ return this == &MSVC_except_handler || this == &MSVC_C_specific_handler ||
+ this == &MSVC_CxxFrameHandler3;
+ }
+
+ bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; }
};
}
}