diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 13:34:49 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 13:34:49 +0000 |
commit | 63b24cc778504ffd19e4c30a730e574c346312ee (patch) | |
tree | 28726ef2038e86121e353aabf52297b35a48efa2 /contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h | |
parent | 9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (diff) | |
parent | 3176e97f130184ece0e1a21352c8124cc83ff24a (diff) | |
download | FreeBSD-src-63b24cc778504ffd19e4c30a730e574c346312ee.zip FreeBSD-src-63b24cc778504ffd19e4c30a730e574c346312ee.tar.gz |
Update clang to trunk r256633.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h | 125 |
1 files changed, 105 insertions, 20 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h b/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h index 81c6412..909f00b 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h @@ -15,6 +15,8 @@ #define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H #include "EHScopeStack.h" + +#include "Address.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -26,7 +28,17 @@ class AllocaInst; } namespace clang { +class FunctionDecl; namespace CodeGen { +class CodeGenModule; +class CodeGenFunction; + +/// The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the +/// type of a catch handler, so we use this wrapper. +struct CatchTypeInfo { + llvm::Constant *RTTI; + unsigned Flags; +}; /// A protected scope for zero-cost EH handling. class EHScope { @@ -37,9 +49,9 @@ class EHScope { class CommonBitFields { friend class EHScope; - unsigned Kind : 2; + unsigned Kind : 3; }; - enum { NumCommonBits = 2 }; + enum { NumCommonBits = 3 }; protected: class CatchBitFields { @@ -78,7 +90,7 @@ protected: /// 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 { @@ -96,7 +108,7 @@ protected: }; public: - enum Kind { Cleanup, Catch, Terminate, Filter }; + enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd }; EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope) : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr), @@ -148,12 +160,12 @@ public: struct Handler { /// A type info value, or null (C++ null, not an LLVM null pointer) /// for a catch-all. - llvm::Constant *Type; + CatchTypeInfo Type; /// The catch handler for this type. llvm::BasicBlock *Block; - bool isCatchAll() const { return Type == nullptr; } + bool isCatchAll() const { return Type.RTTI == nullptr; } }; private: @@ -183,11 +195,17 @@ public: } void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) { - setHandler(I, /*catchall*/ nullptr, Block); + setHandler(I, CatchTypeInfo{nullptr, 0}, Block); } void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) { assert(I < getNumHandlers()); + getHandlers()[I].Type = CatchTypeInfo{Type, 0}; + getHandlers()[I].Block = Block; + } + + void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block) { + assert(I < getNumHandlers()); getHandlers()[I].Type = Type; getHandlers()[I].Block = Block; } @@ -216,7 +234,7 @@ public: }; /// A cleanup scope which generates the cleanup blocks lazily. -class EHCleanupScope : public EHScope { +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EHCleanupScope : public EHScope { /// The nearest normal cleanup scope enclosing this one. EHScopeStack::stable_iterator EnclosingNormal; @@ -302,8 +320,14 @@ public: bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; } void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; } - llvm::AllocaInst *getActiveFlag() const { return ActiveFlag; } - void setActiveFlag(llvm::AllocaInst *Var) { ActiveFlag = Var; } + bool hasActiveFlag() const { return ActiveFlag != nullptr; } + Address getActiveFlag() const { + return Address(ActiveFlag, CharUnits::One()); + } + void setActiveFlag(Address Var) { + assert(Var.getAlignment().isOne()); + ActiveFlag = cast<llvm::AllocaInst>(Var.getPointer()); + } void setTestFlagInNormalCleanup() { CleanupBits.TestFlagInNormalCleanup = true; @@ -396,6 +420,15 @@ public: return (Scope->getKind() == Cleanup); } }; +// NOTE: there's a bunch of different data classes tacked on after an +// EHCleanupScope. It is asserted (in EHScopeStack::pushCleanup*) that +// they don't require greater alignment than ScopeStackAlignment. So, +// EHCleanupScope ought to have alignment equal to that -- not more +// (would be misaligned by the stack allocator), and not less (would +// break the appended classes). +static_assert(llvm::AlignOf<EHCleanupScope>::Alignment == + EHScopeStack::ScopeStackAlignment, + "EHCleanupScope expected alignment"); /// An exceptions scope which filters exceptions thrown through it. /// Only exceptions matching the filter types will be permitted to be @@ -454,6 +487,17 @@ public: } }; +class EHPadEndScope : public EHScope { +public: + EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope) + : EHScope(PadEnd, enclosingEHScope) {} + static size_t getSize() { return sizeof(EHPadEndScope); } + + static bool classof(const EHScope *scope) { + return scope->getKind() == PadEnd; + } +}; + /// A non-stable pointer into the scope stack. class EHScopeStack::iterator { char *Ptr; @@ -472,27 +516,31 @@ public: EHScope &operator*() const { return *get(); } iterator &operator++() { + size_t Size; switch (get()->getKind()) { case EHScope::Catch: - Ptr += EHCatchScope::getSizeForNumHandlers( - static_cast<const EHCatchScope*>(get())->getNumHandlers()); + Size = EHCatchScope::getSizeForNumHandlers( + static_cast<const EHCatchScope *>(get())->getNumHandlers()); break; case EHScope::Filter: - Ptr += EHFilterScope::getSizeForNumFilters( - static_cast<const EHFilterScope*>(get())->getNumFilters()); + Size = EHFilterScope::getSizeForNumFilters( + static_cast<const EHFilterScope *>(get())->getNumFilters()); break; case EHScope::Cleanup: - Ptr += static_cast<const EHCleanupScope*>(get()) - ->getAllocatedSize(); + Size = static_cast<const EHCleanupScope *>(get())->getAllocatedSize(); break; case EHScope::Terminate: - Ptr += EHTerminateScope::getSize(); + Size = EHTerminateScope::getSize(); break; - } + case EHScope::PadEnd: + Size = EHPadEndScope::getSize(); + break; + } + Ptr += llvm::RoundUpToAlignment(Size, ScopeStackAlignment); return *this; } @@ -528,7 +576,7 @@ inline void EHScopeStack::popCatch() { EHCatchScope &scope = cast<EHCatchScope>(*begin()); InnermostEHScope = scope.getEnclosingEHScope(); - StartOfData += EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()); + deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers())); } inline void EHScopeStack::popTerminate() { @@ -536,7 +584,7 @@ inline void EHScopeStack::popTerminate() { EHTerminateScope &scope = cast<EHTerminateScope>(*begin()); InnermostEHScope = scope.getEnclosingEHScope(); - StartOfData += EHTerminateScope::getSize(); + deallocate(EHTerminateScope::getSize()); } inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const { @@ -551,6 +599,43 @@ EHScopeStack::stabilize(iterator ir) const { return stable_iterator(EndOfBuffer - ir.Ptr); } +/// The exceptions personality for a function. +struct EHPersonality { + const char *PersonalityFn; + + // If this is non-null, this personality requires a non-standard + // function for rethrowing an exception after a catchall cleanup. + // This function must have prototype void(void*). + const char *CatchallRethrowFn; + + static const EHPersonality &get(CodeGenModule &CGM, const FunctionDecl *FD); + static const EHPersonality &get(CodeGenFunction &CGF); + + static const EHPersonality GNU_C; + static const EHPersonality GNU_C_SJLJ; + static const EHPersonality GNU_C_SEH; + static const EHPersonality GNU_ObjC; + static const EHPersonality GNUstep_ObjC; + static const EHPersonality GNU_ObjCXX; + static const EHPersonality NeXT_ObjC; + static const EHPersonality GNU_CPlusPlus; + static const EHPersonality GNU_CPlusPlus_SJLJ; + static const EHPersonality GNU_CPlusPlus_SEH; + static const EHPersonality MSVC_except_handler; + static const EHPersonality MSVC_C_specific_handler; + static const EHPersonality MSVC_CxxFrameHandler3; + + /// Does this personality use landingpads or the family of pad instructions + /// designed to form funclets? + bool usesFuncletPads() const { return isMSVCPersonality(); } + + bool isMSVCPersonality() const { + return this == &MSVC_except_handler || this == &MSVC_C_specific_handler || + this == &MSVC_CxxFrameHandler3; + } + + bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; } +}; } } |