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