1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CONFIG
11#define _LIBCPP___CONFIG
12
13/* zig patch: instead of including __config_site, zig adds -D flags when compiling */
14#include <__configuration/abi.h>
15#include <__configuration/availability.h>
16#include <__configuration/compiler.h>
17#include <__configuration/experimental.h>
18#include <__configuration/hardening.h>
19#include <__configuration/language.h>
20#include <__configuration/platform.h>
21
22#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
23# pragma GCC system_header
24#endif
25
26#ifdef __cplusplus
27
28# include <__configuration/abi.h>
29# include <__configuration/attributes.h>
30# include <__configuration/availability.h>
31# include <__configuration/compiler.h>
32# include <__configuration/diagnostic_suppression.h>
33# include <__configuration/experimental.h>
34# include <__configuration/hardening.h>
35# include <__configuration/language.h>
36# include <__configuration/namespace.h>
37# include <__configuration/platform.h>
38# include <__configuration/pstl.h>
39# include <__configuration/utility.h>
40
41// The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html
42
43// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
44// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
45// defined to XXYYZZ.
46# define _LIBCPP_VERSION 230100
47
48# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
49# define _LIBCPP_ABI_VCRUNTIME
50# endif
51
52# if defined(_WIN32)
53# define _LIBCPP_WIN32API
54# define _LIBCPP_SHORT_WCHAR 1
55// Both MinGW and native MSVC provide a "MSVC"-like environment
56# define _LIBCPP_MSVCRT_LIKE
57// If mingw not explicitly detected, assume using MS C runtime only if
58// a MS compatibility version is specified.
59# if defined(_MSC_VER) && !defined(__MINGW32__)
60# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
61# endif
62# define _LIBCPP_HAS_OPEN_WITH_WCHAR 1
63# else
64# define _LIBCPP_HAS_OPEN_WITH_WCHAR 0
65# endif // defined(_WIN32)
66
67# if defined(_AIX) && !defined(__64BIT__)
68// The size of wchar is 2 byte on 32-bit mode on AIX.
69# define _LIBCPP_SHORT_WCHAR 1
70# endif
71
72// Libc++ supports various implementations of std::random_device.
73//
74// _LIBCPP_USING_DEV_RANDOM
75// Read entropy from the given file, by default `/dev/urandom`.
76// If a token is provided, it is assumed to be the path to a file
77// to read entropy from. This is the default behavior if nothing
78// else is specified. This implementation requires storing state
79// inside `std::random_device`.
80//
81// _LIBCPP_USING_ARC4_RANDOM
82// Use arc4random(). This allows obtaining random data even when
83// using sandboxing mechanisms. On some platforms like Apple, this
84// is the recommended source of entropy for user-space programs.
85// When this option is used, the token passed to `std::random_device`'s
86// constructor *must* be "/dev/urandom" -- anything else is an error.
87//
88// _LIBCPP_USING_GETENTROPY
89// Use getentropy().
90// When this option is used, the token passed to `std::random_device`'s
91// constructor *must* be "/dev/urandom" -- anything else is an error.
92//
93// _LIBCPP_USING_FUCHSIA_CPRNG
94// Use Fuchsia's zx_cprng_draw() system call, which is specified to
95// deliver high-quality entropy and cannot fail.
96// When this option is used, the token passed to `std::random_device`'s
97// constructor *must* be "/dev/urandom" -- anything else is an error.
98//
99// _LIBCPP_USING_WIN32_RANDOM
100// Use rand_s(), for use on Windows.
101// When this option is used, the token passed to `std::random_device`'s
102// constructor *must* be "/dev/urandom" -- anything else is an error.
103# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
104 defined(__DragonFly__)
105# define _LIBCPP_USING_ARC4_RANDOM
106# elif defined(__wasi__) || defined(__EMSCRIPTEN__)
107# define _LIBCPP_USING_GETENTROPY
108# elif defined(__Fuchsia__)
109# define _LIBCPP_USING_FUCHSIA_CPRNG
110# elif defined(_LIBCPP_WIN32API)
111# define _LIBCPP_USING_WIN32_RANDOM
112# else
113# define _LIBCPP_USING_DEV_RANDOM
114# endif
115
116# ifndef _LIBCPP_CXX03_LANG
117
118# define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
119# define _ALIGNAS_TYPE(x) alignas(x)
120# define _ALIGNAS(x) alignas(x)
121# define _NOEXCEPT noexcept
122# define _NOEXCEPT_(...) noexcept(__VA_ARGS__)
123# define _LIBCPP_CONSTEXPR constexpr
124
125# else
126
127# define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__)
128# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
129# define _ALIGNAS(x) __attribute__((__aligned__(x)))
130# define nullptr __nullptr
131# define _NOEXCEPT throw()
132# define _NOEXCEPT_(...)
133# define static_assert(...) _Static_assert(__VA_ARGS__)
134# define decltype(...) __decltype(__VA_ARGS__)
135# define _LIBCPP_CONSTEXPR
136
137typedef __char16_t char16_t;
138typedef __char32_t char32_t;
139
140# endif
141
142# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
143
144# if __has_extension(blocks) && defined(__APPLE__)
145# define _LIBCPP_HAS_BLOCKS_RUNTIME 1
146# else
147# define _LIBCPP_HAS_BLOCKS_RUNTIME 0
148# endif
149
150# if !defined(__SIZEOF_INT128__) || defined(_MSC_VER)
151# define _LIBCPP_HAS_INT128 0
152# else
153# define _LIBCPP_HAS_INT128 1
154# endif
155
156# ifdef _LIBCPP_CXX03_LANG
157# define _LIBCPP_DECLARE_STRONG_ENUM(x) \
158 struct _LIBCPP_EXPORTED_FROM_ABI x { \
159 enum __lx
160// clang-format off
161# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
162 __lx __v_; \
163 _LIBCPP_HIDE_FROM_ABI x(__lx __v) : __v_(__v) {} \
164 _LIBCPP_HIDE_FROM_ABI explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
165 _LIBCPP_HIDE_FROM_ABI operator int() const { return __v_; } \
166 };
167// clang-format on
168
169# else // _LIBCPP_CXX03_LANG
170# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class x
171# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
172# endif // _LIBCPP_CXX03_LANG
173
174# ifdef __FreeBSD__
175# define _DECLARE_C99_LDBL_MATH 1
176# endif
177
178/* zig patch: compiler defines _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION in some cases */
179# if !defined(_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION)
180// If we are getting operator new from the MSVC CRT, then allocation overloads
181// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
182# if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
183# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
184# elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
185// We're deferring to Microsoft's STL to provide aligned new et al. We don't
186// have it unless the language feature test macro is defined.
187# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
188# elif defined(__MVS__)
189# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
190# else
191# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 1
192# endif
193
194# if !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
195# define _LIBCPP_HAS_ALIGNED_ALLOCATION 0
196# else
197# define _LIBCPP_HAS_ALIGNED_ALLOCATION 1
198# endif
199# endif
200
201# if !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
202# define _LIBCPP_HAS_ALIGNED_ALLOCATION 0
203# else
204# define _LIBCPP_HAS_ALIGNED_ALLOCATION 1
205# endif
206
207# if defined(__APPLE__) || defined(__FreeBSD__)
208# define _LIBCPP_WCTYPE_IS_MASK
209# endif
210
211// FIXME: using `#warning` causes diagnostics from system headers which include deprecated headers. This can only be
212// enabled again once https://github.com/llvm/llvm-project/pull/168041 (or a similar feature) has landed, since that
213// allows suppression in system headers.
214# if defined(__DEPRECATED) && __DEPRECATED && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && 0
215# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 1
216# else
217# define _LIBCPP_DIAGNOSE_DEPRECATED_HEADERS 0
218# endif
219
220// Thread API
221// clang-format off
222# if _LIBCPP_HAS_THREADS && \
223 !_LIBCPP_HAS_THREAD_API_PTHREAD && \
224 !_LIBCPP_HAS_THREAD_API_WIN32 && \
225 !_LIBCPP_HAS_THREAD_API_EXTERNAL && \
226 !_LIBCPP_HAS_THREAD_API_C11
227
228# if defined(__FreeBSD__) || \
229 defined(__wasi__) || \
230 defined(__NetBSD__) || \
231 defined(__OpenBSD__) || \
232 defined(__NuttX__) || \
233 defined(__linux__) || \
234 defined(__GNU__) || \
235 defined(__APPLE__) || \
236 defined(__MVS__) || \
237 defined(_AIX) || \
238 defined(__EMSCRIPTEN__) || \
239 defined(__HAIKU__) || \
240 defined(__serenity__)
241// zig patch: haiku support
242// zig patch: serenity support
243// clang-format on
244# undef _LIBCPP_HAS_THREAD_API_PTHREAD
245# define _LIBCPP_HAS_THREAD_API_PTHREAD 1
246# elif defined(__Fuchsia__)
247// TODO(44575): Switch to C11 thread API when possible.
248# undef _LIBCPP_HAS_THREAD_API_PTHREAD
249# define _LIBCPP_HAS_THREAD_API_PTHREAD 1
250# elif defined(_LIBCPP_WIN32API)
251# undef _LIBCPP_HAS_THREAD_API_WIN32
252# define _LIBCPP_HAS_THREAD_API_WIN32 1
253# else
254# error "No thread API"
255# endif // _LIBCPP_HAS_THREAD_API
256# endif // _LIBCPP_HAS_THREADS
257
258# if !_LIBCPP_HAS_THREAD_API_PTHREAD
259# define _LIBCPP_HAS_COND_CLOCKWAIT 0
260# elif (defined(__ANDROID__) && __ANDROID_API__ >= 30) || _LIBCPP_GLIBC_PREREQ(2, 30)
261# define _LIBCPP_HAS_COND_CLOCKWAIT 1
262# else
263# define _LIBCPP_HAS_COND_CLOCKWAIT 0
264# endif
265
266# if !_LIBCPP_HAS_THREADS && _LIBCPP_HAS_THREAD_API_PTHREAD
267# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be true when _LIBCPP_HAS_THREADS is true.
268# endif
269
270# if !_LIBCPP_HAS_THREADS && _LIBCPP_HAS_THREAD_API_EXTERNAL
271# error _LIBCPP_HAS_THREAD_API_EXTERNAL may only be true when _LIBCPP_HAS_THREADS is true.
272# endif
273
274# if !_LIBCPP_HAS_THREADS && _LIBCPP_HAS_THREAD_API_C11
275# error _LIBCPP_HAS_THREAD_API_C11 may only be true when _LIBCPP_HAS_THREADS is true.
276# endif
277
278# if !_LIBCPP_HAS_MONOTONIC_CLOCK && _LIBCPP_HAS_THREADS
279# error _LIBCPP_HAS_MONOTONIC_CLOCK may only be false when _LIBCPP_HAS_THREADS is false.
280# endif
281
282# if _LIBCPP_HAS_THREADS && !defined(__STDCPP_THREADS__)
283# define __STDCPP_THREADS__ 1
284# endif
285
286// The glibc and Bionic implementation of pthreads implements
287// pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32
288// mutexes have no destroy mechanism.
289//
290// This optimization can't be performed on Apple platforms, where
291// pthread_mutex_destroy can allow the kernel to release resources.
292// See https://llvm.org/D64298 for details.
293//
294// TODO(EricWF): Enable this optimization on Bionic after speaking to their
295// respective stakeholders.
296// clang-format off
297# if (_LIBCPP_HAS_THREAD_API_PTHREAD && defined(__GLIBC__)) || \
298 (_LIBCPP_HAS_THREAD_API_C11 && defined(__Fuchsia__)) || \
299 _LIBCPP_HAS_THREAD_API_WIN32
300// clang-format on
301# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION 1
302# else
303# define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION 0
304# endif
305
306// Destroying a condvar is a nop on Windows.
307//
308// This optimization can't be performed on Apple platforms, where
309// pthread_cond_destroy can allow the kernel to release resources.
310// See https://llvm.org/D64298 for details.
311//
312// TODO(EricWF): This is potentially true for some pthread implementations
313// as well.
314# if (_LIBCPP_HAS_THREAD_API_C11 && defined(__Fuchsia__)) || _LIBCPP_HAS_THREAD_API_WIN32
315# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION 1
316# else
317# define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION 0
318# endif
319
320// zig patch: serenity support
321# if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \
322 _LIBCPP_HAS_MUSL_LIBC || defined(__OpenBSD__) || _LIBCPP_LIBC_LLVM_LIBC || defined(__serenity__)
323# define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
324# endif
325
326// We often repeat things just for handling wide characters in the library.
327// When wide characters are disabled, it can be useful to have a quick way of
328// disabling it without having to resort to #if-#endif, which has a larger
329// impact on readability.
330# if !_LIBCPP_HAS_WIDE_CHARACTERS
331# define _LIBCPP_IF_WIDE_CHARACTERS(...)
332# else
333# define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__
334# endif
335
336// clang-format off
337# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh\")") _Pragma("push_macro(\"move\")") _Pragma("push_macro(\"erase\")")
338# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh\")") _Pragma("pop_macro(\"move\")") _Pragma("pop_macro(\"erase\")")
339// clang-format on
340
341# ifndef _LIBCPP_NO_AUTO_LINK
342# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
343# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
344# pragma comment(lib, "c++.lib")
345# else
346# pragma comment(lib, "libc++.lib")
347# endif
348# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
349# endif // _LIBCPP_NO_AUTO_LINK
350
351// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
352// functions is gradually being added to existing C libraries. The conditions
353// below check for known C library versions and conditions under which these
354// functions are declared by the C library.
355//
356// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
357// __cpp_char8_t is defined or if C2X extensions are enabled. Determining
358// the latter depends on internal GNU libc details that are not appropriate
359// to depend on here, so any declarations present when __cpp_char8_t is not
360// defined are ignored.
361# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
362# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
363# else
364# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
365# endif
366
367// There are a handful of public standard library types that are intended to
368// support CTAD but don't need any explicit deduction guides to do so. This
369// macro is used to mark them as such, which suppresses the
370// '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code
371// with these classes.
372# if _LIBCPP_STD_VER >= 17
373# ifdef _LIBCPP_COMPILER_CLANG_BASED
374# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \
375 template <class... _Tag> \
376 [[maybe_unused]] _ClassName(typename _Tag::__allow_ctad...)->_ClassName<_Tag...>
377# else
378# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(ClassName) \
379 template <class... _Tag> \
380 ClassName(typename _Tag::__allow_ctad...)->ClassName<_Tag...>
381# endif
382# else
383# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
384# endif
385
386#endif // __cplusplus
387
388#endif // _LIBCPP___CONFIG