1 /**
2  * Copyright (c) 2021-2022 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 LIBPANDABASE_MACROS_H
17 #define LIBPANDABASE_MACROS_H
18 
19 #include <cassert>
20 #include <iostream>
21 #include "os/stacktrace.h"
22 #include "utils/debug.h"
23 
24 // Inline (disabled for DEBUG)
25 #ifndef NDEBUG
26 #define ALWAYS_INLINE // NOLINT(cppcoreguidelines-macro-usage)
27 #else  // NDEBUG
28 #define ALWAYS_INLINE __attribute__((always_inline)) // NOLINT(cppcoreguidelines-macro-usage)
29 #endif  // !NDEBUG
30 
31 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
32 #define NO_INLINE __attribute__((noinline))
33 
34 #ifdef __clang__
35 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
36 #define NO_OPTIMIZE [[clang::optnone]]
37 #else
38 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
39 #define NO_OPTIMIZE __attribute__((optimize("O0")))
40 #endif
41 
42 #ifdef __clang__
43 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
44 #define FIELD_UNUSED __attribute__((__unused__))
45 #else
46 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
47 #define FIELD_UNUSED
48 #endif
49 
50 #ifndef PANDA_TARGET_WINDOWS
51 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
52 #define PANDA_PUBLIC_API __attribute__((visibility ("default")))
53 #else
54 #define PANDA_PUBLIC_API __declspec(dllexport)
55 #endif
56 
57 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
58 #define MEMBER_OFFSET(T, F) offsetof(T, F)
59 
60 #if defined(__cplusplus)
61 
62 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
63 #define NO_COPY_CTOR(TypeName) \
64     TypeName(const TypeName&) = delete;
65 
66 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
67 #define NO_COPY_OPERATOR(TypeName) \
68     void operator=(const TypeName&) = delete
69 
70 // Disabling copy ctor and copy assignment operator.
71 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
72 #define NO_COPY_SEMANTIC(TypeName) \
73     NO_COPY_CTOR(TypeName)         \
74     NO_COPY_OPERATOR(TypeName)
75 
76 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
77 #define NO_MOVE_CTOR(TypeName)                   \
78     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
79     TypeName(TypeName&&) = delete;
80 
81 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
82 #define NO_MOVE_OPERATOR(TypeName)               \
83     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
84     TypeName& operator=(TypeName&&) = delete
85 
86 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
87 #define NO_MOVE_SEMANTIC(TypeName) \
88     NO_MOVE_CTOR(TypeName)         \
89     NO_MOVE_OPERATOR(TypeName)
90 
91 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
92 #define DEFAULT_MOVE_CTOR(TypeName)              \
93     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
94     TypeName(TypeName&&) = default;
95 
96 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
97 #define DEFAULT_MOVE_OPERATOR(TypeName)          \
98     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
99     TypeName& operator=(TypeName&&) = default
100 
101 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
102 #define DEFAULT_MOVE_SEMANTIC(TypeName) \
103     DEFAULT_MOVE_CTOR(TypeName)         \
104     DEFAULT_MOVE_OPERATOR(TypeName)
105 
106 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
107 #define DEFAULT_COPY_CTOR(TypeName)      \
108     TypeName(const TypeName&) = default; \
109 
110 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
111 #define DEFAULT_COPY_OPERATOR(TypeName)          \
112     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
113     TypeName& operator=(const TypeName&) = default
114 
115 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
116 #define DEFAULT_COPY_SEMANTIC(TypeName) \
117     DEFAULT_COPY_CTOR(TypeName)         \
118     DEFAULT_COPY_OPERATOR(TypeName)
119 
120 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
121 #define DEFAULT_NOEXCEPT_MOVE_CTOR(TypeName)     \
122     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
123     TypeName(TypeName&&) noexcept = default;
124 
125 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
126 #define DEFAULT_NOEXCEPT_MOVE_OPERATOR(TypeName) \
127     /* NOLINTNEXTLINE(misc-macro-parentheses) */ \
128     TypeName& operator=(TypeName&&) noexcept = default
129 
130 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
131 #define DEFAULT_NOEXCEPT_MOVE_SEMANTIC(TypeName) \
132     DEFAULT_NOEXCEPT_MOVE_CTOR(TypeName)         \
133     DEFAULT_NOEXCEPT_MOVE_OPERATOR(TypeName)
134 
135 #endif  // defined(__cplusplus)
136 
137 #define LIKELY(exp) (__builtin_expect((exp) != 0, true))  // NOLINT(cppcoreguidelines-macro-usage)
138 #define UNLIKELY(exp) (__builtin_expect((exp) != 0, false))  // NOLINT(cppcoreguidelines-macro-usage)
139 
140 // NOLINT(cppcoreguidelines-macro-usage)
141 #define ABORT_AND_UNREACHABLE()                                      \
142     do {                                                             \
143         std::cerr << "This line should be unreachable" << std::endl; \
144         std::abort();                                                \
145         __builtin_unreachable();                                     \
146     } while (0)
147 
148 
149 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
150 #define CHECK(expr) \
151     do { \
152         if (UNLIKELY(!(expr))) { \
153             std::cerr << "CHECK FAILED: " << #expr; \
154             std::cerr << "          IN: " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << std::endl; \
155             panda::PrintStack(std::cerr); \
156             std::abort(); \
157         } \
158     } while (0)
159 
160 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
161 #define CHECK_NOT_NULL(ptr) CHECK((ptr) != nullptr)
162 
163 #if !defined(NDEBUG)
164 
165 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
166 #define ASSERT_FAIL(expr) panda::debug::AssertionFail(expr, __FILE__, __LINE__, __FUNCTION__)
167 
168 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
169 #define ASSERT_OP(lhs, op, rhs) do { \
170         auto __lhs = lhs; \
171         auto __rhs = rhs; \
172         if (UNLIKELY(!(__lhs op __rhs))) { \
173             std::cerr << "CHECK FAILED: " << #lhs << " " #op " " #rhs << std::endl; \
174             std::cerr << "      VALUES: " << __lhs << " " #op " " << __rhs << std::endl; \
175             std::cerr << "          IN: " << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION__ << std::endl; \
176             panda::PrintStack(std::cerr); \
177             std::abort(); \
178         } \
179     } while (0)
180 
181 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
182 #define CHECK_LE(lhs, rhs) ASSERT_OP(lhs, <=, rhs)
183 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
184 #define CHECK_LT(lhs, rhs) ASSERT_OP(lhs, <, rhs)
185 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
186 #define CHECK_GE(lhs, rhs) ASSERT_OP(lhs, >=, rhs)
187 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
188 #define CHECK_GT(lhs, rhs) ASSERT_OP(lhs, >, rhs)
189 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
190 #define CHECK_EQ(lhs, rhs) ASSERT_OP(lhs, ==, rhs)
191 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
192 #define CHECK_NE(lhs, rhs) ASSERT_OP(lhs, !=, rhs)
193 
194 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
195 #define ASSERT(cond) \
196     if (UNLIKELY(!(cond))) { \
197         ASSERT_FAIL(#cond); \
198     }
199 
200 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
201 #define ASSERT_DO(cond, func)                                  \
202     do {                                                       \
203         if (auto cond_val = cond; UNLIKELY(!(cond_val))) {     \
204             func;                                              \
205             ASSERT_FAIL(#cond);                                \
206         }                                                      \
207     } while (0)
208 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
209 #define ASSERT_PRINT(cond, message)                         \
210     do {                                                    \
211         if (auto cond_val = cond; UNLIKELY(!(cond_val))) {  \
212             std::cerr << message << std::endl;              \
213             ASSERT_FAIL(#cond);                             \
214         }                                                   \
215     } while (0)
216 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
217 #define ASSERT_RETURN(cond) assert(cond)
218 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
219 #define UNREACHABLE()                                                                            \
220     do {                                                                                         \
221         ASSERT_PRINT(false, "This line should be unreachable"); /* NOLINT(misc-static-assert) */ \
222         __builtin_unreachable();                                                                 \
223     } while (0)
224 #else  // NDEBUG
225 #define ASSERT(cond) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage)
226 #define ASSERT_DO(cond, func) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage)
227 #define ASSERT_PRINT(cond, message) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage)
228 #define ASSERT_RETURN(cond) static_cast<void>(cond) // NOLINT(cppcoreguidelines-macro-usage)
229 #define UNREACHABLE() ABORT_AND_UNREACHABLE()  // NOLINT(cppcoreguidelines-macro-usage)
230 #define ASSERT_OP(lhs, op, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
231 #define CHECK_LE(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
232 #define CHECK_LT(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
233 #define CHECK_GE(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
234 #define CHECK_GT(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
235 #define CHECK_EQ(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
236 #define CHECK_NE(lhs, rhs)  // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
237 #endif  // !NDEBUG
238 
239 // Due to the impossibility of using asserts in constexpr methods
240 // we need an extra version of UNREACHABLE macro that can be used in such situations
241 #define UNREACHABLE_CONSTEXPR()  ABORT_AND_UNREACHABLE()  // NOLINT(cppcoreguidelines-macro-usage)
242 
243 #define MERGE_WORDS_X(A, B) A ## B  // NOLINT(cppcoreguidelines-macro-usage)
244 #define MERGE_WORDS(A, B) MERGE_WORDS_X(A, B)  // NOLINT(cppcoreguidelines-macro-usage)
245 
246 #if defined(__has_feature)
247 #  if __has_feature(thread_sanitizer)
248 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread"))) // NOLINT(cppcoreguidelines-macro-usage)
249 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
250 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
251     AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
252 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
253 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
254     AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
255 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
256 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
257 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() \
258     AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
259 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
260 #define TSAN_ANNOTATE_IGNORE_WRITES_END() \
261     AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
262 extern "C" void AnnotateHappensBefore(const char* f, int l, const volatile void* addr);
263 extern "C" void AnnotateHappensAfter(const char* f, int l, const volatile void* addr);
264 extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l);
265 extern "C" void AnnotateIgnoreWritesEnd(const char* f, int l);
266 #  else
267 #define NO_THREAD_SANITIZE
268 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
269 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
270 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN()
271 #define TSAN_ANNOTATE_IGNORE_WRITES_END()
272 #  endif
273 #else
274 #   ifdef __SANITIZE_THREAD__
275 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread"))) // NOLINT(cppcoreguidelines-macro-usage)
276 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
277 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
278     AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
279 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
280 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
281     AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr))
282 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
283 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
284 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() \
285     AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
286 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
287 #define TSAN_ANNOTATE_IGNORE_WRITES_END() \
288     AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
289 extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr);
290 extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr);
291 extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l);
292 extern "C" void AnnotateIgnoreWritesEnd(const char* f, int l);
293 #  else
294 #define NO_THREAD_SANITIZE
295 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
296 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
297 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN()
298 #define TSAN_ANNOTATE_IGNORE_WRITES_END()
299 #  endif
300 #endif
301 
302 #if defined(__has_feature)
303 #  if __has_feature(undefined_behavior_sanitizer)
304 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined"))) // NOLINT(cppcoreguidelines-macro-usage)
305 #  else
306 #define NO_UB_SANITIZE
307 #  endif
308 #else
309 #   ifdef __SANITIZE_UNDEFINED__
310 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined"))) // NOLINT(cppcoreguidelines-macro-usage)
311 #  else
312 #define NO_UB_SANITIZE
313 #  endif
314 #endif
315 
316 #if defined(__has_feature)
317 #  if __has_feature(address_sanitizer)
318 #define USE_ADDRESS_SANITIZER
319 #  endif
320 #elif defined(__SANITIZE_ADDRESS__)
321 #define USE_ADDRESS_SANITIZER
322 #endif
323 
324 #ifdef USE_ADDRESS_SANITIZER
325 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize("address"))) // NOLINT(cppcoreguidelines-macro-usage)
326 #else
327 #define NO_ADDRESS_SANITIZE
328 #endif  // USE_ADDRESS_SANITIZER
329 
330 #if defined(__has_include)
331 #if __has_include(<filesystem>)
332 #define USE_STD_FILESYSTEM
333 #endif
334 #endif
335 
336 // WEAK_SYMBOLS_FOR_LTO is defined if compiling arkbase_lto and unset otherwise
337 #ifdef WEAK_SYMBOLS_FOR_LTO
338 #define WEAK_FOR_LTO_START _Pragma("clang attribute push(__attribute__((weak)), apply_to = function)")
339 #define WEAK_FOR_LTO_END   _Pragma("clang attribute pop")
340 #else
341 #define WEAK_FOR_LTO_START
342 #define WEAK_FOR_LTO_END
343 #endif
344 
345 #endif  // LIBPANDABASE_MACROS_H
346