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 #ifndef OS_OBJECT_HAVE_OBJC_SUPPORT
59 #if !defined(__OBJC__) || defined(__OBJC_GC__)
60 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 0
61 #elif !defined(TARGET_OS_MAC) || !TARGET_OS_MAC
62 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 0
63 #elif TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
64 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 0
65 #elif TARGET_OS_MAC && !TARGET_OS_IPHONE
66 #  if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
67 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 0
68 #  elif defined(__i386__) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12
69 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 0
70 #  else
71 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 1
72 #  endif
73 #else
74 #  define OS_OBJECT_HAVE_OBJC_SUPPORT 1
75 #endif
76 #endif // OS_OBJECT_HAVE_OBJC_SUPPORT
77 
78 #if OS_OBJECT_HAVE_OBJC_SUPPORT
79 #if defined(__swift__) && __swift__ && !OS_OBJECT_USE_OBJC
80 #define OS_OBJECT_USE_OBJC 1
81 #endif
82 #ifndef OS_OBJECT_USE_OBJC
83 #define OS_OBJECT_USE_OBJC 1
84 #endif
85 #elif defined(OS_OBJECT_USE_OBJC) && OS_OBJECT_USE_OBJC
86 /* Unsupported platform for OS_OBJECT_USE_OBJC=1 */
87 #undef OS_OBJECT_USE_OBJC
88 #define OS_OBJECT_USE_OBJC 0
89 #else
90 #define OS_OBJECT_USE_OBJC 0
91 #endif
92 
93 #ifndef OS_OBJECT_SWIFT3
94 #ifdef __swift__
95 #define OS_OBJECT_SWIFT3 1
96 #else // __swift__
97 #define OS_OBJECT_SWIFT3 0
98 #endif // __swift__
99 #endif // OS_OBJECT_SWIFT3
100 
101 #if OS_OBJECT_USE_OBJC
102 #import <objc/NSObject.h>
103 #if __has_attribute(objc_independent_class)
104 #define OS_OBJC_INDEPENDENT_CLASS __attribute__((objc_independent_class))
105 #endif // __has_attribute(objc_independent_class)
106 #ifndef OS_OBJC_INDEPENDENT_CLASS
107 #define OS_OBJC_INDEPENDENT_CLASS
108 #endif
109 #define OS_OBJECT_CLASS(name) OS_##name
110 #define OS_OBJECT_DECL_PROTOCOL(name, ...) \
111 		@protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \
112 		@end
113 #define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL(name, proto) \
114 		@interface name () <proto> \
115 		@end
116 #define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, proto) \
117 		OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL( \
118 				OS_OBJECT_CLASS(name), OS_OBJECT_CLASS(proto))
119 #define OS_OBJECT_DECL_IMPL(name, ...) \
120 		OS_OBJECT_DECL_PROTOCOL(name, __VA_ARGS__) \
121 		typedef NSObject<OS_OBJECT_CLASS(name)> \
122 				* OS_OBJC_INDEPENDENT_CLASS name##_t
123 #define OS_OBJECT_DECL_BASE(name, ...) \
124 		@interface OS_OBJECT_CLASS(name) : __VA_ARGS__ \
125 		- (instancetype)init OS_SWIFT_UNAVAILABLE("Unavailable in Swift"); \
126 		@end
127 #define OS_OBJECT_DECL_IMPL_CLASS(name, ...) \
128 		OS_OBJECT_DECL_BASE(name, ## __VA_ARGS__) \
129 		typedef OS_OBJECT_CLASS(name) \
130 				* OS_OBJC_INDEPENDENT_CLASS name##_t
131 #define OS_OBJECT_DECL(name, ...) \
132 		OS_OBJECT_DECL_IMPL(name, <NSObject>)
133 #define OS_OBJECT_DECL_SUBCLASS(name, super) \
134 		OS_OBJECT_DECL_IMPL(name, <OS_OBJECT_CLASS(super)>)
135 #if __has_attribute(ns_returns_retained)
136 #define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
137 #else
138 #define OS_OBJECT_RETURNS_RETAINED
139 #endif
140 #if __has_attribute(ns_consumed)
141 #define OS_OBJECT_CONSUMED __attribute__((__ns_consumed__))
142 #else
143 #define OS_OBJECT_CONSUMED
144 #endif
145 #if __has_feature(objc_arc)
146 #define OS_OBJECT_BRIDGE __bridge
147 #define OS_WARN_RESULT_NEEDS_RELEASE
148 #else
149 #define OS_OBJECT_BRIDGE
150 #define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
151 #endif
152 #if __has_attribute(objc_runtime_visible) && \
153 		((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
154 		__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12) || \
155 		(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
156 		!defined(__TV_OS_VERSION_MIN_REQUIRED) && \
157 		!defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
158 		__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0) || \
159 		(defined(__TV_OS_VERSION_MIN_REQUIRED) && \
160 		__TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0) || \
161 		(defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
162 		__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0))
163 /*
164  * To provide backward deployment of ObjC objects in Swift on pre-10.12
165  * SDKs, OS_object classes can be marked as OS_OBJECT_OBJC_RUNTIME_VISIBLE.
166  * When compiling with a deployment target earlier than OS X 10.12 (iOS 10.0,
167  * tvOS 10.0, watchOS 3.0) the Swift compiler will only refer to this type at
168  * runtime (using the ObjC runtime).
169  */
170 #define OS_OBJECT_OBJC_RUNTIME_VISIBLE __attribute__((objc_runtime_visible))
171 #else
172 #define OS_OBJECT_OBJC_RUNTIME_VISIBLE
173 #endif
174 #ifndef OS_OBJECT_USE_OBJC_RETAIN_RELEASE
175 #if defined(__clang_analyzer__)
176 #define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
177 #elif __has_feature(objc_arc) && !OS_OBJECT_SWIFT3
178 #define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
179 #else
180 #define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
181 #endif
182 #endif
183 #if OS_OBJECT_SWIFT3
184 #define OS_OBJECT_DECL_SWIFT(name) \
185 		OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
186 		OS_OBJECT_DECL_IMPL_CLASS(name, NSObject)
187 #define OS_OBJECT_DECL_SUBCLASS_SWIFT(name, super) \
188 		OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
189 		OS_OBJECT_DECL_IMPL_CLASS(name, OS_OBJECT_CLASS(super))
190 OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE
191 OS_OBJECT_DECL_BASE(object, NSObject);
192 #endif // OS_OBJECT_SWIFT3
193 #else
194 /*! @parseOnly */
195 #define OS_OBJECT_RETURNS_RETAINED
196 /*! @parseOnly */
197 #define OS_OBJECT_CONSUMED
198 /*! @parseOnly */
199 #define OS_OBJECT_BRIDGE
200 /*! @parseOnly */
201 #define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
202 /*! @parseOnly */
203 #define OS_OBJECT_OBJC_RUNTIME_VISIBLE
204 #define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
205 #endif
206 
207 #if OS_OBJECT_SWIFT3
208 #define OS_OBJECT_DECL_CLASS(name) \
209 		OS_OBJECT_DECL_SUBCLASS_SWIFT(name, object)
210 #elif OS_OBJECT_USE_OBJC
211 #define OS_OBJECT_DECL_CLASS(name) \
212 		OS_OBJECT_DECL(name)
213 #else
214 #define OS_OBJECT_DECL_CLASS(name) \
215 		typedef struct name##_s *name##_t
216 #endif
217 
218 #define OS_OBJECT_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
219 
220 __BEGIN_DECLS
221 
222 /*!
223  * @function os_retain
224  *
225  * @abstract
226  * Increment the reference count of an os_object.
227  *
228  * @discussion
229  * On a platform with the modern Objective-C runtime this is exactly equivalent
230  * to sending the object the -[retain] message.
231  *
232  * @param object
233  * The object to retain.
234  *
235  * @result
236  * The retained object.
237  */
238 API_AVAILABLE(macos(10.10), ios(8.0))
239 OS_EXPORT OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
240 void*
241 os_retain(void *object);
242 #if OS_OBJECT_USE_OBJC
243 #undef os_retain
244 #define os_retain(object) [object retain]
245 #endif
246 
247 /*!
248  * @function os_release
249  *
250  * @abstract
251  * Decrement the reference count of a os_object.
252  *
253  * @discussion
254  * On a platform with the modern Objective-C runtime this is exactly equivalent
255  * to sending the object the -[release] message.
256  *
257  * @param object
258  * The object to release.
259  */
260 API_AVAILABLE(macos(10.10), ios(8.0))
261 OS_EXPORT
262 void OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
263 os_release(void *object);
264 #if OS_OBJECT_USE_OBJC
265 #undef os_release
266 #define os_release(object) [object release]
267 #endif
268 
269 __END_DECLS
270 
271 #endif