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