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