1 //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_ALIGNOF_H
14 #define LLVM_SUPPORT_ALIGNOF_H
16 #include "llvm/Support/Compiler.h"
21 /// \struct AlignedCharArray
22 /// Helper for building an aligned character array type.
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.
31 // MSVC requires special handling here.
34 template<std::size_t Alignment
, std::size_t Size
>
35 struct AlignedCharArray
{
36 alignas(Alignment
) char buffer
[Size
];
41 /// Create a type with an aligned char buffer.
42 template<std::size_t Alignment
, std::size_t Size
>
43 struct AlignedCharArray
;
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
53 template<std::size_t Size
>
54 struct AlignedCharArray
<1, Size
> {
61 template<std::size_t Size
>
62 struct AlignedCharArray
<2, Size
> {
69 template<std::size_t Size
>
70 struct AlignedCharArray
<4, Size
> {
77 template<std::size_t Size
>
78 struct AlignedCharArray
<8, Size
> {
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.
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]; \
95 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
96 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
97 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
98 LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
100 #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
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>
110 T1 t1
; T2 t2
; T3 t3
; T4 t4
; T5 t5
; T6 t6
; T7 t7
; T8 t8
; T9 t9
; T10 t10
;
112 AlignerImpl() = delete;
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>
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
)];
124 } // end namespace detail
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.
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>
137 struct AlignedCharArrayUnion
: llvm::AlignedCharArray
<
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
>)> {
143 } // end namespace llvm
145 #endif // LLVM_SUPPORT_ALIGNOF_H