1 | /* |
2 | * Copyright (C) 2019 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #ifndef INCLUDE_PERFETTO_BASE_COMPILER_H_ |
18 | #define INCLUDE_PERFETTO_BASE_COMPILER_H_ |
19 | |
20 | #include <stddef.h> |
21 | #include <type_traits> |
22 | |
23 | #include "perfetto/base/build_config.h" |
24 | #include "perfetto/public/compiler.h" |
25 | |
26 | #if __cplusplus >= 201703 |
27 | #define PERFETTO_IS_AT_LEAST_CPP17() 1 |
28 | #else |
29 | #define PERFETTO_IS_AT_LEAST_CPP17() 0 |
30 | #endif |
31 | |
32 | #if !PERFETTO_IS_AT_LEAST_CPP17() && !defined(PERFETTO_ALLOW_SUB_CPP17) |
33 | #error Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this \ |
34 | transitionary period, we are throwing an error when compiling Perfetto \ |
35 | with a standard less than C++17. Please reach out to \ |
36 | perfetto-dev@googlegroups.com if you have objections or thoughts on \ |
37 | this move. To continue compiling this release of Perfetto with \ |
38 | C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. \ |
39 | *Note*: this define *will* stop working in v34 (Feb 2023). |
40 | #endif |
41 | |
42 | // __has_attribute is supported only by clang and recent versions of GCC. |
43 | // Add a layer to wrap the __has_attribute macro. |
44 | #if defined(__has_attribute) |
45 | #define PERFETTO_HAS_ATTRIBUTE(x) __has_attribute(x) |
46 | #else |
47 | #define PERFETTO_HAS_ATTRIBUTE(x) 0 |
48 | #endif |
49 | |
50 | #if defined(__GNUC__) || defined(__clang__) |
51 | #define PERFETTO_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) |
52 | #else |
53 | #define PERFETTO_WARN_UNUSED_RESULT |
54 | #endif |
55 | |
56 | #if defined(__GNUC__) || defined(__clang__) |
57 | #define PERFETTO_UNUSED __attribute__((unused)) |
58 | #else |
59 | #define PERFETTO_UNUSED |
60 | #endif |
61 | |
62 | #if defined(__clang__) |
63 | #define PERFETTO_ALWAYS_INLINE __attribute__((__always_inline__)) |
64 | #define PERFETTO_NO_INLINE __attribute__((__noinline__)) |
65 | #else |
66 | // GCC is too pedantic and often fails with the error: |
67 | // "always_inline function might not be inlinable" |
68 | #define PERFETTO_ALWAYS_INLINE |
69 | #define PERFETTO_NO_INLINE |
70 | #endif |
71 | |
72 | #if defined(__GNUC__) || defined(__clang__) |
73 | #define PERFETTO_NORETURN __attribute__((__noreturn__)) |
74 | #else |
75 | #define PERFETTO_NORETURN __declspec(noreturn) |
76 | #endif |
77 | |
78 | #if defined(__GNUC__) || defined(__clang__) |
79 | #define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __PRETTY_FUNCTION__ |
80 | #elif defined(_MSC_VER) |
81 | #define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __FUNCSIG__ |
82 | #else |
83 | #define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() \ |
84 | static_assert(false, "Not implemented for this compiler") |
85 | #endif |
86 | |
87 | #if defined(__GNUC__) || defined(__clang__) |
88 | #define PERFETTO_PRINTF_FORMAT(x, y) \ |
89 | __attribute__((__format__(__printf__, x, y))) |
90 | #else |
91 | #define PERFETTO_PRINTF_FORMAT(x, y) |
92 | #endif |
93 | |
94 | #if PERFETTO_BUILDFLAG(PERFETTO_OS_IOS) |
95 | // TODO(b/158814068): For iOS builds, thread_local is only supported since iOS |
96 | // 8. We'd have to use pthread for thread local data instead here. For now, just |
97 | // define it to nothing since we don't support running perfetto or the client |
98 | // lib on iOS right now. |
99 | #define PERFETTO_THREAD_LOCAL |
100 | #else |
101 | #define PERFETTO_THREAD_LOCAL thread_local |
102 | #endif |
103 | |
104 | #if defined(__GNUC__) || defined(__clang__) |
105 | #define PERFETTO_POPCOUNT(x) __builtin_popcountll(x) |
106 | #else |
107 | #include <intrin.h> |
108 | #define PERFETTO_POPCOUNT(x) __popcnt64(x) |
109 | #endif |
110 | |
111 | #if defined(__clang__) |
112 | #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) |
113 | extern "C" void __asan_poison_memory_region(void const volatile*, size_t); |
114 | extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t); |
115 | #define PERFETTO_ASAN_POISON(a, s) __asan_poison_memory_region((a), (s)) |
116 | #define PERFETTO_ASAN_UNPOISON(a, s) __asan_unpoison_memory_region((a), (s)) |
117 | #else |
118 | #define PERFETTO_ASAN_POISON(addr, size) |
119 | #define PERFETTO_ASAN_UNPOISON(addr, size) |
120 | #endif // __has_feature(address_sanitizer) |
121 | #else |
122 | #define PERFETTO_ASAN_POISON(addr, size) |
123 | #define PERFETTO_ASAN_UNPOISON(addr, size) |
124 | #endif // __clang__ |
125 | |
126 | #if defined(__GNUC__) || defined(__clang__) |
127 | #define PERFETTO_IS_LITTLE_ENDIAN() __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
128 | #else |
129 | // Assume all MSVC targets are little endian. |
130 | #define PERFETTO_IS_LITTLE_ENDIAN() 1 |
131 | #endif |
132 | |
133 | // This is used for exporting xxxMain() symbols (e.g., PerfettoCmdMain, |
134 | // ProbesMain) from libperfetto.so when the GN arg monolithic_binaries = false. |
135 | #if defined(__GNUC__) || defined(__clang__) |
136 | #define PERFETTO_EXPORT_ENTRYPOINT __attribute__((visibility("default"))) |
137 | #else |
138 | // TODO(primiano): on Windows this should be a pair of dllexport/dllimport. But |
139 | // that requires a -DXXX_IMPLEMENTATION depending on whether we are on the |
140 | // impl-site or call-site. Right now it's not worth the trouble as we |
141 | // force-export the xxxMain() symbols only on Android, where we pack all the |
142 | // code for N binaries into one .so to save binary size. On Windows we support |
143 | // only monolithic binaries, as they are easier to deal with. |
144 | #define PERFETTO_EXPORT_ENTRYPOINT |
145 | #endif |
146 | |
147 | // Disables thread safety analysis for functions where the compiler can't |
148 | // accurate figure out which locks are being held. |
149 | #if defined(__clang__) |
150 | #define PERFETTO_NO_THREAD_SAFETY_ANALYSIS \ |
151 | __attribute__((no_thread_safety_analysis)) |
152 | #else |
153 | #define PERFETTO_NO_THREAD_SAFETY_ANALYSIS |
154 | #endif |
155 | |
156 | // Avoid calling the exit-time destructor on an object with static lifetime. |
157 | #if PERFETTO_HAS_ATTRIBUTE(no_destroy) |
158 | #define PERFETTO_HAS_NO_DESTROY() 1 |
159 | #define PERFETTO_NO_DESTROY __attribute__((no_destroy)) |
160 | #else |
161 | #define PERFETTO_HAS_NO_DESTROY() 0 |
162 | #define PERFETTO_NO_DESTROY |
163 | #endif |
164 | |
165 | // Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional. |
166 | #if defined(__clang__) |
167 | #define PERFETTO_FALLTHROUGH [[clang::fallthrough]] |
168 | #else |
169 | #define PERFETTO_FALLTHROUGH |
170 | #endif |
171 | |
172 | namespace perfetto { |
173 | namespace base { |
174 | |
175 | template <typename... T> |
176 | inline void ignore_result(const T&...) {} |
177 | |
178 | } // namespace base |
179 | } // namespace perfetto |
180 | |
181 | #endif // INCLUDE_PERFETTO_BASE_COMPILER_H_ |
182 | |