• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
139 #define CHECK_EXPR(expr)                                                                                      \
140     do {                                                                                                      \
141         if (UNLIKELY(!(expr))) {                                                                              \
142             std::cerr << "CHECK FAILED: " << #expr;                                                           \
143             std::cerr << "          IN: " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << std::endl; \
144             ark::PrintStack(std::cerr);                                                                       \
145             std::abort();                                                                                     \
146         }                                                                                                     \
147     } while (0)
148 
149 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
150 #define CHECK_NOT_NULL(ptr) CHECK_EXPR((ptr) != nullptr)
151 
152 #if !defined(NDEBUG)
153 
154 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
155 #define ASSERT_FAIL(expr) ark::debug::AssertionFail(expr, __FILE__, __LINE__, __FUNCTION__)
156 
157 // CC-OFFNXT(G.PRE.06) solid logic
158 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
159 #define ASSERT_OP(lhs, op, rhs)                                                                                \
160     do {                                                                                                       \
161         auto __lhs = lhs;                                                                                      \
162         auto __rhs = rhs;                                                                                      \
163         if (UNLIKELY(!(__lhs op __rhs))) {                                                                     \
164             std::cerr << "CHECK FAILED: " << #lhs << " " #op " " #rhs << std::endl;                            \
165             std::cerr << "      VALUES: " << __lhs << " " #op " " << __rhs << std::endl;                       \
166             std::cerr << "          IN: " << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION__ << std::endl; \
167             ark::PrintStack(std::cerr);                                                                        \
168             std::abort();                                                                                      \
169         }                                                                                                      \
170     } while (0)
171 
172 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
173 #define CHECK_LE(lhs, rhs) ASSERT_OP(lhs, <=, rhs)
174 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
175 #define CHECK_LT(lhs, rhs) ASSERT_OP(lhs, <, rhs)
176 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
177 #define CHECK_GE(lhs, rhs) ASSERT_OP(lhs, >=, rhs)
178 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
179 #define CHECK_GT(lhs, rhs) ASSERT_OP(lhs, >, rhs)
180 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
181 #define CHECK_EQ(lhs, rhs) ASSERT_OP(lhs, ==, rhs)
182 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
183 #define CHECK_NE(lhs, rhs) ASSERT_OP(lhs, !=, rhs)
184 
185 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
186 #define ASSERT(cond)         \
187     if (UNLIKELY(!(cond))) { \
188         ASSERT_FAIL(#cond);  \
189     }
190 
191 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
192 #define ASSERT_DO(cond, func)                              \
193     do {                                                   \
194         if (auto cond_val = cond; UNLIKELY(!(cond_val))) { \
195             func;                                          \
196             ASSERT_FAIL(#cond);                            \
197         }                                                  \
198     } while (0)
199 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
200 #define ASSERT_PRINT(cond, message)                        \
201     do {                                                   \
202         if (auto cond_val = cond; UNLIKELY(!(cond_val))) { \
203             /* CC-OFFNXT(G.PRE.02) string arg */           \
204             std::cerr << message << std::endl;             \
205             ASSERT_FAIL(#cond);                            \
206         }                                                  \
207     } while (0)
208 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
209 #define ASSERT_RETURN(cond) assert(cond)
210 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
211 #define UNREACHABLE()                                                                            \
212     do {                                                                                         \
213         ASSERT_PRINT(false, "This line should be unreachable"); /* NOLINT(misc-static-assert) */ \
214         __builtin_unreachable();                                                                 \
215     } while (0)
216 #else                                                     // NDEBUG
217 #define ASSERT(cond) static_cast<void>(0)                 // NOLINT(cppcoreguidelines-macro-usage)
218 #define ASSERT_DO(cond, func) static_cast<void>(0)        // NOLINT(cppcoreguidelines-macro-usage)
219 #define ASSERT_PRINT(cond, message) static_cast<void>(0)  // NOLINT(cppcoreguidelines-macro-usage)
220 #define ASSERT_RETURN(cond) static_cast<void>(cond)       // NOLINT(cppcoreguidelines-macro-usage)
221 #define UNREACHABLE __builtin_unreachable                 // NOLINT(cppcoreguidelines-macro-usage)
222 #define ASSERT_OP(lhs, op, rhs)                           // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
223 #define CHECK_LE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
224 #define CHECK_LT(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
225 #define CHECK_GE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
226 #define CHECK_GT(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
227 #define CHECK_EQ(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
228 #define CHECK_NE(lhs, rhs)                                // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
229 #endif                                                    // !NDEBUG
230 
231 // Due to the impossibility of using asserts in constexpr methods
232 // we need an extra version of UNREACHABLE macro that can be used in such situations
233 #define UNREACHABLE_CONSTEXPR() __builtin_unreachable()  // NOLINT(cppcoreguidelines-macro-usage)
234 
235 #define MERGE_WORDS_X(A, B) A##B               // NOLINT(cppcoreguidelines-macro-usage)
236 #define MERGE_WORDS(A, B) MERGE_WORDS_X(A, B)  // NOLINT(cppcoreguidelines-macro-usage)
237 
238 // for clang
239 #if defined(__has_feature)
240 #if __has_feature(thread_sanitizer)
241 #define USE_THREAD_SANITIZER
242 #endif
243 #endif
244 // for gnu compiler
245 #if defined(__SANITIZE_THREAD__)
246 #define USE_THREAD_SANITIZER
247 #endif
248 
249 #if defined(USE_THREAD_SANITIZER)
250 #if __GNUC__ < 8 && !defined(__clang__)
251 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
252 // Note, clang also defines __GNUC__ macro, so, check __clang also
253 #define NO_THREAD_SANITIZE __attribute__((no_sanitize_thread))  // NOLINT(cppcoreguidelines-macro-usage)
254 #else
255 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread")))  // NOLINT(cppcoreguidelines-macro-usage)
256 #endif
257 // Do not inline no_sanitize functions to avoid gcc bug with missed annotations
258 #define ALWAYS_INLINE_NO_TSAN NO_THREAD_SANITIZE
259 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
260 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
261 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
262 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
263 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
264 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
265 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
266 #define TSAN_ANNOTATE_IGNORE_WRITES_END() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
267 extern "C" void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
268 extern "C" void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
269 extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line);
270 extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line);
271 // Attribute works in clang 14 or higher versions, currently used only for INTRUSIVE_TESTING
272 #define DISABLE_THREAD_SANITIZER_INSTRUMENTATION __attribute__((disable_sanitizer_instrumentation))
273 #else
274 #define NO_THREAD_SANITIZE
275 #define ALWAYS_INLINE_NO_TSAN ALWAYS_INLINE
276 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
277 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
278 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN()
279 #define TSAN_ANNOTATE_IGNORE_WRITES_END()
280 #define DISABLE_THREAD_SANITIZER_INSTRUMENTATION
281 #endif  // USE_THREAD_SANITIZER
282 
283 // for clang
284 #if defined(__has_feature)
285 #if __has_feature(undefined_behavior_sanitizer)
286 #define USE_UB_SANITIZER
287 #endif
288 #endif
289 // for gnu compiler
290 #if defined(__SANITIZE_UNDEFINED__)
291 #define USE_UB_SANITIZER
292 #endif
293 
294 #if defined(USE_UB_SANITIZER)
295 #if __GNUC__ < 8 && !defined(__clang__)
296 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
297 // Note, clang also defines __GNUC__ macro, so, check __clang also
298 #define NO_UB_SANITIZE __attribute__((no_sanitize_undefined))  // NOLINT(cppcoreguidelines-macro-usage)
299 #else
300 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined")))  // NOLINT(cppcoreguidelines-macro-usage)
301 #endif
302 #else
303 #define NO_UB_SANITIZE
304 #endif  // USE_UB_SANITIZER
305 
306 #ifndef __SANITIZE_HWADDRESS__
307 // for clang
308 #if defined(__has_feature)
309 #if __has_feature(address_sanitizer)
310 #define USE_ADDRESS_SANITIZER
311 #endif
312 #endif
313 // for gnu compiler
314 #if defined(__SANITIZE_ADDRESS__)
315 #define USE_ADDRESS_SANITIZER
316 #endif
317 #else
318 #define NO_ADDRESS_SANITIZE
319 #endif
320 
321 #if defined(USE_ADDRESS_SANITIZER)
322 #if __GNUC__ < 8 && !defined(__clang__)
323 // gcc < 8.0 has a bug with attributes: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78204
324 // Note, clang also defines __GNUC__ macro, so, check __clang also
325 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize_address))  // NOLINT(cppcoreguidelines-macro-usage)
326 #else
327 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize("address")))  // NOLINT(cppcoreguidelines-macro-usage)
328 #endif
329 #else
330 #define NO_ADDRESS_SANITIZE
331 #endif  // USE_ADDRESS_SANITIZER
332 
333 #if defined(__has_include)
334 #if __has_include(<filesystem>)
335 #define USE_STD_FILESYSTEM
336 #endif
337 #endif
338 
339 // WEAK_SYMBOLS_FOR_LTO is defined if compiling arkbase_lto and unset otherwise
340 #ifdef WEAK_SYMBOLS_FOR_LTO
341 #define WEAK_FOR_LTO_START _Pragma("clang attribute push(__attribute__((weak)), apply_to = function)")
342 #define WEAK_FOR_LTO_END _Pragma("clang attribute pop")
343 #else
344 #define WEAK_FOR_LTO_START
345 #define WEAK_FOR_LTO_END
346 #endif
347 
348 #ifndef NDEBUG
349 #define CONSTEXPR_IN_RELEASE
350 #else
351 #define CONSTEXPR_IN_RELEASE constexpr
352 #endif
353 
354 #include "os/stacktrace.h"
355 #include "utils/debug.h"
356 
357 #endif  // PANDA_LIBPANDABASE_PBASE_MACROS_H
358