Index: include/llvm/Support/AlignOf.h =================================================================== --- include/llvm/Support/AlignOf.h +++ include/llvm/Support/AlignOf.h @@ -58,6 +58,24 @@ ~AlignmentCalcImpl() override = 0; }; +template struct AlignOfImplOne { + enum { + Alignment = static_cast(sizeof(AlignmentCalcImpl) - sizeof(T)) + }; +}; + +template struct AlignOfImpl { + enum { + X = AlignOfImplOne::Alignment, + Y = AlignOfImpl::Alignment, + Alignment = (X > Y) ? X : Y + }; +}; + +template struct AlignOfImpl { + enum { Alignment = AlignOfImplOne::Alignment }; +}; + } // End detail namespace. /// AlignOf - A templated class that contains an enum value representing @@ -67,27 +85,22 @@ /// the "desired" alignment returned by GCC's __alignof__ (for example). Note /// that because the alignment is an enum value, it can be used as a /// compile-time constant (e.g., for template instantiation). -template -struct AlignOf { +template struct AlignOf { #ifndef _MSC_VER // Avoid warnings from GCC like: // comparison between 'enum llvm::AlignOf::' and 'enum // llvm::AlignOf::' [-Wenum-compare] // by using constexpr instead of enum. // (except on MSVC, since it doesn't support constexpr yet). - static constexpr unsigned Alignment = static_cast( - sizeof(detail::AlignmentCalcImpl) - sizeof(T)); + static constexpr unsigned Alignment = detail::AlignOfImpl::Alignment; #else - enum { - Alignment = static_cast( - sizeof(::llvm::detail::AlignmentCalcImpl) - sizeof(T)) - }; + enum { Alignment = detail::AlignOfImpl::Alignment }; #endif + enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; - enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; @@ -95,15 +108,16 @@ }; #ifndef _MSC_VER -template constexpr unsigned AlignOf::Alignment; +template constexpr unsigned AlignOf::Alignment; #endif /// alignOf - A templated function that returns the minimum alignment of /// of a type. This provides no extra functionality beyond the AlignOf /// class besides some cosmetic cleanliness. Example usage: /// alignOf() returns the alignment of an int. -template -inline unsigned alignOf() { return AlignOf::Alignment; } +template inline unsigned alignOf() { + return AlignOf::Alignment; +} /// \struct AlignedCharArray /// \brief Helper for building an aligned character array type. @@ -216,24 +230,16 @@ #endif // _MSC_VER namespace detail { -template -class AlignerImpl { - T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10; - - AlignerImpl() = delete; +template struct SizerImpl { + enum { + X = sizeof(T), + Y = SizerImpl::SizeOf, + SizeOf = (X > Y) ? X : Y + }; }; -template -union SizerImpl { - char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)], - arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)], - arr9[sizeof(T9)], arr10[sizeof(T10)]; +template struct SizerImpl { + enum { SizeOf = sizeof(T) }; }; } // end namespace detail @@ -242,18 +248,11 @@ /// /// These types may be arrays, structs, or any other types. The goal is to /// expose a char array buffer member which can be used as suitable storage for -/// a placement new of any of these types. Support for more than ten types can -/// be added at the cost of more boilerplate. -template -struct AlignedCharArrayUnion : llvm::AlignedCharArray< - AlignOf >::Alignment, - sizeof(::llvm::detail::SizerImpl)> { -}; +/// a placement new of any of these types. +template +using AlignedCharArrayUnion = + llvm::AlignedCharArray::Alignment, + llvm::detail::SizerImpl::SizeOf>; } // end namespace llvm #endif // LLVM_SUPPORT_ALIGNOF_H Index: include/llvm/Support/TrailingObjects.h =================================================================== --- include/llvm/Support/TrailingObjects.h +++ include/llvm/Support/TrailingObjects.h @@ -57,26 +57,6 @@ namespace llvm { namespace trailing_objects_internal { -/// Helper template to calculate the max alignment requirement for a set of -/// objects. -template class AlignmentCalcHelper { -private: - enum { - FirstAlignment = AlignOf::Alignment, - RestAlignment = AlignmentCalcHelper::Alignment, - }; - -public: - enum { - Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment - }; -}; - -template class AlignmentCalcHelper { -public: - enum { Alignment = AlignOf::Alignment }; -}; - /// The base class for TrailingObjects* classes. class TrailingObjectsBase { protected: @@ -228,11 +208,10 @@ /// See the file comment for details on the usage of the /// TrailingObjects type. template -class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl< - trailing_objects_internal::AlignmentCalcHelper< - TrailingTys...>::Alignment, - BaseTy, TrailingObjects, - BaseTy, TrailingTys...> { +class TrailingObjects + : private trailing_objects_internal::TrailingObjectsImpl< + AlignOf::Alignment, BaseTy, + TrailingObjects, BaseTy, TrailingTys...> { template friend struct trailing_objects_internal::TrailingObjectsImpl; @@ -240,8 +219,8 @@ template class Foo {}; typedef trailing_objects_internal::TrailingObjectsImpl< - trailing_objects_internal::AlignmentCalcHelper::Alignment, - BaseTy, TrailingObjects, BaseTy, TrailingTys...> + AlignOf::Alignment, BaseTy, + TrailingObjects, BaseTy, TrailingTys...> ParentType; using TrailingObjectsBase = trailing_objects_internal::TrailingObjectsBase;