1 /* 2 * Copyright 2011-present Facebook, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <cstddef> 20 21 #include <folly/portability/Config.h> 22 #include <folly/CPortability.h> 23 24 // Unaligned loads and stores 25 namespace folly { 26 #if FOLLY_HAVE_UNALIGNED_ACCESS 27 constexpr bool kHasUnalignedAccess = true; 28 #else 29 constexpr bool kHasUnalignedAccess = false; 30 #endif 31 } // namespace folly 32 33 // compiler specific attribute translation 34 // msvc should come first, so if clang is in msvc mode it gets the right defines 35 36 // NOTE: this will only do checking in msvc with versions that support /analyze 37 #if _MSC_VER 38 #ifdef _USE_ATTRIBUTES_FOR_SAL 39 #undef _USE_ATTRIBUTES_FOR_SAL 40 #endif 41 /* nolint */ 42 #define _USE_ATTRIBUTES_FOR_SAL 1 43 #include <sal.h> // @manual 44 #define FOLLY_PRINTF_FORMAT _Printf_format_string_ 45 #define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/ 46 #else 47 #define FOLLY_PRINTF_FORMAT /**/ 48 #define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) \ 49 __attribute__((__format__(__printf__, format_param, dots_param))) 50 #endif 51 52 // warn unused result 53 #if defined(__has_cpp_attribute) 54 #if __has_cpp_attribute(nodiscard) 55 #define FOLLY_NODISCARD [[nodiscard]] 56 #endif 57 #endif 58 #if !defined FOLLY_NODISCARD 59 #if defined(_MSC_VER) && (_MSC_VER >= 1700) 60 #define FOLLY_NODISCARD _Check_return_ 61 #elif defined(__clang__) || defined(__GNUC__) 62 #define FOLLY_NODISCARD __attribute__((__warn_unused_result__)) 63 #else 64 #define FOLLY_NODISCARD 65 #endif 66 #endif 67 68 // target 69 #ifdef _MSC_VER 70 #define FOLLY_TARGET_ATTRIBUTE(target) 71 #else 72 #define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) 73 #endif 74 75 // detection for 64 bit 76 #if defined(__x86_64__) || defined(_M_X64) 77 #define FOLLY_X64 1 78 #else 79 #define FOLLY_X64 0 80 #endif 81 82 #if defined(__arm__) 83 #define FOLLY_ARM 1 84 #else 85 #define FOLLY_ARM 0 86 #endif 87 88 #if defined(__aarch64__) 89 #define FOLLY_AARCH64 1 90 #else 91 #define FOLLY_AARCH64 0 92 #endif 93 94 #if defined(__powerpc64__) 95 #define FOLLY_PPC64 1 96 #else 97 #define FOLLY_PPC64 0 98 #endif 99 100 namespace folly { 101 constexpr bool kIsArchArm = FOLLY_ARM == 1; 102 constexpr bool kIsArchAmd64 = FOLLY_X64 == 1; 103 constexpr bool kIsArchAArch64 = FOLLY_AARCH64 == 1; 104 constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1; 105 } // namespace folly 106 107 namespace folly { 108 109 /** 110 * folly::kIsSanitizeAddress reports if folly was compiled with ASAN 111 * enabled. Note that for compilation units outside of folly that include 112 * folly/Portability.h, the value of kIsSanitizeAddress may be different 113 * from whether or not the current compilation unit is being compiled with ASAN. 114 */ 115 #if FOLLY_ASAN_ENABLED 116 constexpr bool kIsSanitizeAddress = true; 117 #else 118 constexpr bool kIsSanitizeAddress = false; 119 #endif 120 121 #if FOLLY_SANITIZE_THREAD 122 constexpr bool kIsSanitizeThread = true; 123 #else 124 constexpr bool kIsSanitizeThread = false; 125 #endif 126 127 #if FOLLY_SANITIZE 128 constexpr bool kIsSanitize = true; 129 #else 130 constexpr bool kIsSanitize = false; 131 #endif 132 } // namespace folly 133 134 // packing is very ugly in msvc 135 #ifdef _MSC_VER 136 #define FOLLY_PACK_ATTR /**/ 137 #define FOLLY_PACK_PUSH __pragma(pack(push, 1)) 138 #define FOLLY_PACK_POP __pragma(pack(pop)) 139 #elif defined(__clang__) || defined(__GNUC__) 140 #define FOLLY_PACK_ATTR __attribute__((__packed__)) 141 #define FOLLY_PACK_PUSH /**/ 142 #define FOLLY_PACK_POP /**/ 143 #else 144 #define FOLLY_PACK_ATTR /**/ 145 #define FOLLY_PACK_PUSH /**/ 146 #define FOLLY_PACK_POP /**/ 147 #endif 148 149 // Generalize warning push/pop. 150 #if defined(_MSC_VER) 151 #define FOLLY_PUSH_WARNING __pragma(warning(push)) 152 #define FOLLY_POP_WARNING __pragma(warning(pop)) 153 // Disable the GCC warnings. 154 #define FOLLY_GNU_DISABLE_WARNING(warningName) 155 #define FOLLY_GCC_DISABLE_WARNING(warningName) 156 #define FOLLY_CLANG_DISABLE_WARNING(warningName) 157 #define FOLLY_MSVC_DISABLE_WARNING(warningNumber) \ 158 __pragma(warning(disable : warningNumber)) 159 #elif defined(__GNUC__) 160 // Clang & GCC 161 #define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push") 162 #define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop") 163 #define FOLLY_GNU_DISABLE_WARNING_INTERNAL2(warningName) #warningName 164 #define FOLLY_GNU_DISABLE_WARNING(warningName) \ 165 _Pragma( \ 166 FOLLY_GNU_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName)) 167 #ifdef __clang__ 168 #define FOLLY_CLANG_DISABLE_WARNING(warningName) \ 169 FOLLY_GNU_DISABLE_WARNING(warningName) 170 #define FOLLY_GCC_DISABLE_WARNING(warningName) 171 #else 172 #define FOLLY_CLANG_DISABLE_WARNING(warningName) 173 #define FOLLY_GCC_DISABLE_WARNING(warningName) \ 174 FOLLY_GNU_DISABLE_WARNING(warningName) 175 #endif 176 #define FOLLY_MSVC_DISABLE_WARNING(warningNumber) 177 #else 178 #define FOLLY_PUSH_WARNING 179 #define FOLLY_POP_WARNING 180 #define FOLLY_GNU_DISABLE_WARNING(warningName) 181 #define FOLLY_GCC_DISABLE_WARNING(warningName) 182 #define FOLLY_CLANG_DISABLE_WARNING(warningName) 183 #define FOLLY_MSVC_DISABLE_WARNING(warningNumber) 184 #endif 185 186 #ifdef FOLLY_HAVE_SHADOW_LOCAL_WARNINGS 187 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS \ 188 FOLLY_GNU_DISABLE_WARNING("-Wshadow-compatible-local") \ 189 FOLLY_GNU_DISABLE_WARNING("-Wshadow-local") \ 190 FOLLY_GNU_DISABLE_WARNING("-Wshadow") 191 #else 192 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */ 193 #endif 194 195 // Globally disable -Wshadow for gcc < 5. 196 #if __GNUC__ == 4 && !__clang__ 197 FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS 198 #endif 199 200 /* Platform specific TLS support 201 * gcc implements __thread 202 * msvc implements __declspec(thread) 203 * the semantics are the same 204 * (but remember __thread has different semantics when using emutls (ex. apple)) 205 */ 206 #if defined(_MSC_VER) 207 #define FOLLY_TLS __declspec(thread) 208 #elif defined(__GNUC__) || defined(__clang__) 209 #define FOLLY_TLS __thread 210 #else 211 #error cannot define platform specific thread local storage 212 #endif 213 214 #if FOLLY_MOBILE 215 #undef FOLLY_TLS 216 #endif 217 218 // It turns out that GNU libstdc++ and LLVM libc++ differ on how they implement 219 // the 'std' namespace; the latter uses inline namespaces. Wrap this decision 220 // up in a macro to make forward-declarations easier. 221 #if FOLLY_USE_LIBCPP 222 #include <__config> // @manual 223 #define FOLLY_NAMESPACE_STD_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD 224 #define FOLLY_NAMESPACE_STD_END _LIBCPP_END_NAMESPACE_STD 225 #else 226 #define FOLLY_NAMESPACE_STD_BEGIN namespace std { 227 #define FOLLY_NAMESPACE_STD_END } 228 #endif 229 230 // If the new c++ ABI is used, __cxx11 inline namespace needs to be added to 231 // some types, e.g. std::list. 232 #if _GLIBCXX_USE_CXX11_ABI 233 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN \ 234 inline _GLIBCXX_BEGIN_NAMESPACE_CXX11 235 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_END _GLIBCXX_END_NAMESPACE_CXX11 236 #else 237 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN 238 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_END 239 #endif 240 241 // MSVC specific defines 242 // mainly for posix compat 243 #ifdef _MSC_VER 244 #include <folly/portability/SysTypes.h> 245 246 // compiler specific to compiler specific 247 // nolint 248 #define __PRETTY_FUNCTION__ __FUNCSIG__ 249 250 // Hide a GCC specific thing that breaks MSVC if left alone. 251 #define __extension__ 252 253 // We have compiler support for the newest of the new, but 254 // MSVC doesn't tell us that. 255 #define __SSE4_2__ 1 256 257 #endif 258 259 // Debug 260 namespace folly { 261 #ifdef NDEBUG 262 constexpr auto kIsDebug = false; 263 #else 264 constexpr auto kIsDebug = true; 265 #endif 266 } // namespace folly 267 268 // Endianness 269 namespace folly { 270 #ifdef _MSC_VER 271 // It's MSVC, so we just have to guess ... and allow an override 272 #ifdef FOLLY_ENDIAN_BE 273 constexpr auto kIsLittleEndian = false; 274 #else 275 constexpr auto kIsLittleEndian = true; 276 #endif 277 #else 278 constexpr auto kIsLittleEndian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; 279 #endif 280 constexpr auto kIsBigEndian = !kIsLittleEndian; 281 } // namespace folly 282 283 #ifndef FOLLY_SSE 284 #if defined(__SSE4_2__) 285 #define FOLLY_SSE 4 286 #define FOLLY_SSE_MINOR 2 287 #elif defined(__SSE4_1__) 288 #define FOLLY_SSE 4 289 #define FOLLY_SSE_MINOR 1 290 #elif defined(__SSE4__) 291 #define FOLLY_SSE 4 292 #define FOLLY_SSE_MINOR 0 293 #elif defined(__SSE3__) 294 #define FOLLY_SSE 3 295 #define FOLLY_SSE_MINOR 0 296 #elif defined(__SSE2__) 297 #define FOLLY_SSE 2 298 #define FOLLY_SSE_MINOR 0 299 #elif defined(__SSE__) 300 #define FOLLY_SSE 1 301 #define FOLLY_SSE_MINOR 0 302 #else 303 #define FOLLY_SSE 0 304 #define FOLLY_SSE_MINOR 0 305 #endif 306 #endif 307 308 #define FOLLY_SSE_PREREQ(major, minor) \ 309 (FOLLY_SSE > major || FOLLY_SSE == major && FOLLY_SSE_MINOR >= minor) 310 311 #ifndef FOLLY_NEON 312 #if defined(__ARM_NEON) || defined(__ARM_NEON__) 313 #define FOLLY_NEON 1 314 #endif 315 #endif 316 317 #if FOLLY_UNUSUAL_GFLAGS_NAMESPACE 318 namespace FOLLY_GFLAGS_NAMESPACE {} 319 namespace gflags { 320 using namespace FOLLY_GFLAGS_NAMESPACE; 321 } // namespace gflags 322 #endif 323 324 // for TARGET_OS_IPHONE 325 #ifdef __APPLE__ 326 #include <TargetConditionals.h> // @manual 327 #endif 328 329 // RTTI may not be enabled for this compilation unit. 330 #if defined(__GXX_RTTI) || defined(__cpp_rtti) || \ 331 (defined(_MSC_VER) && defined(_CPPRTTI)) 332 #define FOLLY_HAS_RTTI 1 333 #endif 334 335 #if defined(__APPLE__) || defined(_MSC_VER) 336 #define FOLLY_STATIC_CTOR_PRIORITY_MAX 337 #else 338 // 101 is the highest priority allowed by the init_priority attribute. 339 // This priority is already used by JEMalloc and other memory allocators so 340 // we will take the next one. 341 #define FOLLY_STATIC_CTOR_PRIORITY_MAX __attribute__((__init_priority__(102))) 342 #endif 343 344 namespace folly { 345 346 #if __OBJC__ 347 constexpr auto kIsObjC = true; 348 #else 349 constexpr auto kIsObjC = false; 350 #endif 351 352 #if FOLLY_MOBILE 353 constexpr auto kIsMobile = true; 354 #else 355 constexpr auto kIsMobile = false; 356 #endif 357 358 #if defined(__linux__) && !FOLLY_MOBILE 359 constexpr auto kIsLinux = true; 360 #else 361 constexpr auto kIsLinux = false; 362 #endif 363 364 #if defined(_WIN32) 365 constexpr auto kIsWindows = true; 366 #else 367 constexpr auto kIsWindows = false; 368 #endif 369 370 #if __GLIBCXX__ 371 constexpr auto kIsGlibcxx = true; 372 #else 373 constexpr auto kIsGlibcxx = false; 374 #endif 375 376 #if _LIBCPP_VERSION 377 constexpr auto kIsLibcpp = true; 378 #else 379 constexpr auto kIsLibcpp = false; 380 #endif 381 382 #if FOLLY_USE_LIBSTDCPP 383 constexpr auto kIsLibstdcpp = true; 384 #else 385 constexpr auto kIsLibstdcpp = false; 386 #endif 387 388 #if _MSC_VER 389 constexpr auto kMscVer = _MSC_VER; 390 #else 391 constexpr auto kMscVer = 0; 392 #endif 393 394 #if FOLLY_MICROSOFT_ABI_VER 395 constexpr auto kMicrosoftAbiVer = FOLLY_MICROSOFT_ABI_VER; 396 #else 397 constexpr auto kMicrosoftAbiVer = 0; 398 #endif 399 400 // cpplib is an implementation of the standard library, and is the one typically 401 // used with the msvc compiler 402 #if _CPPLIB_VER 403 constexpr auto kCpplibVer = _CPPLIB_VER; 404 #else 405 constexpr auto kCpplibVer = 0; 406 #endif 407 } // namespace folly 408 409 // Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14 410 // constexpr support is "good enough". 411 #ifndef FOLLY_USE_CPP14_CONSTEXPR 412 #if defined(__clang__) 413 #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L 414 #elif defined(__GNUC__) 415 #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L 416 #else 417 #define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC? 418 #endif 419 #endif 420 421 #if FOLLY_USE_CPP14_CONSTEXPR 422 #define FOLLY_CPP14_CONSTEXPR constexpr 423 #else 424 #define FOLLY_CPP14_CONSTEXPR inline 425 #endif 426 427 // MSVC does not permit: 428 // 429 // extern int const num; 430 // constexpr int const num = 3; 431 // 432 // Instead: 433 // 434 // extern int const num; 435 // FOLLY_STORAGE_CONSTEXPR int const num = 3; 436 // 437 // True for MSVC 2015 and MSVC 2017. 438 #if _MSC_VER 439 #define FOLLY_STORAGE_CONSTEXPR 440 #define FOLLY_STORAGE_CPP14_CONSTEXPR 441 #else 442 #if __ICC 443 #define FOLLY_STORAGE_CONSTEXPR 444 #else 445 #define FOLLY_STORAGE_CONSTEXPR constexpr 446 #endif 447 #if FOLLY_USE_CPP14_CONSTEXPR 448 #define FOLLY_STORAGE_CPP14_CONSTEXPR constexpr 449 #else 450 #define FOLLY_STORAGE_CPP14_CONSTEXPR 451 #endif 452 #endif 453 454 #if __cpp_coroutines >= 201703L && __has_include(<experimental/coroutine>) 455 #define FOLLY_HAS_COROUTINES 1 456 #elif _MSC_VER && _RESUMABLE_FUNCTIONS_SUPPORTED 457 #define FOLLY_HAS_COROUTINES 1 458 #endif 459 460 // MSVC 2017.5 && C++17 461 #if __cpp_noexcept_function_type >= 201510 || \ 462 (_MSC_FULL_VER >= 191225816 && _MSVC_LANG > 201402) 463 #define FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE 1 464 #endif 465 466 // Define FOLLY_HAS_EXCEPTIONS 467 #if __cpp_exceptions >= 199711 || FOLLY_HAS_FEATURE(cxx_exceptions) 468 #define FOLLY_HAS_EXCEPTIONS 1 469 #elif __GNUC__ 470 #if __EXCEPTIONS 471 #define FOLLY_HAS_EXCEPTIONS 1 472 #else // __EXCEPTIONS 473 #define FOLLY_HAS_EXCEPTIONS 0 474 #endif // __EXCEPTIONS 475 #elif FOLLY_MICROSOFT_ABI_VER 476 #if _CPPUNWIND 477 #define FOLLY_HAS_EXCEPTIONS 1 478 #else // _CPPUNWIND 479 #define FOLLY_HAS_EXCEPTIONS 0 480 #endif // _CPPUNWIND 481 #else 482 #define FOLLY_HAS_EXCEPTIONS 1 // default assumption for unknown platforms 483 #endif 484 485 // feature test __cpp_lib_string_view is defined in <string>, which is 486 // too heavy to include here. MSVC __has_include support arrived later 487 // than string_view, so we need an alternate case for it. 488 #ifdef __has_include 489 #if __has_include(<string_view>) && __cplusplus >= 201703L 490 #define FOLLY_HAS_STRING_VIEW 1 491 #else 492 #define FOLLY_HAS_STRING_VIEW 0 493 #endif 494 #else // __has_include 495 #if _MSC_VER >= 1910 && (_MSVC_LANG > 201402 || __cplusplus > 201402) 496 #define FOLLY_HAS_STRING_VIEW 1 497 #else 498 #define FOLLY_HAS_STRING_VIEW 0 499 #endif 500 #endif // __has_include 501