WPILibC++  2020.3.2
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 #include <new>
19 #include <stddef.h>
20 
21 #if defined(_MSC_VER)
22 #include <sal.h>
23 #endif
24 
25 #ifndef __has_feature
26 # define __has_feature(x) 0
27 #endif
28 
29 #ifndef __has_extension
30 # define __has_extension(x) 0
31 #endif
32 
33 #ifndef __has_attribute
34 # define __has_attribute(x) 0
35 #endif
36 
37 #ifndef __has_cpp_attribute
38 # define __has_cpp_attribute(x) 0
39 #endif
40 
41 #ifndef __has_builtin
42 # define __has_builtin(x) 0
43 #endif
44 
48 #ifndef LLVM_GNUC_PREREQ
49 # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
50 # define LLVM_GNUC_PREREQ(maj, min, patch) \
51  ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
52  ((maj) << 20) + ((min) << 10) + (patch))
53 # elif defined(__GNUC__) && defined(__GNUC_MINOR__)
54 # define LLVM_GNUC_PREREQ(maj, min, patch) \
55  ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
56 # else
57 # define LLVM_GNUC_PREREQ(maj, min, patch) 0
58 # endif
59 #endif
60 
65 #ifndef LLVM_MSC_PREREQ
66 #ifdef _MSC_VER
67 #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
68 
69 // We require at least MSVC 2015.
70 #if !LLVM_MSC_PREREQ(1900)
71 #error wpiutil requires at least MSVC 2015.
72 #endif
73 
74 #else
75 #define LLVM_MSC_PREREQ(version) 0
76 #endif
77 #endif
78 
83 #ifndef LLVM_HAS_RVALUE_REFERENCE_THIS
84 #if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
85 #define LLVM_HAS_RVALUE_REFERENCE_THIS 1
86 #else
87 #define LLVM_HAS_RVALUE_REFERENCE_THIS 0
88 #endif
89 #endif
90 
95 #ifndef LLVM_LVALUE_FUNCTION
96 #if LLVM_HAS_RVALUE_REFERENCE_THIS
97 #define LLVM_LVALUE_FUNCTION &
98 #else
99 #define LLVM_LVALUE_FUNCTION
100 #endif
101 #endif
102 
103 #ifndef LLVM_PREFETCH
104 #if defined(__GNUC__)
105 #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
106 #else
107 #define LLVM_PREFETCH(addr, rw, locality)
108 #endif
109 #endif
110 
111 #ifndef LLVM_ATTRIBUTE_USED
112 #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
113 #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
114 #else
115 #define LLVM_ATTRIBUTE_USED
116 #endif
117 #endif
118 
120 #ifndef LLVM_NODISCARD
121 #if __cplusplus > 201402L && __has_cpp_attribute(nodiscard)
122 #define LLVM_NODISCARD [[nodiscard]]
123 // Detect MSVC directly, since __cplusplus still defaults to old version
124 #elif _MSVC_LANG >= 201703L
125 #define LLVM_NODISCARD [[nodiscard]]
126 #elif _MSC_VER
127 #define LLVM_NODISCARD
128 #elif !__cplusplus
129 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
130 // error when __has_cpp_attribute is given a scoped attribute in C mode.
131 #define LLVM_NODISCARD
132 #elif __has_cpp_attribute(clang::warn_unused_result)
133 #define LLVM_NODISCARD [[clang::warn_unused_result]]
134 #else
135 #define LLVM_NODISCARD
136 #endif
137 #endif
138 
139 // Some compilers warn about unused functions. When a function is sometimes
140 // used or not depending on build settings (e.g. a function only called from
141 // within "assert"), this attribute can be used to suppress such warnings.
142 //
143 // However, it shouldn't be used for unused *variables*, as those have a much
144 // more portable solution:
145 // (void)unused_var_name;
146 // Prefer cast-to-void wherever it is sufficient.
147 #ifndef LLVM_ATTRIBUTE_UNUSED
148 #if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
149 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
150 #else
151 #define LLVM_ATTRIBUTE_UNUSED
152 #endif
153 #endif
154 
155 #ifndef LLVM_READNONE
156 // Prior to clang 3.2, clang did not accept any spelling of
157 // __has_attribute(const), so assume it is supported.
158 #if defined(__clang__) || defined(__GNUC__)
159 // aka 'CONST' but following LLVM Conventions.
160 #define LLVM_READNONE __attribute__((__const__))
161 #else
162 #define LLVM_READNONE
163 #endif
164 #endif
165 
166 #ifndef LLVM_READONLY
167 #if __has_attribute(pure) || defined(__GNUC__)
168 // aka 'PURE' but following LLVM Conventions.
169 #define LLVM_READONLY __attribute__((__pure__))
170 #else
171 #define LLVM_READONLY
172 #endif
173 #endif
174 
175 #ifndef LLVM_LIKELY
176 #if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0)
177 #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
178 #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
179 #else
180 #define LLVM_LIKELY(EXPR) (EXPR)
181 #define LLVM_UNLIKELY(EXPR) (EXPR)
182 #endif
183 #endif
184 
187 #ifndef LLVM_ATTRIBUTE_NOINLINE
188 #if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
189 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
190 #elif defined(_MSC_VER)
191 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
192 #else
193 #define LLVM_ATTRIBUTE_NOINLINE
194 #endif
195 #endif
196 
201 #ifndef LLVM_ATTRIBUTE_ALWAYS_INLINE
202 #if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
203 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) inline
204 #elif defined(_MSC_VER)
205 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
206 #else
207 #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
208 #endif
209 #endif
210 
211 #ifndef LLVM_ATTRIBUTE_NORETURN
212 #ifdef __GNUC__
213 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
214 #elif defined(_MSC_VER)
215 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
216 #else
217 #define LLVM_ATTRIBUTE_NORETURN
218 #endif
219 #endif
220 
221 #ifndef LLVM_ATTRIBUTE_RETURNS_NONNULL
222 #if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
223 #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
224 #elif defined(_MSC_VER)
225 #define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
226 #else
227 #define LLVM_ATTRIBUTE_RETURNS_NONNULL
228 #endif
229 #endif
230 
233 #ifndef LLVM_ATTRIBUTE_RETURNS_NOALIAS
234 #ifdef __GNUC__
235 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
236 #elif defined(_MSC_VER)
237 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
238 #else
239 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
240 #endif
241 #endif
242 
244 #ifndef LLVM_FALLTHROUGH
245 #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
246 #define LLVM_FALLTHROUGH [[fallthrough]]
247 // Detect MSVC directly, since __cplusplus still defaults to old version
248 #elif _MSVC_LANG >= 201703L
249 #define LLVM_FALLTHROUGH [[fallthrough]]
250 #elif _MSC_VER
251 #define LLVM_FALLTHROUGH
252 #elif __has_cpp_attribute(gnu::fallthrough)
253 #define LLVM_FALLTHROUGH [[gnu::fallthrough]]
254 #elif !__cplusplus
255 // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
256 // error when __has_cpp_attribute is given a scoped attribute in C mode.
257 #define LLVM_FALLTHROUGH
258 #elif __has_cpp_attribute(clang::fallthrough)
259 #define LLVM_FALLTHROUGH [[clang::fallthrough]]
260 #else
261 #define LLVM_FALLTHROUGH
262 #endif
263 #endif
264 
267 #ifndef LLVM_EXTENSION
268 #ifdef __GNUC__
269 #define LLVM_EXTENSION __extension__
270 #else
271 #define LLVM_EXTENSION
272 #endif
273 #endif
274 
275 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
276 #ifndef LLVM_ATTRIBUTE_DEPRECATED
277 #if __has_feature(attribute_deprecated_with_message)
278 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
279  decl __attribute__((deprecated(message)))
280 #elif defined(__GNUC__)
281 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
282  decl __attribute__((deprecated))
283 #elif defined(_MSC_VER)
284 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
285  __declspec(deprecated(message)) decl
286 #else
287 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
288  decl
289 #endif
290 #endif
291 
295 #ifndef LLVM_BUILTIN_UNREACHABLE
296 #if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
297 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
298 #elif defined(_MSC_VER)
299 # define LLVM_BUILTIN_UNREACHABLE __assume(false)
300 #endif
301 #endif
302 
305 #ifndef LLVM_BUILTIN_TRAP
306 #if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0)
307 # define LLVM_BUILTIN_TRAP __builtin_trap()
308 #elif defined(_MSC_VER)
309 // The __debugbreak intrinsic is supported by MSVC, does not require forward
310 // declarations involving platform-specific typedefs (unlike RaiseException),
311 // results in a call to vectored exception handlers, and encodes to a short
312 // instruction that still causes the trapping behavior we want.
313 # define LLVM_BUILTIN_TRAP __debugbreak()
314 #else
315 # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
316 #endif
317 #endif
318 
322 #ifndef LLVM_BUILTIN_DEBUGTRAP
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 #endif
337 
340 #ifndef LLVM_ASSUME_ALIGNED
341 #if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
342 # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
343 #elif defined(LLVM_BUILTIN_UNREACHABLE)
344 // As of today, clang does not support __builtin_assume_aligned.
345 # define LLVM_ASSUME_ALIGNED(p, a) \
346  (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
347 #else
348 # define LLVM_ASSUME_ALIGNED(p, a) (p)
349 #endif
350 #endif
351 
354 #ifndef LLVM_ALIGNAS
355 #if __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 1)
356 # define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
357 #else
358 # define LLVM_ALIGNAS(x) alignas(x)
359 #endif
360 #endif
361 
380 #ifndef LLVM_PACKED
381 #ifdef _MSC_VER
382 # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
383 # define LLVM_PACKED_START __pragma(pack(push, 1))
384 # define LLVM_PACKED_END __pragma(pack(pop))
385 #else
386 # define LLVM_PACKED(d) d __attribute__((packed))
387 # define LLVM_PACKED_START _Pragma("pack(push, 1)")
388 # define LLVM_PACKED_END _Pragma("pack(pop)")
389 #endif
390 #endif
391 
396 #ifndef LLVM_PTR_SIZE
397 #ifdef __SIZEOF_POINTER__
398 # define LLVM_PTR_SIZE __SIZEOF_POINTER__
399 #elif defined(_WIN64)
400 # define LLVM_PTR_SIZE 8
401 #elif defined(_WIN32)
402 # define LLVM_PTR_SIZE 4
403 #elif defined(_MSC_VER)
404 # error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
405 #else
406 # define LLVM_PTR_SIZE sizeof(void *)
407 #endif
408 #endif
409 
412 #ifndef LLVM_NO_SANITIZE
413 #if __has_attribute(no_sanitize)
414 #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
415 #else
416 #define LLVM_NO_SANITIZE(KIND)
417 #endif
418 #endif
419 
425 // FIXME: Move this to a private config.h as it's not usable in public headers.
426 #ifndef LLVM_DUMP_METHOD
427 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
428 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
429 #else
430 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
431 #endif
432 #endif
433 
439 #ifndef LLVM_PRETTY_FUNCTION
440 #if defined(_MSC_VER)
441 #define LLVM_PRETTY_FUNCTION __FUNCSIG__
442 #elif defined(__GNUC__) || defined(__clang__)
443 #define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__
444 #else
445 #define LLVM_PRETTY_FUNCTION __func__
446 #endif
447 #endif
448 
461 #ifndef LLVM_THREAD_LOCAL
462 #if __has_feature(cxx_thread_local)
463 #define LLVM_THREAD_LOCAL thread_local
464 #elif defined(_MSC_VER)
465 // MSVC supports this with a __declspec.
466 #define LLVM_THREAD_LOCAL __declspec(thread)
467 #else
468 // Clang, GCC, and other compatible compilers used __thread prior to C++11 and
469 // we only need the restricted functionality that provides.
470 #define LLVM_THREAD_LOCAL __thread
471 #endif
472 #endif
473 
474 namespace wpi {
475 
485 inline void *allocate_buffer(size_t Size, size_t Alignment) {
486  return ::operator new(Size
487 #ifdef __cpp_aligned_new
488  ,
489  std::align_val_t(Alignment)
490 #endif
491  );
492 }
493 
501 inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
502  ::operator delete(Ptr
503 #ifdef __cpp_sized_deallocation
504  ,
505  Size
506 #endif
507 #ifdef __cpp_aligned_new
508  ,
509  std::align_val_t(Alignment)
510 #endif
511  );
512 }
513 
514 } // End namespace wpi
515 
516 #endif
wpi::allocate_buffer
void * allocate_buffer(size_t Size, size_t Alignment)
Allocate a buffer of memory with the given size and alignment.
Definition: Compiler.h:485
wpi::deallocate_buffer
void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment)
Deallocate a buffer of memory with the given size and alignment.
Definition: Compiler.h:501
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: EventLoopRunner.h:17