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