diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Support/AlignOf.h | 54 | ||||
-rw-r--r-- | llvm/unittests/Support/AlignOfTest.cpp | 18 |
2 files changed, 31 insertions, 41 deletions
diff --git a/llvm/include/llvm/Support/AlignOf.h b/llvm/include/llvm/Support/AlignOf.h index 2d8297ee87d..abd19afa22f 100644 --- a/llvm/include/llvm/Support/AlignOf.h +++ b/llvm/include/llvm/Support/AlignOf.h @@ -102,37 +102,45 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) #endif // _MSC_VER -// This code implements the equivalent of std::aligned_union from C++11. -// That is supported by Visual Studio 2015 and GCC 5.1. -// Once these are the baselines for LLVM, we can use std::aligned_union instead. - -namespace support { namespace detail { -template <typename T1> constexpr size_t aligner() { return alignof(T1); } - -template <typename T1, typename T2, typename... Ts> constexpr size_t aligner() { - return (alignof(T1) > aligner<T2, Ts...>()) ? alignof(T1) - : aligner<T2, Ts...>(); -} - -template <typename T1> constexpr size_t sizer() { return sizeof(T1); } +template <typename T1, + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> +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 <typename T1, typename T2, typename... Ts> constexpr size_t sizer() { - return (sizeof(T1) > sizer<T2, Ts...>()) ? sizeof(T1) : sizer<T2, Ts...>(); -} +template <typename T1, + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> +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)]; +}; } // end namespace detail -} // end namespace support /// \brief This union template exposes a suitably aligned and sized character -/// array member which can hold elements of any of a number of types. +/// array member which can hold elements of any of up to ten types. /// /// 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. -template <typename... Ts> -struct AlignedCharArrayUnion - : llvm::AlignedCharArray<support::detail::aligner<Ts...>(), - support::detail::sizer<Ts...>()> {}; +/// a placement new of any of these types. Support for more than ten types can +/// be added at the cost of more boilerplate. +template <typename T1, + typename T2 = char, typename T3 = char, typename T4 = char, + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> +struct AlignedCharArrayUnion : llvm::AlignedCharArray< + alignof(llvm::detail::AlignerImpl<T1, T2, T3, T4, T5, + T6, T7, T8, T9, T10>), + sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5, + T6, T7, T8, T9, T10>)> { +}; } // end namespace llvm #endif // LLVM_SUPPORT_ALIGNOF_H diff --git a/llvm/unittests/Support/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp index dfcdc1484b3..388ca11b776 100644 --- a/llvm/unittests/Support/AlignOfTest.cpp +++ b/llvm/unittests/Support/AlignOfTest.cpp @@ -91,24 +91,6 @@ V8::~V8() {} template <typename M> struct T { M m; }; -typedef uint8_t t1; -typedef uint16_t t2; -typedef uint32_t t3; -typedef uint64_t t4; -typedef int8_t t5; -typedef int16_t t6; -typedef int32_t t7; -typedef int64_t t8; -typedef struct { uint8_t bytes[16]; } t9; -typedef struct { uint16_t words[16]; } t10; -typedef struct { uint32_t words[16]; } t11; -typedef struct { uint64_t words[16]; } t12; - -typedef AlignedCharArrayUnion<t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12> U; - -static_assert(sizeof(U) == sizeof(uint64_t[16]), "Statically-computed size must be right"); -static_assert(alignof(U) == alignof(uint64_t), "Statically-computed alignment must be right"); - TEST(AlignOfTest, BasicAlignedArray) { EXPECT_LE(1u, alignof(AlignedCharArrayUnion<A1>)); EXPECT_LE(2u, alignof(AlignedCharArrayUnion<A2>)); |