0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
147
|
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
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 // This file defines several macros, based on the current compiler. This allows
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // use of compiler-specific features in a way that remains portable.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 #ifndef LLVM_SUPPORT_COMPILER_H
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 #define LLVM_SUPPORT_COMPILER_H
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 #include "llvm/Config/llvm-config.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18
|
147
|
19 #include <new>
|
|
20 #include <stddef.h>
|
|
21
|
120
|
22 #if defined(_MSC_VER)
|
|
23 #include <sal.h>
|
|
24 #endif
|
|
25
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 #ifndef __has_feature
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 # define __has_feature(x) 0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29
|
77
|
30 #ifndef __has_extension
|
|
31 # define __has_extension(x) 0
|
|
32 #endif
|
|
33
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 #ifndef __has_attribute
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35 # define __has_attribute(x) 0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37
|
120
|
38 #ifndef __has_cpp_attribute
|
|
39 # define __has_cpp_attribute(x) 0
|
|
40 #endif
|
|
41
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
42 #ifndef __has_builtin
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 # define __has_builtin(x) 0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45
|
83
|
46 /// \macro LLVM_GNUC_PREREQ
|
147
|
47 /// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
|
83
|
48 /// available.
|
|
49 #ifndef LLVM_GNUC_PREREQ
|
|
50 # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
|
|
51 # define LLVM_GNUC_PREREQ(maj, min, patch) \
|
|
52 ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
|
|
53 ((maj) << 20) + ((min) << 10) + (patch))
|
|
54 # elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
55 # define LLVM_GNUC_PREREQ(maj, min, patch) \
|
|
56 ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 # else
|
83
|
58 # define LLVM_GNUC_PREREQ(maj, min, patch) 0
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59 # endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61
|
77
|
62 /// \macro LLVM_MSC_PREREQ
|
147
|
63 /// Is the compiler MSVC of at least the specified version?
|
77
|
64 /// The common \param version values to check for are:
|
147
|
65 /// * 1910: VS2017, version 15.1 & 15.2
|
|
66 /// * 1911: VS2017, version 15.3 & 15.4
|
|
67 /// * 1912: VS2017, version 15.5
|
|
68 /// * 1913: VS2017, version 15.6
|
|
69 /// * 1914: VS2017, version 15.7
|
|
70 /// * 1915: VS2017, version 15.8
|
|
71 /// * 1916: VS2017, version 15.9
|
|
72 /// * 1920: VS2019, version 16.0
|
|
73 /// * 1921: VS2019, version 16.1
|
77
|
74 #ifdef _MSC_VER
|
|
75 #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
|
|
76
|
147
|
77 // We require at least MSVC 2017.
|
|
78 #if !LLVM_MSC_PREREQ(1910)
|
|
79 #error LLVM requires at least MSVC 2017.
|
77
|
80 #endif
|
|
81
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82 #else
|
77
|
83 #define LLVM_MSC_PREREQ(version) 0
|
|
84 #endif
|
|
85
|
147
|
86 /// Does the compiler support ref-qualifiers for *this?
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
87 ///
|
95
|
88 /// Sadly, this is separate from just rvalue reference support because GCC
|
|
89 /// and MSVC implemented this later than everything else.
|
83
|
90 #if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
91 #define LLVM_HAS_RVALUE_REFERENCE_THIS 1
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
92 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93 #define LLVM_HAS_RVALUE_REFERENCE_THIS 0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
94 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95
|
95
|
96 /// Expands to '&' if ref-qualifiers for *this are supported.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
97 ///
|
95
|
98 /// This can be used to provide lvalue/rvalue overrides of member functions.
|
|
99 /// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 #if LLVM_HAS_RVALUE_REFERENCE_THIS
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101 #define LLVM_LVALUE_FUNCTION &
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 #define LLVM_LVALUE_FUNCTION
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 /// into a shared library, then the class should be private to the library and
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 /// not accessible from outside it. Can also be used to mark variables and
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 /// functions, making them private to any shared library they are linked into.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110 /// On PE/COFF targets, library visibility is the default, so this isn't needed.
|
83
|
111 #if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
|
147
|
112 !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
113 #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 #define LLVM_LIBRARY_VISIBILITY
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117
|
120
|
118 #if defined(__GNUC__)
|
|
119 #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
|
|
120 #else
|
|
121 #define LLVM_PREFETCH(addr, rw, locality)
|
|
122 #endif
|
|
123
|
83
|
124 #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
125 #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 #define LLVM_ATTRIBUTE_USED
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129
|
120
|
130 /// LLVM_NODISCARD - Warn if a type or return value is discarded.
|
|
131 #if __cplusplus > 201402L && __has_cpp_attribute(nodiscard)
|
|
132 #define LLVM_NODISCARD [[nodiscard]]
|
|
133 #elif !__cplusplus
|
|
134 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
|
|
135 // error when __has_cpp_attribute is given a scoped attribute in C mode.
|
|
136 #define LLVM_NODISCARD
|
|
137 #elif __has_cpp_attribute(clang::warn_unused_result)
|
|
138 #define LLVM_NODISCARD [[clang::warn_unused_result]]
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 #else
|
120
|
140 #define LLVM_NODISCARD
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142
|
147
|
143 // Indicate that a non-static, non-const C++ member function reinitializes
|
|
144 // the entire object to a known state, independent of the previous state of
|
|
145 // the object.
|
|
146 //
|
|
147 // The clang-tidy check bugprone-use-after-move recognizes this attribute as a
|
|
148 // marker that a moved-from object has left the indeterminate state and can be
|
|
149 // reused.
|
|
150 #if __has_cpp_attribute(clang::reinitializes)
|
|
151 #define LLVM_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
|
|
152 #else
|
|
153 #define LLVM_ATTRIBUTE_REINITIALIZES
|
|
154 #endif
|
|
155
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 // Some compilers warn about unused functions. When a function is sometimes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 // used or not depending on build settings (e.g. a function only called from
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 // within "assert"), this attribute can be used to suppress such warnings.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 // However, it shouldn't be used for unused *variables*, as those have a much
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 // more portable solution:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 // (void)unused_var_name;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 // Prefer cast-to-void wherever it is sufficient.
|
83
|
164 #if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 #define LLVM_ATTRIBUTE_UNUSED
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
168 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170 // FIXME: Provide this for PE/COFF targets.
|
83
|
171 #if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
|
147
|
172 (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173 #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 #define LLVM_ATTRIBUTE_WEAK
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178 // Prior to clang 3.2, clang did not accept any spelling of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
179 // __has_attribute(const), so assume it is supported.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 #if defined(__clang__) || defined(__GNUC__)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181 // aka 'CONST' but following LLVM Conventions.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 #define LLVM_READNONE __attribute__((__const__))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 #define LLVM_READNONE
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 #if __has_attribute(pure) || defined(__GNUC__)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 // aka 'PURE' but following LLVM Conventions.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 #define LLVM_READONLY __attribute__((__pure__))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 #define LLVM_READONLY
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193
|
83
|
194 #if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196 #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
197 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198 #define LLVM_LIKELY(EXPR) (EXPR)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 #define LLVM_UNLIKELY(EXPR) (EXPR)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 /// mark a method "not for inlining".
|
83
|
204 #if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 #elif defined(_MSC_VER)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
209 #define LLVM_ATTRIBUTE_NOINLINE
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212 /// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 /// so, mark a method "always inline" because it is performance sensitive. GCC
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 /// 3.4 supported this but is buggy in various cases and produces unimplemented
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
215 /// errors, just use it in GCC 4.0 and later.
|
83
|
216 #if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
|
95
|
217 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
218 #elif defined(_MSC_VER)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
219 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
220 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 #define LLVM_ATTRIBUTE_ALWAYS_INLINE
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224 #ifdef __GNUC__
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 #elif defined(_MSC_VER)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 #define LLVM_ATTRIBUTE_NORETURN
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231
|
83
|
232 #if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
|
77
|
233 #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
|
120
|
234 #elif defined(_MSC_VER)
|
|
235 #define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
|
77
|
236 #else
|
|
237 #define LLVM_ATTRIBUTE_RETURNS_NONNULL
|
|
238 #endif
|
|
239
|
95
|
240 /// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
|
|
241 /// pointer that does not alias any other valid pointer.
|
|
242 #ifdef __GNUC__
|
|
243 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
|
|
244 #elif defined(_MSC_VER)
|
|
245 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
|
|
246 #else
|
|
247 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
|
|
248 #endif
|
|
249
|
120
|
250 /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
|
|
251 #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
|
|
252 #define LLVM_FALLTHROUGH [[fallthrough]]
|
121
|
253 #elif __has_cpp_attribute(gnu::fallthrough)
|
|
254 #define LLVM_FALLTHROUGH [[gnu::fallthrough]]
|
120
|
255 #elif !__cplusplus
|
|
256 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
|
|
257 // error when __has_cpp_attribute is given a scoped attribute in C mode.
|
|
258 #define LLVM_FALLTHROUGH
|
|
259 #elif __has_cpp_attribute(clang::fallthrough)
|
|
260 #define LLVM_FALLTHROUGH [[clang::fallthrough]]
|
|
261 #else
|
|
262 #define LLVM_FALLTHROUGH
|
|
263 #endif
|
|
264
|
147
|
265 /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
|
|
266 /// they are constant initialized.
|
|
267 #if __has_cpp_attribute(clang::require_constant_initialization)
|
|
268 #define LLVM_REQUIRE_CONSTANT_INITIALIZATION \
|
|
269 [[clang::require_constant_initialization]]
|
|
270 #else
|
|
271 #define LLVM_REQUIRE_CONSTANT_INITIALIZATION
|
|
272 #endif
|
|
273
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 /// pedantic diagnostics.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 #ifdef __GNUC__
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 #define LLVM_EXTENSION __extension__
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 #define LLVM_EXTENSION
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 #if __has_feature(attribute_deprecated_with_message)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 decl __attribute__((deprecated(message)))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
286 #elif defined(__GNUC__)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 decl __attribute__((deprecated))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 #elif defined(_MSC_VER)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 __declspec(deprecated(message)) decl
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
294 decl
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 /// to an expression which states that it is undefined behavior for the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 /// compiler to reach this point. Otherwise is not defined.
|
83
|
300 #if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 #elif defined(_MSC_VER)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 # define LLVM_BUILTIN_UNREACHABLE __assume(false)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
304 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
305
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
306 /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
307 /// which causes the program to exit abnormally.
|
83
|
308 #if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309 # define LLVM_BUILTIN_TRAP __builtin_trap()
|
83
|
310 #elif defined(_MSC_VER)
|
|
311 // The __debugbreak intrinsic is supported by MSVC, does not require forward
|
|
312 // declarations involving platform-specific typedefs (unlike RaiseException),
|
|
313 // results in a call to vectored exception handlers, and encodes to a short
|
|
314 // instruction that still causes the trapping behavior we want.
|
|
315 # define LLVM_BUILTIN_TRAP __debugbreak()
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
319
|
120
|
320 /// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
|
|
321 /// an expression which causes the program to break while running
|
|
322 /// under a debugger.
|
|
323 #if __has_builtin(__builtin_debugtrap)
|
|
324 # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap()
|
|
325 #elif defined(_MSC_VER)
|
|
326 // The __debugbreak intrinsic is supported by MSVC and breaks while
|
|
327 // running under the debugger, and also supports invoking a debugger
|
|
328 // when the OS is configured appropriately.
|
|
329 # define LLVM_BUILTIN_DEBUGTRAP __debugbreak()
|
|
330 #else
|
|
331 // Just continue execution when built with compilers that have no
|
|
332 // support. This is a debugging aid and not intended to force the
|
|
333 // program to abort if encountered.
|
|
334 # define LLVM_BUILTIN_DEBUGTRAP
|
|
335 #endif
|
|
336
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
337 /// \macro LLVM_ASSUME_ALIGNED
|
147
|
338 /// Returns a pointer with an assumed alignment.
|
83
|
339 #if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340 # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
341 #elif defined(LLVM_BUILTIN_UNREACHABLE)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
342 // As of today, clang does not support __builtin_assume_aligned.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
343 # define LLVM_ASSUME_ALIGNED(p, a) \
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
344 (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
345 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
346 # define LLVM_ASSUME_ALIGNED(p, a) (p)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
347 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
348
|
100
|
349 /// \macro LLVM_PACKED
|
147
|
350 /// Used to specify a packed structure.
|
100
|
351 /// LLVM_PACKED(
|
|
352 /// struct A {
|
|
353 /// int i;
|
|
354 /// int j;
|
|
355 /// int k;
|
|
356 /// long long l;
|
|
357 /// });
|
|
358 ///
|
|
359 /// LLVM_PACKED_START
|
|
360 /// struct B {
|
|
361 /// int i;
|
|
362 /// int j;
|
|
363 /// int k;
|
|
364 /// long long l;
|
|
365 /// };
|
121
|
366 /// LLVM_PACKED_END
|
100
|
367 #ifdef _MSC_VER
|
|
368 # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
|
|
369 # define LLVM_PACKED_START __pragma(pack(push, 1))
|
|
370 # define LLVM_PACKED_END __pragma(pack(pop))
|
|
371 #else
|
|
372 # define LLVM_PACKED(d) d __attribute__((packed))
|
|
373 # define LLVM_PACKED_START _Pragma("pack(push, 1)")
|
|
374 # define LLVM_PACKED_END _Pragma("pack(pop)")
|
|
375 #endif
|
|
376
|
95
|
377 /// \macro LLVM_PTR_SIZE
|
147
|
378 /// A constant integer equivalent to the value of sizeof(void*).
|
|
379 /// Generally used in combination with alignas or when doing computation in the
|
|
380 /// preprocessor.
|
95
|
381 #ifdef __SIZEOF_POINTER__
|
|
382 # define LLVM_PTR_SIZE __SIZEOF_POINTER__
|
|
383 #elif defined(_WIN64)
|
|
384 # define LLVM_PTR_SIZE 8
|
|
385 #elif defined(_WIN32)
|
|
386 # define LLVM_PTR_SIZE 4
|
|
387 #elif defined(_MSC_VER)
|
|
388 # error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
|
|
389 #else
|
|
390 # define LLVM_PTR_SIZE sizeof(void *)
|
|
391 #endif
|
|
392
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
393 /// \macro LLVM_MEMORY_SANITIZER_BUILD
|
147
|
394 /// Whether LLVM itself is built with MemorySanitizer instrumentation.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
395 #if __has_feature(memory_sanitizer)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396 # define LLVM_MEMORY_SANITIZER_BUILD 1
|
77
|
397 # include <sanitizer/msan_interface.h>
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399 # define LLVM_MEMORY_SANITIZER_BUILD 0
|
77
|
400 # define __msan_allocated_memory(p, size)
|
|
401 # define __msan_unpoison(p, size)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
402 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404 /// \macro LLVM_ADDRESS_SANITIZER_BUILD
|
147
|
405 /// Whether LLVM itself is built with AddressSanitizer instrumentation.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
406 #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407 # define LLVM_ADDRESS_SANITIZER_BUILD 1
|
100
|
408 # include <sanitizer/asan_interface.h>
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 #else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410 # define LLVM_ADDRESS_SANITIZER_BUILD 0
|
100
|
411 # define __asan_poison_memory_region(p, size)
|
|
412 # define __asan_unpoison_memory_region(p, size)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414
|
95
|
415 /// \macro LLVM_THREAD_SANITIZER_BUILD
|
147
|
416 /// Whether LLVM itself is built with ThreadSanitizer instrumentation.
|
95
|
417 #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
|
418 # define LLVM_THREAD_SANITIZER_BUILD 1
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
419 #else
|
95
|
420 # define LLVM_THREAD_SANITIZER_BUILD 0
|
|
421 #endif
|
|
422
|
|
423 #if LLVM_THREAD_SANITIZER_BUILD
|
|
424 // Thread Sanitizer is a tool that finds races in code.
|
|
425 // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
|
|
426 // tsan detects these exact functions by name.
|
120
|
427 #ifdef __cplusplus
|
95
|
428 extern "C" {
|
120
|
429 #endif
|
95
|
430 void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
|
|
431 void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
|
|
432 void AnnotateIgnoreWritesBegin(const char *file, int line);
|
|
433 void AnnotateIgnoreWritesEnd(const char *file, int line);
|
120
|
434 #ifdef __cplusplus
|
95
|
435 }
|
120
|
436 #endif
|
95
|
437
|
|
438 // This marker is used to define a happens-before arc. The race detector will
|
|
439 // infer an arc from the begin to the end when they share the same pointer
|
|
440 // argument.
|
|
441 # define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
|
|
442
|
|
443 // This marker defines the destination of a happens-before arc.
|
|
444 # define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
|
|
445
|
|
446 // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
|
|
447 # define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
|
|
448
|
|
449 // Resume checking for racy writes.
|
|
450 # define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
|
|
451 #else
|
|
452 # define TsanHappensBefore(cv)
|
|
453 # define TsanHappensAfter(cv)
|
|
454 # define TsanIgnoreWritesBegin()
|
|
455 # define TsanIgnoreWritesEnd()
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
456 #endif
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
457
|
120
|
458 /// \macro LLVM_NO_SANITIZE
|
147
|
459 /// Disable a particular sanitizer for a function.
|
120
|
460 #if __has_attribute(no_sanitize)
|
|
461 #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
|
|
462 #else
|
|
463 #define LLVM_NO_SANITIZE(KIND)
|
|
464 #endif
|
|
465
|
147
|
466 /// Mark debug helper function definitions like dump() that should not be
|
77
|
467 /// stripped from debug builds.
|
121
|
468 /// Note that you should also surround dump() functions with
|
|
469 /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
|
|
470 /// get stripped in release builds.
|
77
|
471 // FIXME: Move this to a private config.h as it's not usable in public headers.
|
|
472 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
473 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
|
|
474 #else
|
|
475 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
476 #endif
|
77
|
477
|
120
|
478 /// \macro LLVM_PRETTY_FUNCTION
|
147
|
479 /// Gets a user-friendly looking function signature for the current scope
|
120
|
480 /// using the best available method on each platform. The exact format of the
|
|
481 /// resulting string is implementation specific and non-portable, so this should
|
|
482 /// only be used, for example, for logging or diagnostics.
|
|
483 #if defined(_MSC_VER)
|
|
484 #define LLVM_PRETTY_FUNCTION __FUNCSIG__
|
|
485 #elif defined(__GNUC__) || defined(__clang__)
|
|
486 #define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
121
|
487 #else
|
120
|
488 #define LLVM_PRETTY_FUNCTION __func__
|
|
489 #endif
|
|
490
|
83
|
491 /// \macro LLVM_THREAD_LOCAL
|
147
|
492 /// A thread-local storage specifier which can be used with globals,
|
83
|
493 /// extern globals, and static globals.
|
|
494 ///
|
|
495 /// This is essentially an extremely restricted analog to C++11's thread_local
|
|
496 /// support, and uses that when available. However, it falls back on
|
|
497 /// platform-specific or vendor-provided extensions when necessary. These
|
|
498 /// extensions don't support many of the C++11 thread_local's features. You
|
|
499 /// should only use this for PODs that you can statically initialize to
|
|
500 /// some constant value. In almost all circumstances this is most appropriate
|
|
501 /// for use with a pointer, integer, or small aggregation of pointers and
|
|
502 /// integers.
|
|
503 #if LLVM_ENABLE_THREADS
|
|
504 #if __has_feature(cxx_thread_local)
|
|
505 #define LLVM_THREAD_LOCAL thread_local
|
|
506 #elif defined(_MSC_VER)
|
|
507 // MSVC supports this with a __declspec.
|
|
508 #define LLVM_THREAD_LOCAL __declspec(thread)
|
|
509 #else
|
|
510 // Clang, GCC, and other compatible compilers used __thread prior to C++11 and
|
|
511 // we only need the restricted functionality that provides.
|
|
512 #define LLVM_THREAD_LOCAL __thread
|
77
|
513 #endif
|
83
|
514 #else // !LLVM_ENABLE_THREADS
|
|
515 // If threading is disabled entirely, this compiles to nothing and you get
|
|
516 // a normal global variable.
|
|
517 #define LLVM_THREAD_LOCAL
|
|
518 #endif
|
|
519
|
121
|
520 /// \macro LLVM_ENABLE_EXCEPTIONS
|
147
|
521 /// Whether LLVM is built with exception support.
|
121
|
522 #if __has_feature(cxx_exceptions)
|
|
523 #define LLVM_ENABLE_EXCEPTIONS 1
|
|
524 #elif defined(__GNUC__) && defined(__EXCEPTIONS)
|
|
525 #define LLVM_ENABLE_EXCEPTIONS 1
|
|
526 #elif defined(_MSC_VER) && defined(_CPPUNWIND)
|
|
527 #define LLVM_ENABLE_EXCEPTIONS 1
|
83
|
528 #endif
|
121
|
529
|
147
|
530 namespace llvm {
|
|
531
|
|
532 /// Allocate a buffer of memory with the given size and alignment.
|
|
533 ///
|
|
534 /// When the compiler supports aligned operator new, this will use it to to
|
|
535 /// handle even over-aligned allocations.
|
|
536 ///
|
|
537 /// However, this doesn't make any attempt to leverage the fancier techniques
|
|
538 /// like posix_memalign due to portability. It is mostly intended to allow
|
|
539 /// compatibility with platforms that, after aligned allocation was added, use
|
|
540 /// reduced default alignment.
|
|
541 inline void *allocate_buffer(size_t Size, size_t Alignment) {
|
|
542 return ::operator new(Size
|
|
543 #ifdef __cpp_aligned_new
|
|
544 ,
|
|
545 std::align_val_t(Alignment)
|
121
|
546 #endif
|
147
|
547 );
|
|
548 }
|
|
549
|
|
550 /// Deallocate a buffer of memory with the given size and alignment.
|
|
551 ///
|
|
552 /// If supported, this will used the sized delete operator. Also if supported,
|
|
553 /// this will pass the alignment to the delete operator.
|
|
554 ///
|
|
555 /// The pointer must have been allocated with the corresponding new operator,
|
|
556 /// most likely using the above helper.
|
|
557 inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
|
|
558 ::operator delete(Ptr
|
|
559 #ifdef __cpp_sized_deallocation
|
|
560 ,
|
|
561 Size
|
|
562 #endif
|
|
563 #ifdef __cpp_aligned_new
|
|
564 ,
|
|
565 std::align_val_t(Alignment)
|
|
566 #endif
|
|
567 );
|
|
568 }
|
|
569
|
|
570 } // End namespace llvm
|
|
571
|
|
572 #endif
|