- //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file defines several macros, based on the current compiler.  This allows 
- // use of compiler-specific features in a way that remains portable. This header 
- // can be included from either C or C++. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_SUPPORT_COMPILER_H 
- #define LLVM_SUPPORT_COMPILER_H 
-   
- #include "llvm/Config/llvm-config.h" 
-   
- #include <stddef.h> 
-   
- #if defined(_MSC_VER) 
- #include <sal.h> 
- #endif 
-   
- #ifndef __has_feature 
- # define __has_feature(x) 0 
- #endif 
-   
- #ifndef __has_extension 
- # define __has_extension(x) 0 
- #endif 
-   
- #ifndef __has_attribute 
- # define __has_attribute(x) 0 
- #endif 
-   
- #ifndef __has_builtin 
- # define __has_builtin(x) 0 
- #endif 
-   
- #ifndef __has_include 
- # define __has_include(x) 0 
- #endif 
-   
- // Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in 
- // C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid. 
- #ifndef LLVM_HAS_CPP_ATTRIBUTE 
- #if defined(__cplusplus) && defined(__has_cpp_attribute) 
- # define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 
- #else 
- # define LLVM_HAS_CPP_ATTRIBUTE(x) 0 
- #endif 
- #endif 
-   
- /// \macro LLVM_GNUC_PREREQ 
- /// Extend the default __GNUC_PREREQ even if glibc's features.h isn't 
- /// available. 
- #ifndef LLVM_GNUC_PREREQ 
- # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 
- #  define LLVM_GNUC_PREREQ(maj, min, patch) \ 
-     ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ 
-      ((maj) << 20) + ((min) << 10) + (patch)) 
- # elif defined(__GNUC__) && defined(__GNUC_MINOR__) 
- #  define LLVM_GNUC_PREREQ(maj, min, patch) \ 
-     ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) 
- # else 
- #  define LLVM_GNUC_PREREQ(maj, min, patch) 0 
- # endif 
- #endif 
-   
- /// \macro LLVM_MSC_PREREQ 
- /// Is the compiler MSVC of at least the specified version? 
- /// The common \param version values to check for are: 
- /// * 1910: VS2017, version 15.1 & 15.2 
- /// * 1911: VS2017, version 15.3 & 15.4 
- /// * 1912: VS2017, version 15.5 
- /// * 1913: VS2017, version 15.6 
- /// * 1914: VS2017, version 15.7 
- /// * 1915: VS2017, version 15.8 
- /// * 1916: VS2017, version 15.9 
- /// * 1920: VS2019, version 16.0 
- /// * 1921: VS2019, version 16.1 
- /// * 1922: VS2019, version 16.2 
- /// * 1923: VS2019, version 16.3 
- /// * 1924: VS2019, version 16.4 
- /// * 1925: VS2019, version 16.5 
- /// * 1926: VS2019, version 16.6 
- /// * 1927: VS2019, version 16.7 
- /// * 1928: VS2019, version 16.8 + 16.9 
- /// * 1929: VS2019, version 16.10 + 16.11 
- /// * 1930: VS2022, version 17.0 
- #ifdef _MSC_VER 
- #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version)) 
-   
- // We require at least VS 2019. 
- #if !defined(LLVM_FORCE_USE_OLD_TOOLCHAIN) 
- #if !LLVM_MSC_PREREQ(1920) 
- #error LLVM requires at least VS 2019. 
- #endif 
- #endif 
-   
- #else 
- #define LLVM_MSC_PREREQ(version) 0 
- #endif 
-   
- /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked 
- /// into a shared library, then the class should be private to the library and 
- /// not accessible from outside it.  Can also be used to mark variables and 
- /// functions, making them private to any shared library they are linked into. 
- /// On PE/COFF targets, library visibility is the default, so this isn't needed. 
- /// 
- /// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with 
- /// this attribute will be made public and visible outside of any shared library 
- /// they are linked in to. 
- #if __has_attribute(visibility) &&                                             \ 
-     (!(defined(_WIN32) || defined(__CYGWIN__)) ||                              \ 
-      (defined(__MINGW32__) && defined(__clang__))) 
- #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) 
- #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) 
- #define LLVM_EXTERNAL_VISIBILITY __attribute__((visibility("default"))) 
- #else 
- #define LLVM_EXTERNAL_VISIBILITY 
- #endif 
- #else 
- #define LLVM_LIBRARY_VISIBILITY 
- #define LLVM_EXTERNAL_VISIBILITY 
- #endif 
-   
- #if defined(__GNUC__) 
- #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality) 
- #else 
- #define LLVM_PREFETCH(addr, rw, locality) 
- #endif 
-   
- #if __has_attribute(used) 
- #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) 
- #else 
- #define LLVM_ATTRIBUTE_USED 
- #endif 
-   
- #if defined(__clang__) 
- #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) 
- #else 
- #define LLVM_DEPRECATED(MSG, FIX) [[deprecated(MSG)]] 
- #endif 
-   
- // Indicate that a non-static, non-const C++ member function reinitializes 
- // the entire object to a known state, independent of the previous state of 
- // the object. 
- // 
- // The clang-tidy check bugprone-use-after-move recognizes this attribute as a 
- // marker that a moved-from object has left the indeterminate state and can be 
- // reused. 
- #if LLVM_HAS_CPP_ATTRIBUTE(clang::reinitializes) 
- #define LLVM_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] 
- #else 
- #define LLVM_ATTRIBUTE_REINITIALIZES 
- #endif 
-   
- // Some compilers warn about unused functions. When a function is sometimes 
- // used or not depending on build settings (e.g. a function only called from 
- // within "assert"), this attribute can be used to suppress such warnings. 
- // 
- // However, it shouldn't be used for unused *variables*, as those have a much 
- // more portable solution: 
- //   (void)unused_var_name; 
- // Prefer cast-to-void wherever it is sufficient. 
- #if __has_attribute(unused) 
- #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) 
- #else 
- #define LLVM_ATTRIBUTE_UNUSED 
- #endif 
-   
- // FIXME: Provide this for PE/COFF targets. 
- #if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) &&  \ 
-     !defined(_WIN32) 
- #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) 
- #else 
- #define LLVM_ATTRIBUTE_WEAK 
- #endif 
-   
- // Prior to clang 3.2, clang did not accept any spelling of 
- // __has_attribute(const), so assume it is supported. 
- #if defined(__clang__) || defined(__GNUC__) 
- // aka 'CONST' but following LLVM Conventions. 
- #define LLVM_READNONE __attribute__((__const__)) 
- #else 
- #define LLVM_READNONE 
- #endif 
-   
- #if __has_attribute(pure) || defined(__GNUC__) 
- // aka 'PURE' but following LLVM Conventions. 
- #define LLVM_READONLY __attribute__((__pure__)) 
- #else 
- #define LLVM_READONLY 
- #endif 
-   
- #if __has_attribute(minsize) 
- #define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize)) 
- #else 
- #define LLVM_ATTRIBUTE_MINSIZE 
- #endif 
-   
- #if __has_builtin(__builtin_expect) || defined(__GNUC__) 
- #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) 
- #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) 
- #else 
- #define LLVM_LIKELY(EXPR) (EXPR) 
- #define LLVM_UNLIKELY(EXPR) (EXPR) 
- #endif 
-   
- /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, 
- /// mark a method "not for inlining". 
- #if __has_attribute(noinline) 
- #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) 
- #elif defined(_MSC_VER) 
- #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) 
- #else 
- #define LLVM_ATTRIBUTE_NOINLINE 
- #endif 
-   
- /// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do 
- /// so, mark a method "always inline" because it is performance sensitive. 
- #if __has_attribute(always_inline) 
- #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) 
- #elif defined(_MSC_VER) 
- #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline 
- #else 
- #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline 
- #endif 
-   
- /// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do 
- /// so, mark a method "no debug" because debug info makes the debugger 
- /// experience worse. 
- #if __has_attribute(nodebug) 
- #define LLVM_ATTRIBUTE_NODEBUG __attribute__((nodebug)) 
- #else 
- #define LLVM_ATTRIBUTE_NODEBUG 
- #endif 
-   
- #if __has_attribute(returns_nonnull) 
- #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) 
- #elif defined(_MSC_VER) 
- #define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_ 
- #else 
- #define LLVM_ATTRIBUTE_RETURNS_NONNULL 
- #endif 
-   
- /// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a 
- /// pointer that does not alias any other valid pointer. 
- #ifdef __GNUC__ 
- #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) 
- #elif defined(_MSC_VER) 
- #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict) 
- #else 
- #define LLVM_ATTRIBUTE_RETURNS_NOALIAS 
- #endif 
-   
- /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements. 
- #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough) 
- #define LLVM_FALLTHROUGH [[fallthrough]] 
- #elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough) 
- #define LLVM_FALLTHROUGH [[gnu::fallthrough]] 
- #elif __has_attribute(fallthrough) 
- #define LLVM_FALLTHROUGH __attribute__((fallthrough)) 
- #elif LLVM_HAS_CPP_ATTRIBUTE(clang::fallthrough) 
- #define LLVM_FALLTHROUGH [[clang::fallthrough]] 
- #else 
- #define LLVM_FALLTHROUGH 
- #endif 
-   
- /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that 
- /// they are constant initialized. 
- #if LLVM_HAS_CPP_ATTRIBUTE(clang::require_constant_initialization) 
- #define LLVM_REQUIRE_CONSTANT_INITIALIZATION                                   \ 
-   [[clang::require_constant_initialization]] 
- #else 
- #define LLVM_REQUIRE_CONSTANT_INITIALIZATION 
- #endif 
-   
- /// LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable 
- /// lifetime warnings. 
- #if LLVM_HAS_CPP_ATTRIBUTE(gsl::Owner) 
- #define LLVM_GSL_OWNER [[gsl::Owner]] 
- #else 
- #define LLVM_GSL_OWNER 
- #endif 
-   
- /// LLVM_GSL_POINTER - Apply this to non-owning classes like 
- /// StringRef to enable lifetime warnings. 
- #if LLVM_HAS_CPP_ATTRIBUTE(gsl::Pointer) 
- #define LLVM_GSL_POINTER [[gsl::Pointer]] 
- #else 
- #define LLVM_GSL_POINTER 
- #endif 
-   
- /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress 
- /// pedantic diagnostics. 
- #ifdef __GNUC__ 
- #define LLVM_EXTENSION __extension__ 
- #else 
- #define LLVM_EXTENSION 
- #endif 
-   
- /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands 
- /// to an expression which states that it is undefined behavior for the 
- /// compiler to reach this point.  Otherwise is not defined. 
- /// 
- /// '#else' is intentionally left out so that other macro logic (e.g., 
- /// LLVM_ASSUME_ALIGNED and llvm_unreachable()) can detect whether 
- /// LLVM_BUILTIN_UNREACHABLE has a definition. 
- #if __has_builtin(__builtin_unreachable) || defined(__GNUC__) 
- # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() 
- #elif defined(_MSC_VER) 
- # define LLVM_BUILTIN_UNREACHABLE __assume(false) 
- #endif 
-   
- /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression 
- /// which causes the program to exit abnormally. 
- #if __has_builtin(__builtin_trap) || defined(__GNUC__) 
- # define LLVM_BUILTIN_TRAP __builtin_trap() 
- #elif defined(_MSC_VER) 
- // The __debugbreak intrinsic is supported by MSVC, does not require forward 
- // declarations involving platform-specific typedefs (unlike RaiseException), 
- // results in a call to vectored exception handlers, and encodes to a short 
- // instruction that still causes the trapping behavior we want. 
- # define LLVM_BUILTIN_TRAP __debugbreak() 
- #else 
- # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 
- #endif 
-   
- /// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to 
- /// an expression which causes the program to break while running 
- /// under a debugger. 
- #if __has_builtin(__builtin_debugtrap) 
- # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap() 
- #elif defined(_MSC_VER) 
- // The __debugbreak intrinsic is supported by MSVC and breaks while 
- // running under the debugger, and also supports invoking a debugger 
- // when the OS is configured appropriately. 
- # define LLVM_BUILTIN_DEBUGTRAP __debugbreak() 
- #else 
- // Just continue execution when built with compilers that have no 
- // support. This is a debugging aid and not intended to force the 
- // program to abort if encountered. 
- # define LLVM_BUILTIN_DEBUGTRAP 
- #endif 
-   
- /// \macro LLVM_ASSUME_ALIGNED 
- /// Returns a pointer with an assumed alignment. 
- #if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__) 
- # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) 
- #elif defined(LLVM_BUILTIN_UNREACHABLE) 
- # define LLVM_ASSUME_ALIGNED(p, a) \ 
-            (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p))) 
- #else 
- # define LLVM_ASSUME_ALIGNED(p, a) (p) 
- #endif 
-   
- /// \macro LLVM_PACKED 
- /// Used to specify a packed structure. 
- /// LLVM_PACKED( 
- ///    struct A { 
- ///      int i; 
- ///      int j; 
- ///      int k; 
- ///      long long l; 
- ///   }); 
- /// 
- /// LLVM_PACKED_START 
- /// struct B { 
- ///   int i; 
- ///   int j; 
- ///   int k; 
- ///   long long l; 
- /// }; 
- /// LLVM_PACKED_END 
- #ifdef _MSC_VER 
- # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop)) 
- # define LLVM_PACKED_START __pragma(pack(push, 1)) 
- # define LLVM_PACKED_END   __pragma(pack(pop)) 
- #else 
- # define LLVM_PACKED(d) d __attribute__((packed)) 
- # define LLVM_PACKED_START _Pragma("pack(push, 1)") 
- # define LLVM_PACKED_END   _Pragma("pack(pop)") 
- #endif 
-   
- /// \macro LLVM_MEMORY_SANITIZER_BUILD 
- /// Whether LLVM itself is built with MemorySanitizer instrumentation. 
- #if __has_feature(memory_sanitizer) 
- # define LLVM_MEMORY_SANITIZER_BUILD 1 
- # include <sanitizer/msan_interface.h> 
- # define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE __attribute__((no_sanitize_memory)) 
- #else 
- # define LLVM_MEMORY_SANITIZER_BUILD 0 
- # define __msan_allocated_memory(p, size) 
- # define __msan_unpoison(p, size) 
- # define LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE 
- #endif 
-   
- /// \macro LLVM_ADDRESS_SANITIZER_BUILD 
- /// Whether LLVM itself is built with AddressSanitizer instrumentation. 
- #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) 
- # define LLVM_ADDRESS_SANITIZER_BUILD 1 
- #if __has_include(<sanitizer/asan_interface.h>) 
- # include <sanitizer/asan_interface.h> 
- #else 
- // These declarations exist to support ASan with MSVC. If MSVC eventually ships 
- // asan_interface.h in their headers, then we can remove this. 
- #ifdef __cplusplus 
- extern "C" { 
- #endif 
- void __asan_poison_memory_region(void const volatile *addr, size_t size); 
- void __asan_unpoison_memory_region(void const volatile *addr, size_t size); 
- #ifdef __cplusplus 
- } // extern "C" 
- #endif 
- #endif 
- #else 
- # define LLVM_ADDRESS_SANITIZER_BUILD 0 
- # define __asan_poison_memory_region(p, size) 
- # define __asan_unpoison_memory_region(p, size) 
- #endif 
-   
- /// \macro LLVM_HWADDRESS_SANITIZER_BUILD 
- /// Whether LLVM itself is built with HWAddressSanitizer instrumentation. 
- #if __has_feature(hwaddress_sanitizer) 
- #define LLVM_HWADDRESS_SANITIZER_BUILD 1 
- #else 
- #define LLVM_HWADDRESS_SANITIZER_BUILD 0 
- #endif 
-   
- /// \macro LLVM_THREAD_SANITIZER_BUILD 
- /// Whether LLVM itself is built with ThreadSanitizer instrumentation. 
- #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) 
- # define LLVM_THREAD_SANITIZER_BUILD 1 
- #else 
- # define LLVM_THREAD_SANITIZER_BUILD 0 
- #endif 
-   
- #if LLVM_THREAD_SANITIZER_BUILD 
- // Thread Sanitizer is a tool that finds races in code. 
- // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations . 
- // tsan detects these exact functions by name. 
- #ifdef __cplusplus 
- extern "C" { 
- #endif 
- void AnnotateHappensAfter(const char *file, int line, const volatile void *cv); 
- void AnnotateHappensBefore(const char *file, int line, const volatile void *cv); 
- void AnnotateIgnoreWritesBegin(const char *file, int line); 
- void AnnotateIgnoreWritesEnd(const char *file, int line); 
- #ifdef __cplusplus 
- } 
- #endif 
-   
- // This marker is used to define a happens-before arc. The race detector will 
- // infer an arc from the begin to the end when they share the same pointer 
- // argument. 
- # define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv) 
-   
- // This marker defines the destination of a happens-before arc. 
- # define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv) 
-   
- // Ignore any races on writes between here and the next TsanIgnoreWritesEnd. 
- # define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__) 
-   
- // Resume checking for racy writes. 
- # define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__) 
- #else 
- # define TsanHappensBefore(cv) 
- # define TsanHappensAfter(cv) 
- # define TsanIgnoreWritesBegin() 
- # define TsanIgnoreWritesEnd() 
- #endif 
-   
- /// \macro LLVM_NO_SANITIZE 
- /// Disable a particular sanitizer for a function. 
- #if __has_attribute(no_sanitize) 
- #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND))) 
- #else 
- #define LLVM_NO_SANITIZE(KIND) 
- #endif 
-   
- /// Mark debug helper function definitions like dump() that should not be 
- /// stripped from debug builds. 
- /// Note that you should also surround dump() functions with 
- /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always 
- /// get stripped in release builds. 
- // FIXME: Move this to a private config.h as it's not usable in public headers. 
- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
- #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED 
- #else 
- #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE 
- #endif 
-   
- /// \macro LLVM_PRETTY_FUNCTION 
- /// Gets a user-friendly looking function signature for the current scope 
- /// using the best available method on each platform.  The exact format of the 
- /// resulting string is implementation specific and non-portable, so this should 
- /// only be used, for example, for logging or diagnostics. 
- #if defined(_MSC_VER) 
- #define LLVM_PRETTY_FUNCTION __FUNCSIG__ 
- #elif defined(__GNUC__) || defined(__clang__) 
- #define LLVM_PRETTY_FUNCTION __PRETTY_FUNCTION__ 
- #else 
- #define LLVM_PRETTY_FUNCTION __func__ 
- #endif 
-   
- /// \macro LLVM_THREAD_LOCAL 
- /// A thread-local storage specifier which can be used with globals, 
- /// extern globals, and static globals. 
- /// 
- /// This is essentially an extremely restricted analog to C++11's thread_local 
- /// support. It uses thread_local if available, falling back on gcc __thread 
- /// if not. __thread doesn't support many of the C++11 thread_local's 
- /// features. You should only use this for PODs that you can statically 
- /// initialize to some constant value. In almost all circumstances this is most 
- /// appropriate for use with a pointer, integer, or small aggregation of 
- /// pointers and integers. 
- #if LLVM_ENABLE_THREADS 
- #if __has_feature(cxx_thread_local) || defined(_MSC_VER) 
- #define LLVM_THREAD_LOCAL thread_local 
- #else 
- // Clang, GCC, and other compatible compilers used __thread prior to C++11 and 
- // we only need the restricted functionality that provides. 
- #define LLVM_THREAD_LOCAL __thread 
- #endif 
- #else // !LLVM_ENABLE_THREADS 
- // If threading is disabled entirely, this compiles to nothing and you get 
- // a normal global variable. 
- #define LLVM_THREAD_LOCAL 
- #endif 
-   
- /// \macro LLVM_ENABLE_EXCEPTIONS 
- /// Whether LLVM is built with exception support. 
- #if __has_feature(cxx_exceptions) 
- #define LLVM_ENABLE_EXCEPTIONS 1 
- #elif defined(__GNUC__) && defined(__EXCEPTIONS) 
- #define LLVM_ENABLE_EXCEPTIONS 1 
- #elif defined(_MSC_VER) && defined(_CPPUNWIND) 
- #define LLVM_ENABLE_EXCEPTIONS 1 
- #endif 
-   
- /// \macro LLVM_NO_PROFILE_INSTRUMENT_FUNCTION 
- /// Disable the profile instrument for a function. 
- #if __has_attribute(no_profile_instrument_function) 
- #define LLVM_NO_PROFILE_INSTRUMENT_FUNCTION                                    \ 
-   __attribute__((no_profile_instrument_function)) 
- #else 
- #define LLVM_NO_PROFILE_INSTRUMENT_FUNCTION 
- #endif 
-   
- #endif 
-