xref: /xnu-11215.81.4/EXTERNAL_HEADERS/image4/shim/base.h (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452)
1 /*
2  * Copyright (c) 2008-2020 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 defined(__cplusplus) && defined(__clang__)
126 #define OS_FALLTHROUGH [[clang::fallthrough]]
127 #elif __has_attribute(fallthrough)
128 #define OS_FALLTHROUGH __attribute__((__fallthrough__))
129 #else
130 #define OS_FALLTHROUGH
131 #endif
132 
133 #if __has_feature(assume_nonnull)
134 #define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
135 #define OS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")
136 #else
137 #define OS_ASSUME_NONNULL_BEGIN
138 #define OS_ASSUME_NONNULL_END
139 #endif
140 
141 #if __has_builtin(__builtin_assume)
142 #define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
143 #else
144 #define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
145 #endif
146 
147 #if __has_extension(attribute_overloadable)
148 #define OS_OVERLOADABLE __attribute__((__overloadable__))
149 #else
150 #define OS_OVERLOADABLE
151 #endif
152 
153 #if __has_attribute(analyzer_suppress)
154 #define OS_ANALYZER_SUPPRESS(RADAR) __attribute__((analyzer_suppress))
155 #else
156 #define OS_ANALYZER_SUPPRESS(RADAR)
157 #endif
158 
159 #if __has_attribute(enum_extensibility)
160 #define __OS_ENUM_ATTR __attribute__((enum_extensibility(open)))
161 #define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed)))
162 #else
163 #define __OS_ENUM_ATTR
164 #define __OS_ENUM_ATTR_CLOSED
165 #endif // __has_attribute(enum_extensibility)
166 
167 #if __has_attribute(flag_enum)
168 /*!
169  * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and
170  * assignment, respectively, i.e. -Wflag-enum prevents you from creating new
171  * enumeration values from illegal values within the enum definition, and
172  * -Wassign-enum prevents you from assigning illegal values to a variable of the
173  * enum type.
174  */
175 #define __OS_OPTIONS_ATTR __attribute__((flag_enum))
176 #else
177 #define __OS_OPTIONS_ATTR
178 #endif // __has_attribute(flag_enum)
179 
180 #if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \
181 		__has_extension(cxx_strong_enums)
182 #define OS_ENUM(_name, _type, ...) \
183 	typedef enum : _type { __VA_ARGS__ } _name##_t
184 #define OS_CLOSED_ENUM(_name, _type, ...) \
185 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED _name##_t
186 #define OS_OPTIONS(_name, _type, ...) \
187 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t
188 #define OS_CLOSED_OPTIONS(_name, _type, ...) \
189 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t
190 #else
191 /*!
192  * There is unfortunately no good way in plain C to have both fixed-type enums
193  * and enforcement for clang's enum_extensibility extensions. The primary goal
194  * of these macros is to allow you to define an enum and specify its width in a
195  * single statement, and for plain C that is accomplished by defining an
196  * anonymous enum and then separately typedef'ing the requested type name to the
197  * requested underlying integer type. So the type emitted actually has no
198  * relationship at all to the enum, and therefore while the compiler could
199  * enforce enum extensibility if you used the enum type, it cannot do so if you
200  * use the "_t" type resulting from this expression.
201  *
202  * But we still define a named enum type and decorate it appropriately for you,
203  * so if you really want the enum extensibility enforcement, you can use the
204  * enum type yourself, i.e. when compiling with a C compiler:
205  *
206  *     OS_CLOSED_ENUM(my_type, uint64_t,
207  *         FOO,
208  *         BAR,
209  *         BAZ,
210  *     );
211  *
212  *     my_type_t mt = 98; // legal
213  *     enum my_type emt = 98; // illegal
214  *
215  * But be aware that the underlying enum type's width is subject only to the C
216  * language's guarantees -- namely that it will be compatible with int, char,
217  * and unsigned char. It is not safe to rely on the size of this type.
218  *
219  * When compiling in ObjC or C++, both of the above assignments are illegal.
220  */
221 #define __OS_ENUM_C_FALLBACK(_name, _type, ...) \
222 	typedef _type _name##_t; enum _name { __VA_ARGS__ }
223 
224 #define OS_ENUM(_name, _type, ...) \
225 	typedef _type _name##_t; enum { __VA_ARGS__ }
226 #define OS_CLOSED_ENUM(_name, _type, ...) \
227 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
228 	__OS_ENUM_ATTR_CLOSED
229 #define OS_OPTIONS(_name, _type, ...) \
230 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
231 	__OS_ENUM_ATTR __OS_OPTIONS_ATTR
232 #define OS_CLOSED_OPTIONS(_name, _type, ...) \
233 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
234 	__OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR
235 #endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
236 
237 #if __has_feature(attribute_availability_swift)
238 // equivalent to __SWIFT_UNAVAILABLE from Availability.h
239 #define OS_SWIFT_UNAVAILABLE(_msg) \
240 	__attribute__((__availability__(swift, unavailable, message=_msg)))
241 #else
242 #define OS_SWIFT_UNAVAILABLE(_msg)
243 #endif
244 
245 #if __has_attribute(__swift_attr__)
246 #define OS_SWIFT_UNAVAILABLE_FROM_ASYNC(msg) \
247 	__attribute__((__swift_attr__("@_unavailableFromAsync(message: \"" msg "\")")))
248 #else
249 #define OS_SWIFT_UNAVAILABLE_FROM_ASYNC(msg)
250 #endif
251 
252 #if __has_attribute(swift_private)
253 # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__))
254 #else
255 # define OS_REFINED_FOR_SWIFT
256 #endif
257 
258 #if __has_attribute(swift_name)
259 # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name)))
260 #else
261 # define OS_SWIFT_NAME(_name)
262 #endif
263 
264 #define __OS_STRINGIFY(s) #s
265 #define OS_STRINGIFY(s) __OS_STRINGIFY(s)
266 #define __OS_CONCAT(x, y) x ## y
267 #define OS_CONCAT(x, y) __OS_CONCAT(x, y)
268 
269 #ifdef __GNUC__
270 #define os_prevent_tail_call_optimization()  __asm__("")
271 #define os_is_compile_time_constant(expr)    __builtin_constant_p(expr)
272 #define os_compiler_barrier()                __asm__ __volatile__("" ::: "memory")
273 #else
274 #define os_prevent_tail_call_optimization()  do { } while (0)
275 #define os_is_compile_time_constant(expr)    0
276 #define os_compiler_barrier()                do { } while (0)
277 #endif
278 
279 #if __has_attribute(not_tail_called)
280 #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__))
281 #else
282 #define OS_NOT_TAIL_CALLED
283 #endif
284 
285 
286 typedef void (*os_function_t)(void *_Nullable);
287 
288 #ifdef __BLOCKS__
289 /*!
290  * @typedef os_block_t
291  *
292  * @abstract
293  * Generic type for a block taking no arguments and returning no value.
294  *
295  * @discussion
296  * When not building with Objective-C ARC, a block object allocated on or
297  * copied to the heap must be released with a -[release] message or the
298  * Block_release() function.
299  *
300  * The declaration of a block literal allocates storage on the stack.
301  * Therefore, this is an invalid construct:
302  * <code>
303  * os_block_t block;
304  * if (x) {
305  *     block = ^{ printf("true\n"); };
306  * } else {
307  *     block = ^{ printf("false\n"); };
308  * }
309  * block(); // unsafe!!!
310  * </code>
311  *
312  * What is happening behind the scenes:
313  * <code>
314  * if (x) {
315  *     struct Block __tmp_1 = ...; // setup details
316  *     block = &__tmp_1;
317  * } else {
318  *     struct Block __tmp_2 = ...; // setup details
319  *     block = &__tmp_2;
320  * }
321  * </code>
322  *
323  * As the example demonstrates, the address of a stack variable is escaping the
324  * scope in which it is allocated. That is a classic C bug.
325  *
326  * Instead, the block literal must be copied to the heap with the Block_copy()
327  * function or by sending it a -[copy] message.
328  */
329 typedef void (^os_block_t)(void);
330 #endif
331 
332 
333 
334 #define OS_ASSUME_PTR_ABI_SINGLE_BEGIN __ASSUME_PTR_ABI_SINGLE_BEGIN
335 #define OS_ASSUME_PTR_ABI_SINGLE_END __ASSUME_PTR_ABI_SINGLE_END
336 #define OS_UNSAFE_INDEXABLE __unsafe_indexable
337 #define OS_HEADER_INDEXABLE __header_indexable
338 #define OS_COUNTED_BY(N) __counted_by(N)
339 #define OS_SIZED_BY(N) __sized_by(N)
340 
341 #endif // __OS_BASE__
342