]>
Commit | Line | Data |
---|---|---|
39037602 | 1 | /* |
cb323159 | 2 | * Copyright (c) 2008-2013 Apple Inc. All rights reserved. |
39037602 A |
3 | * |
4 | * @APPLE_APACHE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
7 | * you may not use this file except in compliance with the License. | |
8 | * You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, software | |
13 | * distributed under the License is distributed on an "AS IS" BASIS, | |
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | * See the License for the specific language governing permissions and | |
16 | * limitations under the License. | |
17 | * | |
18 | * @APPLE_APACHE_LICENSE_HEADER_END@ | |
19 | */ | |
20 | ||
21 | #ifndef __OS_BASE__ | |
22 | #define __OS_BASE__ | |
23 | ||
24 | #include <sys/cdefs.h> | |
25 | ||
26 | #ifndef __has_builtin | |
27 | #define __has_builtin(x) 0 | |
28 | #endif | |
29 | #ifndef __has_include | |
30 | #define __has_include(x) 0 | |
31 | #endif | |
32 | #ifndef __has_feature | |
33 | #define __has_feature(x) 0 | |
34 | #endif | |
35 | #ifndef __has_attribute | |
36 | #define __has_attribute(x) 0 | |
37 | #endif | |
38 | #ifndef __has_extension | |
39 | #define __has_extension(x) 0 | |
40 | #endif | |
41 | ||
42 | #undef OS_INLINE // <sys/_types/_os_inline.h> | |
43 | #if __GNUC__ | |
44 | #define OS_NORETURN __attribute__((__noreturn__)) | |
45 | #define OS_NOTHROW __attribute__((__nothrow__)) | |
46 | #define OS_NONNULL1 __attribute__((__nonnull__(1))) | |
47 | #define OS_NONNULL2 __attribute__((__nonnull__(2))) | |
48 | #define OS_NONNULL3 __attribute__((__nonnull__(3))) | |
49 | #define OS_NONNULL4 __attribute__((__nonnull__(4))) | |
50 | #define OS_NONNULL5 __attribute__((__nonnull__(5))) | |
51 | #define OS_NONNULL6 __attribute__((__nonnull__(6))) | |
52 | #define OS_NONNULL7 __attribute__((__nonnull__(7))) | |
53 | #define OS_NONNULL8 __attribute__((__nonnull__(8))) | |
54 | #define OS_NONNULL9 __attribute__((__nonnull__(9))) | |
55 | #define OS_NONNULL10 __attribute__((__nonnull__(10))) | |
56 | #define OS_NONNULL11 __attribute__((__nonnull__(11))) | |
57 | #define OS_NONNULL12 __attribute__((__nonnull__(12))) | |
58 | #define OS_NONNULL13 __attribute__((__nonnull__(13))) | |
59 | #define OS_NONNULL14 __attribute__((__nonnull__(14))) | |
60 | #define OS_NONNULL15 __attribute__((__nonnull__(15))) | |
61 | #define OS_NONNULL_ALL __attribute__((__nonnull__)) | |
62 | #define OS_SENTINEL __attribute__((__sentinel__)) | |
63 | #define OS_PURE __attribute__((__pure__)) | |
64 | #define OS_CONST __attribute__((__const__)) | |
65 | #define OS_WARN_RESULT __attribute__((__warn_unused_result__)) | |
66 | #define OS_MALLOC __attribute__((__malloc__)) | |
67 | #define OS_USED __attribute__((__used__)) | |
68 | #define OS_UNUSED __attribute__((__unused__)) | |
69 | #define OS_COLD __attribute__((__cold__)) | |
70 | #define OS_WEAK __attribute__((__weak__)) | |
71 | #define OS_WEAK_IMPORT __attribute__((__weak_import__)) | |
72 | #define OS_NOINLINE __attribute__((__noinline__)) | |
73 | #define OS_ALWAYS_INLINE __attribute__((__always_inline__)) | |
74 | #define OS_TRANSPARENT_UNION __attribute__((__transparent_union__)) | |
75 | #define OS_ALIGNED(n) __attribute__((__aligned__((n)))) | |
0a7de745 | 76 | #define OS_FORMAT_PRINTF(x, y) __attribute__((__format__(printf,x,y))) |
39037602 A |
77 | #define OS_EXPORT extern __attribute__((__visibility__("default"))) |
78 | #define OS_INLINE static __inline__ | |
79 | #define OS_EXPECT(x, v) __builtin_expect((x), (v)) | |
80 | #else | |
81 | #define OS_NORETURN | |
82 | #define OS_NOTHROW | |
83 | #define OS_NONNULL1 | |
84 | #define OS_NONNULL2 | |
85 | #define OS_NONNULL3 | |
86 | #define OS_NONNULL4 | |
87 | #define OS_NONNULL5 | |
88 | #define OS_NONNULL6 | |
89 | #define OS_NONNULL7 | |
90 | #define OS_NONNULL8 | |
91 | #define OS_NONNULL9 | |
92 | #define OS_NONNULL10 | |
93 | #define OS_NONNULL11 | |
94 | #define OS_NONNULL12 | |
95 | #define OS_NONNULL13 | |
96 | #define OS_NONNULL14 | |
97 | #define OS_NONNULL15 | |
98 | #define OS_NONNULL_ALL | |
99 | #define OS_SENTINEL | |
100 | #define OS_PURE | |
101 | #define OS_CONST | |
102 | #define OS_WARN_RESULT | |
103 | #define OS_MALLOC | |
104 | #define OS_USED | |
105 | #define OS_UNUSED | |
106 | #define OS_COLD | |
107 | #define OS_WEAK | |
108 | #define OS_WEAK_IMPORT | |
109 | #define OS_NOINLINE | |
110 | #define OS_ALWAYS_INLINE | |
111 | #define OS_TRANSPARENT_UNION | |
112 | #define OS_ALIGNED(n) | |
0a7de745 | 113 | #define OS_FORMAT_PRINTF(x, y) |
39037602 A |
114 | #define OS_EXPORT extern |
115 | #define OS_INLINE static inline | |
116 | #define OS_EXPECT(x, v) (x) | |
117 | #endif | |
118 | ||
119 | #if __has_attribute(noescape) | |
120 | #define OS_NOESCAPE __attribute__((__noescape__)) | |
121 | #else | |
122 | #define OS_NOESCAPE | |
123 | #endif | |
124 | ||
cb323159 A |
125 | #if defined(__cplusplus) && defined(__clang__) |
126 | #define OS_FALLTHROUGH [[clang::fallthrough]] | |
127 | #else | |
128 | #define OS_FALLTHROUGH | |
129 | #endif | |
130 | ||
39037602 A |
131 | #if __has_feature(assume_nonnull) |
132 | #define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") | |
133 | #define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") | |
134 | #else | |
135 | #define OS_ASSUME_NONNULL_BEGIN | |
136 | #define OS_ASSUME_NONNULL_END | |
137 | #endif | |
138 | ||
139 | #if __has_builtin(__builtin_assume) | |
140 | #define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr) | |
141 | #else | |
142 | #define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr)) | |
143 | #endif | |
144 | ||
145 | #if __has_extension(attribute_overloadable) | |
146 | #define OS_OVERLOADABLE __attribute__((__overloadable__)) | |
147 | #else | |
148 | #define OS_OVERLOADABLE | |
149 | #endif | |
150 | ||
cb323159 A |
151 | #if __has_attribute(enum_extensibility) |
152 | #define __OS_ENUM_ATTR __attribute__((enum_extensibility(open))) | |
153 | #define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed))) | |
154 | #else | |
155 | #define __OS_ENUM_ATTR | |
156 | #define __OS_ENUM_ATTR_CLOSED | |
157 | #endif // __has_attribute(enum_extensibility) | |
158 | ||
159 | #if __has_attribute(flag_enum) | |
160 | /*! | |
161 | * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and | |
162 | * assignment, respectively, i.e. -Wflag-enum prevents you from creating new | |
163 | * enumeration values from illegal values within the enum definition, and | |
164 | * -Wassign-enum prevents you from assigning illegal values to a variable of the | |
165 | * enum type. | |
166 | */ | |
167 | #define __OS_OPTIONS_ATTR __attribute__((flag_enum)) | |
168 | #else | |
169 | #define __OS_OPTIONS_ATTR | |
170 | #endif // __has_attribute(flag_enum) | |
171 | ||
172 | #if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \ | |
173 | __has_extension(cxx_strong_enums) | |
39037602 | 174 | #define OS_ENUM(_name, _type, ...) \ |
0a7de745 | 175 | typedef enum : _type { __VA_ARGS__ } _name##_t |
cb323159 A |
176 | #define OS_CLOSED_ENUM(_name, _type, ...) \ |
177 | typedef enum : _type { __VA_ARGS__ } \ | |
178 | __OS_ENUM_ATTR_CLOSED _name##_t | |
179 | #define OS_OPTIONS(_name, _type, ...) \ | |
180 | typedef enum : _type { __VA_ARGS__ } \ | |
181 | __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t | |
182 | #define OS_CLOSED_OPTIONS(_name, _type, ...) \ | |
183 | typedef enum : _type { __VA_ARGS__ } \ | |
184 | __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t | |
39037602 | 185 | #else |
cb323159 A |
186 | /*! |
187 | * There is unfortunately no good way in plain C to have both fixed-type enums | |
188 | * and enforcement for clang's enum_extensibility extensions. The primary goal | |
189 | * of these macros is to allow you to define an enum and specify its width in a | |
190 | * single statement, and for plain C that is accomplished by defining an | |
191 | * anonymous enum and then separately typedef'ing the requested type name to the | |
192 | * requested underlying integer type. So the type emitted actually has no | |
193 | * relationship at all to the enum, and therefore while the compiler could | |
194 | * enforce enum extensibility if you used the enum type, it cannot do so if you | |
195 | * use the "_t" type resulting from this expression. | |
196 | * | |
197 | * But we still define a named enum type and decorate it appropriately for you, | |
198 | * so if you really want the enum extensibility enforcement, you can use the | |
199 | * enum type yourself, i.e. when compiling with a C compiler: | |
200 | * | |
201 | * OS_CLOSED_ENUM(my_type, uint64_t, | |
202 | * FOO, | |
203 | * BAR, | |
204 | * BAZ, | |
205 | * ); | |
206 | * | |
207 | * my_type_t mt = 98; // legal | |
208 | * enum my_type emt = 98; // illegal | |
209 | * | |
210 | * But be aware that the underlying enum type's width is subject only to the C | |
211 | * language's guarantees -- namely that it will be compatible with int, char, | |
212 | * and unsigned char. It is not safe to rely on the size of this type. | |
213 | * | |
214 | * When compiling in ObjC or C++, both of the above assignments are illegal. | |
215 | */ | |
216 | #define __OS_ENUM_C_FALLBACK(_name, _type, ...) \ | |
217 | typedef _type _name##_t; enum _name { __VA_ARGS__ } | |
218 | ||
39037602 | 219 | #define OS_ENUM(_name, _type, ...) \ |
cb323159 A |
220 | typedef _type _name##_t; enum { __VA_ARGS__ } |
221 | #define OS_CLOSED_ENUM(_name, _type, ...) \ | |
222 | __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ | |
223 | __OS_ENUM_ATTR_CLOSED | |
224 | #define OS_OPTIONS(_name, _type, ...) \ | |
225 | __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ | |
226 | __OS_ENUM_ATTR __OS_OPTIONS_ATTR | |
227 | #define OS_CLOSED_OPTIONS(_name, _type, ...) \ | |
228 | __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \ | |
229 | __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR | |
230 | #endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) | |
39037602 A |
231 | |
232 | #if __has_feature(attribute_availability_swift) | |
233 | // equivalent to __SWIFT_UNAVAILABLE from Availability.h | |
234 | #define OS_SWIFT_UNAVAILABLE(_msg) \ | |
0a7de745 | 235 | __attribute__((__availability__(swift, unavailable, message=_msg))) |
39037602 A |
236 | #else |
237 | #define OS_SWIFT_UNAVAILABLE(_msg) | |
238 | #endif | |
239 | ||
240 | #if __has_attribute(swift_private) | |
241 | # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) | |
242 | #else | |
243 | # define OS_REFINED_FOR_SWIFT | |
244 | #endif | |
245 | ||
246 | #if __has_attribute(swift_name) | |
247 | # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) | |
248 | #else | |
249 | # define OS_SWIFT_NAME(_name) | |
250 | #endif | |
251 | ||
252 | #define __OS_STRINGIFY(s) #s | |
253 | #define OS_STRINGIFY(s) __OS_STRINGIFY(s) | |
254 | #define __OS_CONCAT(x, y) x ## y | |
255 | #define OS_CONCAT(x, y) __OS_CONCAT(x, y) | |
256 | ||
257 | #ifdef __GNUC__ | |
258 | #define os_prevent_tail_call_optimization() __asm__("") | |
259 | #define os_is_compile_time_constant(expr) __builtin_constant_p(expr) | |
cb323159 | 260 | #ifndef KERNEL |
39037602 | 261 | #define os_compiler_barrier() __asm__ __volatile__("" ::: "memory") |
cb323159 | 262 | #endif |
39037602 A |
263 | #else |
264 | #define os_prevent_tail_call_optimization() do { } while (0) | |
265 | #define os_is_compile_time_constant(expr) 0 | |
cb323159 | 266 | #ifndef KERNEL |
39037602 A |
267 | #define os_compiler_barrier() do { } while (0) |
268 | #endif | |
cb323159 | 269 | #endif |
39037602 A |
270 | |
271 | #if __has_attribute(not_tail_called) | |
272 | #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) | |
273 | #else | |
274 | #define OS_NOT_TAIL_CALLED | |
275 | #endif | |
276 | ||
cb323159 A |
277 | /* |
278 | * LIBKERN_ALWAYS_DESTROY attribute can be applied to global variables with | |
279 | * destructors. It specifies that and object should have its exit-time | |
280 | * destructor run. This attribute is the default unless clang was invoked with | |
281 | * -fno-c++-static-destructors. | |
282 | */ | |
283 | #if __has_attribute(always_destroy) | |
284 | #define LIBKERN_ALWAYS_DESTROY __attribute__((always_destroy)) | |
285 | #else | |
286 | #define LIBKERN_ALWAYS_DESTROY | |
287 | #endif | |
288 | ||
39037602 A |
289 | typedef void (*os_function_t)(void *_Nullable); |
290 | ||
291 | #ifdef __BLOCKS__ | |
292 | /*! | |
293 | * @typedef os_block_t | |
294 | * | |
295 | * @abstract | |
296 | * Generic type for a block taking no arguments and returning no value. | |
297 | * | |
298 | * @discussion | |
299 | * When not building with Objective-C ARC, a block object allocated on or | |
300 | * copied to the heap must be released with a -[release] message or the | |
301 | * Block_release() function. | |
302 | * | |
303 | * The declaration of a block literal allocates storage on the stack. | |
304 | * Therefore, this is an invalid construct: | |
305 | * <code> | |
306 | * os_block_t block; | |
307 | * if (x) { | |
308 | * block = ^{ printf("true\n"); }; | |
309 | * } else { | |
310 | * block = ^{ printf("false\n"); }; | |
311 | * } | |
312 | * block(); // unsafe!!! | |
313 | * </code> | |
314 | * | |
315 | * What is happening behind the scenes: | |
316 | * <code> | |
317 | * if (x) { | |
318 | * struct Block __tmp_1 = ...; // setup details | |
319 | * block = &__tmp_1; | |
320 | * } else { | |
321 | * struct Block __tmp_2 = ...; // setup details | |
322 | * block = &__tmp_2; | |
323 | * } | |
324 | * </code> | |
325 | * | |
326 | * As the example demonstrates, the address of a stack variable is escaping the | |
327 | * scope in which it is allocated. That is a classic C bug. | |
328 | * | |
329 | * Instead, the block literal must be copied to the heap with the Block_copy() | |
330 | * function or by sending it a -[copy] message. | |
331 | */ | |
332 | typedef void (^os_block_t)(void); | |
333 | #endif | |
334 | ||
335 | #endif // __OS_BASE__ |