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