• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_LIBPANDABASE_PBASE_MACROS_H
17 #define PANDA_LIBPANDABASE_PBASE_MACROS_H
18 
19 #include <cassert>
20 #include <iostream>
21 
22 // Inline (disabled for DEBUG)
23 #ifndef NDEBUG
24 #define ALWAYS_INLINE                                 // NOLINT(cppcoreguidelines-macro-usage)
25 #else                                                 // NDEBUG
26 #define ALWAYS_INLINE __attribute__((always_inline))  // NOLINT(cppcoreguidelines-macro-usage)
27 #endif                                                // !NDEBUG
28 
29 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
30 #define NO_INLINE __attribute__((noinline))
31 
32 #ifdef __clang__
33 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
34 #define NO_OPTIMIZE [[clang::optnone]]
35 #else
36 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
37 #define NO_OPTIMIZE __attribute__((optimize("O0")))
38 #endif
39 
40 #ifdef __clang__
41 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
42 #define FIELD_UNUSED __attribute__((__unused__))
43 #else
44 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
45 #define FIELD_UNUSED
46 #endif
47 
48 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
49 #define UNUSED_VAR(var) (void)(var)
50 
51 #ifndef PANDA_TARGET_WINDOWS
52 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
53 #define PANDA_PUBLIC_API __attribute__((visibility("default")))
54 #else
55 #define PANDA_PUBLIC_API __declspec(dllexport)
56 #endif
57 
58 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
59 #define MEMBER_OFFSET(T, F) offsetof(T, F)
60 
61 #if defined(__cplusplus)
62 
63 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
64 #define NO_COPY_CTOR(TypeName) TypeName(const TypeName &) = delete
65 
66 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
67 #define NO_COPY_OPERATOR(TypeName) void operator=(const TypeName &) = delete
68 
69 // Disabling copy ctor and copy assignment operator.
70 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
71 #define NO_COPY_SEMANTIC(TypeName) \
72     NO_COPY_CTOR(TypeName);        \
73     NO_COPY_OPERATOR(TypeName)
74 
75 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
76 #define NO_MOVE_CTOR(TypeName)                   \
77     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
78     TypeName(TypeName &&) = delete
79 
80 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
81 #define NO_MOVE_OPERATOR(TypeName)               \
82     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
83     TypeName &operator=(TypeName &&) = delete
84 
85 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
86 #define NO_MOVE_SEMANTIC(TypeName) \
87     NO_MOVE_CTOR(TypeName);        \
88     NO_MOVE_OPERATOR(TypeName)
89 
90 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
91 #define DEFAULT_MOVE_CTOR(TypeName)              \
92     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
93     TypeName(TypeName &&) = default
94 
95 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
96 #define DEFAULT_MOVE_OPERATOR(TypeName)          \
97     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
98     TypeName &operator=(TypeName &&) = default
99 
100 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
101 #define DEFAULT_MOVE_SEMANTIC(TypeName) \
102     DEFAULT_MOVE_CTOR(TypeName);        \
103     DEFAULT_MOVE_OPERATOR(TypeName)
104 
105 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
106 #define DEFAULT_COPY_CTOR(TypeName) TypeName(const TypeName &) = default
107 
108 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
109 #define DEFAULT_COPY_OPERATOR(TypeName)          \
110     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
111     TypeName &operator=(const TypeName &) = default
112 
113 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
114 #define DEFAULT_COPY_SEMANTIC(TypeName) \
115     DEFAULT_COPY_CTOR(TypeName);        \
116     DEFAULT_COPY_OPERATOR(TypeName)
117 
118 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
119 #define DEFAULT_NOEXCEPT_MOVE_CTOR(TypeName)     \
120     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
121     TypeName(TypeName &&) noexcept = default
122 
123 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
124 #define DEFAULT_NOEXCEPT_MOVE_OPERATOR(TypeName) \
125     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
126     TypeName &operator=(TypeName &&) noexcept = default
127 
128 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
129 #define DEFAULT_NOEXCEPT_MOVE_SEMANTIC(TypeName) \
130     DEFAULT_NOEXCEPT_MOVE_CTOR(TypeName);        \
131     DEFAULT_NOEXCEPT_MOVE_OPERATOR(TypeName)
132 
133 #endif  // defined(__cplusplus)
134 
135 #define LIKELY(exp) (__builtin_expect((exp) != 0, true))     // NOLINT(cppcoreguidelines-macro-usage)
136 #define UNLIKELY(exp) (__builtin_expect((exp) != 0, false))  // NOLINT(cppcoreguidelines-macro-usage)
137 
138 #if !defined(NDEBUG)
139 
140 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
141 #define ASSERT_FAIL(expr) ark::debug::AssertionFail(expr, __FILE__, __LINE__, __FUNCTION__)
142 
143 // CC-OFFNXT(G.PRE.06) solid logic
144 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
145 #define ASSERT_OP(lhs, op, rhs)                                                                                \
146     do {                                                                                                       \
147         auto __lhs = lhs;                                                                                      \
148         auto __rhs = rhs;                                                                                      \
149         if (UNLIKELY(!(__lhs op __rhs))) {                                                                     \
150             std::cerr << "CHECK FAILED: " << #lhs << " " #op " " #rhs << std::endl;                            \
151             std::cerr << "      VALUES: " << __lhs << " " #op " " << __rhs << std::endl;                       \
152             std::cerr << "          IN: " << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION__ << std::endl; \
153             ark::PrintStack(std::cerr);                                                                        \
154             std::abort();                                                                                      \
155         }                                                                                                      \
156     } while (0)
157 
158 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
159 #define CHECK_LE(lhs, rhs) ASSERT_OP(lhs, <=, rhs)
160 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
161 #define CHECK_LT(lhs, rhs) ASSERT_OP(lhs, <, rhs)
162 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
163 #define CHECK_GE(lhs, rhs) ASSERT_OP(lhs, >=, rhs)
164 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
165 #define CHECK_GT(lhs, rhs) ASSERT_OP(lhs, >, rhs)
166 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
167 #define CHECK_EQ(lhs, rhs) ASSERT_OP(lhs, ==, rhs)
168 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
169 #define CHECK_NE(lhs, rhs) ASSERT_OP(lhs, !=, rhs)
170 
171 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
172 #define ASSERT(cond)         \
173     if (UNLIKELY(!(cond))) { \
174         ASSERT_FAIL(#cond);  \
175     }
176 
177 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
178 #define ASSERT_DO(cond, func)                              \
179     do {                                                   \
180         if (auto cond_val = cond; UNLIKELY(!(cond_val))) { \
181             func;                                          \
182             ASSERT_FAIL(#cond);                            \
183         }                                                  \
184     } while (0)
185 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
186 #define ASSERT_PRINT(cond, message)                        \
187     do {                                                   \
188         if (auto cond_val = cond; UNLIKELY(!(cond_val))) { \
189             /* CC-OFFNXT(G.PRE.02) string arg */           \
190             std::cerr << message << std::endl;             \
191             ASSERT_FAIL(#cond);                            \
192         }                                                  \
193     } while (0)
194 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
195 #define ASSERT_RETURN(cond) assert(cond)
196 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
197 #define UNREACHABLE()                                                                            \
198     do {                                                                                         \
199         ASSERT_PRINT(false, "This line should be unreachable"); /* NOLINT(misc-static-assert) */ \
200         __builtin_unreachable();                                                                 \
201     } while (0)
202 #else                                                     // NDEBUG
203 #define ASSERT(cond) static_cast<void>(0)                 // NOLINT(cppcoreguidelines-macro-usage)
204 #define ASSERT_DO(cond, func) static_cast<void>(0)        // NOLINT(cppcoreguidelines-macro-usage)
205 #define ASSERT_PRINT(cond, message) static_cast<void>(0)  // NOLINT(cppcoreguidelines-macro-usage)
206 #define ASSERT_RETURN(cond) static_cast<void>(cond)       // NOLINT(cppcoreguidelines-macro-usage)
207 #define UNREACHABLE __builtin_unreachable                 // NOLINT(cppcoreguidelines-macro-usage)
208 #define ASSERT_OP(lhs, op, rhs)                           // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
209 #define CHECK_LE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
210 #define CHECK_LT(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
211 #define CHECK_GE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
212 #define CHECK_GT(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
213 #define CHECK_EQ(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
214 #define CHECK_NE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
215 #endif                                                    // !NDEBUG
216 
217 // Due to the impossibility of using asserts in constexpr methods
218 // we need an extra version of UNREACHABLE macro that can be used in such situations
219 #define UNREACHABLE_CONSTEXPR() __builtin_unreachable()  // NOLINT(cppcoreguidelines-macro-usage)
220 
221 #define MERGE_WORDS_X(A, B) A##B               // NOLINT(cppcoreguidelines-macro-usage)
222 #define MERGE_WORDS(A, B) MERGE_WORDS_X(A, B)  // NOLINT(cppcoreguidelines-macro-usage)
223 
224 // for clang
225 #if defined(__has_feature)
226 #if __has_feature(thread_sanitizer)
227 #define USE_THREAD_SANITIZER
228 #endif
229 #endif
230 // for gnu compiler
231 #if defined(__SANITIZE_THREAD__)
232 #define USE_THREAD_SANITIZER
233 #endif
234 
235 #if defined(USE_THREAD_SANITIZER)
236 #if __GNUC__ < 8 && !defined(__clang__)
237 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
238 // Note, clang also defines __GNUC__ macro, so, check __clang also
239 #define NO_THREAD_SANITIZE __attribute__((no_sanitize_thread))  // NOLINT(cppcoreguidelines-macro-usage)
240 #else
241 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread")))  // NOLINT(cppcoreguidelines-macro-usage)
242 #endif
243 // Do not inline no_sanitize functions to avoid gcc bug with missed annotations
244 #define ALWAYS_INLINE_NO_TSAN NO_THREAD_SANITIZE
245 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
246 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
247 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
248 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
249 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
250 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
251 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
252 #define TSAN_ANNOTATE_IGNORE_WRITES_END() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
253 extern "C" void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
254 extern "C" void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
255 extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line);
256 extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line);
257 // Attribute works in clang 14 or higher versions, currently used only for INTRUSIVE_TESTING
258 #define DISABLE_THREAD_SANITIZER_INSTRUMENTATION __attribute__((disable_sanitizer_instrumentation))
259 #else
260 #define NO_THREAD_SANITIZE
261 #define ALWAYS_INLINE_NO_TSAN ALWAYS_INLINE
262 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
263 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
264 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN()
265 #define TSAN_ANNOTATE_IGNORE_WRITES_END()
266 #define DISABLE_THREAD_SANITIZER_INSTRUMENTATION
267 #endif  // USE_THREAD_SANITIZER
268 
269 // for clang
270 #if defined(__has_feature)
271 #if __has_feature(undefined_behavior_sanitizer)
272 #define USE_UB_SANITIZER
273 #endif
274 #endif
275 // for gnu compiler
276 #if defined(__SANITIZE_UNDEFINED__)
277 #define USE_UB_SANITIZER
278 #endif
279 
280 #if defined(USE_UB_SANITIZER)
281 #if __GNUC__ < 8 && !defined(__clang__)
282 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
283 // Note, clang also defines __GNUC__ macro, so, check __clang also
284 #define NO_UB_SANITIZE __attribute__((no_sanitize_undefined))  // NOLINT(cppcoreguidelines-macro-usage)
285 #else
286 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined")))  // NOLINT(cppcoreguidelines-macro-usage)
287 #endif
288 #else
289 #define NO_UB_SANITIZE
290 #endif  // USE_UB_SANITIZER
291 
292 // for clang
293 #if defined(__has_feature)
294 #if __has_feature(address_sanitizer)
295 #define USE_ADDRESS_SANITIZER
296 #endif
297 #endif
298 // for gnu compiler
299 #if defined(__SANITIZE_ADDRESS__)
300 #define USE_ADDRESS_SANITIZER
301 #endif
302 
303 #if defined(USE_ADDRESS_SANITIZER)
304 #if __GNUC__ < 8 && !defined(__clang__)
305 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
306 // Note, clang also defines __GNUC__ macro, so, check __clang also
307 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize_address))  // NOLINT(cppcoreguidelines-macro-usage)
308 #else
309 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize("address")))  // NOLINT(cppcoreguidelines-macro-usage)
310 #endif
311 #else
312 #define NO_ADDRESS_SANITIZE
313 #endif  // USE_ADDRESS_SANITIZER
314 
315 #if defined(__has_include)
316 #if __has_include(<filesystem>)
317 #define USE_STD_FILESYSTEM
318 #endif
319 #endif
320 
321 // WEAK_SYMBOLS_FOR_LTO is defined if compiling arkbase_lto and unset otherwise
322 #ifdef WEAK_SYMBOLS_FOR_LTO
323 #define WEAK_FOR_LTO_START _Pragma("clang attribute push(__attribute__((weak)), apply_to = function)")
324 #define WEAK_FOR_LTO_END _Pragma("clang attribute pop")
325 #else
326 #define WEAK_FOR_LTO_START
327 #define WEAK_FOR_LTO_END
328 #endif
329 
330 #ifndef NDEBUG
331 #define CONSTEXPR_IN_RELEASE
332 #else
333 #define CONSTEXPR_IN_RELEASE constexpr
334 #endif
335 
336 #include "os/stacktrace.h"
337 #include "utils/debug.h"
338 
339 #endif  // PANDA_LIBPANDABASE_PBASE_MACROS_H
340