1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 6 #define THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 7 8 #include "build/build_config.h" 9 10 // A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE. 11 #if defined(__has_attribute) 12 #define HAS_ATTRIBUTE(x) __has_attribute(x) 13 #else 14 #define HAS_ATTRIBUTE(x) 0 15 #endif 16 17 // Annotate a function indicating it should not be inlined. 18 // Use like: 19 // NOINLINE void DoStuff() { ... } 20 #if defined(__clang__) && HAS_ATTRIBUTE(noinline) 21 #define NOINLINE [[clang::noinline]] 22 #elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline) 23 #define NOINLINE __attribute__((noinline)) 24 #elif defined(COMPILER_MSVC) 25 #define NOINLINE __declspec(noinline) 26 #else 27 #define NOINLINE 28 #endif 29 30 // Macro for hinting that an expression is likely to be false. 31 #if !defined(UNLIKELY) 32 #if defined(COMPILER_GCC) || defined(__clang__) 33 #define UNLIKELY(x) __builtin_expect(!!(x), 0) 34 #else 35 #define UNLIKELY(x) (x) 36 #endif // defined(COMPILER_GCC) 37 #endif // !defined(UNLIKELY) 38 39 #if !defined(LIKELY) 40 #if defined(COMPILER_GCC) || defined(__clang__) 41 #define LIKELY(x) __builtin_expect(!!(x), 1) 42 #else 43 #define LIKELY(x) (x) 44 #endif // defined(COMPILER_GCC) 45 #endif // !defined(LIKELY) 46 47 // Marks a type as being eligible for the "trivial" ABI despite having a 48 // non-trivial destructor or copy/move constructor. Such types can be relocated 49 // after construction by simply copying their memory, which makes them eligible 50 // to be passed in registers. The canonical example is std::unique_ptr. 51 // 52 // Use with caution; this has some subtle effects on constructor/destructor 53 // ordering and will be very incorrect if the type relies on its address 54 // remaining constant. When used as a function argument (by value), the value 55 // may be constructed in the caller's stack frame, passed in a register, and 56 // then used and destructed in the callee's stack frame. A similar thing can 57 // occur when values are returned. 58 // 59 // TRIVIAL_ABI is not needed for types which have a trivial destructor and 60 // copy/move constructors, such as base::TimeTicks and other POD. 61 // 62 // It is also not likely to be effective on types too large to be passed in one 63 // or two registers on typical target ABIs. 64 // 65 // See also: 66 // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi 67 // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html 68 #if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi) 69 #define TRIVIAL_ABI [[clang::trivial_abi]] 70 #else 71 #define TRIVIAL_ABI 72 #endif 73 74 #if defined(__clang__) 75 #define GSL_POINTER [[gsl::Pointer]] 76 #else 77 #define GSL_POINTER 78 #endif 79 80 #endif // THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 81