<div dir="ltr">Thanks - please commit whenever you're ready to do so</div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jan 9, 2017 at 1:39 PM Sean Callanan via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">spyffe set the repository for this revision to rL LLVM.<br class="gmail_msg">
spyffe updated this revision to Diff 83679.<br class="gmail_msg">
spyffe added a comment.<br class="gmail_msg">
<br class="gmail_msg">
Added a comment at David's request, and moved the test into the Support/AlignOf unit tests.  Also removed the `memcpy` test.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Repository:<br class="gmail_msg">
  rL LLVM<br class="gmail_msg">
<br class="gmail_msg">
<a href="https://reviews.llvm.org/D28429" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D28429</a><br class="gmail_msg">
<br class="gmail_msg">
Files:<br class="gmail_msg">
  include/llvm/Support/AlignOf.h<br class="gmail_msg">
  unittests/Support/AlignOfTest.cpp<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Index: unittests/Support/AlignOfTest.cpp<br class="gmail_msg">
===================================================================<br class="gmail_msg">
--- unittests/Support/AlignOfTest.cpp<br class="gmail_msg">
+++ unittests/Support/AlignOfTest.cpp<br class="gmail_msg">
@@ -91,6 +91,24 @@<br class="gmail_msg">
<br class="gmail_msg">
 template <typename M> struct T { M m; };<br class="gmail_msg">
<br class="gmail_msg">
+typedef uint8_t t1;<br class="gmail_msg">
+typedef uint16_t t2;<br class="gmail_msg">
+typedef uint32_t t3;<br class="gmail_msg">
+typedef uint64_t t4;<br class="gmail_msg">
+typedef int8_t t5;<br class="gmail_msg">
+typedef int16_t t6;<br class="gmail_msg">
+typedef int32_t t7;<br class="gmail_msg">
+typedef int64_t t8;<br class="gmail_msg">
+typedef struct { uint8_t bytes[16]; } t9;<br class="gmail_msg">
+typedef struct { uint16_t words[16]; } t10;<br class="gmail_msg">
+typedef struct { uint32_t words[16]; } t11;<br class="gmail_msg">
+typedef struct { uint64_t words[16]; } t12;<br class="gmail_msg">
+<br class="gmail_msg">
+typedef AlignedCharArrayUnion<t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12> U;<br class="gmail_msg">
+<br class="gmail_msg">
+static_assert(sizeof(U) == sizeof(uint64_t[16]), "Statically-computed size must be right");<br class="gmail_msg">
+static_assert(alignof(U) == alignof(uint64_t), "Statically-computed alignment must be right");<br class="gmail_msg">
+<br class="gmail_msg">
 TEST(AlignOfTest, BasicAlignedArray) {<br class="gmail_msg">
   EXPECT_LE(1u, alignof(AlignedCharArrayUnion<A1>));<br class="gmail_msg">
   EXPECT_LE(2u, alignof(AlignedCharArrayUnion<A2>));<br class="gmail_msg">
Index: include/llvm/Support/AlignOf.h<br class="gmail_msg">
===================================================================<br class="gmail_msg">
--- include/llvm/Support/AlignOf.h<br class="gmail_msg">
+++ include/llvm/Support/AlignOf.h<br class="gmail_msg">
@@ -102,45 +102,38 @@<br class="gmail_msg">
<br class="gmail_msg">
 #endif // _MSC_VER<br class="gmail_msg">
<br class="gmail_msg">
+// This code implements the equivalent of std::aligned_union from C++11.<br class="gmail_msg">
+// That is supported by Visual Studio 2015 and GCC 5.1.<br class="gmail_msg">
+// Once these are the baselines for LLVM, we can use std::aligned_union instead.<br class="gmail_msg">
+<br class="gmail_msg">
 namespace detail {<br class="gmail_msg">
-template <typename T1,<br class="gmail_msg">
-          typename T2 = char, typename T3 = char, typename T4 = char,<br class="gmail_msg">
-          typename T5 = char, typename T6 = char, typename T7 = char,<br class="gmail_msg">
-          typename T8 = char, typename T9 = char, typename T10 = char><br class="gmail_msg">
-class AlignerImpl {<br class="gmail_msg">
-  T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;<br class="gmail_msg">
+template <typename... Ts> class AlignerImpl;<br class="gmail_msg">
<br class="gmail_msg">
+template <typename T1, typename... Ts><br class="gmail_msg">
+class AlignerImpl<T1, Ts...> : AlignerImpl<Ts...> {<br class="gmail_msg">
+  T1 t;<br class="gmail_msg">
   AlignerImpl() = delete;<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
-template <typename T1,<br class="gmail_msg">
-          typename T2 = char, typename T3 = char, typename T4 = char,<br class="gmail_msg">
-          typename T5 = char, typename T6 = char, typename T7 = char,<br class="gmail_msg">
-          typename T8 = char, typename T9 = char, typename T10 = char><br class="gmail_msg">
-union SizerImpl {<br class="gmail_msg">
-  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],<br class="gmail_msg">
-       arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],<br class="gmail_msg">
-       arr9[sizeof(T9)], arr10[sizeof(T10)];<br class="gmail_msg">
-};<br class="gmail_msg">
+template <> class AlignerImpl<> { AlignerImpl() = delete; };<br class="gmail_msg">
+<br class="gmail_msg">
+template <typename T1> constexpr size_t sizer() { return sizeof(T1); }<br class="gmail_msg">
+<br class="gmail_msg">
+template <typename T1, typename T2, typename... Ts> constexpr size_t sizer() {<br class="gmail_msg">
+  return (sizeof(T1) > sizer<T2, Ts...>()) ? sizeof(T1) : sizer<T2, Ts...>();<br class="gmail_msg">
+}<br class="gmail_msg">
 } // end namespace detail<br class="gmail_msg">
<br class="gmail_msg">
 /// \brief This union template exposes a suitably aligned and sized character<br class="gmail_msg">
-/// array member which can hold elements of any of up to ten types.<br class="gmail_msg">
+/// array member which can hold elements of any of a number of types.<br class="gmail_msg">
 ///<br class="gmail_msg">
 /// These types may be arrays, structs, or any other types. The goal is to<br class="gmail_msg">
 /// expose a char array buffer member which can be used as suitable storage for<br class="gmail_msg">
-/// a placement new of any of these types. Support for more than ten types can<br class="gmail_msg">
-/// be added at the cost of more boilerplate.<br class="gmail_msg">
-template <typename T1,<br class="gmail_msg">
-          typename T2 = char, typename T3 = char, typename T4 = char,<br class="gmail_msg">
-          typename T5 = char, typename T6 = char, typename T7 = char,<br class="gmail_msg">
-          typename T8 = char, typename T9 = char, typename T10 = char><br class="gmail_msg">
-struct AlignedCharArrayUnion : llvm::AlignedCharArray<<br class="gmail_msg">
-    alignof(llvm::detail::AlignerImpl<T1, T2, T3, T4, T5,<br class="gmail_msg">
-                                      T6, T7, T8, T9, T10>),<br class="gmail_msg">
-    sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5,<br class="gmail_msg">
-                                     T6, T7, T8, T9, T10>)> {<br class="gmail_msg">
-};<br class="gmail_msg">
+/// a placement new of any of these types.<br class="gmail_msg">
+template <typename... Ts><br class="gmail_msg">
+struct AlignedCharArrayUnion<br class="gmail_msg">
+    : llvm::AlignedCharArray<alignof(llvm::detail::AlignerImpl<Ts...>),<br class="gmail_msg">
+                             detail::sizer<Ts...>()> {};<br class="gmail_msg">
 } // end namespace llvm<br class="gmail_msg">
<br class="gmail_msg">
 #endif // LLVM_SUPPORT_ALIGNOF_H<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div>