[llvm] r291514 - Fix MSVC build of AlignedCharArrayUnion

Sean Callanan via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 9 17:56:06 PST 2017


Reid,

I'm sorry, I thought I'd reverted this.  Thanks for jumping in!

I was trying to implement a similar solution.  My solution was going to be:
–
namespace detail {
template <typename T1> constexpr size_t aligner() { return alignof(T1); }

template <typename T1, typename T2> struct U {
    union {
        T1 t1;
        T2 t2;
    };
};
    
template <typename T1, typename T2, typename... Ts> constexpr size_t aligner() {
    return alignof(U<T1, llvm::AlignedCharArray<aligner<T2, Ts...>(), 1>>);
}

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...>();
}
} // end namespace detail
–
I'm fine with either one – since alignments must be powers of 2, your approach is just as sound.

Sean

> On Jan 9, 2017, at 4:26 PM, Reid Kleckner via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> Author: rnk
> Date: Mon Jan  9 18:26:56 2017
> New Revision: 291514
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=291514&view=rev
> Log:
> Fix MSVC build of AlignedCharArrayUnion
> 
> 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).
> 
> Modified:
>    llvm/trunk/include/llvm/Support/AlignOf.h
> 
> Modified: llvm/trunk/include/llvm/Support/AlignOf.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/AlignOf.h?rev=291514&r1=291513&r2=291514&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/AlignOf.h (original)
> +++ llvm/trunk/include/llvm/Support/AlignOf.h Mon Jan  9 18:26:56 2017
> @@ -107,20 +107,18 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
> // 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, type
> /// 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
> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list