diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index cf7125173ee..8c389afa80d 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -72,6 +72,10 @@ template struct AlignedCharArrayImpl {}; template <> struct AlignedCharArrayImpl<0> { typedef char type; }; + +// MSVC requires special handling here. +#ifndef _MSC_VER + #if __has_feature(cxx_alignas) #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ template <> struct AlignedCharArrayImpl { \ @@ -82,11 +86,6 @@ template <> struct AlignedCharArrayImpl<0> { template <> struct AlignedCharArrayImpl { \ typedef char type __attribute__((aligned(x))); \ } -#elif defined(_MSC_VER) -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template <> struct AlignedCharArrayImpl { \ - typedef __declspec(align(x)) char type; \ - } #else # error No supported align as directive. #endif @@ -104,9 +103,38 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); + +#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT + +#else // _MSC_VER + +// 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. +template <> struct AlignedCharArrayImpl<1> { typedef char type; }; +template <> struct AlignedCharArrayImpl<2> { typedef short type; }; +template <> struct AlignedCharArrayImpl<4> { typedef int type; }; +template <> struct AlignedCharArrayImpl<8> { typedef double type; }; + +#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ + template <> struct AlignedCharArrayImpl { \ + typedef __declspec(align(x)) char type; \ + } +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); +LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); // Any larger and MSVC complains. #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT +#endif // _MSC_VER + /// \brief This union template exposes a suitably aligned and sized character /// array member which can hold elements of any of up to four types. ///