diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2016-10-20 15:53:04 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2016-10-20 15:53:04 +0000 |
commit | b667ef79ea12eccd72d2402e871f16cf2ae55e1a (patch) | |
tree | 0a8e9d3e231d66d12fa3c306362d1c198cb567d8 /llvm | |
parent | e9425b24b7849fe3316bd74fd401a105c139d5c5 (diff) | |
download | bcm5719-llvm-b667ef79ea12eccd72d2402e871f16cf2ae55e1a.tar.gz bcm5719-llvm-b667ef79ea12eccd72d2402e871f16cf2ae55e1a.zip |
[Support] Put back the MSVC hack for AlignedCharArray.
MSVC 2015 still errors when passing an alignas'd object by value as an
argument.
llvm-svn: 284738
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Support/AlignOf.h | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/llvm/include/llvm/Support/AlignOf.h b/llvm/include/llvm/Support/AlignOf.h index c90075e7669..9570ca33d20 100644 --- a/llvm/include/llvm/Support/AlignOf.h +++ b/llvm/include/llvm/Support/AlignOf.h @@ -23,12 +23,85 @@ namespace llvm { /// \brief Helper for building an aligned character array type. /// /// This template is used to explicitly build up a collection of aligned -/// character array types. +/// character array types. We have to build these up using a macro and explicit +/// specialization to cope with old versions of MSVC where only an +/// integer literal can be used to specify an alignment constraint. Once built +/// up here, we can then begin to indirect between these using normal C++ +/// template parameters. + +// MSVC requires special handling here. +#ifndef _MSC_VER + template<std::size_t Alignment, std::size_t Size> struct AlignedCharArray { LLVM_ALIGNAS(Alignment) char buffer[Size]; }; +#else // _MSC_VER + +/// \brief Create a type with an aligned char buffer. +template<std::size_t Alignment, std::size_t Size> +struct AlignedCharArray; + +// We provide special variations of this template for the most common +// alignments because __declspec(align(...)) doesn't actually work when it is +// a member of a by-value function argument in MSVC, even if the alignment +// request is something reasonably like 8-byte or 16-byte. Note that we can't +// even include the declspec with the union that forces the alignment because +// MSVC warns on the existence of the declspec despite the union member forcing +// proper alignment. + +template<std::size_t Size> +struct AlignedCharArray<1, Size> { + union { + char aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<2, Size> { + union { + short aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<4, Size> { + union { + int aligned; + char buffer[Size]; + }; +}; + +template<std::size_t Size> +struct AlignedCharArray<8, Size> { + union { + double aligned; + char buffer[Size]; + }; +}; + + +// The rest of these are provided with a __declspec(align(...)) and we simply +// can't pass them by-value as function arguments on MSVC. + +#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ + template<std::size_t Size> \ + struct AlignedCharArray<x, Size> { \ + __declspec(align(x)) char buffer[Size]; \ + }; + +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) + +#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT + +#endif // _MSC_VER + namespace detail { template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char, |