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__) 262extern "C" void AnnotateHappensBefore(const char* f, int l, const volatile void* addr); 263extern "C" void AnnotateHappensAfter(const char* f, int l, const volatile void* addr); 264extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l); 265extern "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__) 289extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr); 290extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr); 291extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l); 292extern "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