Portability.h 13 KB

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