zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

base.h (11490B) - Raw


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