text: // Copyright 2016 The Fuchsia Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  // This file provides macros for unifying differences in C/C++ compiler
  // extensions, and providing backwards-compatibility for older C++ standards.
  //
  // May be included by C, C++, and assembly files.
  
  #ifndef SYSROOT_ZIRCON_COMPILER_H_
  #define SYSROOT_ZIRCON_COMPILER_H_
  
  // Ensure we are using a known compiler.
  #if !defined(__GNUC__) && !defined(__clang__)
  #error "Unrecognized compiler!"
  #endif
  
  // Feature checking macros.
  //
  // If feature checking macros are not provided by the compiler, we assume that the
  // checked features are unavailable.
  
  // C++11 attribute checking.
  #ifndef __has_cpp_attribute
  #define __has_cpp_attribute(x) 0
  #endif
  
  // clang feature checking.
  #ifndef __has_feature
  #define __has_feature(x) 0
  #endif
  
  #if !defined(__ASSEMBLER__)
  
  // C++ header guards.
  #ifdef __cplusplus
  #define __BEGIN_CDECLS extern "C" {
  #define __END_CDECLS }
  #else
  #define __BEGIN_CDECLS
  #define __END_CDECLS
  #endif
  
  //
  // Function and data attributes.
  //
  
  // Function inlining directives.
  #define __NO_INLINE __attribute__((__noinline__))
  #define __ALWAYS_INLINE __attribute__((__always_inline__))
  
  // Avoid issuing a warning if the given variable/function is unused.
  #define __UNUSED __attribute__((__unused__))
  
  // Pack the given structure or class, omitting padding between fields.
  #define __PACKED __attribute__((packed))
  
  // Place the variable in thread-local storage.
  #define __THREAD __thread
  
  // Align the variable or type to at least `x` bytes. `x` must be a power of two.
  #define __ALIGNED(x) __attribute__((aligned(x)))
  
  // Declare the given function will never return. (such as `exit`, `abort`, etc).
  #define __NO_RETURN __attribute__((__noreturn__))
  
  // Warn if the result of this function is ignored by the caller.
  #define __WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
  
  // Declare that the given stack variable may be left uninitialized if it does
  // not have a specified initial value.
  #if defined(__clang__)
  #define __UNINITIALIZED __attribute__((uninitialized))
  #else
  #define __UNINITIALIZED
  #endif
  
  // Warn if a constructed objected is not used by the caller.
  //
  // Generates a warning on code like this:
  //
  //   {
  //     AutoLock(&mutex);  // error: the AutoLock goes out of scope immediately.
  //     locked_variable = 42;
  //   }
  //
  // C++17 defines [[nodiscard]] to do this, but some older but supported
  // versions of GCC support [[nodiscard]] on functions but not constructors.
  // Having a separate __WARN_UNUSED_CONSTRUCTOR allows us to hide the attribute
  // only on constructors on old versions of GCC.
  #if defined(__cplusplus)
  #if __cplusplus >= 201703L && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 10)))
  #define __WARN_UNUSED_CONSTRUCTOR [[nodiscard]]
  #else
  #define __WARN_UNUSED_CONSTRUCTOR
  #endif
  #endif
  
  // Mark a function or variable as deprecated, warning about any callers.
  #if !defined(__DEPRECATE)
  #define __DEPRECATE __attribute__((__deprecated__))
  #endif
  
  // Mark a function as having no visible side-effects: It may read memory, but
  // will not modify it.
  //
  // Multiple calls to the function may be optimized away by the compiler.
  #define __PURE __attribute__((__pure__))
  
  // Mark a function has having an output determined solely on its input
  // parameters (but not memory).
  //
  // Multiple calls to the function may be optimized away by the compiler, even
  // if memory is modified between calls.
  #define __CONST __attribute__((__const__))
  
  // The given function is malloc-like, returning a pointer to new, unused
  // memory.
  //
  // The compiler can assume that the returned pointer does not alias any other
  // pointer, which may help the compiler optimize the program.
  #define __MALLOC __attribute__((__malloc__))
  
  // The given function allocates memory of size argument |x| or |x| * |y| and returns
  // a pointer to that memory. Argument indexes are one-based. The compiler can use this
  // information to support compile-time __builtin_object_size checks.
  #if defined(__clang__)
  #define __ALLOC_SIZE(x, ...) __attribute__((__alloc_size__(x, ##__VA_ARGS__)))
  #else
  // TODO(fxrev.dev/571541): GCC warns incorrectly on constructs that could result in
  // large allocations for type reasons but cannot for other (checked) reasons. Disable
  // the attribute there.
  #define __ALLOC_SIZE(x, ...)
  #endif
  
  // Indicate that the given function takes a printf/scanf-style format string.
  //
  // "__fmt" is the argument number of the format string, indexed from 1.
  // "__varargs" is the argument number of the variable args "..." argument
  // counting from 1.
  //
  // If applied to a class method, the implicit "this" parameter counts as the
  // first argument.
  #define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
  #define __SCANFLIKE(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
  
  // Indicate that the `n`th argument to a function is non-null.
  //
  // The compiler will emit warnings if it can prove an argument is null, and
  // may optimise assuming that the values are non-null.
  #define __NONNULL(n) __attribute__((__nonnull__ n))
  
  // The given function is a "leaf", and won't call further functions.
  //
  // Leaf functions must only return directly, and not call back into the
  // current compilation unit (either via direct calls, or function pointers).
  //
  // May help the compiler optimize calls to the function in some cases.
  #define __LEAF_FN __attribute__((__leaf__))
  
  // Mark the given function or variable as `constexpr`.
  //
  // Used in code included by both C and C++. Code that is pure C++ should use
  // `constexpr` directly.
  #ifdef __cplusplus
  #define __CONSTEXPR constexpr
  #else
  #define __CONSTEXPR
  #endif
  
  // Optimize the given function using custom flags.
  //
  // For example,
  //
  //  __OPTIMIZE("O3") int myfunction() { ... }
  //
  // will cause GCC to optimize the function at the O3 level, independent
  // of what the compiler optimization flags are.
  #if !defined(__clang__)
  #define __OPTIMIZE(x) __attribute__((__optimize__(x)))
  #else
  #define __OPTIMIZE(x)
  #endif
  
  // Indicate the given function should not use LLVM's stack hardening features,
  // but instead put all local variables on the standard stack.
  //
  // c.f. https://clang.llvm.org/docs/SafeStack.html
  #if defined(__clang__)
  #define __NO_SAFESTACK __attribute__((__no_sanitize__("safe-stack", "shadow-call-stack")))
  #else
  #define __NO_SAFESTACK
  #endif
  
  // Indicate the given function or global variable shouldn't be instrumented
  // for ASAN.
  #if defined(__clang__)
  #define __NO_ASAN [[clang::no_sanitize("address")]]
  #else
  #define __NO_ASAN __attribute__((no_sanitize_address))
  #endif
  
  // The given C++ class or struct need not have a unique address when part of
  // a larger struct or class, but can be safely collapsed into a zero-byte
  // object by the compiler.
  #if __has_cpp_attribute(no_unique_address)
  #define __NO_UNIQUE_ADDRESS [[no_unique_address]]
  #else
  #define __NO_UNIQUE_ADDRESS
  #endif
  
  // Indicate that the given function should be treated by the Clang static
  // analyzer as if it doesn't return.
  //
  // A workaround to help static analyzer identify assertion failures
  #if defined(__clang__)
  #define __ANALYZER_CREATE_SINK __attribute__((analyzer_noreturn))
  #else
  #define __ANALYZER_CREATE_SINK
  #endif
  
  // Mark the given function as externally visible, and shouldn't be optimized
  // away by link-time optimizations or whole-program optimizations.
  #if !defined(__clang__)
  #define __EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
  #else
  #define __EXTERNALLY_VISIBLE
  #endif
  
  // Declare that this function declaration should be emitted as an alias for
  // another function.
  #define __ALIAS(x) __attribute__((__alias__(x)))
  
  // Place the given global into a particular linker section.
  #define __SECTION(x) __attribute__((__section__(x)))
  
  // The given function or global should be given a weak symbol, or a weak
  // alias to another symbol.
  #define __WEAK __attribute__((__weak__))
  #define __WEAK_ALIAS(x) __attribute__((__weak__, __alias__(x)))
  
  // The given static variable should still be emitted by the compiler, even if it
  // appears unused to the compiler.
  //
  // Rarely needed. Not to be confused with "__UNUSED", which avoids the
  // compiler warning if a variable appears unused.
  #define __ALWAYS_EMIT __attribute__((__used__))
  
  // Declare this object's ELF symbol visibility.
  #define __EXPORT __attribute__((__visibility__("default")))
  #define __LOCAL __attribute__((__visibility__("hidden")))
  
  //
  // Builtin functions.
  //
  
  // Provide a hint to the compiler that the given expression is likely/unlikely
  // to be true.
  //
  //   if (unlikely(status != ZX_OK)) {
  //     error(...);
  //   }
  //
  #define likely(x) __builtin_expect(!!(x), 1)
  #define unlikely(x) __builtin_expect(!!(x), 0)
  
  // Return the program counter of the calling function.
  #define __GET_CALLER(x) __builtin_return_address(0)
  
  // Return the address of the current stack frame.
  #define __GET_FRAME(x) __builtin_frame_address(0)
  
  // Return true if the given expression is a known compile-time constant.
  #define __ISCONSTANT(x) __builtin_constant_p(x)
  
  // Assume this branch of code cannot be reached.
  #define __UNREACHABLE __builtin_unreachable()
  
  // Get the offset of `field` from the beginning of the struct or class `type`.
  #define __offsetof(type, field) __builtin_offsetof(type, field)
  
  // Return the number of elements in the given C-style array.
  //
  // TODO: add type check
  #if !defined(countof)
  #define countof(a) (sizeof(a) / sizeof((a)[0]))
  #endif
  
  // Perform an arithmetic operation, returning "true" if the operation overflowed.
  //
  // Equivalent to: { *result = a + b; return _overflow_occurred; }
  #define add_overflow(a, b, result) __builtin_add_overflow(a, b, result)
  #define sub_overflow(a, b, result) __builtin_sub_overflow(a, b, result)
  #define mul_overflow(a, b, result) __builtin_mul_overflow(a, b, result)
  
  // Indicate the given case of a switch statement is intended to fall through
  // to the next case, and avoid generating a compiler warning.
  //
  //   switch (n) {
  //     case 0:
  //     case 1:
  //       handle_zero_and_one_case();
  //       __FALLTHROUGH;
  //     default:
  //       handle_all_cases();
  //       break;
  //   }
  //
  #if defined(__cplusplus) && __cplusplus >= 201703L
  #define __FALLTHROUGH [[fallthrough]]
  #elif defined(__cplusplus) && defined(__clang__)
  #define __FALLTHROUGH [[clang::fallthrough]]
  // The GNU style attribute is supported by Clang for C code, but __GNUC__ for
  // clang right now is 4.
  #elif __GNUC__ >= 7 || (!defined(__cplusplus) && defined(__clang__))
  #define __FALLTHROUGH __attribute__((__fallthrough__))
  #else
  #define __FALLTHROUGH \
    do {                \
    } while (0)
  #endif
  
  // Locking annotations.
  //
  // The following annotations allow compile-time checking that annotated data
  // is only accessed while holding the correct locks.
  //
  // The annotations are only supported by Clang, and frequently used with C++
  // standard library types in userspace, so only enable in Clang when we know
  // that the C++ standard library types are annotated or if we're in kernel
  // code.
  #if defined(__clang__) && (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) || defined(_KERNEL))
  #define __THREAD_ANNOTATION(x) __attribute__((x))
  #else
  #define __THREAD_ANNOTATION(x)
  #endif
  #define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
  #define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
  #define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
  #define __TA_ACQUIRE_SHARED(...) __THREAD_ANNOTATION(__acquire_shared_capability__(__VA_ARGS__))
  #define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
  #define __TA_TRY_ACQUIRE_SHARED(...) \
    __THREAD_ANNOTATION(__try_acquire_shared_capability__(__VA_ARGS__))
  // Neither ACQUIRED_BEFORE nor ACQUIRED_AFTER are implemented in clang. Users of these macros must
  // not rely upon them to catch lock ordering bugs, and must treat them as documentation only.
  // See:
  // https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquired-before-and-acquired-after-are-currently-unimplemented
  #define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
  #define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
  #define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
  #define __TA_RELEASE_SHARED(...) __THREAD_ANNOTATION(__release_shared_capability__(__VA_ARGS__))
  #define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
  #define __TA_REQUIRES_SHARED(...) __THREAD_ANNOTATION(__requires_shared_capability__(__VA_ARGS__))
  #define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
  #define __TA_ASSERT(...) __THREAD_ANNOTATION(__assert_capability__(__VA_ARGS__))
  #define __TA_ASSERT_SHARED(...) __THREAD_ANNOTATION(__assert_shared_capability__(__VA_ARGS__))
  #define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
  #define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
  #define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
  
  // Experimental lifetime analysis annotations.
  #ifndef __OWNER
  #ifdef __clang__
  #define __OWNER(x) [[gsl::Owner(x)]]
  #define __POINTER(x) [[gsl::Pointer(x)]]
  #else
  #define __OWNER(x)
  #define __POINTER(x)
  #endif
  #endif
  
  #endif  // !defined(__ASSEMBLER__)
  
  #endif  // SYSROOT_ZIRCON_COMPILER_H_
  