master
1/*
2 * Copyright (c) 2011-2014 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_OBJECT__
22#define __OS_OBJECT__
23
24#ifdef __APPLE__
25#include <Availability.h>
26#include <os/availability.h>
27#include <TargetConditionals.h>
28#include <os/base.h>
29#elif defined(_WIN32)
30#include <os/generic_win_base.h>
31#elif defined(__unix__)
32#include <os/generic_unix_base.h>
33#endif
34
35/*!
36 * @header
37 *
38 * @preprocinfo
39 * By default, libSystem objects such as GCD and XPC objects are declared as
40 * Objective-C types when building with an Objective-C compiler. This allows
41 * them to participate in ARC, in RR management by the Blocks runtime and in
42 * leaks checking by the static analyzer, and enables them to be added to Cocoa
43 * collections.
44 *
45 * NOTE: this requires explicit cancellation of dispatch sources and xpc
46 * connections whose handler blocks capture the source/connection object,
47 * resp. ensuring that such captures do not form retain cycles (e.g. by
48 * declaring the source as __weak).
49 *
50 * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
51 * compiler flags.
52 *
53 * This mode requires a platform with the modern Objective-C runtime, the
54 * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
55 * or iOS 6.0 deployment target.
56 */
57
58#define OS_OBJECT_ASSUME_ABI_SINGLE_BEGIN OS_ASSUME_PTR_ABI_SINGLE_BEGIN
59#define OS_OBJECT_ASSUME_ABI_SINGLE_END OS_ASSUME_PTR_ABI_SINGLE_END
60
61#ifndef OS_OBJECT_HAVE_OBJC_SUPPORT
62#if !defined(__OBJC__) || defined(__OBJC_GC__)
63# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
64#elif !defined(TARGET_OS_MAC) || !TARGET_OS_MAC
65# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
66#elif TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
67# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
68#elif TARGET_OS_MAC && !TARGET_OS_IPHONE
69# if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
70# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
71# elif defined(__i386__) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12
72# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
73# else
74# define OS_OBJECT_HAVE_OBJC_SUPPORT 1
75# endif
76#else
77# define OS_OBJECT_HAVE_OBJC_SUPPORT 1
78#endif
79#endif // OS_OBJECT_HAVE_OBJC_SUPPORT
80
81#if OS_OBJECT_HAVE_OBJC_SUPPORT
82#if defined(__swift__) && __swift__ && !OS_OBJECT_USE_OBJC
83#define OS_OBJECT_USE_OBJC 1
84#endif
85#ifndef OS_OBJECT_USE_OBJC
86#define OS_OBJECT_USE_OBJC 1
87#endif
88#elif defined(OS_OBJECT_USE_OBJC) && OS_OBJECT_USE_OBJC
89/* Unsupported platform for OS_OBJECT_USE_OBJC=1 */
90#undef OS_OBJECT_USE_OBJC
91#define OS_OBJECT_USE_OBJC 0
92#else
93#define OS_OBJECT_USE_OBJC 0
94#endif
95
96#ifndef OS_OBJECT_SWIFT3
97#ifdef __swift__
98#define OS_OBJECT_SWIFT3 1
99#else // __swift__
100#define OS_OBJECT_SWIFT3 0
101#endif // __swift__
102#endif // OS_OBJECT_SWIFT3
103
104#if __has_feature(assume_nonnull)
105#define OS_OBJECT_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
106#define OS_OBJECT_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
107#else
108#define OS_OBJECT_ASSUME_NONNULL_BEGIN
109#define OS_OBJECT_ASSUME_NONNULL_END
110#endif
111#define OS_OBJECT_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
112
113#if OS_OBJECT_USE_OBJC
114#import <objc/NSObject.h>
115#if __has_attribute(objc_independent_class)
116#define OS_OBJC_INDEPENDENT_CLASS __attribute__((objc_independent_class))
117#endif // __has_attribute(objc_independent_class)
118#ifndef OS_OBJC_INDEPENDENT_CLASS
119#define OS_OBJC_INDEPENDENT_CLASS
120#endif
121#define OS_OBJECT_CLASS(name) OS_##name
122#define OS_OBJECT_DECL_PROTOCOL(name, ...) \
123 @protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \
124 @end
125#define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL(name, proto) \
126 @interface name () <proto> \
127 @end
128#define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, proto) \
129 OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL( \
130 OS_OBJECT_CLASS(name), OS_OBJECT_CLASS(proto))
131#define OS_OBJECT_DECL_IMPL(name, adhere, ...) \
132 OS_OBJECT_DECL_PROTOCOL(name, __VA_ARGS__) \
133 typedef adhere<OS_OBJECT_CLASS(name)> \
134 * OS_OBJC_INDEPENDENT_CLASS name##_t
135#define OS_OBJECT_DECL_BASE(name, ...) \
136 @interface OS_OBJECT_CLASS(name) : __VA_ARGS__ \
137 - (instancetype)init OS_SWIFT_UNAVAILABLE("Unavailable in Swift"); \
138 @end
139#define OS_OBJECT_DECL_IMPL_CLASS(name, ...) \
140 OS_OBJECT_DECL_BASE(name, ## __VA_ARGS__) \
141 typedef OS_OBJECT_CLASS(name) \
142 * OS_OBJC_INDEPENDENT_CLASS name##_t
143#define OS_OBJECT_DECL(name, ...) \
144 OS_OBJECT_DECL_IMPL(name, NSObject, <NSObject>)
145#define OS_OBJECT_DECL_SUBCLASS(name, super) \
146 OS_OBJECT_DECL_IMPL(name, NSObject, <OS_OBJECT_CLASS(super)>)
147#if __has_attribute(ns_returns_retained)
148#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
149#else
150#define OS_OBJECT_RETURNS_RETAINED
151#endif
152#if __has_attribute(ns_consumed)
153#define OS_OBJECT_CONSUMED __attribute__((__ns_consumed__))
154#else
155#define OS_OBJECT_CONSUMED
156#endif
157#if __has_feature(objc_arc)
158#define OS_OBJECT_BRIDGE __bridge
159#define OS_WARN_RESULT_NEEDS_RELEASE
160#else
161#define OS_OBJECT_BRIDGE
162#define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
163#endif
164
165
166#if __has_attribute(objc_runtime_visible) && \
167 ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
168 __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12) || \
169 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
170 !defined(__TV_OS_VERSION_MIN_REQUIRED) && \
171 !defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
172 __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0) || \
173 (defined(__TV_OS_VERSION_MIN_REQUIRED) && \
174 __TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0) || \
175 (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
176 __WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0))
177/*
178 * To provide backward deployment of ObjC objects in Swift on pre-10.12
179 * SDKs, OS_object classes can be marked as OS_OBJECT_OBJC_RUNTIME_VISIBLE.
180 * When compiling with a deployment target earlier than OS X 10.12 (iOS 10.0,
181 * tvOS 10.0, watchOS 3.0) the Swift compiler will only refer to this type at
182 * runtime (using the ObjC runtime).
183 */
184#define OS_OBJECT_OBJC_RUNTIME_VISIBLE __attribute__((objc_runtime_visible))
185#else
186#define OS_OBJECT_OBJC_RUNTIME_VISIBLE
187#endif
188#ifndef OS_OBJECT_USE_OBJC_RETAIN_RELEASE
189#if defined(__clang_analyzer__)
190#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
191#elif __has_feature(objc_arc) && !OS_OBJECT_SWIFT3
192#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
193#else
194#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
195#endif
196#endif
197
198#if __has_attribute(__swift_attr__)
199#define OS_OBJECT_SWIFT_SENDABLE __attribute__((swift_attr("@Sendable")))
200#define OS_OBJECT_SWIFT_HAS_MISSING_DESIGNATED_INIT \
201 __attribute__((swift_attr("@_hasMissingDesignatedInitializers")))
202#else
203#define OS_OBJECT_SWIFT_SENDABLE
204#define OS_OBJECT_SWIFT_HAS_MISSING_DESIGNATED_INIT
205#endif // __has_attribute(__swift_attr__)
206
207#if OS_OBJECT_SWIFT3
208#define OS_OBJECT_DECL_SWIFT(name) \
209 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
210 OS_OBJECT_DECL_IMPL_CLASS(name, NSObject)
211#define OS_OBJECT_DECL_SENDABLE_SWIFT(name) \
212 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE OS_OBJECT_SWIFT_SENDABLE \
213 OS_OBJECT_DECL_IMPL_CLASS(name, NSObject)
214#define OS_OBJECT_DECL_SUBCLASS_SWIFT(name, super) \
215 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
216 OS_OBJECT_DECL_IMPL_CLASS(name, OS_OBJECT_CLASS(super))
217#define OS_OBJECT_DECL_SENDABLE_SUBCLASS_SWIFT(name, super) \
218 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE OS_OBJECT_SWIFT_SENDABLE \
219 OS_OBJECT_DECL_IMPL_CLASS(name, OS_OBJECT_CLASS(super))
220#endif // OS_OBJECT_SWIFT3
221OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE
222OS_OBJECT_DECL_BASE(object, NSObject);
223#else
224/*! @parseOnly */
225#define OS_OBJECT_RETURNS_RETAINED
226/*! @parseOnly */
227#define OS_OBJECT_CONSUMED
228/*! @parseOnly */
229#define OS_OBJECT_BRIDGE
230/*! @parseOnly */
231#define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
232/*! @parseOnly */
233#define OS_OBJECT_OBJC_RUNTIME_VISIBLE
234#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
235#endif
236
237#if OS_OBJECT_SWIFT3
238#define OS_OBJECT_DECL_CLASS(name) \
239 OS_OBJECT_DECL_SUBCLASS_SWIFT(name, object)
240#define OS_OBJECT_DECL_SENDABLE_CLASS(name) \
241 OS_OBJECT_DECL_SENDABLE_SUBCLASS_SWIFT(name, object)
242#elif OS_OBJECT_USE_OBJC
243#define OS_OBJECT_DECL_CLASS(name) \
244 OS_OBJECT_DECL(name)
245#define OS_OBJECT_DECL_SENDABLE_CLASS(name) \
246 OS_OBJECT_DECL(name)
247#else
248#define OS_OBJECT_DECL_CLASS(name) \
249 typedef struct name##_s *name##_t
250#define OS_OBJECT_DECL_SENDABLE_CLASS(name) \
251 typedef struct name##_s *name##_t
252#endif
253
254#if OS_OBJECT_USE_OBJC
255/* Declares a class of the specific name and exposes the interface and typedefs
256 * name##_t to the pointer to the class */
257#define OS_OBJECT_SHOW_CLASS(name, ...) \
258 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
259 OS_OBJECT_DECL_IMPL_CLASS(name, ## __VA_ARGS__ )
260/* Declares a subclass of the same name, and
261 * subclass adheres to protocol specified. Typedefs baseclass<proto> * to subclass##_t */
262#define OS_OBJECT_SHOW_SUBCLASS(subclass_name, super, proto_name) \
263 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
264 OS_OBJECT_DECL_BASE(subclass_name, OS_OBJECT_CLASS(super)<OS_OBJECT_CLASS(proto_name)>); \
265 typedef OS_OBJECT_CLASS(super)<OS_OBJECT_CLASS(proto_name)> \
266 * OS_OBJC_INDEPENDENT_CLASS subclass_name##_t
267#else /* Plain C */
268#define OS_OBJECT_DECL_PROTOCOL(name, ...)
269#define OS_OBJECT_SHOW_CLASS(name, ...) \
270 typedef struct name##_s *name##_t
271#define OS_OBJECT_SHOW_SUBCLASS(name, super, ...) \
272 typedef super##_t name##_t
273#endif
274
275#define OS_OBJECT_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
276
277__BEGIN_DECLS
278OS_OBJECT_ASSUME_ABI_SINGLE_BEGIN
279
280/*!
281 * @function os_retain
282 *
283 * @abstract
284 * Increment the reference count of an os_object.
285 *
286 * @discussion
287 * On a platform with the modern Objective-C runtime this is exactly equivalent
288 * to sending the object the -[retain] message.
289 *
290 * @param object
291 * The object to retain.
292 *
293 * @result
294 * The retained object.
295 */
296API_AVAILABLE(macos(10.10), ios(8.0))
297OS_EXPORT OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
298void*
299os_retain(void *object);
300#if OS_OBJECT_USE_OBJC
301#undef os_retain
302#define os_retain(object) [object retain]
303#endif
304
305/*!
306 * @function os_release
307 *
308 * @abstract
309 * Decrement the reference count of a os_object.
310 *
311 * @discussion
312 * On a platform with the modern Objective-C runtime this is exactly equivalent
313 * to sending the object the -[release] message.
314 *
315 * @param object
316 * The object to release.
317 */
318API_AVAILABLE(macos(10.10), ios(8.0))
319OS_EXPORT
320void OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
321os_release(void *object);
322#if OS_OBJECT_USE_OBJC
323#undef os_release
324#define os_release(object) [object release]
325#endif
326
327OS_OBJECT_ASSUME_ABI_SINGLE_END
328__END_DECLS
329
330#endif