From: Benjamin Kramer Date: Thu, 2 Apr 2015 11:32:48 +0000 (+0000) Subject: [support] Add a macro wrapper for alignas and simplify some code. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=efdcf3d62d52a80c57b8629f294d308fe3d0d180 [support] Add a macro wrapper for alignas and simplify some code. We wrap __attribute((aligned)) for GCC 4.7 and __declspec(align) for MSVC. The latter behaves weird in some contexts so this should be used carefully. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233910 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index 061d5acf232..f30467d5440 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -70,38 +70,11 @@ inline unsigned alignOf() { return AlignOf::Alignment; } // MSVC requires special handling here. #ifndef _MSC_VER -#if __has_feature(cxx_alignas) template struct AlignedCharArray { - alignas(Alignment) char buffer[Size]; + LLVM_ALIGNAS(Alignment) char buffer[Size]; }; -#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) -/// \brief Create a type with an aligned char buffer. -template -struct AlignedCharArray; - -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template \ - struct AlignedCharArray { \ - __attribute__((aligned(x))) char buffer[Size]; \ - }; - -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8) -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 - -#else -# error No supported align as directive. -#endif - #else // _MSC_VER /// \brief Create a type with an aligned char buffer. diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index f7de840437d..1a49956e225 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -281,6 +281,20 @@ # define LLVM_ASSUME_ALIGNED(p, a) (p) #endif +/// \macro LLVM_ALIGNAS +/// \brief Used to specify a minimum alignment for a structure or variable. The +/// alignment must be a constant integer. +/// +/// Note that __declspec(align) has special quirks, it's not legal to pass a +/// structure with __declspec(align) as a formal parameter. +#ifdef _MSC_VER +# define LLVM_ALIGNAS(x) __declspec(align(x)) +#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0) +# define LLVM_ALIGNAS(x) __attribute__((aligned(x))) +#else +# define LLVM_ALIGNAS(x) alignas(x) +#endif + /// \macro LLVM_FUNCTION_NAME /// \brief Expands to __func__ on compilers which support it. Otherwise, /// expands to a compiler-dependent replacement. diff --git a/unittests/Support/AlignOfTest.cpp b/unittests/Support/AlignOfTest.cpp index d2090867e26..b9d423e8eee 100644 --- a/unittests/Support/AlignOfTest.cpp +++ b/unittests/Support/AlignOfTest.cpp @@ -39,24 +39,10 @@ namespace { #endif // Define some fixed alignment types to use in these tests. -#if __has_feature(cxx_alignas) -struct alignas(1) A1 { }; -struct alignas(2) A2 { }; -struct alignas(4) A4 { }; -struct alignas(8) A8 { }; -#elif defined(__GNUC__) -struct A1 { } __attribute__((aligned(1))); -struct A2 { } __attribute__((aligned(2))); -struct A4 { } __attribute__((aligned(4))); -struct A8 { } __attribute__((aligned(8))); -#elif defined(_MSC_VER) -__declspec(align(1)) struct A1 { }; -__declspec(align(2)) struct A2 { }; -__declspec(align(4)) struct A4 { }; -__declspec(align(8)) struct A8 { }; -#else -# error No supported align as directive. -#endif +struct LLVM_ALIGNAS(1) A1 {}; +struct LLVM_ALIGNAS(2) A2 {}; +struct LLVM_ALIGNAS(4) A4 {}; +struct LLVM_ALIGNAS(8) A8 {}; struct S1 {}; struct S2 { char a; };