// Copyright 2024 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CORE_FXCRT_COMPILER_SPECIFIC_H_ #define CORE_FXCRT_COMPILER_SPECIFIC_H_ #include "build/build_config.h" // A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE. #if defined(__has_attribute) #define HAS_ATTRIBUTE(x) … #else #define HAS_ATTRIBUTE … #endif // Annotate a function indicating it should not be inlined. // Use like: // NOINLINE void DoStuff() { ... } #if defined(__clang__) && HAS_ATTRIBUTE(noinline) #define NOINLINE … #elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline) #define NOINLINE … #elif defined(COMPILER_MSVC) #define NOINLINE … #else #define NOINLINE #endif // Macro for hinting that an expression is likely to be false. #if !defined(UNLIKELY) #if defined(COMPILER_GCC) || defined(__clang__) #define UNLIKELY(x) … #else #define UNLIKELY … #endif // defined(COMPILER_GCC) #endif // !defined(UNLIKELY) #if !defined(LIKELY) #if defined(COMPILER_GCC) || defined(__clang__) #define LIKELY(x) … #else #define LIKELY … #endif // defined(COMPILER_GCC) #endif // !defined(LIKELY) // Marks a type as being eligible for the "trivial" ABI despite having a // non-trivial destructor or copy/move constructor. Such types can be relocated // after construction by simply copying their memory, which makes them eligible // to be passed in registers. The canonical example is std::unique_ptr. // // Use with caution; this has some subtle effects on constructor/destructor // ordering and will be very incorrect if the type relies on its address // remaining constant. When used as a function argument (by value), the value // may be constructed in the caller's stack frame, passed in a register, and // then used and destructed in the callee's stack frame. A similar thing can // occur when values are returned. // // TRIVIAL_ABI is not needed for types which have a trivial destructor and // copy/move constructors, such as base::TimeTicks and other POD. // // It is also not likely to be effective on types too large to be passed in one // or two registers on typical target ABIs. // // See also: // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html #if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi) #define TRIVIAL_ABI … #else #define TRIVIAL_ABI #endif #if defined(__clang__) #define GSL_POINTER … #else #define GSL_POINTER #endif #if defined(__clang__) && HAS_ATTRIBUTE(unsafe_buffer_usage) #define UNSAFE_BUFFER_USAGE … #else #define UNSAFE_BUFFER_USAGE #endif // clang-format off // Formatting is off so that we can put each _Pragma on its own line, as // recommended by the gcc docs. #if defined(PDF_USE_CHROME_PLUGINS) #define UNSAFE_BUFFERS(...) … #else #define UNSAFE_BUFFERS … #endif // clang-format on // Like UNSAFE_BUFFERS(), but indicates there is a TODO() task to // investigate safety, // TODO(crbug.com/pdfium/2155): remove all usage. #define UNSAFE_TODO(...) … #endif // CORE_FXCRT_COMPILER_SPECIFIC_H_