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 &lt;= version &lt; 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 &lt;= version &lt; 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