|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 | //
|
9 | 9 | // This file defines several macros, based on the current compiler. This allows
|
10 |
| -// use of compiler-specific features in a way that remains portable. |
| 10 | +// use of compiler-specific features in a way that remains portable. This header |
| 11 | +// can be included from either C or C++. |
11 | 12 | //
|
12 | 13 | //===----------------------------------------------------------------------===//
|
13 | 14 |
|
|
16 | 17 |
|
17 | 18 | #include "llvm/Config/llvm-config.h"
|
18 | 19 |
|
| 20 | +#ifdef __cplusplus |
19 | 21 | #include <new>
|
| 22 | +#endif |
20 | 23 | #include <stddef.h>
|
21 | 24 |
|
22 | 25 | #if defined(_MSC_VER)
|
|
35 | 38 | # define __has_attribute(x) 0
|
36 | 39 | #endif
|
37 | 40 |
|
38 |
| -#ifndef __has_cpp_attribute |
39 |
| -# define __has_cpp_attribute(x) 0 |
40 |
| -#endif |
41 |
| - |
42 | 41 | #ifndef __has_builtin
|
43 | 42 | # define __has_builtin(x) 0
|
44 | 43 | #endif
|
45 | 44 |
|
| 45 | +// Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in |
| 46 | +// C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid. |
| 47 | +#ifndef LLVM_HAS_CPP_ATTRIBUTE |
| 48 | +#if defined(__cplusplus) && defined(__has_cpp_attribute) |
| 49 | +# define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) |
| 50 | +#else |
| 51 | +# define LLVM_HAS_CPP_ATTRIBUTE(x) 0 |
| 52 | +#endif |
| 53 | +#endif |
| 54 | + |
46 | 55 | /// \macro LLVM_GNUC_PREREQ
|
47 | 56 | /// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
|
48 | 57 | /// available.
|
|
120 | 129 | #endif
|
121 | 130 |
|
122 | 131 | /// LLVM_NODISCARD - Warn if a type or return value is discarded.
|
123 |
| -#if __cplusplus > 201402L && __has_cpp_attribute(nodiscard) |
| 132 | +#if __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) |
124 | 133 | #define LLVM_NODISCARD [[nodiscard]]
|
125 |
| -#elif !__cplusplus |
126 |
| -// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious |
127 |
| -// error when __has_cpp_attribute is given a scoped attribute in C mode. |
128 |
| -#define LLVM_NODISCARD |
129 |
| -#elif __has_cpp_attribute(clang::warn_unused_result) |
| 134 | +#elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result) |
130 | 135 | #define LLVM_NODISCARD [[clang::warn_unused_result]]
|
131 | 136 | #else
|
132 | 137 | #define LLVM_NODISCARD
|
|
139 | 144 | // The clang-tidy check bugprone-use-after-move recognizes this attribute as a
|
140 | 145 | // marker that a moved-from object has left the indeterminate state and can be
|
141 | 146 | // reused.
|
142 |
| -#if __has_cpp_attribute(clang::reinitializes) |
| 147 | +#if LLVM_HAS_CPP_ATTRIBUTE(clang::reinitializes) |
143 | 148 | #define LLVM_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
|
144 | 149 | #else
|
145 | 150 | #define LLVM_ATTRIBUTE_REINITIALIZES
|
|
240 | 245 | #endif
|
241 | 246 |
|
242 | 247 | /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
|
243 |
| -#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough) |
| 248 | +#if __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough) |
244 | 249 | #define LLVM_FALLTHROUGH [[fallthrough]]
|
245 |
| -#elif __has_cpp_attribute(gnu::fallthrough) |
| 250 | +#elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough) |
246 | 251 | #define LLVM_FALLTHROUGH [[gnu::fallthrough]]
|
247 |
| -#elif !__cplusplus |
248 |
| -// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious |
249 |
| -// error when __has_cpp_attribute is given a scoped attribute in C mode. |
250 |
| -#define LLVM_FALLTHROUGH |
251 |
| -#elif __has_cpp_attribute(clang::fallthrough) |
| 252 | +#elif __has_attribute(fallthrough) |
| 253 | +#define LLVM_FALLTHROUGH __attribute__((fallthrough)) |
| 254 | +#elif LLVM_HAS_CPP_ATTRIBUTE(clang::fallthrough) |
252 | 255 | #define LLVM_FALLTHROUGH [[clang::fallthrough]]
|
253 | 256 | #else
|
254 | 257 | #define LLVM_FALLTHROUGH
|
255 | 258 | #endif
|
256 | 259 |
|
257 | 260 | /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
|
258 | 261 | /// they are constant initialized.
|
259 |
| -#if __has_cpp_attribute(clang::require_constant_initialization) |
| 262 | +#if LLVM_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization) |
260 | 263 | #define LLVM_REQUIRE_CONSTANT_INITIALIZATION \
|
261 | 264 | [[clang::require_constant_initialization]]
|
262 | 265 | #else
|
@@ -527,6 +530,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
|
527 | 530 | #define LLVM_ENABLE_EXCEPTIONS 1
|
528 | 531 | #endif
|
529 | 532 |
|
| 533 | +#ifdef __cplusplus |
530 | 534 | namespace llvm {
|
531 | 535 |
|
532 | 536 | /// Allocate a buffer of memory with the given size and alignment.
|
@@ -569,4 +573,5 @@ inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
|
569 | 573 |
|
570 | 574 | } // End namespace llvm
|
571 | 575 |
|
| 576 | +#endif // __cplusplus |
572 | 577 | #endif
|
0 commit comments