Wrapping __popcnt64 for MSVC so that it's only used on 64-bit builds.
[oota-llvm.git] / include / llvm / Support / AlignOf.h
index f8e2cfa243826d20d132d1a9a2e2262e80ab88c6..bba34248569a55e9838150c9b5d319928042ca1b 100644 (file)
@@ -111,13 +111,16 @@ 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.
+// 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;
-    __declspec(align(1)) char buffer[Size];
+    char buffer[Size];
   };
 };
 
@@ -125,7 +128,7 @@ template<std::size_t Size>
 struct AlignedCharArray<2, Size> {
   union {
     short aligned;
-    __declspec(align(2)) char buffer[Size];
+    char buffer[Size];
   };
 };
 
@@ -133,7 +136,7 @@ template<std::size_t Size>
 struct AlignedCharArray<4, Size> {
   union {
     int aligned;
-    __declspec(align(4)) char buffer[Size];
+    char buffer[Size];
   };
 };
 
@@ -141,10 +144,14 @@ template<std::size_t Size>
 struct AlignedCharArray<8, Size> {
   union {
     double aligned;
-    __declspec(align(8)) char buffer[Size];
+    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> { \
@@ -162,17 +169,20 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
 
 namespace detail {
 template <typename T1,
-          typename T2 = char, typename T3 = char, typename T4 = char>
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char>
 class AlignerImpl {
-  T1 t1; T2 t2; T3 t3; T4 t4;
+  T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7;
 
   AlignerImpl(); // Never defined or instantiated.
 };
 
 template <typename T1,
-          typename T2 = char, typename T3 = char, typename T4 = char>
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char>
 union SizerImpl {
-  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
+  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
+       arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)];
 };
 } // end namespace detail
 
@@ -181,14 +191,14 @@ union SizerImpl {
 ///
 /// These types may be arrays, structs, or any other types. The goal is to
 /// expose a char array buffer member which can be used as suitable storage for
-/// a placement new of any of these types. Support for more than four types can
+/// a placement new of any of these types. Support for more than seven types can
 /// be added at the cost of more boiler plate.
 template <typename T1,
-          typename T2 = char, typename T3 = char, typename T4 = char>
-struct AlignedCharArrayUnion :
-  llvm::AlignedCharArray<AlignOf<detail::AlignerImpl<T1, T2, T3, T4> >
-                                            ::Alignment,
-                                 sizeof(detail::SizerImpl<T1, T2, T3, T4>)> {
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char>
+struct AlignedCharArrayUnion : llvm::AlignedCharArray<
+    AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment,
+    sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> {
 };
 } // end namespace llvm
 #endif