v2 / thirdparty / libgc / include / gc / gc_config_macros.h
548 lines · 498 sloc · 18.38 KB · a4b7f7369d5359a002beced36c1e6644403220e7
Raw
1/*
2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
3 * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
4 * Copyright (c) 1998 by Fergus Henderson. All rights reserved.
5 * Copyright (c) 2000-2009 by Hewlett-Packard Development Company.
6 * All rights reserved.
7 * Copyright (c) 2008-2025 Ivan Maidanski
8 *
9 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
10 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
11 *
12 * Permission is hereby granted to use or copy this program
13 * for any purpose, provided the above notices are retained on all copies.
14 * Permission to modify the code and to distribute modified code is granted,
15 * provided the above notices are retained, and a notice that the code was
16 * modified is included with the above copyright notice.
17 */
18
19/*
20 * This should never be included directly; it is included only from
21 * `gc.h` file. We separate it only to make `gc.h` file more suitable
22 * as documentation.
23 */
24#if defined(GC_H)
25
26/* Convenient internal macro to test version of gcc. */
27# if defined(__GNUC__) && defined(__GNUC_MINOR__)
28# define GC_GNUC_PREREQ(major, minor) \
29 ((__GNUC__ << 8) + __GNUC_MINOR__ >= ((major) << 8) + (minor))
30# else
31# define GC_GNUC_PREREQ(major, minor) 0 /*< false */
32# endif
33
34/*
35 * A macro to define integer types of a pointer size. There seems to
36 * be no way to do this even semi-portably. The following is probably
37 * no better/worse than almost anything else.
38 * The ANSI standard suggests that `size_t` and `ptrdiff_t` might be
39 * better choices. But those had incorrect definitions on some older
40 * systems; notably `typedef int size_t` is wrong.
41 */
42# ifdef _WIN64
43# if defined(__int64) && !defined(CPPCHECK)
44# define GC_SIGNEDWORD __int64
45# else
46# define GC_SIGNEDWORD long long
47# endif
48# else
49# define GC_SIGNEDWORD long
50# endif
51# define GC_UNSIGNEDWORD unsigned GC_SIGNEDWORD
52
53/* Size of a pointer in bytes. */
54# if defined(__SIZEOF_POINTER__)
55# define GC_SIZEOF_PTR __SIZEOF_POINTER__
56# elif defined(__LP64__) || defined(_LP64) || defined(_WIN64) \
57 || defined(__alpha__) || defined(__arch64__) || defined(__powerpc64__) \
58 || defined(__s390x__) || defined(__sparcv9) \
59 || (defined(__x86_64__) && !defined(__ILP32__))
60# define GC_SIZEOF_PTR 8
61# else
62# define GC_SIZEOF_PTR 4
63# endif
64
65/*
66 * The return type of `GC_get_version()`. A 32-bit unsigned integer
67 * or longer.
68 */
69# define GC_VERSION_VAL_T unsigned
70
71/*
72 * Some tests for old macros. These violate our namespace rules and
73 * are deprecated. Use the `GC_` names instead.
74 */
75# if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \
76 || defined(_SOLARIS_PTHREADS) || defined(GC_SOLARIS_PTHREADS)
77/*
78 * We no longer support old style Solaris threads.
79 * `GC_SOLARIS_THREADS` now means `pthreads`.
80 */
81# ifndef GC_SOLARIS_THREADS
82# define GC_SOLARIS_THREADS
83# endif
84# endif
85# if defined(IRIX_THREADS)
86# define GC_IRIX_THREADS
87# endif
88# if defined(DGUX_THREADS) && !defined(GC_DGUX386_THREADS)
89# define GC_DGUX386_THREADS
90# endif
91# if defined(AIX_THREADS)
92# define GC_AIX_THREADS
93# endif
94# if defined(HPUX_THREADS)
95# define GC_HPUX_THREADS
96# endif
97# if defined(OSF1_THREADS)
98# define GC_OSF1_THREADS
99# endif
100# if defined(LINUX_THREADS)
101# define GC_LINUX_THREADS
102# endif
103# if defined(WIN32_THREADS)
104# define GC_WIN32_THREADS
105# endif
106# if defined(RTEMS_THREADS)
107# define GC_RTEMS_PTHREADS
108# endif
109# if defined(USE_LD_WRAP)
110# define GC_USE_LD_WRAP
111# endif
112
113# if defined(GC_WIN32_PTHREADS) && !defined(GC_WIN32_THREADS)
114/* Using pthreads-win32 library (or other Win32 implementation). */
115# define GC_WIN32_THREADS
116# endif
117
118# if defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \
119 || defined(GC_DGUX386_THREADS) || defined(GC_FREEBSD_THREADS) \
120 || defined(GC_HPUX_THREADS) || defined(GC_IRIX_THREADS) \
121 || defined(GC_LINUX_THREADS) || defined(GC_NETBSD_THREADS) \
122 || defined(GC_OPENBSD_THREADS) || defined(GC_OSF1_THREADS) \
123 || defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \
124 || defined(GC_RTEMS_PTHREADS)
125# ifndef GC_THREADS
126# define GC_THREADS
127# endif
128# elif defined(GC_THREADS)
129# if defined(__linux__) || defined(__native_client__)
130# define GC_LINUX_THREADS
131# elif defined(__OpenBSD__)
132# define GC_OPENBSD_THREADS
133# elif defined(_PA_RISC1_1) || defined(_PA_RISC2_0) || defined(hppa) \
134 || defined(__HPPA) || (defined(__ia64) && defined(_HPUX_SOURCE))
135# define GC_HPUX_THREADS
136# elif defined(__HAIKU__)
137# define GC_HAIKU_THREADS
138# elif (defined(__DragonFly__) || defined(__FreeBSD_kernel__) \
139 || defined(__FreeBSD__)) \
140 && !defined(GC_NO_FREEBSD)
141# define GC_FREEBSD_THREADS
142# elif defined(__NetBSD__)
143# define GC_NETBSD_THREADS
144# elif defined(__alpha) || defined(__alpha__) /*< not Linux, not xBSD */
145# define GC_OSF1_THREADS
146# elif (defined(mips) || defined(__mips) || defined(_mips)) \
147 && !(defined(nec_ews) || defined(_nec_ews) || defined(ultrix) \
148 || defined(__ultrix))
149# define GC_IRIX_THREADS
150# elif defined(__sparc) /* `&& !defined(__linux__)` */ \
151 || ((defined(sun) || defined(__sun)) \
152 && (defined(i386) || defined(__i386__) || defined(__amd64) \
153 || defined(__amd64__)))
154# define GC_SOLARIS_THREADS
155# elif defined(__APPLE__) && defined(__MACH__)
156# define GC_DARWIN_THREADS
157# endif
158# if defined(DGUX) && (defined(i386) || defined(__i386__))
159# define GC_DGUX386_THREADS
160# endif
161# if defined(_AIX)
162# define GC_AIX_THREADS
163# endif
164# if (defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) \
165 || defined(__CYGWIN32__) || defined(__CYGWIN__) \
166 || defined(__CEGCC__) || defined(_WIN32_WCE) \
167 || defined(__MINGW32__)) \
168 && !defined(GC_WIN32_THREADS)
169/* Either POSIX or native Win32 threads. */
170# define GC_WIN32_THREADS
171# endif
172# if defined(__rtems__) && (defined(i386) || defined(__i386__))
173# define GC_RTEMS_PTHREADS
174# endif
175# endif /* GC_THREADS */
176
177# undef GC_PTHREADS
178# if (!defined(GC_WIN32_THREADS) || defined(GC_WIN32_PTHREADS) \
179 || defined(__CYGWIN32__) || defined(__CYGWIN__)) \
180 && defined(GC_THREADS) && !defined(NN_PLATFORM_CTR) \
181 && !defined(NN_BUILD_TARGET_PLATFORM_NX)
182/* POSIX threads (`pthreads`). */
183# define GC_PTHREADS
184# endif
185
186# if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS)
187# define _PTHREADS
188# endif
189
190# if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
191# define _POSIX4A_DRAFT10_SOURCE 1
192# endif
193
194# if !defined(_REENTRANT) && defined(GC_PTHREADS) \
195 && !defined(GC_WIN32_THREADS)
196/*
197 * Better late than never. This fails if system headers that depend
198 * on this were previously included.
199 */
200# define _REENTRANT 1
201# endif
202
203# if defined(__clang__) && defined(__CYGWIN__) && defined(GC_THREADS) \
204 && defined(__LP64__)
205/*
206 * Workaround "__stdcall__ ignored for this target" clang warning.
207 * Note: `__stdcall` is defined implicitly based on `__stdcall__`.
208 */
209# define __stdcall__ /*< empty */
210# endif
211
212# define __GC
213# if !defined(_WIN32_WCE) || defined(__GNUC__)
214# include <stddef.h>
215# if defined(__MINGW32__) && !defined(_WIN32_WCE) \
216 || defined(__CHERI_PURE_CAPABILITY__)
217# include <stdint.h>
218/*
219 * We mention `uintptr_t`. Perhaps this should be included in pure
220 * MS environments as well.
221 */
222# endif
223# else
224/* Yet more kludges for WinCE. */
225# include <stdlib.h> /*< for `size_t` */
226# ifndef _PTRDIFF_T_DEFINED
227/* `ptrdiff_t` is not defined. */
228# define _PTRDIFF_T_DEFINED
229typedef long ptrdiff_t;
230# endif
231# endif /* _WIN32_WCE */
232
233# if !defined(GC_NOT_DLL) && !defined(GC_DLL) \
234 && ((defined(_DLL) && !defined(__GNUC__)) \
235 || (defined(DLL_EXPORT) && defined(GC_BUILD)))
236# define GC_DLL
237# endif
238
239# if defined(GC_DLL) && !defined(GC_API)
240
241# if defined(__CEGCC__)
242# if defined(GC_BUILD)
243# define GC_API __declspec(dllexport)
244# else
245# define GC_API __declspec(dllimport)
246# endif
247
248# elif defined(__MINGW32__)
249# if defined(__cplusplus) && defined(GC_BUILD)
250# define GC_API extern __declspec(dllexport)
251# elif defined(GC_BUILD) || defined(__MINGW32_DELAY_LOAD__)
252# define GC_API __declspec(dllexport)
253# else
254# define GC_API extern __declspec(dllimport)
255# endif
256
257# elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
258 || defined(__CYGWIN__)
259# ifdef GC_BUILD
260# define GC_API extern __declspec(dllexport)
261# else
262# define GC_API __declspec(dllimport)
263# endif
264
265# elif defined(__WATCOMC__)
266# ifdef GC_BUILD
267# define GC_API extern __declspec(dllexport)
268# else
269# define GC_API extern __declspec(dllimport)
270# endif
271
272# elif defined(__SYMBIAN32__)
273# ifdef GC_BUILD
274# define GC_API extern EXPORT_C
275# else
276# define GC_API extern IMPORT_C
277# endif
278
279# elif defined(__GNUC__)
280/* Only matters if used in conjunction with `-fvisibility=hidden` option. */
281# if defined(GC_BUILD) && !defined(GC_NO_VISIBILITY) \
282 && (GC_GNUC_PREREQ(4, 0) || defined(GC_VISIBILITY_HIDDEN_SET))
283# define GC_API extern __attribute__((__visibility__("default")))
284# endif
285# endif
286# endif /* GC_DLL */
287
288# ifndef GC_API
289# define GC_API extern
290# endif
291
292# ifndef GC_CALL
293# define GC_CALL
294# endif
295
296# ifndef GC_CALLBACK
297# define GC_CALLBACK GC_CALL
298# endif
299
300# ifndef GC_ATTR_MALLOC
301/*
302 * `malloc` attribute should be used for all `malloc`-like functions
303 * (to tell the compiler that a function may be treated as if any
304 * non-`NULL` pointer it returns cannot alias any other pointer valid
305 * when the function returns). If the client code violates this rule
306 * by using custom `GC_oom_func`, then the client should define
307 * `GC_OOM_FUNC_RETURNS_ALIAS` macro.
308 */
309# ifdef GC_OOM_FUNC_RETURNS_ALIAS
310# define GC_ATTR_MALLOC /*< empty */
311# elif GC_GNUC_PREREQ(3, 1)
312# define GC_ATTR_MALLOC __attribute__((__malloc__))
313# elif defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(__EDG__)
314# define GC_ATTR_MALLOC \
315 __declspec(allocator) __declspec(noalias) __declspec(restrict)
316# elif defined(_MSC_VER) && _MSC_VER >= 1400
317# define GC_ATTR_MALLOC __declspec(noalias) __declspec(restrict)
318# else
319# define GC_ATTR_MALLOC
320# endif
321# endif
322
323# ifndef GC_ATTR_ALLOC_SIZE
324/* `alloc_size` attribute improves `__builtin_object_size` correctness. */
325# undef GC_ATTR_CALLOC_SIZE
326# ifdef __clang__
327# if __has_attribute(__alloc_size__)
328# define GC_ATTR_ALLOC_SIZE(argnum) \
329 __attribute__((__alloc_size__(argnum)))
330# define GC_ATTR_CALLOC_SIZE(n, s) __attribute__((__alloc_size__(n, s)))
331# else
332# define GC_ATTR_ALLOC_SIZE(argnum) /*< empty */
333# endif
334# elif GC_GNUC_PREREQ(4, 3) && !defined(__ICC)
335# define GC_ATTR_ALLOC_SIZE(argnum) \
336 __attribute__((__alloc_size__(argnum)))
337# define GC_ATTR_CALLOC_SIZE(n, s) __attribute__((__alloc_size__(n, s)))
338# else
339# define GC_ATTR_ALLOC_SIZE(argnum) /*< empty */
340# endif
341# endif
342
343# ifndef GC_ATTR_CALLOC_SIZE
344# define GC_ATTR_CALLOC_SIZE(n, s) /*< empty */
345# endif
346
347# ifndef GC_ATTR_NONNULL
348# if GC_GNUC_PREREQ(4, 0)
349# define GC_ATTR_NONNULL(argnum) __attribute__((__nonnull__(argnum)))
350# else
351# define GC_ATTR_NONNULL(argnum) /*< empty */
352# endif
353# endif
354
355# ifndef GC_ATTR_CONST
356# if GC_GNUC_PREREQ(4, 0)
357# define GC_ATTR_CONST __attribute__((__const__))
358# else
359# define GC_ATTR_CONST /*< empty */
360# endif
361# endif
362
363# ifndef GC_ATTR_DEPRECATED
364# ifdef GC_BUILD
365# undef GC_ATTR_DEPRECATED
366# define GC_ATTR_DEPRECATED /*< empty */
367# elif GC_GNUC_PREREQ(4, 0)
368# define GC_ATTR_DEPRECATED __attribute__((__deprecated__))
369# elif defined(_MSC_VER) && _MSC_VER >= 1200
370# define GC_ATTR_DEPRECATED __declspec(deprecated)
371# else
372# define GC_ATTR_DEPRECATED /*< empty */
373# endif
374# endif
375
376# ifndef GC_ATTR_NORETURN
377# if GC_GNUC_PREREQ(2, 7)
378# define GC_ATTR_NORETURN __attribute__((__noreturn__))
379# elif defined(_MSC_VER) && _MSC_VER >= 1310 /*< VS 2003+ */
380# define GC_ATTR_NORETURN __declspec(noreturn)
381# elif defined(__NORETURN) /*< used in Solaris */
382# define GC_ATTR_NORETURN __NORETURN
383# else
384# define GC_ATTR_NORETURN /*< empty */
385# endif
386# endif
387
388# if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
389# define GC_ADD_CALLER
390# define GC_RETURN_ADDR ((GC_return_addr_t)__return_address)
391# endif
392
393# if defined(__linux__) || defined(__GLIBC__)
394# if !defined(__native_client__)
395# include <features.h>
396# endif
397# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
398 && !defined(__ia64__) && !defined(GC_MISSING_EXECINFO_H) \
399 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
400# define GC_HAVE_BUILTIN_BACKTRACE
401# endif
402# if defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
403# define GC_CAN_SAVE_CALL_STACKS
404# endif
405# endif /* GLIBC */
406
407# if defined(_MSC_VER) && (_MSC_VER >= 1200 /* v12.0+ (MSVC 6.0+) */) \
408 && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(_AMD64_) \
409 && !defined(_M_X64) && !defined(_WIN32_WCE) \
410 && !defined(GC_HAVE_NO_BUILTIN_BACKTRACE) \
411 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
412# define GC_HAVE_BUILTIN_BACKTRACE
413# endif
414
415# if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS) \
416 || defined(__sparc)
417# define GC_CAN_SAVE_CALL_STACKS
418# endif
419
420/*
421 * If we are on a platform on which we cannot save call stacks, but
422 * gcc is normally used, we go ahead and define `GC_ADD_CALLER` macro.
423 * We make this decision independent of whether gcc is actually being
424 * used, in order to keep the interface consistent, and allow mixing
425 * of compilers.
426 * This may also be desirable if it is possible but expensive to
427 * retrieve the call chain.
428 */
429# if (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) \
430 || defined(__FreeBSD_kernel__) || defined(__HAIKU__) \
431 || defined(__NetBSD__) || defined(__OpenBSD__) \
432 || defined(HOST_ANDROID) || defined(__ANDROID__)) \
433 && !defined(GC_CAN_SAVE_CALL_STACKS)
434# define GC_ADD_CALLER
435# if GC_GNUC_PREREQ(2, 95)
436/*
437 * gcc knows how to retrieve return address, but we do not know how to
438 * generate call stacks.
439 */
440# define GC_RETURN_ADDR ((GC_return_addr_t)__builtin_return_address(0))
441# if GC_GNUC_PREREQ(4, 0) \
442 && (defined(__i386__) || defined(__amd64__) \
443 || defined(__x86_64__) /* and probably others... */) \
444 && !defined(GC_NO_RETURN_ADDR_PARENT)
445# define GC_HAVE_RETURN_ADDR_PARENT
446# define GC_RETURN_ADDR_PARENT \
447 ((GC_return_addr_t)__builtin_extract_return_addr( \
448 __builtin_return_address(1)))
449/*
450 * Note: a compiler might complain that calling `__builtin_return_address`
451 * with a nonzero argument is unsafe.
452 */
453# endif
454# else
455/* Just pass 0 for gcc compatibility. */
456# define GC_RETURN_ADDR ((GC_return_addr_t)0)
457# endif
458# endif /* !GC_CAN_SAVE_CALL_STACKS */
459
460# ifdef GC_PTHREADS
461
462# if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
463 || defined(__native_client__) || defined(GC_RTEMS_PTHREADS)) \
464 && !defined(GC_NO_DLOPEN)
465/* Either there is no `dlopen()` or we do not need to intercept it. */
466# define GC_NO_DLOPEN
467# endif
468
469# if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
470 || defined(__native_client__)) \
471 && !defined(GC_NO_PTHREAD_SIGMASK)
472/* Either there is no `pthread_sigmask()` or no need to intercept it. */
473# define GC_NO_PTHREAD_SIGMASK
474# endif
475
476# if defined(__native_client__)
477/*
478 * At present, NaCl `pthread_create()` prototype does not have
479 * `const` for its `attr` argument; also, NaCl `pthread_exit()` one
480 * does not have `noreturn` attribute.
481 */
482# ifndef GC_PTHREAD_CREATE_CONST
483# define GC_PTHREAD_CREATE_CONST /*< empty */
484# endif
485# ifndef GC_HAVE_PTHREAD_EXIT
486# define GC_HAVE_PTHREAD_EXIT
487# define GC_PTHREAD_EXIT_ATTRIBUTE /*< empty */
488# endif
489# endif
490
491# if !defined(GC_HAVE_PTHREAD_EXIT) \
492 && ((defined(GC_LINUX_THREADS) && !defined(HOST_ANDROID) \
493 && !defined(__ANDROID__)) \
494 || defined(GC_SOLARIS_THREADS) || defined(__COSMOPOLITAN__))
495/* Intercept `pthread_exit()` where available and needed. */
496# define GC_HAVE_PTHREAD_EXIT
497# define GC_PTHREAD_EXIT_ATTRIBUTE GC_ATTR_NORETURN
498# endif
499
500# if (!defined(GC_HAVE_PTHREAD_EXIT) || defined(__native_client__)) \
501 && !defined(GC_NO_PTHREAD_CANCEL)
502/* Either there is no `pthread_cancel()` or no need to intercept it. */
503# define GC_NO_PTHREAD_CANCEL
504# endif
505
506# endif /* GC_PTHREADS */
507
508# ifdef __cplusplus
509
510# ifndef GC_ATTR_EXPLICIT
511# if __cplusplus >= 201103L && !defined(__clang__) \
512 || _MSVC_LANG >= 201103L || defined(CPPCHECK)
513# define GC_ATTR_EXPLICIT explicit
514# else
515# define GC_ATTR_EXPLICIT /*< empty */
516# endif
517# endif
518
519# ifndef GC_NOEXCEPT
520# if defined(__DMC__) \
521 || (defined(__BORLANDC__) \
522 && (defined(_RWSTD_NO_EXCEPTIONS) \
523 || defined(_RWSTD_NO_EX_SPEC))) \
524 || (defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) \
525 && !_HAS_EXCEPTIONS) \
526 || (defined(__WATCOMC__) && !defined(_CPPUNWIND))
527# define GC_NOEXCEPT /*< empty */
528# ifndef GC_NEW_ABORTS_ON_OOM
529# define GC_NEW_ABORTS_ON_OOM
530# endif
531# elif __cplusplus >= 201103L || _MSVC_LANG >= 201103L
532# define GC_NOEXCEPT noexcept
533# else
534# define GC_NOEXCEPT throw()
535# endif
536# endif
537
538# ifndef GC_CONSTEXPR
539# if __cplusplus >= 202002L
540# define GC_CONSTEXPR constexpr
541# else
542# define GC_CONSTEXPR /*< empty */
543# endif
544# endif
545
546# endif /* __cplusplus */
547
548#endif
549