10b57cec5SDimitry Andric //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines several macros, based on the current compiler.  This allows
108bcb0991SDimitry Andric // use of compiler-specific features in a way that remains portable. This header
118bcb0991SDimitry Andric // can be included from either C or C++.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_SUPPORT_COMPILER_H
160b57cec5SDimitry Andric #define LLVM_SUPPORT_COMPILER_H
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include <stddef.h>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #if defined(_MSC_VER)
230b57cec5SDimitry Andric #include <sal.h>
240b57cec5SDimitry Andric #endif
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #ifndef __has_feature
270b57cec5SDimitry Andric # define __has_feature(x) 0
280b57cec5SDimitry Andric #endif
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric #ifndef __has_extension
310b57cec5SDimitry Andric # define __has_extension(x) 0
320b57cec5SDimitry Andric #endif
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #ifndef __has_attribute
350b57cec5SDimitry Andric # define __has_attribute(x) 0
360b57cec5SDimitry Andric #endif
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #ifndef __has_builtin
390b57cec5SDimitry Andric # define __has_builtin(x) 0
400b57cec5SDimitry Andric #endif
410b57cec5SDimitry Andric 
4281ad6265SDimitry Andric #ifndef __has_include
4381ad6265SDimitry Andric # define __has_include(x) 0
4481ad6265SDimitry Andric #endif
4581ad6265SDimitry Andric 
468bcb0991SDimitry Andric // Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in
478bcb0991SDimitry Andric // C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid.
488bcb0991SDimitry Andric #ifndef LLVM_HAS_CPP_ATTRIBUTE
498bcb0991SDimitry Andric #if defined(__cplusplus) && defined(__has_cpp_attribute)
508bcb0991SDimitry Andric # define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
518bcb0991SDimitry Andric #else
528bcb0991SDimitry Andric # define LLVM_HAS_CPP_ATTRIBUTE(x) 0
538bcb0991SDimitry Andric #endif
548bcb0991SDimitry Andric #endif
558bcb0991SDimitry Andric 
560b57cec5SDimitry Andric /// \macro LLVM_GNUC_PREREQ
570b57cec5SDimitry Andric /// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
580b57cec5SDimitry Andric /// available.
590b57cec5SDimitry Andric #ifndef LLVM_GNUC_PREREQ
600b57cec5SDimitry Andric # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
610b57cec5SDimitry Andric #  define LLVM_GNUC_PREREQ(maj, min, patch) \
620b57cec5SDimitry Andric     ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
630b57cec5SDimitry Andric      ((maj) << 20) + ((min) << 10) + (patch))
640b57cec5SDimitry Andric # elif defined(__GNUC__) && defined(__GNUC_MINOR__)
650b57cec5SDimitry Andric #  define LLVM_GNUC_PREREQ(maj, min, patch) \
660b57cec5SDimitry Andric     ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
670b57cec5SDimitry Andric # else
680b57cec5SDimitry Andric #  define LLVM_GNUC_PREREQ(maj, min, patch) 0
690b57cec5SDimitry Andric # endif
700b57cec5SDimitry Andric #endif
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric /// \macro LLVM_MSC_PREREQ
730b57cec5SDimitry Andric /// Is the compiler MSVC of at least the specified version?
740b57cec5SDimitry Andric /// The common \param version values to check for are:
758bcb0991SDimitry Andric /// * 1910: VS2017, version 15.1 & 15.2
768bcb0991SDimitry Andric /// * 1911: VS2017, version 15.3 & 15.4
778bcb0991SDimitry Andric /// * 1912: VS2017, version 15.5
788bcb0991SDimitry Andric /// * 1913: VS2017, version 15.6
798bcb0991SDimitry Andric /// * 1914: VS2017, version 15.7
808bcb0991SDimitry Andric /// * 1915: VS2017, version 15.8
818bcb0991SDimitry Andric /// * 1916: VS2017, version 15.9
828bcb0991SDimitry Andric /// * 1920: VS2019, version 16.0
838bcb0991SDimitry Andric /// * 1921: VS2019, version 16.1
841fd87a68SDimitry Andric /// * 1922: VS2019, version 16.2
851fd87a68SDimitry Andric /// * 1923: VS2019, version 16.3
861fd87a68SDimitry Andric /// * 1924: VS2019, version 16.4
871fd87a68SDimitry Andric /// * 1925: VS2019, version 16.5
881fd87a68SDimitry Andric /// * 1926: VS2019, version 16.6
891fd87a68SDimitry Andric /// * 1927: VS2019, version 16.7
901fd87a68SDimitry Andric /// * 1928: VS2019, version 16.8 + 16.9
911fd87a68SDimitry Andric /// * 1929: VS2019, version 16.10 + 16.11
921fd87a68SDimitry Andric /// * 1930: VS2022, version 17.0
930b57cec5SDimitry Andric #ifdef _MSC_VER
940b57cec5SDimitry Andric #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
950b57cec5SDimitry Andric 
961fd87a68SDimitry Andric // We require at least VS 2019.
97d56accc7SDimitry Andric #if !defined(LLVM_FORCE_USE_OLD_TOOLCHAIN)
981fd87a68SDimitry Andric #if !LLVM_MSC_PREREQ(1920)
991fd87a68SDimitry Andric #error LLVM requires at least VS 2019.
1000b57cec5SDimitry Andric #endif
101d56accc7SDimitry Andric #endif
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric #else
1040b57cec5SDimitry Andric #define LLVM_MSC_PREREQ(version) 0
1050b57cec5SDimitry Andric #endif
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
1080b57cec5SDimitry Andric /// into a shared library, then the class should be private to the library and
1090b57cec5SDimitry Andric /// not accessible from outside it.  Can also be used to mark variables and
1100b57cec5SDimitry Andric /// functions, making them private to any shared library they are linked into.
1110b57cec5SDimitry Andric /// On PE/COFF targets, library visibility is the default, so this isn't needed.
112480093f4SDimitry Andric ///
113480093f4SDimitry Andric /// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with
114480093f4SDimitry Andric /// this attribute will be made public and visible outside of any shared library
115480093f4SDimitry Andric /// they are linked in to.
11606c3fb27SDimitry Andric 
11706c3fb27SDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility)
11806c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN [[gnu::visibility("hidden")]]
11906c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT [[gnu::visibility("default")]]
12006c3fb27SDimitry Andric #elif __has_attribute(visibility)
12106c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
12206c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT __attribute__((visibility("default")))
12306c3fb27SDimitry Andric #else
12406c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
12506c3fb27SDimitry Andric #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
12606c3fb27SDimitry Andric #endif
12706c3fb27SDimitry Andric 
12806c3fb27SDimitry Andric 
12906c3fb27SDimitry Andric #if (!(defined(_WIN32) || defined(__CYGWIN__)) ||                              \
130bdd1243dSDimitry Andric      (defined(__MINGW32__) && defined(__clang__)))
13106c3fb27SDimitry Andric #define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN
1320eae32dcSDimitry Andric #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
13306c3fb27SDimitry Andric #define LLVM_EXTERNAL_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
1340b57cec5SDimitry Andric #else
1350eae32dcSDimitry Andric #define LLVM_EXTERNAL_VISIBILITY
1360eae32dcSDimitry Andric #endif
1370eae32dcSDimitry Andric #else
1380b57cec5SDimitry Andric #define LLVM_LIBRARY_VISIBILITY
139480093f4SDimitry Andric #define LLVM_EXTERNAL_VISIBILITY
1400b57cec5SDimitry Andric #endif
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric #if defined(__GNUC__)
1430b57cec5SDimitry Andric #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
1440b57cec5SDimitry Andric #else
1450b57cec5SDimitry Andric #define LLVM_PREFETCH(addr, rw, locality)
1460b57cec5SDimitry Andric #endif
1470b57cec5SDimitry Andric 
148349cc55cSDimitry Andric #if __has_attribute(used)
1490b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
1500b57cec5SDimitry Andric #else
1510b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_USED
1520b57cec5SDimitry Andric #endif
1530b57cec5SDimitry Andric 
154bdd1243dSDimitry Andric #if defined(__clang__)
155bdd1243dSDimitry Andric #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX)))
1560b57cec5SDimitry Andric #else
157bdd1243dSDimitry Andric #define LLVM_DEPRECATED(MSG, FIX) [[deprecated(MSG)]]
1580b57cec5SDimitry Andric #endif
1590b57cec5SDimitry Andric 
1605f757f3fSDimitry Andric // clang-format off
1615f757f3fSDimitry Andric #if defined(__clang__) || defined(__GNUC__)
1625f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH                             \
1635f757f3fSDimitry Andric   _Pragma("GCC diagnostic push")                                               \
1645f757f3fSDimitry Andric   _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1655f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP                              \
1665f757f3fSDimitry Andric   _Pragma("GCC diagnostic pop")
1675f757f3fSDimitry Andric #elif defined(_MSC_VER)
1685f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH                             \
1695f757f3fSDimitry Andric   _Pragma("warning(push)")                                                     \
1705f757f3fSDimitry Andric   _Pragma("warning(disable : 4996)")
1715f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP                              \
1725f757f3fSDimitry Andric   _Pragma("warning(pop)")
1735f757f3fSDimitry Andric #else
1745f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH
1755f757f3fSDimitry Andric #define LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP
1765f757f3fSDimitry Andric #endif
1775f757f3fSDimitry Andric // clang-format on
1785f757f3fSDimitry Andric 
1790b57cec5SDimitry Andric // Indicate that a non-static, non-const C++ member function reinitializes
1800b57cec5SDimitry Andric // the entire object to a known state, independent of the previous state of
1810b57cec5SDimitry Andric // the object.
1820b57cec5SDimitry Andric //
1830b57cec5SDimitry Andric // The clang-tidy check bugprone-use-after-move recognizes this attribute as a
1840b57cec5SDimitry Andric // marker that a moved-from object has left the indeterminate state and can be
1850b57cec5SDimitry Andric // reused.
1868bcb0991SDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(clang::reinitializes)
1870b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
1880b57cec5SDimitry Andric #else
1890b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_REINITIALIZES
1900b57cec5SDimitry Andric #endif
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric // Some compilers warn about unused functions. When a function is sometimes
1930b57cec5SDimitry Andric // used or not depending on build settings (e.g. a function only called from
1940b57cec5SDimitry Andric // within "assert"), this attribute can be used to suppress such warnings.
1950b57cec5SDimitry Andric //
1960b57cec5SDimitry Andric // However, it shouldn't be used for unused *variables*, as those have a much
1970b57cec5SDimitry Andric // more portable solution:
1980b57cec5SDimitry Andric //   (void)unused_var_name;
1990b57cec5SDimitry Andric // Prefer cast-to-void wherever it is sufficient.
200349cc55cSDimitry Andric #if __has_attribute(unused)
2010b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
2020b57cec5SDimitry Andric #else
2030b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_UNUSED
2040b57cec5SDimitry Andric #endif
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric // FIXME: Provide this for PE/COFF targets.
207349cc55cSDimitry Andric #if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) &&  \
208349cc55cSDimitry Andric     !defined(_WIN32)
2090b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
2100b57cec5SDimitry Andric #else
2110b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_WEAK
2120b57cec5SDimitry Andric #endif
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric // Prior to clang 3.2, clang did not accept any spelling of
2150b57cec5SDimitry Andric // __has_attribute(const), so assume it is supported.
2160b57cec5SDimitry Andric #if defined(__clang__) || defined(__GNUC__)
2170b57cec5SDimitry Andric // aka 'CONST' but following LLVM Conventions.
2180b57cec5SDimitry Andric #define LLVM_READNONE __attribute__((__const__))
2190b57cec5SDimitry Andric #else
2200b57cec5SDimitry Andric #define LLVM_READNONE
2210b57cec5SDimitry Andric #endif
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric #if __has_attribute(pure) || defined(__GNUC__)
2240b57cec5SDimitry Andric // aka 'PURE' but following LLVM Conventions.
2250b57cec5SDimitry Andric #define LLVM_READONLY __attribute__((__pure__))
2260b57cec5SDimitry Andric #else
2270b57cec5SDimitry Andric #define LLVM_READONLY
2280b57cec5SDimitry Andric #endif
2290b57cec5SDimitry Andric 
230349cc55cSDimitry Andric #if __has_attribute(minsize)
231349cc55cSDimitry Andric #define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize))
232349cc55cSDimitry Andric #else
233349cc55cSDimitry Andric #define LLVM_ATTRIBUTE_MINSIZE
234349cc55cSDimitry Andric #endif
235349cc55cSDimitry Andric 
236349cc55cSDimitry Andric #if __has_builtin(__builtin_expect) || defined(__GNUC__)
2370b57cec5SDimitry Andric #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
2380b57cec5SDimitry Andric #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
2390b57cec5SDimitry Andric #else
2400b57cec5SDimitry Andric #define LLVM_LIKELY(EXPR) (EXPR)
2410b57cec5SDimitry Andric #define LLVM_UNLIKELY(EXPR) (EXPR)
2420b57cec5SDimitry Andric #endif
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
2450b57cec5SDimitry Andric /// mark a method "not for inlining".
246349cc55cSDimitry Andric #if __has_attribute(noinline)
2470b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
2480b57cec5SDimitry Andric #elif defined(_MSC_VER)
2490b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
2500b57cec5SDimitry Andric #else
2510b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_NOINLINE
2520b57cec5SDimitry Andric #endif
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
255349cc55cSDimitry Andric /// so, mark a method "always inline" because it is performance sensitive.
256349cc55cSDimitry Andric #if __has_attribute(always_inline)
257e8d8bef9SDimitry Andric #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
2580b57cec5SDimitry Andric #elif defined(_MSC_VER)
2590b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
2600b57cec5SDimitry Andric #else
261e8d8bef9SDimitry Andric #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
2620b57cec5SDimitry Andric #endif
2630b57cec5SDimitry Andric 
264349cc55cSDimitry Andric /// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do
265349cc55cSDimitry Andric /// so, mark a method "no debug" because debug info makes the debugger
266349cc55cSDimitry Andric /// experience worse.
267349cc55cSDimitry Andric #if __has_attribute(nodebug)
268349cc55cSDimitry Andric #define LLVM_ATTRIBUTE_NODEBUG __attribute__((nodebug))
2690b57cec5SDimitry Andric #else
270349cc55cSDimitry Andric #define LLVM_ATTRIBUTE_NODEBUG
2710b57cec5SDimitry Andric #endif
2720b57cec5SDimitry Andric 
273349cc55cSDimitry Andric #if __has_attribute(returns_nonnull)
2740b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
2750b57cec5SDimitry Andric #elif defined(_MSC_VER)
2760b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
2770b57cec5SDimitry Andric #else
2780b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NONNULL
2790b57cec5SDimitry Andric #endif
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric /// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
2820b57cec5SDimitry Andric /// pointer that does not alias any other valid pointer.
2830b57cec5SDimitry Andric #ifdef __GNUC__
2840b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
2850b57cec5SDimitry Andric #elif defined(_MSC_VER)
2860b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
2870b57cec5SDimitry Andric #else
2880b57cec5SDimitry Andric #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
2890b57cec5SDimitry Andric #endif
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
292e8d8bef9SDimitry Andric #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)
2930b57cec5SDimitry Andric #define LLVM_FALLTHROUGH [[fallthrough]]
2948bcb0991SDimitry Andric #elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
2950b57cec5SDimitry Andric #define LLVM_FALLTHROUGH [[gnu::fallthrough]]
2968bcb0991SDimitry Andric #elif __has_attribute(fallthrough)
2978bcb0991SDimitry Andric #define LLVM_FALLTHROUGH __attribute__((fallthrough))
2988bcb0991SDimitry Andric #elif LLVM_HAS_CPP_ATTRIBUTE(clang::fallthrough)
2990b57cec5SDimitry Andric #define LLVM_FALLTHROUGH [[clang::fallthrough]]
3000b57cec5SDimitry Andric #else
3010b57cec5SDimitry Andric #define LLVM_FALLTHROUGH
3020b57cec5SDimitry Andric #endif
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
3050b57cec5SDimitry Andric /// they are constant initialized.
3068bcb0991SDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization)
3070b57cec5SDimitry Andric #define LLVM_REQUIRE_CONSTANT_INITIALIZATION                                   \
3080b57cec5SDimitry Andric   [[clang::require_constant_initialization]]
3090b57cec5SDimitry Andric #else
3100b57cec5SDimitry Andric #define LLVM_REQUIRE_CONSTANT_INITIALIZATION
3110b57cec5SDimitry Andric #endif
3120b57cec5SDimitry Andric 
3135ffd83dbSDimitry Andric /// LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable
3145ffd83dbSDimitry Andric /// lifetime warnings.
3155ffd83dbSDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(gsl::Owner)
3165ffd83dbSDimitry Andric #define LLVM_GSL_OWNER [[gsl::Owner]]
3175ffd83dbSDimitry Andric #else
3185ffd83dbSDimitry Andric #define LLVM_GSL_OWNER
3195ffd83dbSDimitry Andric #endif
3205ffd83dbSDimitry Andric 
3215ffd83dbSDimitry Andric /// LLVM_GSL_POINTER - Apply this to non-owning classes like
3225ffd83dbSDimitry Andric /// StringRef to enable lifetime warnings.
3235ffd83dbSDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(gsl::Pointer)
3245ffd83dbSDimitry Andric #define LLVM_GSL_POINTER [[gsl::Pointer]]
3255ffd83dbSDimitry Andric #else
3265ffd83dbSDimitry Andric #define LLVM_GSL_POINTER
3275ffd83dbSDimitry Andric #endif
3285ffd83dbSDimitry Andric 
3295f757f3fSDimitry Andric #if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
3305f757f3fSDimitry Andric #define LLVM_CTOR_NODISCARD [[nodiscard]]
3315f757f3fSDimitry Andric #else
3325f757f3fSDimitry Andric #define LLVM_CTOR_NODISCARD
3335f757f3fSDimitry Andric #endif
3345f757f3fSDimitry Andric 
3350b57cec5SDimitry Andric /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
3360b57cec5SDimitry Andric /// pedantic diagnostics.
3370b57cec5SDimitry Andric #ifdef __GNUC__
3380b57cec5SDimitry Andric #define LLVM_EXTENSION __extension__
3390b57cec5SDimitry Andric #else
3400b57cec5SDimitry Andric #define LLVM_EXTENSION
3410b57cec5SDimitry Andric #endif
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
3440b57cec5SDimitry Andric /// to an expression which states that it is undefined behavior for the
3450b57cec5SDimitry Andric /// compiler to reach this point.  Otherwise is not defined.
34681ad6265SDimitry Andric ///
34781ad6265SDimitry Andric /// '#else' is intentionally left out so that other macro logic (e.g.,
34881ad6265SDimitry Andric /// LLVM_ASSUME_ALIGNED and llvm_unreachable()) can detect whether
34981ad6265SDimitry Andric /// LLVM_BUILTIN_UNREACHABLE has a definition.
350349cc55cSDimitry Andric #if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
3510b57cec5SDimitry Andric # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
3520b57cec5SDimitry Andric #elif defined(_MSC_VER)
3530b57cec5SDimitry Andric # define LLVM_BUILTIN_UNREACHABLE __assume(false)
3540b57cec5SDimitry Andric #endif
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
3570b57cec5SDimitry Andric /// which causes the program to exit abnormally.
358349cc55cSDimitry Andric #if __has_builtin(__builtin_trap) || defined(__GNUC__)
3590b57cec5SDimitry Andric # define LLVM_BUILTIN_TRAP __builtin_trap()
3600b57cec5SDimitry Andric #elif defined(_MSC_VER)
3610b57cec5SDimitry Andric // The __debugbreak intrinsic is supported by MSVC, does not require forward
3620b57cec5SDimitry Andric // declarations involving platform-specific typedefs (unlike RaiseException),
3630b57cec5SDimitry Andric // results in a call to vectored exception handlers, and encodes to a short
3640b57cec5SDimitry Andric // instruction that still causes the trapping behavior we want.
3650b57cec5SDimitry Andric # define LLVM_BUILTIN_TRAP __debugbreak()
3660b57cec5SDimitry Andric #else
3670b57cec5SDimitry Andric # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
3680b57cec5SDimitry Andric #endif
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric /// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
3710b57cec5SDimitry Andric /// an expression which causes the program to break while running
3720b57cec5SDimitry Andric /// under a debugger.
3730b57cec5SDimitry Andric #if __has_builtin(__builtin_debugtrap)
3740b57cec5SDimitry Andric # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap()
3750b57cec5SDimitry Andric #elif defined(_MSC_VER)
3760b57cec5SDimitry Andric // The __debugbreak intrinsic is supported by MSVC and breaks while
3770b57cec5SDimitry Andric // running under the debugger, and also supports invoking a debugger
3780b57cec5SDimitry Andric // when the OS is configured appropriately.
3790b57cec5SDimitry Andric # define LLVM_BUILTIN_DEBUGTRAP __debugbreak()
3800b57cec5SDimitry Andric #else
3810b57cec5SDimitry Andric // Just continue execution when built with compilers that have no
3820b57cec5SDimitry Andric // support. This is a debugging aid and not intended to force the
3830b57cec5SDimitry Andric // program to abort if encountered.
3840b57cec5SDimitry Andric # define LLVM_BUILTIN_DEBUGTRAP
3850b57cec5SDimitry Andric #endif
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric /// \macro LLVM_ASSUME_ALIGNED
3880b57cec5SDimitry Andric /// Returns a pointer with an assumed alignment.
389349cc55cSDimitry Andric #if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__)
3900b57cec5SDimitry Andric # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
3910b57cec5SDimitry Andric #elif defined(LLVM_BUILTIN_UNREACHABLE)
3920b57cec5SDimitry Andric # define LLVM_ASSUME_ALIGNED(p, a) \
3930b57cec5SDimitry Andric            (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
3940b57cec5SDimitry Andric #else
3950b57cec5SDimitry Andric # define LLVM_ASSUME_ALIGNED(p, a) (p)
3960b57cec5SDimitry Andric #endif
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric /// \macro LLVM_PACKED
3990b57cec5SDimitry Andric /// Used to specify a packed structure.
4000b57cec5SDimitry Andric /// LLVM_PACKED(
4010b57cec5SDimitry Andric ///    struct A {
4020b57cec5SDimitry Andric ///      int i;
4030b57cec5SDimitry Andric ///      int j;
4040b57cec5SDimitry Andric ///      int k;
4050b57cec5SDimitry Andric ///      long long l;
4060b57cec5SDimitry Andric ///   });
4070b57cec5SDimitry Andric ///
4080b57cec5SDimitry Andric /// LLVM_PACKED_START
4090b57cec5SDimitry Andric /// struct B {
4100b57cec5SDimitry Andric ///   int i;
4110b57cec5SDimitry Andric ///   int j;
4120b57cec5SDimitry Andric ///   int k;
4130b57cec5SDimitry Andric ///   long long l;
4140b57cec5SDimitry Andric /// };
4150b57cec5SDimitry Andric /// LLVM_PACKED_END
4160b57cec5SDimitry Andric #ifdef _MSC_VER
4170b57cec5SDimitry Andric # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
4180b57cec5SDimitry Andric # define LLVM_PACKED_START __pragma(pack(push, 1))
4190b57cec5SDimitry Andric # define LLVM_PACKED_END   __pragma(pack(pop))
4200b57cec5SDimitry Andric #else
4210b57cec5SDimitry Andric # define LLVM_PACKED(d) d __attribute__((packed))
4220b57cec5SDimitry Andric # define LLVM_PACKED_START _Pragma("pack(push, 1)")
4230b57cec5SDimitry Andric # define LLVM_PACKED_END   _Pragma("pack(pop)")
4240b57cec5SDimitry Andric #endif
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric /// \macro LLVM_MEMORY_SANITIZER_BUILD
4270b57cec5SDimitry Andric /// Whether LLVM itself is built with MemorySanitizer instrumentation.
4280b57cec5SDimitry Andric #if __has_feature(memory_sanitizer)
4290b57cec5SDimitry Andric # define LLVM_MEMORY_SANITIZER_BUILD 1
4300b57cec5SDimitry Andric # include <sanitizer/msan_interface.h>
431480093f4SDimitry Andric # define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE __attribute__((no_sanitize_memory))
4320b57cec5SDimitry Andric #else
4330b57cec5SDimitry Andric # define LLVM_MEMORY_SANITIZER_BUILD 0
4340b57cec5SDimitry Andric # define __msan_allocated_memory(p, size)
4350b57cec5SDimitry Andric # define __msan_unpoison(p, size)
436480093f4SDimitry Andric # define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE
4370b57cec5SDimitry Andric #endif
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric /// \macro LLVM_ADDRESS_SANITIZER_BUILD
4400b57cec5SDimitry Andric /// Whether LLVM itself is built with AddressSanitizer instrumentation.
4410b57cec5SDimitry Andric #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
4420b57cec5SDimitry Andric # define LLVM_ADDRESS_SANITIZER_BUILD 1
44381ad6265SDimitry Andric #if __has_include(<sanitizer/asan_interface.h>)
4440b57cec5SDimitry Andric # include <sanitizer/asan_interface.h>
4450b57cec5SDimitry Andric #else
44681ad6265SDimitry Andric // These declarations exist to support ASan with MSVC. If MSVC eventually ships
44781ad6265SDimitry Andric // asan_interface.h in their headers, then we can remove this.
44881ad6265SDimitry Andric #ifdef __cplusplus
44981ad6265SDimitry Andric extern "C" {
45081ad6265SDimitry Andric #endif
45181ad6265SDimitry Andric void __asan_poison_memory_region(void const volatile *addr, size_t size);
45281ad6265SDimitry Andric void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
45381ad6265SDimitry Andric #ifdef __cplusplus
45481ad6265SDimitry Andric } // extern "C"
45581ad6265SDimitry Andric #endif
45681ad6265SDimitry Andric #endif
45781ad6265SDimitry Andric #else
4580b57cec5SDimitry Andric # define LLVM_ADDRESS_SANITIZER_BUILD 0
4590b57cec5SDimitry Andric # define __asan_poison_memory_region(p, size)
4600b57cec5SDimitry Andric # define __asan_unpoison_memory_region(p, size)
4610b57cec5SDimitry Andric #endif
4620b57cec5SDimitry Andric 
463bdd1243dSDimitry Andric /// \macro LLVM_HWADDRESS_SANITIZER_BUILD
464bdd1243dSDimitry Andric /// Whether LLVM itself is built with HWAddressSanitizer instrumentation.
465bdd1243dSDimitry Andric #if __has_feature(hwaddress_sanitizer)
466bdd1243dSDimitry Andric #define LLVM_HWADDRESS_SANITIZER_BUILD 1
467bdd1243dSDimitry Andric #else
468bdd1243dSDimitry Andric #define LLVM_HWADDRESS_SANITIZER_BUILD 0
469bdd1243dSDimitry Andric #endif
470bdd1243dSDimitry Andric 
4710b57cec5SDimitry Andric /// \macro LLVM_THREAD_SANITIZER_BUILD
4720b57cec5SDimitry Andric /// Whether LLVM itself is built with ThreadSanitizer instrumentation.
4730b57cec5SDimitry Andric #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
4740b57cec5SDimitry Andric # define LLVM_THREAD_SANITIZER_BUILD 1
4750b57cec5SDimitry Andric #else
4760b57cec5SDimitry Andric # define LLVM_THREAD_SANITIZER_BUILD 0
4770b57cec5SDimitry Andric #endif
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric #if LLVM_THREAD_SANITIZER_BUILD
4800b57cec5SDimitry Andric // Thread Sanitizer is a tool that finds races in code.
4810b57cec5SDimitry Andric // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
4820b57cec5SDimitry Andric // tsan detects these exact functions by name.
4830b57cec5SDimitry Andric #ifdef __cplusplus
4840b57cec5SDimitry Andric extern "C" {
4850b57cec5SDimitry Andric #endif
4860b57cec5SDimitry Andric void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
4870b57cec5SDimitry Andric void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
4880b57cec5SDimitry Andric void AnnotateIgnoreWritesBegin(const char *file, int line);
4890b57cec5SDimitry Andric void AnnotateIgnoreWritesEnd(const char *file, int line);
4900b57cec5SDimitry Andric #ifdef __cplusplus
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric #endif
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric // This marker is used to define a happens-before arc. The race detector will
4950b57cec5SDimitry Andric // infer an arc from the begin to the end when they share the same pointer
4960b57cec5SDimitry Andric // argument.
4970b57cec5SDimitry Andric # define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric // This marker defines the destination of a happens-before arc.
5000b57cec5SDimitry Andric # define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
5030b57cec5SDimitry Andric # define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric // Resume checking for racy writes.
5060b57cec5SDimitry Andric # define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
5070b57cec5SDimitry Andric #else
5080b57cec5SDimitry Andric # define TsanHappensBefore(cv)
5090b57cec5SDimitry Andric # define TsanHappensAfter(cv)
5100b57cec5SDimitry Andric # define TsanIgnoreWritesBegin()
5110b57cec5SDimitry Andric # define TsanIgnoreWritesEnd()
5120b57cec5SDimitry Andric #endif
5130b57cec5SDimitry Andric 
5140b57cec5SDimitry Andric /// \macro LLVM_NO_SANITIZE
5150b57cec5SDimitry Andric /// Disable a particular sanitizer for a function.
5160b57cec5SDimitry Andric #if __has_attribute(no_sanitize)
5170b57cec5SDimitry Andric #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
5180b57cec5SDimitry Andric #else
5190b57cec5SDimitry Andric #define LLVM_NO_SANITIZE(KIND)
5200b57cec5SDimitry Andric #endif
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric /// Mark debug helper function definitions like dump() that should not be
5230b57cec5SDimitry Andric /// stripped from debug builds.
5240b57cec5SDimitry Andric /// Note that you should also surround dump() functions with
5250b57cec5SDimitry Andric /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
5260b57cec5SDimitry Andric /// get stripped in release builds.
5270b57cec5SDimitry Andric // FIXME: Move this to a private config.h as it's not usable in public headers.
5280b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5290b57cec5SDimitry Andric #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
5300b57cec5SDimitry Andric #else
5310b57cec5SDimitry Andric #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
5320b57cec5SDimitry Andric #endif
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric /// \macro LLVM_PRETTY_FUNCTION
5350b57cec5SDimitry Andric /// Gets a user-friendly looking function signature for the current scope
5360b57cec5SDimitry Andric /// using the best available method on each platform.  The exact format of the
5370b57cec5SDimitry Andric /// resulting string is implementation specific and non-portable, so this should
5380b57cec5SDimitry Andric /// only be used, for example, for logging or diagnostics.
5390b57cec5SDimitry Andric #if defined(_MSC_VER)
5400b57cec5SDimitry Andric #define LLVM_PRETTY_FUNCTION __FUNCSIG__
5410b57cec5SDimitry Andric #elif defined(__GNUC__) || defined(__clang__)
5420b57cec5SDimitry Andric #define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__
5430b57cec5SDimitry Andric #else
5440b57cec5SDimitry Andric #define LLVM_PRETTY_FUNCTION __func__
5450b57cec5SDimitry Andric #endif
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric /// \macro LLVM_THREAD_LOCAL
5480b57cec5SDimitry Andric /// A thread-local storage specifier which can be used with globals,
5490b57cec5SDimitry Andric /// extern globals, and static globals.
5500b57cec5SDimitry Andric ///
5510b57cec5SDimitry Andric /// This is essentially an extremely restricted analog to C++11's thread_local
552480093f4SDimitry Andric /// support. It uses thread_local if available, falling back on gcc __thread
553480093f4SDimitry Andric /// if not. __thread doesn't support many of the C++11 thread_local's
554480093f4SDimitry Andric /// features. You should only use this for PODs that you can statically
555480093f4SDimitry Andric /// initialize to some constant value. In almost all circumstances this is most
556480093f4SDimitry Andric /// appropriate for use with a pointer, integer, or small aggregation of
557480093f4SDimitry Andric /// pointers and integers.
5580b57cec5SDimitry Andric #if LLVM_ENABLE_THREADS
559480093f4SDimitry Andric #if __has_feature(cxx_thread_local) || defined(_MSC_VER)
5600b57cec5SDimitry Andric #define LLVM_THREAD_LOCAL thread_local
5610b57cec5SDimitry Andric #else
5620b57cec5SDimitry Andric // Clang, GCC, and other compatible compilers used __thread prior to C++11 and
5630b57cec5SDimitry Andric // we only need the restricted functionality that provides.
5640b57cec5SDimitry Andric #define LLVM_THREAD_LOCAL __thread
5650b57cec5SDimitry Andric #endif
5660b57cec5SDimitry Andric #else // !LLVM_ENABLE_THREADS
5670b57cec5SDimitry Andric // If threading is disabled entirely, this compiles to nothing and you get
5680b57cec5SDimitry Andric // a normal global variable.
5690b57cec5SDimitry Andric #define LLVM_THREAD_LOCAL
5700b57cec5SDimitry Andric #endif
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric /// \macro LLVM_ENABLE_EXCEPTIONS
5730b57cec5SDimitry Andric /// Whether LLVM is built with exception support.
5740b57cec5SDimitry Andric #if __has_feature(cxx_exceptions)
5750b57cec5SDimitry Andric #define LLVM_ENABLE_EXCEPTIONS 1
5760b57cec5SDimitry Andric #elif defined(__GNUC__) && defined(__EXCEPTIONS)
5770b57cec5SDimitry Andric #define LLVM_ENABLE_EXCEPTIONS 1
5780b57cec5SDimitry Andric #elif defined(_MSC_VER) && defined(_CPPUNWIND)
5790b57cec5SDimitry Andric #define LLVM_ENABLE_EXCEPTIONS 1
5800b57cec5SDimitry Andric #endif
5810b57cec5SDimitry Andric 
582349cc55cSDimitry Andric /// \macro LLVM_NO_PROFILE_INSTRUMENT_FUNCTION
583349cc55cSDimitry Andric /// Disable the profile instrument for a function.
584349cc55cSDimitry Andric #if __has_attribute(no_profile_instrument_function)
585349cc55cSDimitry Andric #define LLVM_NO_PROFILE_INSTRUMENT_FUNCTION                                    \
586349cc55cSDimitry Andric   __attribute__((no_profile_instrument_function))
587349cc55cSDimitry Andric #else
588349cc55cSDimitry Andric #define LLVM_NO_PROFILE_INSTRUMENT_FUNCTION
589349cc55cSDimitry Andric #endif
590349cc55cSDimitry Andric 
5915f757f3fSDimitry Andric /// \macro LLVM_PREFERRED_TYPE
5925f757f3fSDimitry Andric /// Adjust type of bit-field in debug info.
5935f757f3fSDimitry Andric #if __has_attribute(preferred_type)
5945f757f3fSDimitry Andric #define LLVM_PREFERRED_TYPE(T) __attribute__((preferred_type(T)))
5955f757f3fSDimitry Andric #else
5965f757f3fSDimitry Andric #define LLVM_PREFERRED_TYPE(T)
5975f757f3fSDimitry Andric #endif
5985f757f3fSDimitry Andric 
5990b57cec5SDimitry Andric #endif
600