• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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