Index: include/llvm/Support/AlignOf.h =================================================================== --- include/llvm/Support/AlignOf.h +++ include/llvm/Support/AlignOf.h @@ -103,44 +103,34 @@ #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; +template class AlignerImpl; +template class AlignerImpl : AlignerImpl { + T1 t; AlignerImpl() = delete; }; -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 <> class AlignerImpl<> { + AlignerImpl() = delete; }; + +template constexpr size_t sizer() { return sizeof(T1); } + +template constexpr size_t sizer() { + return (sizeof(T1) > sizer()) ? sizeof(T1) : sizer(); +} } // end namespace detail /// \brief This union template exposes a suitably aligned and sized character -/// array member which can hold elements of any of up to ten types. +/// array member which can hold elements of any of a number of 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. Support for more than ten types can -/// be added at the cost of more boilerplate. -template -struct AlignedCharArrayUnion : llvm::AlignedCharArray< - alignof(llvm::detail::AlignerImpl), - sizeof(::llvm::detail::SizerImpl)> { -}; +/// a placement new of any of these types. +template +struct AlignedCharArrayUnion + : llvm::AlignedCharArray), + detail::sizer()> {}; } // end namespace llvm #endif // LLVM_SUPPORT_ALIGNOF_H Index: unittests/ADT/AlignOfTest.cpp =================================================================== --- unittests/ADT/AlignOfTest.cpp +++ unittests/ADT/AlignOfTest.cpp @@ -0,0 +1,43 @@ +//===----------- AlignOfTest.cpp - AlignOf unit tests ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/Support/AlignOf.h" + +using namespace llvm; +namespace { + +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 U; + +struct static_tests { + 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(AlignOf, BufferCanBeUsed) { + U MyU; + memset(MyU.buffer, 'X', sizeof(U)); + + EXPECT_EQ(MyU.buffer[sizeof(uint64_t[16]) - 1], 'X'); +} + +} // namespace Index: unittests/ADT/CMakeLists.txt =================================================================== --- unittests/ADT/CMakeLists.txt +++ unittests/ADT/CMakeLists.txt @@ -3,6 +3,7 @@ ) set(ADTSources + AlignOfTest.cpp APFloatTest.cpp APIntTest.cpp APSIntTest.cpp