15 #ifndef WPIUTIL_WPI_COMPILER_H
16 #define WPIUTIL_WPI_COMPILER_H
23 # define __has_feature(x) 0
26 #ifndef __has_extension
27 # define __has_extension(x) 0
30 #ifndef __has_attribute
31 # define __has_attribute(x) 0
34 #ifndef __has_cpp_attribute
35 # define __has_cpp_attribute(x) 0
39 # define __has_builtin(x) 0
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))
54 # define LLVM_GNUC_PREREQ(maj, min, patch) 0
62 #ifndef LLVM_MSC_PREREQ
64 #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
67 #if !LLVM_MSC_PREREQ(1900)
68 #error wpiutil requires at least MSVC 2015.
72 #define LLVM_MSC_PREREQ(version) 0
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
84 #define LLVM_HAS_RVALUE_REFERENCE_THIS 0
92 #ifndef LLVM_LVALUE_FUNCTION
93 #if LLVM_HAS_RVALUE_REFERENCE_THIS
94 #define LLVM_LVALUE_FUNCTION &
96 #define LLVM_LVALUE_FUNCTION
100 #ifndef LLVM_PREFETCH
101 #if defined(__GNUC__)
102 #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
104 #define LLVM_PREFETCH(addr, rw, locality)
108 #ifndef LLVM_ATTRIBUTE_USED
109 #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
110 #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
112 #define LLVM_ATTRIBUTE_USED
117 #ifndef LLVM_NODISCARD
118 #if __cplusplus > 201402L && __has_cpp_attribute(nodiscard)
119 #define LLVM_NODISCARD [[nodiscard]]
123 #define LLVM_NODISCARD
124 #elif __has_cpp_attribute(clang::warn_unused_result)
125 #define LLVM_NODISCARD [[clang::warn_unused_result]]
127 #define LLVM_NODISCARD
139 #ifndef LLVM_ATTRIBUTE_UNUSED
140 #if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
141 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
143 #define LLVM_ATTRIBUTE_UNUSED
147 #ifndef LLVM_READNONE
150 #if defined(__clang__) || defined(__GNUC__)
152 #define LLVM_READNONE __attribute__((__const__))
154 #define LLVM_READNONE
158 #ifndef LLVM_READONLY
159 #if __has_attribute(pure) || defined(__GNUC__)
161 #define LLVM_READONLY __attribute__((__pure__))
163 #define LLVM_READONLY
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)
172 #define LLVM_LIKELY(EXPR) (EXPR)
173 #define LLVM_UNLIKELY(EXPR) (EXPR)
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)
185 #define LLVM_ATTRIBUTE_NOINLINE
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
199 #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
203 #ifndef LLVM_ATTRIBUTE_NORETURN
205 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
206 #elif defined(_MSC_VER)
207 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
209 #define LLVM_ATTRIBUTE_NORETURN
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_
219 #define LLVM_ATTRIBUTE_RETURNS_NONNULL
225 #ifndef LLVM_ATTRIBUTE_RETURNS_NOALIAS
227 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
228 #elif defined(_MSC_VER)
229 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
231 #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
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]]
244 #define LLVM_FALLTHROUGH
245 #elif __has_cpp_attribute(clang::fallthrough)
246 #define LLVM_FALLTHROUGH [[clang::fallthrough]]
248 #define LLVM_FALLTHROUGH
254 #ifndef LLVM_EXTENSION
256 #define LLVM_EXTENSION __extension__
258 #define LLVM_EXTENSION
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
274 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
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)
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)
297 # define LLVM_ASSUME_ALIGNED(p, a) \
298 (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
300 # define LLVM_ASSUME_ALIGNED(p, a) (p)
307 #if __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 1)
308 # define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
310 # define LLVM_ALIGNAS(x) alignas(x)
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))
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)")
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"
358 # define LLVM_PTR_SIZE sizeof(void *)
364 #ifndef LLVM_NO_SANITIZE
365 #if __has_attribute(no_sanitize)
366 #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
368 #define LLVM_NO_SANITIZE(KIND)
378 #ifndef LLVM_DUMP_METHOD
379 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
380 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
382 #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
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__
397 #define LLVM_PRETTY_FUNCTION __func__
413 #ifndef LLVM_THREAD_LOCAL
414 #if __has_feature(cxx_thread_local)
415 #define LLVM_THREAD_LOCAL thread_local
416 #elif defined(_MSC_VER)
418 #define LLVM_THREAD_LOCAL __declspec(thread)
422 #define LLVM_THREAD_LOCAL __thread