1 | /* |
2 | * Copyright (c) 2008-2016 Apple Inc. All rights reserved. |
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)))) |
76 | #define OS_FORMAT_PRINTF(x,y) __attribute__((__format__(printf,x,y))) |
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) |
113 | #define OS_FORMAT_PRINTF(x,y) |
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 | |
125 | #if __has_feature(assume_nonnull) |
126 | #define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") |
127 | #define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") |
128 | #else |
129 | #define OS_ASSUME_NONNULL_BEGIN |
130 | #define OS_ASSUME_NONNULL_END |
131 | #endif |
132 | |
133 | #if __has_builtin(__builtin_assume) |
134 | #define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr) |
135 | #else |
136 | #define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr)) |
137 | #endif |
138 | |
139 | #if __has_extension(attribute_overloadable) |
140 | #define OS_OVERLOADABLE __attribute__((__overloadable__)) |
141 | #else |
142 | #define OS_OVERLOADABLE |
143 | #endif |
144 | |
145 | #if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) |
146 | #define OS_ENUM(_name, _type, ...) \ |
147 | typedef enum : _type { __VA_ARGS__ } _name##_t |
148 | #else |
149 | #define OS_ENUM(_name, _type, ...) \ |
150 | enum { __VA_ARGS__ }; typedef _type _name##_t |
151 | #endif |
152 | |
153 | #if __has_feature(attribute_availability_swift) |
154 | // equivalent to __SWIFT_UNAVAILABLE from Availability.h |
155 | #define OS_SWIFT_UNAVAILABLE(_msg) \ |
156 | __attribute__((__availability__(swift, unavailable, message=_msg))) |
157 | #else |
158 | #define OS_SWIFT_UNAVAILABLE(_msg) |
159 | #endif |
160 | |
161 | #if __has_attribute(swift_private) |
162 | # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) |
163 | #else |
164 | # define OS_REFINED_FOR_SWIFT |
165 | #endif |
166 | |
167 | #if __has_attribute(swift_name) |
168 | # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) |
169 | #else |
170 | # define OS_SWIFT_NAME(_name) |
171 | #endif |
172 | |
173 | #define __OS_STRINGIFY(s) #s |
174 | #define OS_STRINGIFY(s) __OS_STRINGIFY(s) |
175 | #define __OS_CONCAT(x, y) x ## y |
176 | #define OS_CONCAT(x, y) __OS_CONCAT(x, y) |
177 | |
178 | #ifdef __GNUC__ |
179 | #define os_prevent_tail_call_optimization() __asm__("") |
180 | #define os_is_compile_time_constant(expr) __builtin_constant_p(expr) |
181 | #define os_compiler_barrier() __asm__ __volatile__("" ::: "memory") |
182 | #else |
183 | #define os_prevent_tail_call_optimization() do { } while (0) |
184 | #define os_is_compile_time_constant(expr) 0 |
185 | #define os_compiler_barrier() do { } while (0) |
186 | #endif |
187 | |
188 | #if __has_attribute(not_tail_called) |
189 | #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) |
190 | #else |
191 | #define OS_NOT_TAIL_CALLED |
192 | #endif |
193 | |
194 | typedef void (*os_function_t)(void *_Nullable); |
195 | |
196 | #ifdef __BLOCKS__ |
197 | /*! |
198 | * @typedef os_block_t |
199 | * |
200 | * @abstract |
201 | * Generic type for a block taking no arguments and returning no value. |
202 | * |
203 | * @discussion |
204 | * When not building with Objective-C ARC, a block object allocated on or |
205 | * copied to the heap must be released with a -[release] message or the |
206 | * Block_release() function. |
207 | * |
208 | * The declaration of a block literal allocates storage on the stack. |
209 | * Therefore, this is an invalid construct: |
210 | * <code> |
211 | * os_block_t block; |
212 | * if (x) { |
213 | * block = ^{ printf("true\n"); }; |
214 | * } else { |
215 | * block = ^{ printf("false\n"); }; |
216 | * } |
217 | * block(); // unsafe!!! |
218 | * </code> |
219 | * |
220 | * What is happening behind the scenes: |
221 | * <code> |
222 | * if (x) { |
223 | * struct Block __tmp_1 = ...; // setup details |
224 | * block = &__tmp_1; |
225 | * } else { |
226 | * struct Block __tmp_2 = ...; // setup details |
227 | * block = &__tmp_2; |
228 | * } |
229 | * </code> |
230 | * |
231 | * As the example demonstrates, the address of a stack variable is escaping the |
232 | * scope in which it is allocated. That is a classic C bug. |
233 | * |
234 | * Instead, the block literal must be copied to the heap with the Block_copy() |
235 | * function or by sending it a -[copy] message. |
236 | */ |
237 | typedef void (^os_block_t)(void); |
238 | #endif |
239 | |
240 | #endif // __OS_BASE__ |
241 | |