CompilerEnvironmentClang.h 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #pragma once
  2. // This defines the compiler environment for clang based compilers. Please make sure to define all required features
  3. // (see VerifyCompilerEnvironment.h for reference)
  4. #if defined(__cplusplus) && __cplusplus < 201103L
  5. #error "Baselib requires C++11 support"
  6. #endif
  7. #define COMPILER_CLANG 1
  8. #define HAS_CLANG_FEATURE(x) (__has_feature(x))
  9. #define COMPILER_SUPPORTS_EXCEPTIONS HAS_CLANG_FEATURE(cxx_exceptions)
  10. #define COMPILER_SUPPORTS_RTTI HAS_CLANG_FEATURE(cxx_rtti)
  11. #define COMPILER_SUPPORTS_GENERIC_LAMBDA_EXPRESSIONS HAS_CLANG_FEATURE(cxx_generic_lambdas) // Clang >=3.4
  12. #define COMPILER_BUILTIN_EXPECT(X_, Y_) __builtin_expect((X_), (Y_))
  13. // Tells the compiler to assume that this statement is never reached.
  14. // (reaching it anyways is undefined behavior!)
  15. #define COMPILER_BUILTIN_UNREACHABLE() __builtin_unreachable()
  16. // Tells the compiler to assume that the given expression is true until the expression is modified.
  17. // (it is undefined behavior if the expression is not true after all)
  18. #define COMPILER_BUILTIN_ASSUME(EXPR_) __builtin_assume(EXPR_)
  19. #define COMPILER_NOINLINE __attribute__((unused, noinline)) // unused is needed to avoid warning when a function is not used
  20. #define COMPILER_INLINE __attribute__((unused)) inline
  21. #define COMPILER_FORCEINLINE __attribute__((unused, always_inline, nodebug)) inline
  22. #define COMPILER_EMPTYINLINE __attribute__((const, always_inline, nodebug)) inline
  23. #define COMPILER_NORETURN __attribute__((noreturn))
  24. #if __has_extension(attribute_deprecated_with_message)
  25. #define COMPILER_DEPRECATED(msg) __attribute__((deprecated(msg)))
  26. #if __has_extension(enumerator_attributes)
  27. #define COMPILER_DEPRECATED_ENUM_VALUE(msg) __attribute__((deprecated(msg)))
  28. #else
  29. #define COMPILER_DEPRECATED_ENUM_VALUE(msg)
  30. #endif
  31. #else
  32. #define COMPILER_DEPRECATED(msg) __attribute__((deprecated))
  33. #if __has_extension(enumerator_attributes)
  34. #define COMPILER_DEPRECATED_ENUM_VALUE(msg) __attribute__((deprecated))
  35. #else
  36. #define COMPILER_DEPRECATED_ENUM_VALUE(msg)
  37. #endif
  38. #endif
  39. #define COMPILER_ALIGN_OF(TYPE_) __alignof__(TYPE_)
  40. #define COMPILER_ALIGN_AS(ALIGN_) __attribute__((aligned(ALIGN_)))
  41. #define COMPILER_C_STATIC_ASSERT(EXPR_, MSG_) _Static_assert(EXPR_, MSG_)
  42. #define COMPILER_ATTRIBUTE_UNUSED __attribute__((unused))
  43. // Note that this is how the compiler defines a debug break which is not necessarily the standard way on any given platform.
  44. // For a platform friendly implementation, use `BASELIB_DEBUG_TRAP`
  45. #define COMPILER_DEBUG_TRAP() __builtin_debugtrap()
  46. #define COMPILER_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
  47. // Warning management
  48. // pragma message on clang does always generate a warning that cannot be disabled, therefore the clang version
  49. // of COMPILER_PRINT_MESSAGE() does nothing
  50. #define COMPILER_PRINT_MESSAGE(MESSAGE_)
  51. #define COMPILER_PRINT_WARNING(MESSAGE_) _Pragma(PP_STRINGIZE(message(__FILE__ "warning: " MESSAGE_)))
  52. #define COMPILER_WARNING_UNUSED_VARIABLE PP_STRINGIZE(-Wunused-variable)
  53. #define COMPILER_WARNING_DEPRECATED PP_STRINGIZE(-Wdeprecated)
  54. #define COMPILER_WARNINGS_PUSH _Pragma(PP_STRINGIZE(clang diagnostic push))
  55. #define COMPILER_WARNINGS_POP _Pragma(PP_STRINGIZE(clang diagnostic pop))
  56. #define COMPILER_WARNINGS_DISABLE(Warn) _Pragma(PP_STRINGIZE(clang diagnostic ignored Warn))
  57. // Prefetches memory for reading from address `address` if supported on the current architecture
  58. #define COMPILER_PREFETCH_READ(address) __builtin_prefetch(address, 0)
  59. // Prefetches memory for writing from address `address` if supported on the current architecture
  60. #define COMPILER_PREFETCH_WRITE(address) __builtin_prefetch(address, 1)