]> granicus.if.org Git - llvm/commitdiff
Fix MSVC build of AlignedCharArrayUnion
authorReid Kleckner <rnk@google.com>
Tue, 10 Jan 2017 00:26:56 +0000 (00:26 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 10 Jan 2017 00:26:56 +0000 (00:26 +0000)
Use constexpr recursion for alignof like we do for sizeof. Seems to work
with Clang and MSVC. Also, don't recurse twice to avoid slowdowns in
compilers that don't memoize constexpr results (Clang).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291514 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/AlignOf.h

index 5fda901a1009e62d6ade679ab92c9508583a8bb6..e1e304f4c1a93beeb1f6b4f5cb7f87c39f226b1b 100644 (file)
@@ -107,20 +107,18 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
 // Once these are the baselines for LLVM, we can use std::aligned_union instead.
 
 namespace detail {
-template <typename... Ts> class AlignerImpl;
+template <typename T1> constexpr size_t aligner() { return alignof(T1); }
 
-template <typename T1, typename... Ts>
-class AlignerImpl<T1, Ts...> : AlignerImpl<Ts...> {
-  T1 t;
-  AlignerImpl() = delete;
-};
-
-template <> class AlignerImpl<> { AlignerImpl() = delete; };
+template <typename T1, typename T2, typename... Ts> constexpr size_t aligner() {
+  size_t rest = aligner<T2, Ts...>();
+  return (alignof(T1) > rest) ? alignof(T1) : rest;
+}
 
 template <typename T1> constexpr size_t sizer() { return sizeof(T1); }
 
 template <typename T1, typename T2, typename... Ts> constexpr size_t sizer() {
-  return (sizeof(T1) > sizer<T2, Ts...>()) ? sizeof(T1) : sizer<T2, Ts...>();
+  size_t rest = sizer<T2, Ts...>();
+  return (sizeof(T1) > rest) ? sizeof(T1) : rest;
 }
 } // end namespace detail
 
@@ -132,7 +130,7 @@ template <typename T1, typename T2, typename... Ts> constexpr size_t sizer() {
 /// a placement new of any of these types.
 template <typename... Ts>
 struct AlignedCharArrayUnion
-    : llvm::AlignedCharArray<alignof(llvm::detail::AlignerImpl<Ts...>),
+    : llvm::AlignedCharArray<detail::aligner<Ts...>(),
                              detail::sizer<Ts...>()> {};
 } // end namespace llvm