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 "explicit" for C++11 safe-bool operator
52 #if (__cplusplus >= 201103) || (_MSC_VER >= 1800)
53  #define SYS_SAFE_BOOL explicit
54 #else
55  #define SYS_SAFE_BOOL
56 #endif
57 
58 // Define the [[fallthrough]] and [[maybe_unused]] attributes.
59 #if defined(__has_cpp_attribute)
60  #if __has_cpp_attribute(fallthrough) == 201603
61  #define SYS_FALLTHROUGH [[fallthrough]]
62  #endif
63  #if __has_cpp_attribute(maybe_unused) == 201603
64  #define SYS_MAYBE_UNUSED [[maybe_unused]]
65  #endif
66 #endif
67 #if !defined(SYS_FALLTHROUGH)
68  #define SYS_FALLTHROUGH
69 #endif
70 #if !defined(SYS_MAYBE_UNUSED)
71  #define SYS_MAYBE_UNUSED
72 #endif
73 
74 // gcc 7 & 8 produce warnings about ignored attributes when using maybe_unused
75 // on a member variable.
76 #if SYS_IS_GCC_GE(7, 0)
77  #define SYS_MAYBE_UNUSED_MEMBER
78 #else
79  #define SYS_MAYBE_UNUSED_MEMBER SYS_MAYBE_UNUSED
80 #endif
81 
82 #if defined(__has_cpp_attribute)
83  #if __has_cpp_attribute(nodiscard) >= 201603L
84  #define SYS_NO_DISCARD_RESULT [[nodiscard]]
85  #endif
86 #elif __cplusplus >= 201703L // We live in the future and using c++17 or later!
87  #define SYS_NO_DISCARD_RESULT [[nodiscard]]
88 #endif
89 #if !defined(SYS_NO_DISCARD_RESULT)
90  #if defined(__GNUC__)
91  #define SYS_NO_DISCARD_RESULT __attribute__((warn_unused_result))
92  #else
93  #define SYS_NO_DISCARD_RESULT
94  #endif
95 #endif
96 
97 // Use to mark declared variables as unused. This is typically for
98 // static function variables which are declared just to run initialization
99 // code, or if the variable is used only in debug builds.
100 #if defined(__GNUC__) || defined(__clang__)
101 # define SYS_UNUSED_VAR_ATTRIB __attribute__((unused))
102 #else
103 # define SYS_UNUSED_VAR_ATTRIB
104 #endif
105 
106 // Use to mark a function as not returning. This is typically just used for
107 // exit().
108 #define SYS_FUNC_NORETURN [[noreturn]]
109 
110 // Apple dropped the ball on implementing C++11 thread_local in clang on OSX.
111 // Cited reason was that they thought they could do better than previous
112 // implementation, but then never did.
113 // See: https://devforums.apple.com/message/1079348#1079348
114 #if !(defined(__APPLE__) && defined(__clang__))
115  #define SYS_THREAD_LOCAL thread_local
116 #else
117  #define SYS_THREAD_LOCAL __thread
118 #endif
119 
120 // Instruct the compiler to assume that the expression given will be true and
121 // use that information to guide optimizations.
122 #if defined(_MSC_VER)
123  #define SYS_ASSUME(EXPR) __assume(EXPR)
124 #elif defined(__clang__)
125  #if __has_builtin(__builtin_assume)
126  #define SYS_ASSUME(EXPR) __builtin_assume(EXPR)
127  #else
128  #define SYS_ASSUME(EXPR) if (!(EXPR)) __builtin_unreachable()
129  #endif
130 #else
131  #define SYS_ASSUME(EXPR) if (!(EXPR)) __builtin_unreachable()
132 #endif
133 
134 // Defines to disable compiler sanitizer checks
135 #if defined(__has_feature)
136  #if __has_feature(thread_sanitizer)
137  #define SYS_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
138  #endif
139  #if __has_feature(memory_sanitizer)
140  #define SYS_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
141  #endif
142  #if __has_feature(address_sanitizer)
143  #define SYS_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
144  #endif
145 #endif
146 #if !defined(SYS_NO_SANITIZE_THREAD)
147  #define SYS_NO_SANITIZE_THREAD
148 #endif
149 #if !defined(SYS_NO_SANITIZE_MEMORY)
150  #define SYS_NO_SANITIZE_MEMORY
151 #endif
152 #if !defined(SYS_NO_SANITIZE_ADDRESS)
153  #define SYS_NO_SANITIZE_ADDRESS
154 #endif
155 
156 #endif // __SYS_COMPILER_H_INCLUDED__