HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SYS_Compiler.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SYS_Compiler.h (SYS Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __SYS_COMPILER_H_INCLUDED__
12 #define __SYS_COMPILER_H_INCLUDED__
13 
14 #if defined(__GNUC__)
15  #define SYS_IS_GCC_GE(MAJOR, MINOR) \
16  (__GNUC__ > MAJOR || (__GNUC__ == MAJOR && __GNUC_MINOR__ >= MINOR))
17  #define SYS_IS_GCC_EQ(MAJOR, MINOR) \
18  (__GNUC__ == MAJOR && __GNUC_MINOR__ == MINOR)
19 #else
20  #define SYS_IS_GCC_GE(MAJOR, MINOR) 0
21  #define SYS_IS_GCC_EQ(MAJOR, MINOR) 0
22 #endif
23 
24 #if defined(__clang__)
25  #define SYS_IS_CLANG_GE(MAJOR, MINOR) \
26  (__clang_major__ > MAJOR || (__clang_major__ == MAJOR && __clang_minor__ >= MINOR))
27 #else
28  #define SYS_IS_CLANG_GE(MAJOR, MINOR) 0
29 #endif
30 
31 #if (__cplusplus >= 201402) || (defined(_MSC_VER) && _MSVC_LANG >= 201402)
32  #define SYS_HAS_CXX14 1
33 #else
34  #define SYS_HAS_CXX14 0
35 #endif
36 
37 // Token concatenation
38 #define SYS_CONCAT(a, b) SYS_CONCAT_(a, b)
39 #define SYS_CONCAT_(a, b) a ## b
40 
41 #define SYS_TO_STRING_(a) # a
42 #define SYS_TO_STRING(a) SYS_TO_STRING_(a)
43 
44 // Handy macro to add warnings (for fix-me's etc.)
45 #if defined(_MSC_VER)
46 #define SYS_MESSAGE(desc) __pragma(message(__FILE__ "(" SYS_TO_STRING(__LINE__) ") : Warning: " #desc))
47 #else
48 #define SYS_MESSAGE(__msg__) _Pragma(SYS_TO_STRING(message __msg__))
49 #endif
50 
51 // Define the [[fallthrough]] and [[maybe_unused]] attributes.
52 #if defined(__has_cpp_attribute)
53  #if __has_cpp_attribute(fallthrough) == 201603
54  #define SYS_FALLTHROUGH [[fallthrough]]
55  #endif
56  #if __has_cpp_attribute(maybe_unused) == 201603
57  #define SYS_MAYBE_UNUSED [[maybe_unused]]
58  #endif
59 #endif
60 #if !defined(SYS_FALLTHROUGH)
61  #define SYS_FALLTHROUGH
62 #endif
63 #if !defined(SYS_MAYBE_UNUSED)
64  #define SYS_MAYBE_UNUSED
65 #endif
66 
67 // gcc 7 & 8 produce warnings about ignored attributes when using maybe_unused
68 // on a member variable.
69 #if SYS_IS_GCC_GE(7, 0)
70  #define SYS_MAYBE_UNUSED_MEMBER
71 #else
72  #define SYS_MAYBE_UNUSED_MEMBER SYS_MAYBE_UNUSED
73 #endif
74 
75 #if defined(__has_cpp_attribute)
76  #if __has_cpp_attribute(nodiscard) >= 201603L
77  #define SYS_NO_DISCARD_RESULT [[nodiscard]]
78  #endif
79 #elif __cplusplus >= 201703L // We live in the future and using c++17 or later!
80  #define SYS_NO_DISCARD_RESULT [[nodiscard]]
81 #endif
82 #if !defined(SYS_NO_DISCARD_RESULT)
83  #if defined(__GNUC__)
84  #define SYS_NO_DISCARD_RESULT __attribute__((warn_unused_result))
85  #else
86  #define SYS_NO_DISCARD_RESULT
87  #endif
88 #endif
89 
90 // Use to mark declared variables as unused. This is typically for
91 // static function variables which are declared just to run initialization
92 // code, or if the variable is used only in debug builds.
93 #if defined(__GNUC__) || defined(__clang__)
94 # define SYS_UNUSED_VAR_ATTRIB __attribute__((unused))
95 #else
96 # define SYS_UNUSED_VAR_ATTRIB
97 #endif
98 
99 // Use to mark a function as not returning. This is typically just used for
100 // exit().
101 #define SYS_FUNC_NORETURN [[noreturn]]
102 
103 // Apple dropped the ball on implementing C++11 thread_local in clang on OSX.
104 // Cited reason was that they thought they could do better than previous
105 // implementation, but then never did.
106 // See: https://devforums.apple.com/message/1079348#1079348
107 #if !(defined(__APPLE__) && defined(__clang__))
108  #define SYS_THREAD_LOCAL thread_local
109 #else
110  #define SYS_THREAD_LOCAL __thread
111 #endif
112 
113 // Instruct the compiler to assume that the expression given will be true and
114 // use that information to guide optimizations.
115 #if defined(_MSC_VER)
116  #define SYS_ASSUME(EXPR) __assume(EXPR)
117 #elif defined(__clang__)
118  #if __has_builtin(__builtin_assume)
119  #define SYS_ASSUME(EXPR) __builtin_assume(EXPR)
120  #else
121  #define SYS_ASSUME(EXPR) if (!(EXPR)) __builtin_unreachable()
122  #endif
123 #else
124  #define SYS_ASSUME(EXPR) if (!(EXPR)) __builtin_unreachable()
125 #endif
126 
127 // Defines to disable compiler sanitizer checks
128 #if defined(__has_feature)
129  #if __has_feature(thread_sanitizer)
130  #define SYS_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
131  #endif
132  #if __has_feature(memory_sanitizer)
133  #define SYS_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
134  #endif
135  #if __has_feature(address_sanitizer)
136  #define SYS_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
137  #endif
138 #endif
139 #if !defined(SYS_NO_SANITIZE_THREAD)
140  #define SYS_NO_SANITIZE_THREAD
141 #endif
142 #if !defined(SYS_NO_SANITIZE_MEMORY)
143  #define SYS_NO_SANITIZE_MEMORY
144 #endif
145 #if !defined(SYS_NO_SANITIZE_ADDRESS)
146  #define SYS_NO_SANITIZE_ADDRESS
147 #endif
148 
149 // Defines whether or not ASAN is enabled
150 #if defined(__SANITIZE_ADDRESS__)
151  #define SYS_ASAN_ENABLED 1
152 #elif defined(__has_feature)
153  #if __has_feature(address_sanitizer)
154  #define SYS_ASAN_ENABLED 1
155  #else
156  #define SYS_ASAN_ENABLED 0
157  #endif
158 #else
159  #define SYS_ASAN_ENABLED 0
160 #endif
161 
162 #endif // __SYS_COMPILER_H_INCLUDED__