| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 | // Copyright The OpenTelemetry Authors// SPDX-License-Identifier: Apache-2.0#pragma once/*   OPENTELEMETRY_HAVE_BUILTIN&OPENTELEMETRY_HAVE_FEATURE   Checks whether the compiler supports a Clang Feature Checking Macro, and if   so, checks whether it supports the provided builtin function "x" where x   is one of the functions noted in   https://clang.llvm.org/docs/LanguageExtensions.html   Note: Use this macro to avoid an extra level of #ifdef __has_builtin check.   http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html*/#if !defined(OPENTELEMETRY_HAVE_BUILTIN)#  ifdef __has_builtin#    define OPENTELEMETRY_HAVE_BUILTIN(x) __has_builtin(x)#  else#    define OPENTELEMETRY_HAVE_BUILTIN(x) 0#  endif#endif#if !defined(OPENTELEMETRY_HAVE_FEATURE)#  ifdef __has_feature#    define OPENTELEMETRY_HAVE_FEATURE(f) __has_feature(f)#  else#    define OPENTELEMETRY_HAVE_FEATURE(f) 0#  endif#endif/*   has feature   OPENTELEMETRY_HAVE_ATTRIBUTE   A function-like feature checking macro that is a wrapper around   `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a   nonzero constant integer if the attribute is supported or 0 if not.   It evaluates to zero if `__has_attribute` is not defined by the compiler.   GCC: https://gcc.gnu.org/gcc-5/changes.html   Clang: https://clang.llvm.org/docs/LanguageExtensions.html*/#if !defined(OPENTELEMETRY_HAVE_ATTRIBUTE)#  ifdef __has_attribute#    define OPENTELEMETRY_HAVE_ATTRIBUTE(x) __has_attribute(x)#  else#    define OPENTELEMETRY_HAVE_ATTRIBUTE(x) 0#  endif#endif/*   OPENTELEMETRY_HAVE_CPP_ATTRIBUTE   A function-like feature checking macro that accepts C++11 style attributes.   It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6   (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't   find `__has_cpp_attribute`, will evaluate to 0.*/#if !defined(OPENTELEMETRY_HAVE_CPP_ATTRIBUTE)#  if defined(__cplusplus) && defined(__has_cpp_attribute)// NOTE: requiring __cplusplus above should not be necessary, but// works around https://bugs.llvm.org/show_bug.cgi?id=23435.#    define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)#  else#    define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) 0#  endif#endif/*   Expected usage pattern:   if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr)   {     do_something_likely();   } else {     do_something_unlikely();   }   This pattern works with gcc/clang and __builtin_expect(),   as well as with C++20.   It is unclear if __builtin_expect() will be deprecated   in favor of C++20 [[likely]] or not.   OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY,   to be revisited when C++20 is required.*/#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus)// Only use likely with C++20#  if __cplusplus >= 202002L// GCC 9 has likely attribute but do not support declare it at the beginning of statement#    if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)#      if __has_cpp_attribute(likely)#        define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]]#      endif#    endif#  endif#endif#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))// Only use if supported by the compiler#  define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true))#endif#ifndef OPENTELEMETRY_LIKELY_CONDITION// Do not use likely annotations#  define OPENTELEMETRY_LIKELY_CONDITION(C) (C)#endif#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus)// Only use unlikely with C++20#  if __cplusplus >= 202002L// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement#    if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)#      if __has_cpp_attribute(unlikely)#        define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]]#      endif#    endif#  endif#endif#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))// Only use if supported by the compiler#  define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false))#endif#ifndef OPENTELEMETRY_UNLIKELY_CONDITION// Do not use unlikely annotations#  define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C)#endif/*   Expected usage pattern:   if (ptr != nullptr)   OPENTELEMETRY_LIKELY   {     do_something_likely();   } else {     do_something_unlikely();   }   This pattern works starting with C++20.   See https://en.cppreference.com/w/cpp/language/attributes/likely   Please use OPENTELEMETRY_LIKELY_CONDITION instead for now.*/#if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus)// Only use likely with C++20#  if __cplusplus >= 202002L// GCC 9 has likely attribute but do not support declare it at the beginning of statement#    if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)#      if __has_cpp_attribute(likely)#        define OPENTELEMETRY_LIKELY [[likely]]#      endif#    endif#  endif#endif#ifndef OPENTELEMETRY_LIKELY#  define OPENTELEMETRY_LIKELY#endif#if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus)// Only use unlikely with C++20#  if __cplusplus >= 202002L// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement#    if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)#      if __has_cpp_attribute(unlikely)#        define OPENTELEMETRY_UNLIKELY [[unlikely]]#      endif#    endif#  endif#endif#ifndef OPENTELEMETRY_UNLIKELY#  define OPENTELEMETRY_UNLIKELY#endif/// \brief Declare variable as maybe unused/// usage:///   OPENTELEMETRY_MAYBE_UNUSED int a;///   class OPENTELEMETRY_MAYBE_UNUSED a;///   OPENTELEMETRY_MAYBE_UNUSED int a();///#if defined(__cplusplus) && __cplusplus >= 201703L#  define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]]#elif defined(__clang__)#  define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused))#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))#  define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused))#elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)#  define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]]#else#  define OPENTELEMETRY_MAYBE_UNUSED#endif#ifndef OPENTELEMETRY_RTTI_ENABLED#  if defined(__clang__)#    if __has_feature(cxx_rtti)#      define OPENTELEMETRY_RTTI_ENABLED#    endif#  elif defined(__GNUG__)#    if defined(__GXX_RTTI)#      define OPENTELEMETRY_RTTI_ENABLED#    endif#  elif defined(_MSC_VER)#    if defined(_CPPRTTI)#      define OPENTELEMETRY_RTTI_ENABLED#    endif#  endif#endif#if defined(__cplusplus) && __cplusplus >= 201402L#  define OPENTELEMETRY_DEPRECATED [[deprecated]]#elif defined(__clang__)#  define OPENTELEMETRY_DEPRECATED __attribute__((deprecated))#elif defined(__GNUC__)#  define OPENTELEMETRY_DEPRECATED __attribute__((deprecated))#elif defined(_MSC_VER)#  if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L#    define OPENTELEMETRY_DEPRECATED [[deprecated]]#  else#    define OPENTELEMETRY_DEPRECATED __declspec(deprecated)#  endif#else#  define OPENTELEMETRY_DEPRECATED#endif#if defined(__cplusplus) && __cplusplus >= 201402L#  define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]#elif defined(__clang__)#  define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg)))#elif defined(__GNUC__)#  define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg)))#elif defined(_MSC_VER)#  if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L#    define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]]#  else#    define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg))#  endif#else#  define OPENTELEMETRY_DEPRECATED_MESSAGE(msg)#endif// Regex support#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9))#  define OPENTELEMETRY_HAVE_WORKING_REGEX 0#else#  define OPENTELEMETRY_HAVE_WORKING_REGEX 1#endif/* clang-format off *//**  @page HEADER_ONLY_SINGLETON Header only singleton.  @section ELF_SINGLETON  For clang and gcc, the desired coding pattern is as follows.  @verbatim  class Foo  {    // (a)    __attribute__((visibility("default")))    // (b)    T& get_singleton()    {      // (c)      static T singleton;      return singleton;    }  };  @endverbatim  (a) is needed when the code is build with  @code -fvisibility="hidden" @endcode  to ensure that all instances of (b) are visible to the linker.  What is duplicated in the binary is @em code, in (b).  The linker will make sure only one instance  of all the (b) methods is used.  (c) is a singleton implemented inside a method.  This is very desirable, because:  - the C++ compiler guarantees that construction    of the variable (c) is thread safe.  - constructors for (c) singletons are executed in code path order,    or not at all if the singleton is never used.  @section OTHER_SINGLETON  For other platforms, header only singletons are not supported at thispoint.  @section CODING_PATTERN  The coding pattern to use in the source code is as follows  @verbatim  class Foo  {    OPENTELEMETRY_API_SINGLETON    T& get_singleton()    {      static T singleton;      return singleton;    }  };  @endverbatim*//* clang-format on */#if defined(__clang__)#  define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default")))#  define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden")))#elif defined(__GNUC__)#  define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default")))#  define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden")))#else/* Add support for other compilers here. */#  define OPENTELEMETRY_API_SINGLETON#  define OPENTELEMETRY_LOCAL_SYMBOL#endif//// Atomic wrappers based on compiler intrinsics for memory read/write.// The tailing number is read/write length in bits.//// N.B. Compiler intrinsic is used because the usage of C++ standard library is restricted in the// OpenTelemetry C++ API.//#if defined(__GNUC__)#  define OPENTELEMETRY_ATOMIC_READ_8(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST)#  define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST)#elif defined(_MSC_VER)#  include <intrin.h>#  define OPENTELEMETRY_ATOMIC_READ_8(ptr) \    static_cast<uint8_t>(_InterlockedCompareExchange8(reinterpret_cast<char *>(ptr), 0, 0))#  define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) \    _InterlockedExchange8(reinterpret_cast<char *>(ptr), static_cast<char>(value))#else#  error port atomics read/write for the current platform#endif/* clang-format on *///// The if/elif order matters here. If both OPENTELEMETRY_BUILD_IMPORT_DLL and// OPENTELEMETRY_BUILD_EXPORT_DLL are defined, the former takes precedence.//// TODO: consider define OPENTELEMETRY_EXPORT for cygwin/gcc, see below link.// https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support//#if defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_IMPORT_DLL)#  define OPENTELEMETRY_EXPORT __declspec(dllimport)#elif defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_EXPORT_DLL)#  define OPENTELEMETRY_EXPORT __declspec(dllexport)#else//// build OpenTelemetry as static library or not on Windows.//#  define OPENTELEMETRY_EXPORT#endif// OPENTELEMETRY_HAVE_EXCEPTIONS//// Checks whether the compiler both supports and enables exceptions. Many// compilers support a "no exceptions" mode that disables exceptions.//// Generally, when OPENTELEMETRY_HAVE_EXCEPTIONS is not defined://// * Code using `throw` and `try` may not compile.// * The `noexcept` specifier will still compile and behave as normal.// * The `noexcept` operator may still return `false`.//// For further details, consult the compiler's documentation.#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS#  if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__) < 306// Clang < 3.6// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro#    if defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)#      define OPENTELEMETRY_HAVE_EXCEPTIONS 1#    endif  // defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)#  elif OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)#    define OPENTELEMETRY_HAVE_EXCEPTIONS 1// Handle remaining special cases and default to exceptions being supported.#  elif !(defined(__GNUC__) && !defined(__EXCEPTIONS) && !defined(__cpp_exceptions)) && \      !(defined(_MSC_VER) && !defined(_CPPUNWIND))#    define OPENTELEMETRY_HAVE_EXCEPTIONS 1#  endif#endif#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS#  define OPENTELEMETRY_HAVE_EXCEPTIONS 0#endif/*   OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function   parameter or implicit object parameter is retained by the return value of the   annotated function (or, for a parameter of a constructor, in the value of the   constructed object). This attribute causes warnings to be produced if a   temporary object does not live long enough.   When applied to a reference parameter, the referenced object is assumed to be   retained by the return value of the function. When applied to a non-reference   parameter (for example, a pointer or a class type), all temporaries   referenced by the parameter are assumed to be retained by the return value of   the function.   See also the upstream documentation:   https://clang.llvm.org/docs/AttributeReference.html#lifetimebound*/#ifndef OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND#  if OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)#    define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]#  elif OPENTELEMETRY_HAVE_ATTRIBUTE(lifetimebound)#    define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))#  else#    define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND#  endif#endif// OPENTELEMETRY_HAVE_MEMORY_SANITIZER//// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of// a compiler instrumentation module and a run-time library.#ifndef OPENTELEMETRY_HAVE_MEMORY_SANITIZER#  if !defined(__native_client__) && OPENTELEMETRY_HAVE_FEATURE(memory_sanitizer)#    define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 1#  else#    define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 0#  endif#endif#if OPENTELEMETRY_HAVE_MEMORY_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_memory)#  define OPENTELEMETRY_SANITIZER_NO_MEMORY \    __attribute__((no_sanitize_memory))  // __attribute__((no_sanitize("memory")))#else#  define OPENTELEMETRY_SANITIZER_NO_MEMORY#endif// OPENTELEMETRY_HAVE_THREAD_SANITIZER//// ThreadSanitizer (TSan) is a fast data race detector.#ifndef OPENTELEMETRY_HAVE_THREAD_SANITIZER#  if defined(__SANITIZE_THREAD__)#    define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1#  elif OPENTELEMETRY_HAVE_FEATURE(thread_sanitizer)#    define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1#  else#    define OPENTELEMETRY_HAVE_THREAD_SANITIZER 0#  endif#endif#if OPENTELEMETRY_HAVE_THREAD_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_thread)#  define OPENTELEMETRY_SANITIZER_NO_THREAD \    __attribute__((no_sanitize_thread))  // __attribute__((no_sanitize("thread")))#else#  define OPENTELEMETRY_SANITIZER_NO_THREAD#endif// OPENTELEMETRY_HAVE_ADDRESS_SANITIZER//// AddressSanitizer (ASan) is a fast memory error detector.#ifndef OPENTELEMETRY_HAVE_ADDRESS_SANITIZER#  if defined(__SANITIZE_ADDRESS__)#    define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1#  elif OPENTELEMETRY_HAVE_FEATURE(address_sanitizer)#    define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1#  else#    define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 0#  endif#endif// OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER//// Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan// memory error detector which can use CPU features like ARM TBI, Intel LAM or// AMD UAI.#ifndef OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER#  if defined(__SANITIZE_HWADDRESS__)#    define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1#  elif OPENTELEMETRY_HAVE_FEATURE(hwaddress_sanitizer)#    define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1#  else#    define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 0#  endif#endif#if OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_address)#  define OPENTELEMETRY_SANITIZER_NO_ADDRESS \    __attribute__((no_sanitize_address))  // __attribute__((no_sanitize("address")))#elif OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && defined(_MSC_VER) && _MSC_VER >= 1928#  define OPENTELEMETRY_SANITIZER_NO_ADDRESS __declspec(no_sanitize_address)#elif OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize)#  define OPENTELEMETRY_SANITIZER_NO_ADDRESS __attribute__((no_sanitize("hwaddress")))#else#  define OPENTELEMETRY_SANITIZER_NO_ADDRESS#endif
 |