[support] Add a macro wrapper for alignas and simplify some code.
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 2 Apr 2015 11:32:48 +0000 (11:32 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 2 Apr 2015 11:32:48 +0000 (11:32 +0000)
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

include/llvm/Support/AlignOf.h
include/llvm/Support/Compiler.h
unittests/Support/AlignOfTest.cpp

index 061d5acf2322b570ad197b753db150d10c2f1b4b..f30467d5440ded5ebbdd98c1cb805fed471c1d14 100644 (file)
@@ -70,38 +70,11 @@ inline unsigned alignOf() { return AlignOf<T>::Alignment; }
 // MSVC requires special handling here.
 #ifndef _MSC_VER
 
-#if __has_feature(cxx_alignas)
 template<std::size_t Alignment, std::size_t Size>
 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<std::size_t Alignment, std::size_t Size>
-struct AlignedCharArray;
-
-#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
-  template<std::size_t Size> \
-  struct AlignedCharArray<x, Size> { \
-    __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.
index f7de840437df29f77e4f919a2be6576ab8f2060c..1a49956e22526bbd57fa2cadb3c4bf58da0d1a81 100644 (file)
 # 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.
index d2090867e2639b1c6f2de896c4c3d1afecdd6b49..b9d423e8eee88eeeef7dca8e8098994f9b932349 100644 (file)
@@ -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; };