WPILibC++  2019.1.1-2-g444b899
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Compiler.h
1 //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines several macros, based on the current compiler. This allows
11 // use of compiler-specific features in a way that remains portable.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef WPIUTIL_WPI_COMPILER_H
16 #define WPIUTIL_WPI_COMPILER_H
17 
18 #if defined(_MSC_VER)
19 #include <sal.h>
20 #endif
21 
22 #ifndef __has_feature
23 # define __has_feature(x) 0
24 #endif
25 
26 #ifndef __has_extension
27 # define __has_extension(x) 0
28 #endif
29 
30 #ifndef __has_attribute
31 # define __has_attribute(x) 0
32 #endif
33 
34 #ifndef __has_cpp_attribute
35 # define __has_cpp_attribute(x) 0
36 #endif
37 
38 #ifndef __has_builtin
39 # define __has_builtin(x) 0
40 #endif
41 
45 #ifndef LLVM_GNUC_PREREQ
46 # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
47 # define LLVM_GNUC_PREREQ(maj, min, patch) \
48  ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
49  ((maj) << 20) + ((min) << 10) + (patch))
50 # elif defined(__GNUC__) && defined(__GNUC_MINOR__)
51 # define LLVM_GNUC_PREREQ(maj, min, patch) \
52  ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
53 # else
54 # define LLVM_GNUC_PREREQ(maj, min, patch) 0
55 # endif
56 #endif
57 
62 #ifndef LLVM_MSC_PREREQ
63 #ifdef _MSC_VER
64 #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
65 
66 // We require at least MSVC 2015.
67 #if !LLVM_MSC_PREREQ(1900)
68 #error wpiutil requires at least MSVC 2015.
69 #endif
70 
71 #else
72 #define LLVM_MSC_PREREQ(version) 0
73 #endif
74 #endif
75 
80 #ifndef LLVM_HAS_RVALUE_REFERENCE_THIS
81 #if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
82 #define LLVM_HAS_RVALUE_REFERENCE_THIS 1
83 #else
84 #define LLVM_HAS_RVALUE_REFERENCE_THIS 0
85 #endif
86 #endif
87 
92 #ifndef LLVM_LVALUE_FUNCTION
93 #if LLVM_HAS_RVALUE_REFERENCE_THIS
94 #define LLVM_LVALUE_FUNCTION &
95 #else
96 #define LLVM_LVALUE_FUNCTION
97 #endif
98 #endif
99 
100 #ifndef LLVM_PREFETCH
101 #if defined(__GNUC__)
102 #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
103 #else
104 #define LLVM_PREFETCH(addr, rw, locality)
105 #endif
106 #endif
107 
108 #ifndef LLVM_ATTRIBUTE_USED
109 #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
110 #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
111 #else
112 #define LLVM_ATTRIBUTE_USED
113 #endif
114 #endif
115 
117 #ifndef LLVM_NODISCARD
118 #if __cplusplus > 201402L && __has_cpp_attribute(nodiscard)
119 #define LLVM_NODISCARD [[nodiscard]]
120 #elif !__cplusplus
121 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
122 // error when __has_cpp_attribute is given a scoped attribute in C mode.
123 #define LLVM_NODISCARD
124 #elif __has_cpp_attribute(clang::warn_unused_result)
125 #define LLVM_NODISCARD [[clang::warn_unused_result]]
126 #else
127 #define LLVM_NODISCARD
128 #endif
129 #endif
130 
131 // Some compilers warn about unused functions. When a function is sometimes
132 // used or not depending on build settings (e.g. a function only called from
133 // within "assert"), this attribute can be used to suppress such warnings.
134 //
135 // However, it shouldn't be used for unused *variables*, as those have a much
136 // more portable solution:
137 // (void)unused_var_name;
138 // Prefer cast-to-void wherever it is sufficient.
139 #ifndef LLVM_ATTRIBUTE_UNUSED
140 #if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
141 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
142 #else
143 #define LLVM_ATTRIBUTE_UNUSED
144 #endif
145 #endif
146 
147 #ifndef LLVM_READNONE
148 // Prior to clang 3.2, clang did not accept any spelling of
149 // __has_attribute(const), so assume it is supported.
150 #if defined(__clang__) || defined(__GNUC__)
151 // aka 'CONST' but following LLVM Conventions.
152 #define LLVM_READNONE __attribute__((__const__))
153 #else
154 #define LLVM_READNONE
155 #endif
156 #endif
157 
158 #ifndef LLVM_READONLY
159 #if __has_attribute(pure) || defined(__GNUC__)
160 // aka 'PURE' but following LLVM Conventions.
161 #define LLVM_READONLY __attribute__((__pure__))
162 #else
163 #define LLVM_READONLY
164 #endif
165 #endif
166 
167 #ifndef LLVM_LIKELY
168 #if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0)
169 #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
170 #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
171 #else
172 #define LLVM_LIKELY(EXPR) (EXPR)
173 #define LLVM_UNLIKELY(EXPR) (EXPR)
174 #endif
175 #endif
176 
179 #ifndef LLVM_ATTRIBUTE_NOINLINE
180 #if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
181 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
182 #elif defined(_MSC_VER)
183 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
184 #else
185 #define LLVM_ATTRIBUTE_NOINLINE
186 #endif
187 #endif
188 
193 #ifndef LLVM_ATTRIBUTE_ALWAYS_INLINE
194 #if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
195 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) inline
196 #elif defined(_MSC_VER)
197 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
198 #else
199 #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
200 #endif
201 #endif
202 
203 #ifndef LLVM_ATTRIBUTE_NORETURN
204 #ifdef __GNUC__
205 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
206 #elif defined(_MSC_VER)
207 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
208 #else
209 #define LLVM_ATTRIBUTE_NORETURN
210 #endif
211 #endif
212 
213 #ifndef LLVM_ATTRIBUTE_RETURNS_NONNULL
214 #if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
215 #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
216 #elif defined(_MSC_VER)
217 #define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
218 #else
219 #define LLVM_ATTRIBUTE_RETURNS_NONNULL
220 #endif
221 #endif
222 
225 #ifndef LLVM_ATTRIBUTE_RETURNS_NOALIAS
226 #ifdef __GNUC__
227 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
228 #elif defined(_MSC_VER)
229 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
230 #else
231 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
232 #endif
233 #endif
234 
236 #ifndef LLVM_FALLTHROUGH
237 #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
238 #define LLVM_FALLTHROUGH [[fallthrough]]
239 #elif __has_cpp_attribute(gnu::fallthrough)
240 #define LLVM_FALLTHROUGH [[gnu::fallthrough]]
241 #elif !__cplusplus
242 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
243 // error when __has_cpp_attribute is given a scoped attribute in C mode.
244 #define LLVM_FALLTHROUGH
245 #elif __has_cpp_attribute(clang::fallthrough)
246 #define LLVM_FALLTHROUGH [[clang::fallthrough]]
247 #else
248 #define LLVM_FALLTHROUGH
249 #endif
250 #endif
251 
254 #ifndef LLVM_EXTENSION
255 #ifdef __GNUC__
256 #define LLVM_EXTENSION __extension__
257 #else
258 #define LLVM_EXTENSION
259 #endif
260 #endif
261 
262 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
263 #ifndef LLVM_ATTRIBUTE_DEPRECATED
264 #if __has_feature(attribute_deprecated_with_message)
265 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
266  decl __attribute__((deprecated(message)))
267 #elif defined(__GNUC__)
268 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
269  decl __attribute__((deprecated))
270 #elif defined(_MSC_VER)
271 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
272  __declspec(deprecated(message)) decl
273 #else
274 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
275  decl
276 #endif
277 #endif
278 
282 #ifndef LLVM_BUILTIN_UNREACHABLE
283 #if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
284 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
285 #elif defined(_MSC_VER)
286 # define LLVM_BUILTIN_UNREACHABLE __assume(false)
287 #endif
288 #endif
289 
292 #ifndef LLVM_ASSUME_ALIGNED
293 #if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
294 # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
295 #elif defined(LLVM_BUILTIN_UNREACHABLE)
296 // As of today, clang does not support __builtin_assume_aligned.
297 # define LLVM_ASSUME_ALIGNED(p, a) \
298  (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
299 #else
300 # define LLVM_ASSUME_ALIGNED(p, a) (p)
301 #endif
302 #endif
303 
306 #ifndef LLVM_ALIGNAS
307 #if __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 1)
308 # define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
309 #else
310 # define LLVM_ALIGNAS(x) alignas(x)
311 #endif
312 #endif
313 
332 #ifndef LLVM_PACKED
333 #ifdef _MSC_VER
334 # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
335 # define LLVM_PACKED_START __pragma(pack(push, 1))
336 # define LLVM_PACKED_END __pragma(pack(pop))
337 #else
338 # define LLVM_PACKED(d) d __attribute__((packed))
339 # define LLVM_PACKED_START _Pragma("pack(push, 1)")
340 # define LLVM_PACKED_END _Pragma("pack(pop)")
341 #endif
342 #endif
343 
348 #ifndef LLVM_PTR_SIZE
349 #ifdef __SIZEOF_POINTER__
350 # define LLVM_PTR_SIZE __SIZEOF_POINTER__
351 #elif defined(_WIN64)
352 # define LLVM_PTR_SIZE 8
353 #elif defined(_WIN32)
354 # define LLVM_PTR_SIZE 4
355 #elif defined(_MSC_VER)
356 # error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
357 #else
358 # define LLVM_PTR_SIZE sizeof(void *)
359 #endif
360 #endif
361 
364 #ifndef LLVM_NO_SANITIZE
365 #if __has_attribute(no_sanitize)
366 #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
367 #else
368 #define LLVM_NO_SANITIZE(KIND)
369 #endif
370 #endif
371 
377 // FIXME: Move this to a private config.h as it's not usable in public headers.
378 #ifndef LLVM_DUMP_METHOD
379 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
380 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
381 #else
382 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
383 #endif
384 #endif
385 
391 #ifndef LLVM_PRETTY_FUNCTION
392 #if defined(_MSC_VER)
393 #define LLVM_PRETTY_FUNCTION __FUNCSIG__
394 #elif defined(__GNUC__) || defined(__clang__)
395 #define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__
396 #else
397 #define LLVM_PRETTY_FUNCTION __func__
398 #endif
399 #endif
400 
413 #ifndef LLVM_THREAD_LOCAL
414 #if __has_feature(cxx_thread_local)
415 #define LLVM_THREAD_LOCAL thread_local
416 #elif defined(_MSC_VER)
417 // MSVC supports this with a __declspec.
418 #define LLVM_THREAD_LOCAL __declspec(thread)
419 #else
420 // Clang, GCC, and other compatible compilers used __thread prior to C++11 and
421 // we only need the restricted functionality that provides.
422 #define LLVM_THREAD_LOCAL __thread
423 #endif
424 #endif
425 
426 #endif