-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmacros.h
211 lines (180 loc) · 5.53 KB
/
macros.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#pragma once
#define PASTE(a, b) a##b
#define XPASTE(a, b) PASTE(a, b)
#define STRLEN(str) (sizeof("" str "") - 1)
#define DO_PRAGMA(x) _Pragma(#x)
#define VERCMP(x, y, cx, cy) ((cx > x) || ((cx == x) && (cy >= y)))
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
#define GNUC_AT_LEAST(x, y) VERCMP(x, y, __GNUC__, __GNUC_MINOR__)
#else
#define GNUC_AT_LEAST(x, y) 0
#endif
#if defined(__clang_major__) && defined(__clang_minor__)
#define CLANG_AT_LEAST(x, y) VERCMP(x, y, __clang_major__, __clang_minor__)
#else
#define CLANG_AT_LEAST(x, y) 0
#endif
#ifdef __has_attribute
#define HAS_ATTRIBUTE(x) __has_attribute(x)
#else
#define HAS_ATTRIBUTE(x) 0
#endif
#ifdef __has_builtin
#define HAS_BUILTIN(x) __has_builtin(x)
#else
#define HAS_BUILTIN(x) 0
#endif
#ifdef __has_include
#define HAS_INCLUDE(x) __has_include(x)
#else
#define HAS_INCLUDE(x) 0
#endif
#ifdef __has_feature
#define HAS_FEATURE(x) __has_feature(x)
#else
#define HAS_FEATURE(x) 0
#endif
// __has_extension() is a Clang macro used to determine if a feature is
// available even if not standardized in the current "-std" mode.
#ifdef __has_extension
#define HAS_EXTENSION(x) __has_extension(x)
#else
// Clang versions prior to 3.0 only supported __has_feature()
#define HAS_EXTENSION(x) HAS_FEATURE(x)
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(unused) || defined(__TINYC__)
#define UNUSED __attribute__((__unused__))
#else
#define UNUSED
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(const)
#define CONST __attribute__((__const__))
#else
#define CONST
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(malloc)
#define MALLOC __attribute__((__malloc__))
#else
#define MALLOC
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(constructor)
#define CONSTRUCTOR __attribute__((__constructor__))
#define HAVE_ATTR_CONSTRUCTOR 1
#else
#define CONSTRUCTOR
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(destructor)
#define DESTRUCTOR __attribute__((__destructor__))
#else
#define DESTRUCTOR
#endif
#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(format)
#define PRINTF(x) __attribute__((__format__(__printf__, (x), (x + 1))))
#define VPRINTF(x) __attribute__((__format__(__printf__, (x), 0)))
#else
#define PRINTF(x)
#define VPRINTF(x)
#endif
#if (GNUC_AT_LEAST(3, 0) || HAS_BUILTIN(__builtin_expect)) && defined(__OPTIMIZE__)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#if GNUC_AT_LEAST(3, 1) || HAS_ATTRIBUTE(noinline)
#define NOINLINE __attribute__((__noinline__))
#else
#define NOINLINE
#endif
#if GNUC_AT_LEAST(3, 1) || HAS_ATTRIBUTE(always_inline)
#define ALWAYS_INLINE __attribute__((__always_inline__))
#else
#define ALWAYS_INLINE
#endif
#if GNUC_AT_LEAST(3, 3) || HAS_ATTRIBUTE(nonnull)
#define NONNULL_ARGS __attribute__((__nonnull__))
#define NONNULL_ARG(...) __attribute__((__nonnull__(__VA_ARGS__)))
#else
#define NONNULL_ARGS
#define NONNULL_ARG(...)
#endif
#if GNUC_AT_LEAST(3, 4) || HAS_ATTRIBUTE(warn_unused_result)
#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#else
#define WARN_UNUSED_RESULT
#endif
#if GNUC_AT_LEAST(4, 1) || HAS_ATTRIBUTE(flatten)
#define FLATTEN __attribute__((__flatten__))
#else
#define FLATTEN
#endif
#if GNUC_AT_LEAST(4, 3) || HAS_ATTRIBUTE(hot)
#define HOT __attribute__((__hot__))
#else
#define HOT
#endif
#if GNUC_AT_LEAST(4, 3) || HAS_ATTRIBUTE(cold)
#define COLD __attribute__((__cold__))
#else
#define COLD
#endif
#if GNUC_AT_LEAST(4, 5) || HAS_BUILTIN(__builtin_unreachable)
#define UNREACHABLE() __builtin_unreachable()
#else
#define UNREACHABLE()
#endif
#if GNUC_AT_LEAST(5, 0) || HAS_ATTRIBUTE(returns_nonnull)
#define RETURNS_NONNULL __attribute__((__returns_nonnull__))
#else
#define RETURNS_NONNULL
#endif
#if HAS_ATTRIBUTE(diagnose_if)
#define DIAGNOSE_IF(x) __attribute__((diagnose_if((x), (#x), "error")))
#else
#define DIAGNOSE_IF(x)
#endif
#define XMALLOC MALLOC RETURNS_NONNULL WARN_UNUSED_RESULT
#define XSTRDUP XMALLOC NONNULL_ARGS
#if __STDC_VERSION__ >= 201112L
#define noreturn _Noreturn
#elif GNUC_AT_LEAST(3, 0)
#define noreturn __attribute__((__noreturn__))
#else
#define noreturn
#endif
#if CLANG_AT_LEAST(3, 6)
#define UNROLL_LOOP(n) DO_PRAGMA(clang loop unroll_count(n))
#elif GNUC_AT_LEAST(8, 0)
#define UNROLL_LOOP(n) DO_PRAGMA(GCC unroll (n))
#else
#define UNROLL_LOOP(n)
#endif
#ifdef __COUNTER__
// Supported by GCC 4.3+ and Clang
#define COUNTER_ __COUNTER__
#else
#define COUNTER_ __LINE__
#endif
#if defined(_DEBUG) && defined(HAVE_ATTR_CONSTRUCTOR)
#define UNITTEST static void CONSTRUCTOR XPASTE(unittest_, COUNTER_)(void)
#else
#define UNITTEST static void UNUSED XPASTE(unittest_, COUNTER_)(void)
#endif
#ifdef __clang__
#define IGNORE_WARNING(wflag) \
DO_PRAGMA(clang diagnostic push) \
DO_PRAGMA(clang diagnostic ignored "-Wunknown-pragmas") \
DO_PRAGMA(clang diagnostic ignored "-Wunknown-warning-option") \
DO_PRAGMA(clang diagnostic ignored wflag)
#define UNIGNORE_WARNINGS DO_PRAGMA(clang diagnostic pop)
#elif GNUC_AT_LEAST(4, 6)
#define IGNORE_WARNING(wflag) \
DO_PRAGMA(GCC diagnostic push) \
DO_PRAGMA(GCC diagnostic ignored "-Wpragmas") \
DO_PRAGMA(GCC diagnostic ignored wflag)
#define UNIGNORE_WARNINGS DO_PRAGMA(GCC diagnostic pop)
#else
#define IGNORE_WARNING(wflag)
#define UNIGNORE_WARNINGS
#endif