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