1 /* GSVersionMacros.h - macros for managing API versioning and visibility
2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
3
4 Written by: Richard Frith-Macdonald <rfm@gnu.org>
5 Date: Oct, October 2006
6
7 This file is part of GNUstep.
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free
21 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23 */
24
25 #ifndef __GNUSTEP_GSVERSIONMACROS_H_INCLUDED_
26 #define __GNUSTEP_GSVERSIONMACROS_H_INCLUDED_
27
28 /* By default we defined NO_GNUSTEP to 0 so that we will include extensions.
29 */
30 #if !defined(NO_GNUSTEP)
31 # define NO_GNUSTEP 0
32 #endif
33
34 /* Check consistency of definitions for system compatibility.
35 */
36 #if defined(STRICT_OPENSTEP)
37 # define GS_OPENSTEP_V 10000
38 # undef NO_GNUSTEP
39 # define NO_GNUSTEP 1
40 #elif defined(STRICT_MACOS_X)
41 # define GS_OPENSTEP_V 100600
42 # undef NO_GNUSTEP
43 # define NO_GNUSTEP 1
44 #endif
45
46 /* Define the GS_OSX_ADJUST() macro to adjust OSX style version macros
47 * to GNUstep style version macros.
48 */
49 #define GS_OSX_ADJUST(V) ((V) >= 10000 ? (V) : ((V)/100*10000 + (V)%100*10))
50
51 /* Define OSX compatibility version macros if necessary.
52 */
53 #if !defined(MAC_OS_X_VERSION_10_0)
54 #define MAC_OS_X_VERSION_10_0 1000
55 #define MAC_OS_X_VERSION_10_1 1010
56 #define MAC_OS_X_VERSION_10_2 1020
57 #define MAC_OS_X_VERSION_10_3 1030
58 #define MAC_OS_X_VERSION_10_4 1040
59 #define MAC_OS_X_VERSION_10_5 1050
60 #define MAC_OS_X_VERSION_10_6 1060
61 #define MAC_OS_X_VERSION_10_7 1070
62 #define MAC_OS_X_VERSION_10_8 1080
63 #define MAC_OS_X_VERSION_10_9 1090
64 #define MAC_OS_X_VERSION_10_10 1100
65 #define MAC_OS_X_VERSION_10_11 1110
66 #define MAC_OS_X_VERSION_10_12 1120
67 #define MAC_OS_X_VERSION_10_13 1130
68 #define MAC_OS_X_VERSION_10_14 1140
69 #endif /* MAC_OS_X_VERSION_10_0 */
70
71 /* Allow MAC_OS_X_VERSION_MAX_ALLOWED to be used in place of GS_OPENSTEP_V
72 * if GS_OPENSTEP_V is not defined.
73 */
74 #ifndef GS_OPENSTEP_V
75 #ifdef MAC_OS_X_VERSION_MAX_ALLOWED
76 #define GS_OPENSTEP_V GS_OSX_ADJUST(MAC_OS_X_VERSION_MAX_ALLOWED)
77 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
78 #endif /* GS_OPENSTEP_V */
79
80 /*
81 * NB. The version values below must be integers ... by convention these are
82 * made up of two digits each for major, minor and subminor version numbers
83 * (ie each is in the range 00 to 99 though a leading zero in the major
84 * number is not permitted).
85 * So for a MacOS-X 10.3.9 release the version number would be 100309
86 *
87 * You may define GS_GNUSTEP_V or GS_OPENSTEP_V to ensure that your
88 * program only 'sees' the specified varsion of the API.
89 */
90
91 /**
92 * <p>Macro to check a defined GNUstep version number (GS_GNUSTEP_V) against
93 * the supplied arguments. Returns true if no GNUstep version is specified,
94 * or if ADD <= version < REM, where ADD is the version
95 * number at which a feature guarded by the macro was introduced and
96 * REM is the version number at which it was removed.
97 * </p>
98 * <p>The version number arguments are six digit integers where the first
99 * two digits are the major version number, the second two are the minor
100 * version number and the last two are the subminor number (all left padded
101 * with a zero where necessary). However, for convenience you can also
102 * use the predefined constants ...
103 * <ref type="macro" id="GS_API_NONE">GS_API_NONE</ref>,
104 * <ref type="macro" id="GS_API_LATEST">GS_API_LATEST</ref>,
105 * </p>
106 * <p>Also see <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
107 * </p>
108 * <p>NB. If you are changing the API (eg adding a new feature) you need
109 * to control the visibility io the new header file code using<br />
110 * <code>#if GS_API_VERSION(ADD,GS_API_LATEST)</code><br />
111 * where <code>ADD</code> is the version number of the next minor
112 * release after the most recent one.<br />
113 * As a general principle you should <em>not</em> change the API with
114 * changing subminor version numbers ... as that tends to confuse
115 * people (though Apple has sometimes done it).
116 * </p>
117 */
118 #define GS_API_VERSION(ADD,REM) \
119 (!defined(GS_GNUSTEP_V) || (GS_GNUSTEP_V >= ADD && GS_GNUSTEP_V < REM))
120
121 /**
122 * <p>Macro to check a defined OpenStep/OPENSTEP/MacOS-X version against the
123 * supplied arguments. Returns true if no version is specified, or if
124 * ADD <= version < REM, where ADD is the version
125 * number at which a feature guarded by the macro was introduced and
126 * REM is the version number at which it was removed.
127 * </p>
128 * <p>The version number arguments are six digit integers where the first
129 * two digits are the major version number, the second two are the minor
130 * version number and the last two are the subminor number (all left padded
131 * with a zero where necessary). However, for convenience you can also
132 * use any of several predefined constants ...
133 * <ref type="macro" id="GS_API_NONE">GS_API_NONE</ref>,
134 * <ref type="macro" id="GS_API_LATEST">GS_API_LATEST</ref>,
135 * <ref type="macro" id="GS_API_OSSPEC">GS_API_OSSPEC</ref>,
136 * <ref type="macro" id="GS_API_OPENSTEP">GS_API_OPENSTEP</ref>,
137 * <ref type="macro" id="GS_API_MACOSX">GS_API_MACOSX</ref>
138 * </p>
139 * <p>Also see <ref type="macro" id="GS_API_VERSION">GS_API_VERSION</ref>
140 * </p>
141 * <p>For OSX compatibility, this macro also supports the use of Apple's
142 * symbolic constants for version numbering. Their contants are currently
143 * four digit values (two digits for the major version, one for the minor,
144 * and one for the subminor).
145 * </p>
146 * <p>The Apple compatibility version macros are currently:
147 * <ref type="macro" id="MAC_OS_X_VERSION_10_0">MAC_OS_X_VERSION_10_0</ref>,
148 * <ref type="macro" id="MAC_OS_X_VERSION_10_1">MAC_OS_X_VERSION_10_1</ref>,
149 * <ref type="macro" id="MAC_OS_X_VERSION_10_2">MAC_OS_X_VERSION_10_2</ref>,
150 * <ref type="macro" id="MAC_OS_X_VERSION_10_3">MAC_OS_X_VERSION_10_3</ref>,
151 * <ref type="macro" id="MAC_OS_X_VERSION_10_4">MAC_OS_X_VERSION_10_4</ref>,
152 * <ref type="macro" id="MAC_OS_X_VERSION_10_5">MAC_OS_X_VERSION_10_5</ref>,
153 * <ref type="macro" id="MAC_OS_X_VERSION_10_6">MAC_OS_X_VERSION_10_6</ref>,
154 * <ref type="macro" id="MAC_OS_X_VERSION_10_7">MAC_OS_X_VERSION_10_7</ref>,
155 * <ref type="macro" id="MAC_OS_X_VERSION_10_8">MAC_OS_X_VERSION_10_8</ref>
156 * <ref type="macro" id="MAC_OS_X_VERSION_10_9">MAC_OS_X_VERSION_10_9</ref>
157 * </p>
158 */
159 #define OS_API_VERSION(ADD,REM) \
160 (!defined(GS_OPENSTEP_V) \
161 || (GS_OPENSTEP_V>=GS_OSX_ADJUST(ADD) && GS_OPENSTEP_V<GS_OSX_ADJUST(REM)))
162
163 /**
164 * A constant which is the lowest possible version number (0) so that
165 * when used as the removal version (second argument of the GS_API_VERSION
166 * or OS_API_VERSION macro) represents a feature which is not present in
167 * any version.<br />
168 * eg.<br />
169 * #if <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
170 * (GS_API_NONE, GS_API_NONE)<br />
171 * denotes code not present in OpenStep/OPENSTEP/MacOS-X
172 */
173 #define GS_API_NONE 0
174
175 /**
176 * A constant to represent a feature which is still present in the latest
177 * version. This is the highest possible version number.<br />
178 * eg.<br />
179 * #if <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
180 * (GS_API_MACOSX, GS_API_LATEST)<br />
181 * denotes code present from the initial MacOS-X version onwards.
182 */
183 #define GS_API_LATEST 999999
184
185 /**
186 * The version number of the initial OpenStep specification.<br />
187 * eg.<br />
188 * #if <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
189 * (GS_API_OSSPEC, GS_API_LATEST)<br />
190 * denotes code present from the OpenStep specification onwards.
191 */
192 #define GS_API_OSSPEC 10000
193
194 /**
195 * The version number of the first OPENSTEP implementation.<br />
196 * eg.<br />
197 * #if <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
198 * (GS_API_OPENSTEP, GS_API_LATEST)<br />
199 * denotes code present from the initial OPENSTEP version onwards.
200 */
201 #define GS_API_OPENSTEP 40000
202
203 /**
204 * The version number of the first MacOS-X implementation.<br />
205 * eg.<br />
206 * #if <ref type="macro" id="OS_API_VERSION">OS_API_VERSION</ref>
207 * (GS_API_MACOSX, GS_API_LATEST)<br />
208 * denotes code present from the initial MacOS-X version onwards.
209 */
210 #define GS_API_MACOSX 100000
211
212 /* Allow OSX code comparing MAC_OS_X_VERSION_MAX_ALLOWED with a specific
213 * version to see if that version is allowed, to always have it allowed
214 * on GNUstep.
215 */
216 #ifndef MAC_OS_X_VERSION_MAX_ALLOWED
217 #define MAC_OS_X_VERSION_MAX_ALLOWED GS_API_LATEST
218 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
219
220
221 #if defined(GNUSTEP_BASE_INTERNAL)
222 #include "GNUstepBase/GSConfig.h"
223 #else
224 #include "GSConfig.h"
225 #endif
226
227
228 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__clang__)
229 # define GS_GCC_MINREQ(maj, min) \
230 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
231 #else
232 # define GS_GCC_MINREQ(maj, min) 0
233 #endif
234
235 #if defined(__clang__)
236 # define GS_CLANG_MINREQ(maj, min) \
237 ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
238 #else
239 # define GS_CLANG_MINREQ(maj, min) 0
240 #endif
241
242 /* Attribute definitions for attributes which may or may not be supported
243 * depending on the compiler being used.
244 * NB we currently expect gcc to be version 4 or later.
245 *
246 * The definition should be of the form GS_XXX_CONTEXT where XXX is the
247 * name of the attribute and CONTEXT is one of FUNC, METH, or IVAR
248 * depending on where the attribute can be applied.
249 */
250
251 #if defined(__clang__) || GS_GCC_MINREQ(3,1)
252 # define GS_DEPRECATED_FUNC __attribute__ ((deprecated))
253 #else
254 # define GS_DEPRECATED_FUNC
255 #endif
256
257 #define GS_UNUSED_ARG __attribute__((unused))
258
259 #define GS_UNUSED_FUNC __attribute__((unused))
260
261 // FIXME ... what version of gcc?
262 #if __clang__
263 # define GS_UNUSED_IVAR __attribute__((unused))
264 #else
265 # define GS_UNUSED_IVAR
266 #endif
267
268
269
270 #ifndef __has_feature
271 #define __has_feature(x) 0
272 #endif
273
274 /* The following is for deciding whether private instance variables
275 * should be visible ... if we are building with a compiler which
276 * does not define __has_feature then we know we don't have non-fragile
277 * ivar support.
278 * In the header we bracket instance variable declarations in a
279 * '#if GS_EXPOSE(classname) ... #endif' sequence, so that the variables
280 * will not be visible to code which uses the library.
281 * In the source file we define EXPOSE_classname_IVARS to be 1
282 * before including the header, so that the ivars are always available
283 * in the class source itsself
284 */
285
286 #if GS_MIXEDABI
287 # undef GS_NONFRAGILE
288 # define GS_NONFRAGILE 0 /* Mixed is treated as fragile */
289 #else
290 # if (__has_feature(objc_nonfragile_abi))
291 # if !GS_NONFRAGILE
292 # if defined(GNUSTEP_BASE_INTERNAL)
293 # error "You are building gnustep-base using the objc-nonfragile-abi but your gnustep-base was not configured to use it."
294 # endif
295 # endif
296 # else
297 # if GS_NONFRAGILE
298 # error "Your gnustep-base was configured for the objc-nonfragile-abi but you are not using it now."
299 # endif
300 # endif
301 #endif
302
303 #define GS_EXPOSE(X) (!GS_NONFRAGILE || defined(EXPOSE_##X##_IVARS))
304
305 /* Static analyser macros: Provide annotations to help the analyser */
306 #ifdef __clang__
307 # define GS_NORETURN_METHOD __attribute__((__noreturn__))
308 #else
309 # define GS_NORETURN_METHOD
310 #endif
311
312 #ifndef NS_RETURNS_RETAINED
313 # if __has_feature(attribute_ns_returns_retained)
314 # define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
315 # else
316 # define NS_RETURNS_RETAINED
317 # endif
318 #endif
319
320 #ifndef NS_RETURNS_NOT_RETAINED
321 # if __has_feature(attribute_ns_returns_not_retained)
322 # define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
323 # else
324 # define NS_RETURNS_NOT_RETAINED
325 # endif
326 #endif
327
328 #ifndef NS_CONSUMED
329 # if __has_feature(attribute_ns_consumed)
330 # define NS_CONSUMED __attribute__((ns_consumed))
331 # else
332 # define NS_CONSUMED
333 # endif
334 #endif
335
336
337 #ifndef NS_CONSUMES_SELF
338 # if __has_feature(attribute_ns_consumes_self)
339 # define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
340 # else
341 # define NS_CONSUMES_SELF
342 # endif
343 #endif
344
345 #if defined(__clang__) && defined(__OBJC__)
346 static inline void gs_consumed(id NS_CONSUMED o) GS_UNUSED_FUNC;
gs_consumed(id NS_CONSUMED GS_UNUSED_ARG o)347 static inline void gs_consumed(id NS_CONSUMED GS_UNUSED_ARG o) { return; }
348 #define GS_CONSUMED(O) gs_consumed(O);
349 #else
350 #define GS_CONSUMED(O)
351 #endif
352
353 /* Include the appropriate header for ObjC2 blocks support if it is in use.
354 *
355 * FIXME: "OBJC2RUNTIME" is set to "1" if the runtime supports the ObjC2
356 * runtime API, which is unrelated to whether the compiler has blocks
357 * support or not.
358 */
359 #if __has_feature(blocks)
360 # if OBJC2RUNTIME
361 # if defined(__APPLE__)
362 # include <Block.h>
363 # else
364 # include <objc/blocks_runtime.h>
365 # endif
366 # else
367 # include <ObjectiveC2/blocks_runtime.h>
368 # endif
369 #endif
370
371 /* Attribute definition for root classes, annotates the interface declaration
372 * of the class.
373 */
374 #ifndef GS_ROOT_CLASS
375 # if GS_HAVE_OBJC_ROOT_CLASS_ATTR || __has_feature(attribute_objc_root_class)
376 # define GS_ROOT_CLASS __attribute__((objc_root_class))
377 # else
378 # define GS_ROOT_CLASS
379 # endif
380 #endif
381
382
383
384 #if defined(GNUSTEP_WITH_DLL)
385
386 #if BUILD_libgnustep_base_DLL
387 #
388 # if defined(__MINGW__)
389 /* On Mingw, the compiler will export all symbols automatically, so
390 * __declspec(dllexport) is not needed.
391 */
392 # define GS_EXPORT extern
393 # define GS_DECLARE
394 # else
395 # define GS_EXPORT __declspec(dllexport)
396 # define GS_DECLARE __declspec(dllexport)
397 # endif
398 #else
399 # define GS_EXPORT extern __declspec(dllimport)
400 # define GS_DECLARE __declspec(dllimport)
401 #endif
402
403 #else /* GNUSTEP_WITH[OUT]_DLL */
404
405 # define GS_EXPORT extern
406 # define GS_DECLARE
407
408 #endif
409
410
411 /* Attribute macros compatible with Apple.
412 */
413
414 #ifndef NS_FORMAT_ARGUMENT
415 #if defined(__clang__) || GS_GCC_MINREQ(4,2)
416 # define NS_FORMAT_ARGUMENT(A) __attribute__((format_arg(A)))
417 #else
418 # define NS_FORMAT_ARGUMENT(F,A)
419 #endif
420 #endif
421
422 // FIXME ... what version of gcc?
423 #ifndef NS_FORMAT_FUNCTION
424 #if __clang__
425 # define NS_FORMAT_FUNCTION(F,A) __attribute__((format(__NSString__, F, A)))
426 #else
427 # define NS_FORMAT_FUNCTION(F,A)
428 #endif
429 #endif
430
431 #ifndef NS_REQUIRES_NIL_TERMINATION
432 #define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel))
433 #endif
434
435 // FIXME ... what exact version of clang and gcc?
436 #ifndef UNAVAILABLE_ATTRIBUTE
437 #if defined(__clang__) || GS_GCC_MINREQ(4,0)
438 # define UNAVAILABLE_ATTRIBUTE __attribute__((unavailable))
439 #else
440 # define UNAVAILABLE_ATTRIBUTE
441 #endif
442 #endif
443
444 /* Check if compiler supports @optional in protocols
445 */
446 #if defined(__clang__) || GS_GCC_MINREQ(4,6)
447 # define GS_PROTOCOLS_HAVE_OPTIONAL 1
448 #else
449 # define GS_PROTOCOLS_HAVE_OPTIONAL 0
450 #endif
451
452 /* Check if compiler supports declared properties
453 */
454 #if defined(__clang__) || GS_GCC_MINREQ(4,6)
455 # define GS_HAS_DECLARED_PROPERTIES 1
456 #else
457 # define GS_HAS_DECLARED_PROPERTIES 0
458 #endif
459
460 #endif /* __GNUSTEP_GSVERSIONMACROS_H_INCLUDED_ */
461