LLVM  9.0.0svn
AlignOf.h
Go to the documentation of this file.
1 //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_SUPPORT_ALIGNOF_H
14 #define LLVM_SUPPORT_ALIGNOF_H
15 
16 #include "llvm/Support/Compiler.h"
17 #include <cstddef>
18 
19 namespace llvm {
20 
21 /// \struct AlignedCharArray
22 /// Helper for building an aligned character array type.
23 ///
24 /// This template is used to explicitly build up a collection of aligned
25 /// character array types. We have to build these up using a macro and explicit
26 /// specialization to cope with MSVC (at least till 2015) where only an
27 /// integer literal can be used to specify an alignment constraint. Once built
28 /// up here, we can then begin to indirect between these using normal C++
29 /// template parameters.
30 
31 // MSVC requires special handling here.
32 #ifndef _MSC_VER
33 
34 template<std::size_t Alignment, std::size_t Size>
36  alignas(Alignment) char buffer[Size];
37 };
38 
39 #else // _MSC_VER
40 
41 /// Create a type with an aligned char buffer.
42 template<std::size_t Alignment, std::size_t Size>
43 struct AlignedCharArray;
44 
45 // We provide special variations of this template for the most common
46 // alignments because __declspec(align(...)) doesn't actually work when it is
47 // a member of a by-value function argument in MSVC, even if the alignment
48 // request is something reasonably like 8-byte or 16-byte. Note that we can't
49 // even include the declspec with the union that forces the alignment because
50 // MSVC warns on the existence of the declspec despite the union member forcing
51 // proper alignment.
52 
53 template<std::size_t Size>
54 struct AlignedCharArray<1, Size> {
55  union {
56  char aligned;
57  char buffer[Size];
58  };
59 };
60 
61 template<std::size_t Size>
62 struct AlignedCharArray<2, Size> {
63  union {
64  short aligned;
65  char buffer[Size];
66  };
67 };
68 
69 template<std::size_t Size>
70 struct AlignedCharArray<4, Size> {
71  union {
72  int aligned;
73  char buffer[Size];
74  };
75 };
76 
77 template<std::size_t Size>
78 struct AlignedCharArray<8, Size> {
79  union {
80  double aligned;
81  char buffer[Size];
82  };
83 };
84 
85 
86 // The rest of these are provided with a __declspec(align(...)) and we simply
87 // can't pass them by-value as function arguments on MSVC.
88 
89 #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
90  template<std::size_t Size> \
91  struct AlignedCharArray<x, Size> { \
92  __declspec(align(x)) char buffer[Size]; \
93  };
94 
95 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
96 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
97 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
98 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
99 
100 #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
101 
102 #endif // _MSC_VER
103 
104 namespace detail {
105 template <typename T1,
106  typename T2 = char, typename T3 = char, typename T4 = char,
107  typename T5 = char, typename T6 = char, typename T7 = char,
108  typename T8 = char, typename T9 = char, typename T10 = char>
109 class AlignerImpl {
110  T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
111 
112  AlignerImpl() = delete;
113 };
114 
115 template <typename T1,
116  typename T2 = char, typename T3 = char, typename T4 = char,
117  typename T5 = char, typename T6 = char, typename T7 = char,
118  typename T8 = char, typename T9 = char, typename T10 = char>
119 union SizerImpl {
120  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
121  arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
122  arr9[sizeof(T9)], arr10[sizeof(T10)];
123 };
124 } // end namespace detail
125 
126 /// This union template exposes a suitably aligned and sized character
127 /// array member which can hold elements of any of up to ten types.
128 ///
129 /// These types may be arrays, structs, or any other types. The goal is to
130 /// expose a char array buffer member which can be used as suitable storage for
131 /// a placement new of any of these types. Support for more than ten types can
132 /// be added at the cost of more boilerplate.
133 template <typename T1,
134  typename T2 = char, typename T3 = char, typename T4 = char,
135  typename T5 = char, typename T6 = char, typename T7 = char,
136  typename T8 = char, typename T9 = char, typename T10 = char>
138  alignof(llvm::detail::AlignerImpl<T1, T2, T3, T4, T5,
139  T6, T7, T8, T9, T10>),
140  sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5,
141  T6, T7, T8, T9, T10>)> {
142 };
143 } // end namespace llvm
144 
145 #endif // LLVM_SUPPORT_ALIGNOF_H
This class represents lattice values for constants.
Definition: AllocatorList.h:23
char buffer[Size]
Definition: AlignOf.h:36
This union template exposes a suitably aligned and sized character array member which can hold elemen...
Definition: AlignOf.h:137
uint32_t Size
Definition: Profile.cpp:46
Helper for building an aligned character array type.
Definition: AlignOf.h:35
#define T1