Index: libcxx/CMakeLists.txt =================================================================== --- libcxx/CMakeLists.txt +++ libcxx/CMakeLists.txt @@ -104,7 +104,21 @@ the shared library they shipped should turn this on and see `include/__availability` for more details." OFF) option(LIBCXX_ENABLE_CLANG_TIDY "Whether to compile and run clang-tidy checks" OFF) - +option(LIBCXX_FREESTANDING + "Build libc++ in freestanding mode. This toggle allows the libc++ to work without libc + for environments like operating systems kernels or embedded systems." OFF) + +if (LIBCXX_FREESTANDING) + set(LIBCXX_ENABLE_FILESYSTEM OFF) + set(LIBCXX_ENABLE_RANDOM_DEVICE OFF) + set(LIBCXX_ENABLE_PARALLEL_ALGORITHMS OFF) + set(LIBCXX_ENABLE_SHARED OFF) + set(LIBCXX_ENABLE_STATIC OFF) + set(CMAKE_C_COMPILER_WORKS ON) + set(CMAKE_CXX_COMPILER_WORKS ON) + set(LIBCXX_ENABLE_LOCALIZATION OFF) + set(LIBCXX_ENABLE_FSTREAM OFF) +else() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") elseif(MINGW) @@ -122,6 +136,8 @@ set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static.cfg.in") endif() endif() +endif() + set(LIBCXX_TEST_CONFIG "${LIBCXX_DEFAULT_TEST_CONFIG}" CACHE STRING "The path to the Lit testing configuration to use when running the tests. If a relative path is provided, it is assumed to be relative to '/libcxx/test/configs'.") @@ -135,6 +151,10 @@ # Benchmark options ----------------------------------------------------------- option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON) +if (LIBCXX_FREESTANDING) + set(LIBCXX_INCLUDE_BENCHMARKS Off) +endif() + set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01) set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING "Arguments to pass when running the benchmarks using check-cxx-benchmarks") @@ -322,9 +342,14 @@ # Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when # LIBCXX_ENABLE_THREADS is on. -if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK) - message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF" - " when LIBCXX_ENABLE_THREADS is also set to OFF.") +if (LIBCXX_FREESTANDING) + set(LIBCXX_ENABLE_THREADS Off) + set(LIBCXX_ENABLE_MONOTONIC_CLOCK Off) +else() + if (LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK) + message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF" + " when LIBCXX_ENABLE_THREADS is also set to OFF.") + endif() endif() if(NOT LIBCXX_ENABLE_THREADS) @@ -867,6 +892,9 @@ else() config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) endif() +if (LIBCXX_FREESTANDING) + config_define(LIBCXX_FREESTANDING _LIBCPP_FREESTANDING) +endif() if (LIBCXX_ABI_DEFINES) set(abi_defines) @@ -920,8 +948,10 @@ # Setup Source Code And Tests #=============================================================================== add_subdirectory(include) +if (NOT LIBCXX_FREESTANDING) add_subdirectory(src) add_subdirectory(utils) +endif() set(LIBCXX_TEST_DEPS "cxx_experimental") Index: libcxx/include/__algorithm/sort.h =================================================================== --- libcxx/include/__algorithm/sort.h +++ libcxx/include/__algorithm/sort.h @@ -924,6 +924,7 @@ std::__sort<__less&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); } +#ifndef _LIBCPP_FREESTANDING extern template _LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&); #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS extern template _LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); @@ -961,6 +962,7 @@ extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&); extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&); +#endif template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -46,7 +46,7 @@ // generate identifiers that must be unique for every released libc++ version. # define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION) -# if __STDC_HOSTED__ == 0 +# if __STDC_HOSTED__ == 0 && !defined(_LIBCPP_FREESTANDING) # define _LIBCPP_FREESTANDING # endif @@ -252,7 +252,7 @@ # endif // Need to detect which libc we're using if we're on Linux. -# if defined(__linux__) +# if defined(__linux__) && __has_include() # include # if defined(__GLIBC_PREREQ) # define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) @@ -261,7 +261,7 @@ # endif // defined(__GLIBC_PREREQ) # endif // defined(__linux__) -# if defined(__MVS__) +# if defined(__MVS__) && __has_include() # include // for __NATIVE_ASCII_F # endif @@ -285,7 +285,7 @@ # endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # endif // __BYTE_ORDER__ -# ifdef __FreeBSD__ +# if defined(__FreeBSD__) && __has_include() && __has_include() # include # include # if _BYTE_ORDER == _LITTLE_ENDIAN @@ -295,7 +295,7 @@ # endif // _BYTE_ORDER == _LITTLE_ENDIAN # endif // __FreeBSD__ -# if defined(__NetBSD__) || defined(__OpenBSD__) +# if (defined(__NetBSD__) || defined(__OpenBSD__)) && __has_include() # include # if _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN @@ -321,7 +321,7 @@ # define _LIBCPP_HAS_OPEN_WITH_WCHAR # endif // defined(_WIN32) -# ifdef __sun__ +# if defined(__sun__) && __has_include() # include # ifdef _LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN @@ -388,7 +388,7 @@ # define _LIBCPP_USING_DEV_RANDOM # endif -# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) +# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) && __has_include() # include # if __BYTE_ORDER == __LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN Index: libcxx/include/__config_site.in =================================================================== --- libcxx/include/__config_site.in +++ libcxx/include/__config_site.in @@ -32,6 +32,7 @@ #cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS #cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT #cmakedefine _LIBCPP_ENABLE_DEBUG_MODE +#cmakedefine _LIBCPP_FREESTANDING // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ Index: libcxx/include/__thread/poll_with_backoff.h =================================================================== --- libcxx/include/__thread/poll_with_backoff.h +++ libcxx/include/__thread/poll_with_backoff.h @@ -21,8 +21,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; - // Polls a thread for a condition given by a predicate, and backs off based on a backoff policy // before polling again. // @@ -34,25 +32,40 @@ // // - __max_elapsed is the maximum duration to try polling for. If the maximum duration is exceeded, // the polling loop will return false to report a timeout. +#ifdef _LIBCPP_FREESTANDING +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_backoff(_Fn&& __f, _BFn&&) { + for (;;) { + if (__f()) + return true; // _Fn completion means success + } +} +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool +__libcpp_thread_poll_with_backoff(_Fn&& __f, _BFn&& __bf, chrono::nanoseconds) { + return __libcpp_thread_poll_with_backoff(__f, __bf); +} +#else +static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; template _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_backoff(_Fn&& __f, _BFn&& __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) { - auto const __start = chrono::high_resolution_clock::now(); - for (int __count = 0;;) { - if (__f()) - return true; // _Fn completion means success - if (__count < __libcpp_polling_count) { - __count += 1; - continue; - } - chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; - if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) - return false; // timeout failure - if (__bf(__elapsed)) - return false; // _BFn completion means failure + auto const __start = chrono::high_resolution_clock::now(); + for (int __count = 0;;) { + if (__f()) + return true; // _Fn completion means success + if (__count < __libcpp_polling_count) { + __count += 1; + continue; } + chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; + if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) + return false; // timeout failure + if (__bf(__elapsed)) + return false; // _BFn completion means failure + } } - +#endif // A trivial backoff policy that always immediately returns the control to // the polling loop. // Index: libcxx/include/chrono =================================================================== --- libcxx/include/chrono +++ libcxx/include/chrono @@ -769,7 +769,8 @@ // [time.syn] #include -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && _LIBCPP_STD_VER > 17 +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && _LIBCPP_STD_VER > 17 && \ + !defined(_LIBCPP_FREESTANDING) # include <__chrono/formatter.h> # include <__chrono/ostream.h> # include <__chrono/parser_std_format_spec.h> Index: libcxx/include/complex =================================================================== --- libcxx/include/complex +++ libcxx/include/complex @@ -239,8 +239,8 @@ #include #include -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include // for std::basic_ostringstream +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_FREESTANDING) +# include // for std::basic_ostringstream #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -1373,7 +1373,7 @@ return complex<_Tp>(__z.imag(), -__z.real()); } -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_FREESTANDING) template _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) Index: libcxx/include/cstdio =================================================================== --- libcxx/include/cstdio +++ libcxx/include/cstdio @@ -157,7 +157,9 @@ using ::fopen _LIBCPP_USING_IF_EXISTS; using ::freopen _LIBCPP_USING_IF_EXISTS; +#ifndef _LIBCPP_FREESTANDING using ::remove _LIBCPP_USING_IF_EXISTS; +#endif using ::rename _LIBCPP_USING_IF_EXISTS; using ::tmpfile _LIBCPP_USING_IF_EXISTS; using ::tmpnam _LIBCPP_USING_IF_EXISTS; Index: libcxx/include/ctime =================================================================== --- libcxx/include/ctime +++ libcxx/include/ctime @@ -54,6 +54,11 @@ # ifdef _LIBCPP_TIME_H # error "If libc++ starts defining , the __has_include check should move to libc++'s " # endif +#else +# include +extern "C" { +typedef ::std::uint_least64_t time_t; +} #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) Index: libcxx/include/cwchar =================================================================== --- libcxx/include/cwchar +++ libcxx/include/cwchar @@ -194,8 +194,10 @@ #if __has_builtin(__builtin_wcslen) return __builtin_wcslen(__str); #else +# ifndef _LIBCPP_FREESTANDING if (!__libcpp_is_constant_evaluated()) return std::wcslen(__str); +# endif size_t __len = 0; for (; *__str != L'\0'; ++__str) @@ -209,8 +211,10 @@ #if __has_builtin(__builtin_wmemcmp) return __builtin_wmemcmp(__lhs, __rhs, __count); #else +# ifndef _LIBCPP_FREESTANDING if (!__libcpp_is_constant_evaluated()) return std::wmemcmp(__lhs, __rhs, __count); +# endif for (; __count; --__count, ++__lhs, ++__rhs) { if (*__lhs < *__rhs) @@ -227,8 +231,10 @@ #if __has_feature(cxx_constexpr_string_builtins) return __builtin_wmemchr(__str, __char, __count); #else +# ifndef _LIBCPP_FREESTANDING if (!__libcpp_is_constant_evaluated()) return std::wmemchr(__str, __char, __count); +# endif for (; __count; --__count) { if (*__str == __char) Index: libcxx/include/errno.h =================================================================== --- libcxx/include/errno.h +++ libcxx/include/errno.h @@ -30,6 +30,148 @@ #if __has_include_next() # include_next +#else + +/* Adjusted to the linux asm/errno.h */ +# define EPERM 1 /* Operation not permitted */ +# define ENOENT 2 /* No such file or directory */ +# define ESRCH 3 /* No such process */ +# define EINTR 4 /* Interrupted system call */ +# define EIO 5 /* I/O error */ +# define ENXIO 6 /* No such device or address */ +# define E2BIG 7 /* Arg list too long */ +# define ENOEXEC 8 /* Exec format error */ +# define EBADF 9 /* Bad file number */ +# define ECHILD 10 /* No child processes */ +# define EAGAIN 11 /* Try again */ +# define ENOMEM 12 /* Out of memory */ +# define EACCES 13 /* Permission denied */ +# define EFAULT 14 /* Bad address */ +# define ENOTBLK 15 /* Block device required */ +# define EBUSY 16 /* Device or resource busy */ +# define EEXIST 17 /* File exists */ +# define EXDEV 18 /* Cross-device link */ +# define ENODEV 19 /* No such device */ +# define ENOTDIR 20 /* Not a directory */ +# define EISDIR 21 /* Is a directory */ +# define EINVAL 22 /* Invalid argument */ +# define ENFILE 23 /* File table overflow */ +# define EMFILE 24 /* Too many open files */ +# define ENOTTY 25 /* Not a typewriter */ +# define ETXTBSY 26 /* Text file busy */ +# define EFBIG 27 /* File too large */ +# define ENOSPC 28 /* No space left on device */ +# define ESPIPE 29 /* Illegal seek */ +# define EROFS 30 /* Read-only file system */ +# define EMLINK 31 /* Too many links */ +# define EPIPE 32 /* Broken pipe */ +# define EDOM 33 /* Math argument out of domain of func */ +# define ERANGE 34 /* Math result not representable */ +# define EDEADLK 35 /* Resource deadlock would occur */ +# define ENAMETOOLONG 36 /* File name too long */ +# define ENOLCK 37 /* No record locks available */ +# define ENOSYS 38 /* Function not implemented */ +# define ENOTEMPTY 39 /* Directory not empty */ +# define ELOOP 40 /* Too many symbolic links encountered */ +# define EWOULDBLOCK EAGAIN /* Operation would block */ +# define ENOMSG 42 /* No message of desired type */ +# define EIDRM 43 /* Identifier removed */ +# define ECHRNG 44 /* Channel number out of range */ +# define EL2NSYNC 45 /* Level 2 not synchronized */ +# define EL3HLT 46 /* Level 3 halted */ +# define EL3RST 47 /* Level 3 reset */ +# define ELNRNG 48 /* Link number out of range */ +# define EUNATCH 49 /* Protocol driver not attached */ +# define ENOCSI 50 /* No CSI structure available */ +# define EL2HLT 51 /* Level 2 halted */ +# define EBADE 52 /* Invalid exchange */ +# define EBADR 53 /* Invalid request descriptor */ +# define EXFULL 54 /* Exchange full */ +# define ENOANO 55 /* No anode */ +# define EBADRQC 56 /* Invalid request code */ +# define EBADSLT 57 /* Invalid slot */ +# define EDEADLOCK EDEADLK +# define EBFONT 59 /* Bad font file format */ +# define EFTYPE EBFONT /* Inappropriate file type or format */ +# define ENOSTR 60 /* Device not a stream */ +# define ENODATA 61 /* No data available */ +# define ETIME 62 /* Timer expired */ +# define ENOSR 63 /* Out of streams resources */ +# define ENONET 64 /* Machine is not on the network */ +# define ENOPKG 65 /* Package not installed */ +# define EREMOTE 66 /* Object is remote */ +# define ENOLINK 67 /* Link has been severed */ +# define EADV 68 /* Advertise error */ +# define ESRMNT 69 /* Srmount error */ +# define ECOMM 70 /* Communication error on send */ +# define EPROTO 71 /* Protocol error */ +# define EMULTIHOP 72 /* Multihop attempted */ +# define EDOTDOT 73 /* RFS specific error */ +# define EBADMSG 74 /* Not a data message */ +# define EOVERFLOW 75 /* Value too large for defined data type */ +# define ENOTUNIQ 76 /* Name not unique on network */ +# define EBADFD 77 /* File descriptor in bad state */ +# define EREMCHG 78 /* Remote address changed */ +# define ELIBACC 79 /* Can not access a needed shared library */ +# define ELIBBAD 80 /* Accessing a corrupted shared library */ +# define ELIBSCN 81 /* .lib section in a.out corrupted */ +# define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +# define ELIBEXEC 83 /* Cannot exec a shared library directly */ +# define EILSEQ 84 /* Illegal byte sequence */ +# define ERESTART 85 /* Interrupted system call should be restarted */ +# define ESTRPIPE 86 /* Streams pipe error */ +# define EUSERS 87 /* Too many users */ +# define ENOTSOCK 88 /* Socket operation on non-socket */ +# define EDESTADDRREQ 89 /* Destination address required */ +# define EMSGSIZE 90 /* Message too long */ +# define EPROTOTYPE 91 /* Protocol wrong type for socket */ +# define ENOPROTOOPT 92 /* Protocol not available */ +# define EPROTONOSUPPORT 93 /* Protocol not supported */ +# define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +# define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +# define EPFNOSUPPORT 96 /* Protocol family not supported */ +# define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +# define EADDRINUSE 98 /* Address already in use */ +# define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +# define ENETDOWN 100 /* Network is down */ +# define ENETUNREACH 101 /* Network is unreachable */ +# define ENETRESET 102 /* Network dropped connection because of reset */ +# define ECONNABORTED 103 /* Software caused connection abort */ +# define ECONNRESET 104 /* Connection reset by peer */ +# define ENOBUFS 105 /* No buffer space available */ +# define EISCONN 106 /* Transport endpoint is already connected */ +# define ENOTCONN 107 /* Transport endpoint is not connected */ +# define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +# define ETOOMANYREFS 109 /* Too many references: cannot splice */ +# define ETIMEDOUT 110 /* Connection timed out */ +# define ECONNREFUSED 111 /* Connection refused */ +# define EHOSTDOWN 112 /* Host is down */ +# define EHOSTUNREACH 113 /* No route to host */ +# define EALREADY 114 /* Operation already in progress */ +# define EINPROGRESS 115 /* Operation now in progress */ +# define ESTALE 116 /* Stale NFS file handle */ +# define EUCLEAN 117 /* Structure needs cleaning */ +# define ENOTNAM 118 /* Not a XENIX named type file */ +# define ENAVAIL 119 /* No XENIX semaphores available */ +# define EISNAM 120 /* Is a named type file */ +# define EREMOTEIO 121 /* Remote I/O error */ +# define EDQUOT 122 /* Quota exceeded */ + +# define ENOMEDIUM 123 /* No medium found */ +# define EMEDIUMTYPE 124 /* Wrong medium type */ +# define ECANCELED 125 /* Operation Canceled */ +# define ENOKEY 126 /* Required key not available */ +# define EKEYEXPIRED 127 /* Key has expired */ +# define EKEYREVOKED 128 /* Key has been revoked */ +# define EKEYREJECTED 129 /* Key was rejected by service */ + +# define EOWNERDEAD 130 /* Owner died */ +# define ENOTRECOVERABLE 131 /* State not recoverable */ + +/* Widely known to be a synonym in Linux. */ +# define ENOTSUP EOPNOTSUPP + +# define __ELASTERROR 2000 /* Users can add values starting here */ #endif #ifdef __cplusplus Index: libcxx/include/functional =================================================================== --- libcxx/include/functional +++ libcxx/include/functional @@ -512,7 +512,9 @@ #include <__functional/bind_front.h> #include <__functional/binder1st.h> #include <__functional/binder2nd.h> -#include <__functional/boyer_moore_searcher.h> +#ifndef _LIBCPP_FREESTANDING +# include <__functional/boyer_moore_searcher.h> +#endif #include <__functional/compose.h> #include <__functional/default_searcher.h> #include <__functional/function.h> Index: libcxx/include/math.h =================================================================== --- libcxx/include/math.h +++ libcxx/include/math.h @@ -299,9 +299,17 @@ # if __has_include_next() # include_next +# else +# define NAN __builtin_nanf("") +# define INFINITY __builtin_inff() +# define FP_NAN 0 +# define FP_INFINITE 1 +# define FP_ZERO 2 +# define FP_SUBNORMAL 3 +# define FP_NORMAL 4 # endif -#ifdef __cplusplus +# ifdef __cplusplus // We support including .h headers inside 'extern "C"' contexts, so switch // back to C++ linkage before including these C++ headers. @@ -1722,7 +1730,7 @@ } // extern "C++" -#endif // __cplusplus +# endif // __cplusplus #else // _LIBCPP_MATH_H Index: libcxx/include/new =================================================================== --- libcxx/include/new +++ libcxx/include/new @@ -332,7 +332,7 @@ #endif } -#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) +#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && !defined(_LIBCPP_FREESTANDING) // Low-level helpers to call the aligned allocation and deallocation functions // on the target platform. This is used to implement libc++'s own memory // allocation routines -- if you need to allocate memory inside the library, Index: libcxx/include/stdio.h =================================================================== --- libcxx/include/stdio.h +++ libcxx/include/stdio.h @@ -106,16 +106,20 @@ # if __has_include_next() # include_next +# else +# ifndef EOF +# define EOF (-1) +# endif # endif -#ifdef __cplusplus +# ifdef __cplusplus -#undef getc -#undef putc -#undef clearerr -#undef feof -#undef ferror +# undef getc +# undef putc +# undef clearerr +# undef feof +# undef ferror -#endif +# endif #endif // _LIBCPP_STDIO_H Index: libcxx/include/stdlib.h =================================================================== --- libcxx/include/stdlib.h +++ libcxx/include/stdlib.h @@ -92,33 +92,53 @@ # if __has_include_next() # include_next +# else + +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +# endif +# ifdef __cplusplus +extern "C" { +# endif +// freestanding C++ +// 17.6, start and termination +_LIBCPP_NORETURN void abort() _NOEXCEPT; +int at_quick_exit(void (*)(void)) _NOEXCEPT; +_LIBCPP_NORETURN void exit(int); +_LIBCPP_NORETURN void _Exit(int) _NOEXCEPT; +_LIBCPP_NORETURN void quick_exit(int) _NOEXCEPT; +# ifdef __cplusplus +} +# endif # endif -#ifdef __cplusplus +# ifdef __cplusplus extern "C++" { // abs - -#ifdef abs -# undef abs -#endif -#ifdef labs -# undef labs -#endif -#ifdef llabs -# undef llabs -#endif +# ifdef abs +# undef abs +# endif +# ifdef labs +# undef labs +# endif +# ifdef llabs +# undef llabs +# endif // MSVCRT already has the correct prototype in if __cplusplus is defined -#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) +# if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { return __builtin_labs(__x); } inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { return __builtin_llabs(__x); } -#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) +# endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) -#if !defined(__sun__) +# if !defined(__sun__) inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT { return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h } @@ -131,33 +151,34 @@ abs(long double __lcpp_x) _NOEXCEPT { return __builtin_fabsl(__lcpp_x); } -#endif // !defined(__sun__) +# endif // !defined(__sun__) // div -#ifdef div -# undef div -#endif -#ifdef ldiv -# undef ldiv -#endif -#ifdef lldiv -# undef lldiv -#endif - +# ifdef div +# undef div +# endif +# ifdef ldiv +# undef ldiv +# endif +# ifdef lldiv +# undef lldiv +# endif +# ifndef _LIBCPP_FREESTANDING // MSVCRT already has the correct prototype in if __cplusplus is defined -#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) +# if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT { return ::ldiv(__x, __y); } -#if !(defined(__FreeBSD__) && !defined(__LONG_LONG_SUPPORTED)) +# if !(defined(__FreeBSD__) && !defined(__LONG_LONG_SUPPORTED)) inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT { return ::lldiv(__x, __y); } -#endif -#endif // _LIBCPP_MSVCRT / __sun__ +# endif +# endif +# endif // _LIBCPP_MSVCRT / __sun__ } // extern "C++" -#endif // __cplusplus +# endif // __cplusplus #endif // _LIBCPP_STDLIB_H Index: libcxx/include/string.h =================================================================== --- libcxx/include/string.h +++ libcxx/include/string.h @@ -59,6 +59,18 @@ #if __has_include_next() # include_next +#else +# include +# ifdef __cplusplus +extern "C" { +# endif +void* memcpy(void*, void const*, size_t); +void* memmove(void*, void const*, size_t); +void* memset(void*, int, size_t); +int memcmp(void const*, void const*, size_t); +# ifdef __cplusplus +} +# endif #endif // MSVCRT, GNU libc and its derivates may already have the correct prototype in Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -220,11 +220,15 @@ # define __cpp_lib_make_reverse_iterator 201402L # define __cpp_lib_make_unique 201304L # define __cpp_lib_null_iterators 201304L -# define __cpp_lib_quoted_string_io 201304L +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_quoted_string_io 201304L +# endif # define __cpp_lib_result_of_sfinae 201210L # define __cpp_lib_robust_nonmodifying_seq_ops 201304L -# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex) -# define __cpp_lib_shared_timed_mutex 201402L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex) +# define __cpp_lib_shared_timed_mutex 201402L +# endif # endif # define __cpp_lib_string_udls 201304L # define __cpp_lib_transformation_trait_aliases 201304L @@ -246,10 +250,14 @@ # define __cpp_lib_byte 201603L # define __cpp_lib_chrono 201611L # define __cpp_lib_clamp 201603L -# define __cpp_lib_enable_shared_from_this 201603L +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_enable_shared_from_this 201603L +# endif // # define __cpp_lib_execution 201603L -# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) -# define __cpp_lib_filesystem 201703L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) +# define __cpp_lib_filesystem 201703L +# endif # endif # define __cpp_lib_gcd_lcm 201606L # if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) @@ -267,20 +275,32 @@ # define __cpp_lib_make_from_tuple 201606L # define __cpp_lib_map_try_emplace 201411L // # define __cpp_lib_math_special_functions 201603L -# define __cpp_lib_memory_resource 201603L +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_memory_resource 201603L +# endif # define __cpp_lib_node_extract 201606L # define __cpp_lib_nonmember_container_access 201411L # define __cpp_lib_not_fn 201603L # define __cpp_lib_optional 201606L -// # define __cpp_lib_parallel_algorithm 201603L +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_parallel_algorithm 201603L +# endif # define __cpp_lib_raw_memory_algorithms 201606L # define __cpp_lib_sample 201603L -# define __cpp_lib_scoped_lock 201703L -# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex) -# define __cpp_lib_shared_mutex 201505L +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_scoped_lock 201703L +# endif +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex) +# define __cpp_lib_shared_mutex 201505L +# endif +# endif +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_shared_ptr_arrays 201611L +# endif +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_shared_ptr_weak_type 201606L # endif -# define __cpp_lib_shared_ptr_arrays 201611L -# define __cpp_lib_shared_ptr_weak_type 201606L # define __cpp_lib_string_view 201606L // # define __cpp_lib_to_chars 201611L # undef __cpp_lib_transparent_operators @@ -300,13 +320,17 @@ // # define __cpp_lib_atomic_float 201711L # define __cpp_lib_atomic_lock_free_type_aliases 201907L // # define __cpp_lib_atomic_ref 201806L -// # define __cpp_lib_atomic_shared_ptr 201711L +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_atomic_shared_ptr 201711L +# endif # define __cpp_lib_atomic_value_initialization 201911L # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait) # define __cpp_lib_atomic_wait 201907L # endif -# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier) -# define __cpp_lib_barrier 201907L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier) +# define __cpp_lib_barrier 201907L +# endif # endif # define __cpp_lib_bind_front 201907L # define __cpp_lib_bit_cast 201806L @@ -336,8 +360,10 @@ # define __cpp_lib_erase_if 202002L # undef __cpp_lib_execution // # define __cpp_lib_execution 201902L -# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) -// # define __cpp_lib_format 202106L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) +// # define __cpp_lib_format 202106L +# endif # endif # define __cpp_lib_generic_unordered_lookup 201811L # define __cpp_lib_int_pow2 202002L @@ -347,31 +373,45 @@ // # define __cpp_lib_is_layout_compatible 201907L # define __cpp_lib_is_nothrow_convertible 201806L // # define __cpp_lib_is_pointer_interconvertible 201907L -# if !defined(_LIBCPP_HAS_NO_THREADS) -// # define __cpp_lib_jthread 201911L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) +// # define __cpp_lib_jthread 201911L +# endif # endif -# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch) -# define __cpp_lib_latch 201907L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch) +# define __cpp_lib_latch 201907L +# endif # endif # define __cpp_lib_list_remove_return_type 201806L # define __cpp_lib_math_constants 201907L -# define __cpp_lib_polymorphic_allocator 201902L +# ifndef LIBCXX_FREESTANDING +# define __cpp_lib_polymorphic_allocator 201902L +# endif # define __cpp_lib_ranges 201811L # define __cpp_lib_remove_cvref 201711L -# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore) -# define __cpp_lib_semaphore 201907L +# ifndef LIBCXX_FREESTANDING +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore) +# define __cpp_lib_semaphore 201907L +# endif # endif +# ifndef LIBCXX_FREESTANDING # undef __cpp_lib_shared_ptr_arrays -# define __cpp_lib_shared_ptr_arrays 201707L +# define __cpp_lib_shared_ptr_arrays 201707L +# endif # define __cpp_lib_shift 201806L -// # define __cpp_lib_smart_ptr_for_overwrite 202002L +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_smart_ptr_for_overwrite 202002L +# endif // # define __cpp_lib_source_location 201907L # define __cpp_lib_span 202002L # define __cpp_lib_ssize 201902L # define __cpp_lib_starts_ends_with 201711L # undef __cpp_lib_string_view # define __cpp_lib_string_view 201803L -// # define __cpp_lib_syncbuf 201803L +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_syncbuf 201803L +# endif // # define __cpp_lib_three_way_comparison 201907L # define __cpp_lib_to_address 201711L # define __cpp_lib_to_array 201907L @@ -408,8 +448,12 @@ // # define __cpp_lib_ranges_to_container 202202L // # define __cpp_lib_ranges_zip 202110L // # define __cpp_lib_reference_from_temporary 202202L -// # define __cpp_lib_spanstream 202106L -// # define __cpp_lib_stacktrace 202011L +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_spanstream 202106L +# endif +# ifndef LIBCXX_FREESTANDING +// # define __cpp_lib_stacktrace 202011L +# endif # define __cpp_lib_stdatomic_h 202011L # define __cpp_lib_string_contains 202011L # define __cpp_lib_string_resize_and_overwrite 202110L Index: libcxx/include/wchar.h =================================================================== --- libcxx/include/wchar.h +++ libcxx/include/wchar.h @@ -122,22 +122,35 @@ # if __has_include_next() # include_next +# else +# ifdef __cplusplus +extern "C" { +# endif +typedef unsigned wint_t; +# ifndef WEOF +# define WEOF (wint_t)(-1) +# endif +struct mbstate_t {}; +# ifdef __cplusplus +} +# endif # endif // Determine whether we have const-correct overloads for wcschr and friends. -#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_) -# define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 -#elif defined(__GLIBC_PREREQ) -# if __GLIBC_PREREQ(2, 10) -# define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 -# endif -#elif defined(_LIBCPP_MSVCRT) -# if defined(_CRT_CONST_CORRECT_OVERLOADS) +# if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_) # define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 +# elif defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 10) +# define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 +# endif +# elif defined(_LIBCPP_MSVCRT) +# if defined(_CRT_CONST_CORRECT_OVERLOADS) +# define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 +# endif # endif -#endif -#if defined(__cplusplus) && !defined(_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) +# if defined(__cplusplus) && !defined(_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) && \ + !defined(_LIBCPP_FREESTANDING) extern "C++" { inline _LIBCPP_INLINE_VISIBILITY wchar_t* __libcpp_wcschr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcschr(__s, __c);} @@ -174,15 +187,15 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return __libcpp_wmemchr(__s, __c, __n);} } -#endif +# endif -#if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT_LIKE) || defined(__MVS__)) +# if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT_LIKE) || defined(__MVS__)) && !defined(_LIBCPP_FREESTANDING) extern "C" { size_t mbsnrtowcs(wchar_t *__restrict __dst, const char **__restrict __src, size_t __nmc, size_t __len, mbstate_t *__restrict __ps); size_t wcsnrtombs(char *__restrict __dst, const wchar_t **__restrict __src, size_t __nwc, size_t __len, mbstate_t *__restrict __ps); } // extern "C" -#endif // __cplusplus && (_LIBCPP_MSVCRT || __MVS__) +# endif // __cplusplus && (_LIBCPP_MSVCRT || __MVS__) #endif // _LIBCPP_WCHAR_H Index: libcxx/test/libcxx/libcpp_freestanding.sh.cpp =================================================================== --- libcxx/test/libcxx/libcpp_freestanding.sh.cpp +++ libcxx/test/libcxx/libcpp_freestanding.sh.cpp @@ -10,11 +10,104 @@ // to the compiler but defined when -ffreestanding is passed to the compiler. // RUN: %{cxx} %{flags} %{compile_flags} -fsyntax-only %s -// RUN: %{cxx} %{flags} %{compile_flags} -fsyntax-only -ffreestanding -DFREESTANDING %s +// RUN: %{cxx} %{flags} %{compile_flags} -fsyntax-only -ffreestanding %s #include <__config> -#if defined(FREESTANDING) != defined(_LIBCPP_FREESTANDING) -#error _LIBCPP_FREESTANDING should be defined in freestanding mode and not \ - defined in non-freestanding mode +#if defined(__has_feature) +# if __has_feature(modules) +# define _LIBCPP_FREESTANDING_NO_TEST_MODULES +# endif +#elif defined(__cpp_modules) +# define _LIBCPP_FREESTANDING_NO_TEST_MODULES +#endif + +#if defined(_LIBCPP_FREESTANDING) && !defined(_LIBCPP_FREESTANDING_NO_TEST_MODULES) +# include +# include +# include +# include +# include +# include +# include +# include +# if __has_include() +# include +# endif +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +/* +We tested these headers are for preventing build issues +*/ +# include +# include +# include +# include +# include +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# include +# endif +/* + * libc++ libstdc++ like extensions + */ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +/* + * libc++ Containers Extensions + */ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# if __has_include() +# include +# endif +# include + +# if _LIBCPP_STD_VER < 20 +# include +# if __has_include() +# include +# endif +# include +# endif #endif Index: libcxx/utils/generate_feature_test_macro_components.py =================================================================== --- libcxx/utils/generate_feature_test_macro_components.py +++ libcxx/utils/generate_feature_test_macro_components.py @@ -60,6 +60,7 @@ # is only used when a feature isn't fully implemented. Once # you've fully implemented the feature, you should remove # this field. +# hosted We do not define this macro in freestanding mode. # ================ ============================================================ feature_test_macros = [ add_version_header(x) for x in [ { @@ -130,6 +131,7 @@ "values": { "c++20": 201711 }, "headers": ["atomic"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_atomic_value_initialization", "values": { "c++20": 201911 }, @@ -146,6 +148,7 @@ "headers": ["barrier"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)", + "hosted": True, }, { "name": "__cpp_lib_bind_back", "values": { "c++2b": 202202 }, @@ -291,6 +294,7 @@ "name": "__cpp_lib_enable_shared_from_this", "values": { "c++17": 201603 }, "headers": ["memory"], + "hosted": True, }, { "name": "__cpp_lib_endian", "values": { "c++20": 201907 }, @@ -317,7 +321,8 @@ "values": { "c++17": 201703 }, "headers": ["filesystem"], "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)", - "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)" + "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)", + "hosted": True, }, { "name": "__cpp_lib_format", "values": { @@ -331,6 +336,7 @@ "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)", "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)", "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_forward_like", "values": { "c++2b": 202207 }, @@ -443,12 +449,14 @@ "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_latch", "values": { "c++20": 201907 }, "headers": ["latch"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)", + "hosted": True, }, { "name": "__cpp_lib_launder", "values": { "c++17": 201606 }, @@ -490,6 +498,7 @@ "name": "__cpp_lib_memory_resource", "values": { "c++17": 201603 }, "headers": ["memory_resource"], + "hosted": True, }, { "name": "__cpp_lib_move_only_function", "values": { "c++2b": 202110 }, @@ -525,14 +534,17 @@ "values": { "c++17": 201603 }, "headers": ["algorithm", "numeric"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_polymorphic_allocator", "values": { "c++20": 201902 }, "headers": ["memory_resource"], + "hosted": True, }, { "name": "__cpp_lib_quoted_string_io", "values": { "c++14": 201304 }, "headers": ["iomanip"], + "hosted": True, }, { "name": "__cpp_lib_ranges", "values": { "c++20": 201811 }, @@ -606,32 +618,38 @@ "name": "__cpp_lib_scoped_lock", "values": { "c++17": 201703 }, "headers": ["mutex"], + "hosted": True, }, { "name": "__cpp_lib_semaphore", "values": { "c++20": 201907 }, "headers": ["semaphore"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)", + "hosted": True, }, { "name": "__cpp_lib_shared_mutex", "values": { "c++17": 201505 }, "headers": ["shared_mutex"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)", + "hosted": True, }, { "name": "__cpp_lib_shared_ptr_arrays", "values": { "c++17": 201611, "c++20": 201707 }, "headers": ["memory"], + "hosted": True, }, { "name": "__cpp_lib_shared_ptr_weak_type", "values": { "c++17": 201606 }, "headers": ["memory"], + "hosted": True, }, { "name": "__cpp_lib_shared_timed_mutex", "values": { "c++14": 201402 }, "headers": ["shared_mutex"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)", + "hosted": True, }, { "name": "__cpp_lib_shift", "values": { "c++20": 201806 }, @@ -641,6 +659,7 @@ "values": { "c++20": 202002 }, "headers": ["memory"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_source_location", "values": { "c++20": 201907 }, @@ -655,6 +674,7 @@ "values": { "c++2b": 202106 }, "headers": ["spanstream"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_ssize", "values": { "c++20": 201902 }, @@ -664,6 +684,7 @@ "values": { "c++2b": 202011 }, "headers": ["stacktrace"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_starts_ends_with", "values": { "c++20": 201711 }, @@ -693,6 +714,7 @@ "values": { "c++20": 201803 }, "headers": ["syncstream"], "unimplemented": True, + "hosted": True, }, { "name": "__cpp_lib_three_way_comparison", "values": { "c++20": 201907 }, @@ -769,7 +791,7 @@ assert feature_test_macros == sorted(feature_test_macros, key=lambda tc: tc["name"]) assert all(tc["headers"] == sorted(tc["headers"]) for tc in feature_test_macros) assert all(("libcxx_guard" in tc) == ("test_suite_guard" in tc) for tc in feature_test_macros) -assert all(all(key in ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented"] for key in tc.keys()) for tc in feature_test_macros) +assert all(all(key in ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented", "hosted"] for key in tc.keys()) for tc in feature_test_macros) # Map from each header to the Lit annotations that should be used for # tests that include that header. @@ -856,9 +878,16 @@ for tc in feature_test_macros: if std not in tc["values"]: continue + ishosted = "hosted" in tc.keys() inner_indent = 1 + if ishosted: + result += "# ifndef LIBCXX_FREESTANDING\n" + inner_indent += 2 if 'test_suite_guard' in tc.keys(): - result += "# if %s\n" % tc["libcxx_guard"] + ishosted_test_guard = "# if %s\n" + if ishosted: + ishosted_test_guard = "# if %s\n" + result += ishosted_test_guard % tc["libcxx_guard"] inner_indent += 2 if get_value_before(tc["values"], std) is not None: assert 'test_suite_guard' not in tc.keys() @@ -871,6 +900,11 @@ result += line result += "\n" if 'test_suite_guard' in tc.keys(): + if ishosted: + result += "# endif\n" + else: + result += "# endif\n" + if ishosted: result += "# endif\n" return result.strip()