mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 22:04:55 +00:00
Try to appease MSVC even more elaborately in the alignment hacking space.
MSVC doesn't support passing by-value parameters with alignment of 16-bytes or higher apparantly. What is deeply confusing is that it seems to *sometimes* (but not always) apply this to any type whose alignment is set using __declspec(align(...)). This caused lots of errors when we switch SmallVector over to use the automatically aligned character array utilities as they used __declspec(align(...)) heavily. As a pretty horrible but effective work-around, we instead cherry pick the smallest alignment sizes with specific types that happen to have the correct alignment, and then fall back to the attribute solution past them. This should resolve the MSVC build errors folks have been hitting. Sorry for that. In good news, it will do this without introducing other UB I hope. =] Thanks to Timur Iskhodzhanov for helping me test this! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162549 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0e292376d0
commit
be06428ba3
@ -72,6 +72,10 @@ template <size_t Alignment> 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<x> { \
|
||||
@ -82,11 +86,6 @@ template <> struct AlignedCharArrayImpl<0> {
|
||||
template <> struct AlignedCharArrayImpl<x> { \
|
||||
typedef char type __attribute__((aligned(x))); \
|
||||
}
|
||||
#elif defined(_MSC_VER)
|
||||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
|
||||
template <> struct AlignedCharArrayImpl<x> { \
|
||||
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<x> { \
|
||||
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.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user