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 PANDA_LIBPANDABASE_PBASE_MACROS_H_ 17 #define PANDA_LIBPANDABASE_PBASE_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 #if !defined(NDEBUG) 141 142 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 143 #define ASSERT_FAIL(expr) panda::debug::AssertionFail(expr, __FILE__, __LINE__, __FUNCTION__) 144 145 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 146 #define ASSERT_OP(lhs, op, rhs) 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 panda::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 std::cerr << message << std::endl; \ 190 ASSERT_FAIL(#cond); \ 191 } \ 192 } while (0) 193 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 194 #define ASSERT_RETURN(cond) assert(cond) 195 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 196 #define UNREACHABLE() \ 197 do { \ 198 ASSERT_PRINT(false, "This line should be unreachable"); /* NOLINT(misc-static-assert) */ \ 199 __builtin_unreachable(); \ 200 } while (0) 201 #else // NDEBUG 202 #define ASSERT(cond) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage) 203 #define ASSERT_DO(cond, func) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage) 204 #define ASSERT_PRINT(cond, message) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage) 205 #define ASSERT_RETURN(cond) static_cast<void>(cond) // NOLINT(cppcoreguidelines-macro-usage) 206 #define UNREACHABLE __builtin_unreachable // NOLINT(cppcoreguidelines-macro-usage) 207 #define ASSERT_OP(lhs, op, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 208 #define CHECK_LE(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 209 #define CHECK_LT(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 210 #define CHECK_GE(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 211 #define CHECK_GT(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 212 #define CHECK_EQ(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 213 #define CHECK_NE(lhs, rhs) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 214 #endif // !NDEBUG 215 216 // Due to the impossibility of using asserts in constexpr methods 217 // we need an extra version of UNREACHABLE macro that can be used in such situations 218 #define UNREACHABLE_CONSTEXPR() __builtin_unreachable() // NOLINT(cppcoreguidelines-macro-usage) 219 220 #define MERGE_WORDS_X(A, B) A ## B // NOLINT(cppcoreguidelines-macro-usage) 221 #define MERGE_WORDS(A, B) MERGE_WORDS_X(A, B) // NOLINT(cppcoreguidelines-macro-usage) 222 223 #if defined(__has_feature) 224 # if __has_feature(thread_sanitizer) 225 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread"))) // NOLINT(cppcoreguidelines-macro-usage) 226 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 227 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \ 228 AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr)) 229 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 230 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \ 231 AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr)) 232 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 233 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 234 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() \ 235 AnnotateIgnoreWritesBegin(__FILE__, __LINE__) 236 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 237 #define TSAN_ANNOTATE_IGNORE_WRITES_END() \ 238 AnnotateIgnoreWritesEnd(__FILE__, __LINE__) 239 extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr); 240 extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr); 241 extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l); 242 extern "C" void AnnotateIgnoreWritesEnd(const char* f, int l); 243 # else 244 #define NO_THREAD_SANITIZE 245 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) 246 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) 247 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() 248 #define TSAN_ANNOTATE_IGNORE_WRITES_END() 249 # endif 250 #else 251 # ifdef __SANITIZE_THREAD__ 252 #define NO_THREAD_SANITIZE __attribute__((no_sanitize("thread"))) // NOLINT(cppcoreguidelines-macro-usage) 253 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 254 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \ 255 AnnotateHappensBefore(__FILE__, __LINE__, reinterpret_cast<void *>(addr)) 256 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 257 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \ 258 AnnotateHappensAfter(__FILE__, __LINE__, reinterpret_cast<void *>(addr)) 259 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 260 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 261 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() \ 262 AnnotateIgnoreWritesBegin(__FILE__, __LINE__) 263 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 264 #define TSAN_ANNOTATE_IGNORE_WRITES_END() \ 265 AnnotateIgnoreWritesEnd(__FILE__, __LINE__) 266 extern "C" void AnnotateHappensBefore(const char* f, int l, void* addr); 267 extern "C" void AnnotateHappensAfter(const char* f, int l, void* addr); 268 extern "C" void AnnotateIgnoreWritesBegin(const char* f, int l); 269 extern "C" void AnnotateIgnoreWritesEnd(const char* f, int l); 270 # else 271 #define NO_THREAD_SANITIZE 272 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) 273 #define TSAN_ANNOTATE_HAPPENS_AFTER(addr) 274 #define TSAN_ANNOTATE_IGNORE_WRITES_BEGIN() 275 #define TSAN_ANNOTATE_IGNORE_WRITES_END() 276 # endif 277 #endif 278 279 #if defined(__has_feature) 280 # if __has_feature(undefined_behavior_sanitizer) 281 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined"))) // NOLINT(cppcoreguidelines-macro-usage) 282 # else 283 #define NO_UB_SANITIZE 284 # endif 285 #else 286 # ifdef __SANITIZE_UNDEFINED__ 287 #define NO_UB_SANITIZE __attribute__((no_sanitize("undefined"))) // NOLINT(cppcoreguidelines-macro-usage) 288 # else 289 #define NO_UB_SANITIZE 290 # endif 291 #endif 292 293 #if defined(__has_feature) 294 # if __has_feature(address_sanitizer) 295 #define USE_ADDRESS_SANITIZER 296 # endif 297 #elif defined(__SANITIZE_ADDRESS__) 298 #define USE_ADDRESS_SANITIZER 299 #endif 300 301 #ifdef USE_ADDRESS_SANITIZER 302 #define NO_ADDRESS_SANITIZE __attribute__((no_sanitize("address"))) // NOLINT(cppcoreguidelines-macro-usage) 303 #else 304 #define NO_ADDRESS_SANITIZE 305 #endif // USE_ADDRESS_SANITIZER 306 307 #if defined(__has_include) 308 #if __has_include(<filesystem>) 309 #define USE_STD_FILESYSTEM 310 #endif 311 #endif 312 313 // WEAK_SYMBOLS_FOR_LTO is defined if compiling arkbase_lto and unset otherwise 314 #ifdef WEAK_SYMBOLS_FOR_LTO 315 #define WEAK_FOR_LTO_START _Pragma("clang attribute push(__attribute__((weak)), apply_to = function)") 316 #define WEAK_FOR_LTO_END _Pragma("clang attribute pop") 317 #else 318 #define WEAK_FOR_LTO_START 319 #define WEAK_FOR_LTO_END 320 #endif 321 322 #endif // PANDA_LIBPANDABASE_PBASE_MACROS_H_ 323