Index: libcxx/CMakeLists.txt =================================================================== --- libcxx/CMakeLists.txt +++ libcxx/CMakeLists.txt @@ -103,7 +103,19 @@ to provide compile-time errors when using features unavailable on some version of the shared library they shipped should turn this on and see `include/__availability` for more details." OFF) - +option(LIBCXX_FREESTANDING + "Build libc++ with freestanding headers. This toggle allows the libc to work for + freestanding environments like operating systems kernels or embedded systems." OFF) + +if (LIBCXX_FREESTANDING) + set(LIBCXX_ENABLE_FILESYSTEM 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) @@ -121,6 +133,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'.") @@ -134,6 +148,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") @@ -321,9 +339,13 @@ # 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) +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) @@ -866,6 +888,9 @@ else() config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) endif() +if (LIBCXX_FREESTANDING) + config_define(1 _LIBCPP_FREESTANDING) +endif() if (LIBCXX_ABI_DEFINES) set(abi_defines) @@ -919,8 +944,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 @@ -641,6 +641,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&); @@ -678,6 +679,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/__compare/strong_order.h =================================================================== --- libcxx/include/__compare/strong_order.h +++ libcxx/include/__compare/strong_order.h @@ -15,7 +15,9 @@ #include <__config> #include <__utility/forward.h> #include <__utility/priority_tag.h> -#include +#ifndef _LIBCPP_FREESTANDING +# include +#endif #include #include #include @@ -41,7 +43,7 @@ noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } - +# ifndef _LIBCPP_FREESTANDING template> requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering @@ -106,7 +108,7 @@ } } } - +# endif template requires is_same_v, decay_t<_Up>> _LIBCPP_HIDE_FROM_ABI static constexpr auto Index: libcxx/include/__compare/weak_order.h =================================================================== --- libcxx/include/__compare/weak_order.h +++ libcxx/include/__compare/weak_order.h @@ -15,7 +15,9 @@ #include <__config> #include <__utility/forward.h> #include <__utility/priority_tag.h> -#include +#ifndef _LIBCPP_FREESTANDING +# include +#endif #include #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -36,7 +38,7 @@ noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } - +# ifndef _LIBCPP_FREESTANDING template> requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering @@ -64,7 +66,7 @@ } } } - +# endif template requires is_same_v, decay_t<_Up>> _LIBCPP_HIDE_FROM_ABI static constexpr auto 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__) && !defined(_LIBCPP_FREESTANDING) # 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__) && !defined(_LIBCPP_FREESTANDING) # include // for __NATIVE_ASCII_F # endif @@ -285,7 +285,7 @@ # endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # endif // __BYTE_ORDER__ -# ifdef __FreeBSD__ +# if defined(__FreeBSD__) && !defined(_LIBCPP_FREESTANDING) # 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__)) && !defined(_LIBCPP_FREESTANDING) # 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__) && !defined(_LIBCPP_FREESTANDING) # include # ifdef _LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN @@ -866,6 +866,11 @@ # define _LIBCPP_WEAK __attribute__((__weak__)) # endif +# if defined(_LIBCPP_FREESTANDING) && \ + !defined(_LIBCPP_HAS_NO_THREADS) +# define _LIBCPP_HAS_NO_THREADS +#endif + // Thread API // clang-format off # if !defined(_LIBCPP_HAS_NO_THREADS) && \ 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/__random/uniform_int_distribution.h =================================================================== --- libcxx/include/__random/uniform_int_distribution.h +++ libcxx/include/__random/uniform_int_distribution.h @@ -16,7 +16,9 @@ #include #include #include -#include +#ifndef _LIBCPP_FREESTANDING +# include +#endif #include #include Index: libcxx/include/__string/char_traits.h =================================================================== --- libcxx/include/__string/char_traits.h +++ libcxx/include/__string/char_traits.h @@ -21,12 +21,14 @@ #include <__type_traits/is_constant_evaluated.h> #include #include -#include +#ifndef _LIBCPP_FREESTANDING +# include +#endif #include #include -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -# include // for wmemcpy +#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) +# include // for wmemcpy #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -166,8 +168,13 @@ {return int_type(__c);} static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { +#ifdef EOF + return int_type(EOF); +#else + return int_type(-1); +#endif + } }; template @@ -254,8 +261,13 @@ {return int_type((unsigned char)__c);} static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { +#ifdef EOF + return int_type(EOF); +#else + return int_type(-1); +#endif + } }; // char_traits @@ -265,7 +277,11 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { using char_type = wchar_t; +# ifdef WEOF using int_type = wint_t; +# else + using int_type = unsigned; +# endif using off_type = streamoff; using pos_type = streampos; using state_type = mbstate_t; @@ -324,8 +340,13 @@ {return int_type(__c);} static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(WEOF);} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { +# ifdef WEOF + return int_type(WEOF); +# else + return int_type(-1); +# endif + } }; #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS @@ -388,8 +409,13 @@ {return int_type(__c);} static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept {return __c1 == __c2;} - static inline constexpr int_type eof() noexcept - {return int_type(EOF);} + static inline constexpr int_type eof() noexcept { +# ifdef EOF + return int_type(EOF); +# else + return int_type(-1); +# endif + } }; // TODO use '__builtin_strlen' if it ever supports char8_t ?? Index: libcxx/include/__thread/poll_with_backoff.h =================================================================== --- libcxx/include/__thread/poll_with_backoff.h +++ libcxx/include/__thread/poll_with_backoff.h @@ -9,11 +9,12 @@ #ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H #define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H - -#include <__availability> -#include <__chrono/duration.h> -#include <__chrono/high_resolution_clock.h> #include <__config> +#ifndef _LIBCPP_FREESTANDING +# include <__availability> +# include <__chrono/duration.h> +# include <__chrono/high_resolution_clock.h> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#ifdef _LIBCPP_FREESTANDING + +template +_LIBCPP_INLINE_VISIBILITY bool __libcpp_thread_poll_with_backoff_freestanding(_Fn&& __f) { + for (;;) { + if (__f()) + return true; // _Fn completion means success + } +} +#else + 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 @@ -34,6 +46,7 @@ // // - __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. + 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()) { @@ -52,7 +65,7 @@ return false; // _BFn completion means failure } } - +#endif // A trivial backoff policy that always immediately returns the control to // the polling loop. // Index: libcxx/include/atomic =================================================================== --- libcxx/include/atomic +++ libcxx/include/atomic @@ -523,7 +523,9 @@ #include <__chrono/duration.h> #include <__config> #include <__thread/poll_with_backoff.h> -#include <__thread/timed_backoff_policy.h> +#ifndef _LIBCPP_FREESTANDING +# include <__thread/timed_backoff_policy.h> +#endif #include #include #include @@ -1469,8 +1471,12 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) { +#ifdef _LIBCPP_FREESTANDING + return __libcpp_thread_poll_with_backoff_freestanding(__test_fn); +#else __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn}; return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); +#endif } #else // _LIBCPP_HAS_NO_THREADS @@ -1482,7 +1488,11 @@ template _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) { +#ifdef _LIBCPP_FREESTANDING + return __libcpp_thread_poll_with_backoff_freestanding(__test_fn); +#else return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); +#endif } #endif // _LIBCPP_HAS_NO_THREADS 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/cstdlib =================================================================== --- libcxx/include/cstdlib +++ libcxx/include/cstdlib @@ -94,6 +94,8 @@ not be the case. #endif +#ifndef _LIBCPP_FREESTANDING + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif @@ -150,4 +152,6 @@ _LIBCPP_END_NAMESPACE_STD +#endif + #endif // _LIBCPP_CSTDLIB 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/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/new =================================================================== --- libcxx/include/new +++ libcxx/include/new @@ -330,7 +330,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/numeric =================================================================== --- libcxx/include/numeric +++ libcxx/include/numeric @@ -146,7 +146,9 @@ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#ifndef _LIBCPP_FREESTANDING #include // for isnormal +#endif #include #include <__numeric/accumulate.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 @@ -208,8 +208,10 @@ // clang-format off #if _LIBCPP_STD_VER > 11 +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_chrono_udls 201304L # define __cpp_lib_complex_udls 201309L +# endif # define __cpp_lib_exchange_function 201304L # define __cpp_lib_generic_associative_lookup 201304L # define __cpp_lib_integer_sequence 201304L @@ -219,13 +221,17 @@ # define __cpp_lib_make_reverse_iterator 201402L # define __cpp_lib_make_unique 201304L # define __cpp_lib_null_iterators 201304L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_quoted_string_io 201304L +# endif # define __cpp_lib_result_of_sfinae 201210L # define __cpp_lib_robust_nonmodifying_seq_ops 201304L +# ifndef _LIBCPP_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 # define __cpp_lib_string_udls 201304L +# endif # define __cpp_lib_transformation_trait_aliases 201304L # define __cpp_lib_transparent_operators 201210L # define __cpp_lib_tuple_element_t 201402L @@ -241,22 +247,30 @@ # define __cpp_lib_as_const 201510L # define __cpp_lib_atomic_is_always_lock_free 201603L # define __cpp_lib_bool_constant 201505L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_boyer_moore_searcher 201603L +# endif # define __cpp_lib_byte 201603L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_chrono 201611L +# endif # define __cpp_lib_clamp 201603L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_enable_shared_from_this 201603L // # define __cpp_lib_execution 201603L # 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) # define __cpp_lib_hardware_interference_size 201703L # endif # define __cpp_lib_has_unique_object_representations 201606L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_hypot 201603L # define __cpp_lib_incomplete_container_elements 201505L +# endif # define __cpp_lib_invoke 201411L # define __cpp_lib_is_aggregate 201703L # define __cpp_lib_is_invocable 201703L @@ -264,29 +278,39 @@ # define __cpp_lib_launder 201606L # define __cpp_lib_logical_traits 201510L # define __cpp_lib_make_from_tuple 201606L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_map_try_emplace 201411L // # define __cpp_lib_math_special_functions 201603L # define __cpp_lib_memory_resource 201603L # define __cpp_lib_node_extract 201606L # define __cpp_lib_nonmember_container_access 201411L +# endif # define __cpp_lib_not_fn 201603L # define __cpp_lib_optional 201606L +# ifndef _LIBCPP_FREESTANDING // # define __cpp_lib_parallel_algorithm 201603L # define __cpp_lib_raw_memory_algorithms 201606L +# endif # define __cpp_lib_sample 201603L +# ifndef _LIBCPP_FREESTANDING # 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 # endif # define __cpp_lib_shared_ptr_arrays 201611L # define __cpp_lib_shared_ptr_weak_type 201606L +# endif # define __cpp_lib_string_view 201606L +# ifndef _LIBCPP_FREESTANDING // # define __cpp_lib_to_chars 201611L +# endif # undef __cpp_lib_transparent_operators # define __cpp_lib_transparent_operators 201510L # define __cpp_lib_type_trait_variable_templates 201510L # define __cpp_lib_uncaught_exceptions 201411L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_unordered_map_try_emplace 201411L +# endif # define __cpp_lib_variant 202102L # define __cpp_lib_void_t 201411L #endif @@ -322,11 +346,15 @@ # define __cpp_lib_constexpr_iterator 201811L # define __cpp_lib_constexpr_memory 201811L # define __cpp_lib_constexpr_numeric 201911L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_constexpr_string 201907L +# endif # define __cpp_lib_constexpr_string_view 201811L # define __cpp_lib_constexpr_tuple 201811L # define __cpp_lib_constexpr_utility 201811L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_constexpr_vector 201907L +# endif # define __cpp_lib_coroutine 201902L # if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L # define __cpp_lib_destroying_delete 201806L @@ -335,10 +363,12 @@ # define __cpp_lib_erase_if 202002L # undef __cpp_lib_execution // # define __cpp_lib_execution 201902L +# ifndef _LIBCPP_FREESTANDING # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) // # define __cpp_lib_format 202106L # endif # define __cpp_lib_generic_unordered_lookup 201811L +# endif # define __cpp_lib_int_pow2 202002L # define __cpp_lib_integer_comparison_functions 202002L # define __cpp_lib_interpolate 201902L @@ -346,6 +376,7 @@ // # define __cpp_lib_is_layout_compatible 201907L # define __cpp_lib_is_nothrow_convertible 201806L // # define __cpp_lib_is_pointer_interconvertible 201907L +# ifndef _LIBCPP_FREESTANDING # if !defined(_LIBCPP_HAS_NO_THREADS) // # define __cpp_lib_jthread 201911L # endif @@ -353,15 +384,21 @@ # define __cpp_lib_latch 201907L # endif # define __cpp_lib_list_remove_return_type 201806L +# endif # define __cpp_lib_math_constants 201907L +# ifndef _LIBCPP_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) +# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore) && \ + !defined(_LIBCPP_FREESTANDING) # define __cpp_lib_semaphore 201907L # endif # undef __cpp_lib_shared_ptr_arrays +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_shared_ptr_arrays 201707L +# endif # define __cpp_lib_shift 201806L // # define __cpp_lib_smart_ptr_for_overwrite 202002L // # define __cpp_lib_source_location 201907L @@ -381,11 +418,15 @@ #if _LIBCPP_STD_VER > 20 # define __cpp_lib_adaptor_iterator_pair_constructor 202106L # define __cpp_lib_allocate_at_least 202106L +# ifndef _LIBCPP_FREESTANDING // # define __cpp_lib_associative_heterogeneous_erasure 202110L // # define __cpp_lib_bind_back 202202L +# endif # define __cpp_lib_byteswap 202110L # define __cpp_lib_constexpr_bitset 202207L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_constexpr_charconv 202207L +# endif // # define __cpp_lib_constexpr_cmath 202202L # undef __cpp_lib_constexpr_memory # define __cpp_lib_constexpr_memory 202202L @@ -406,11 +447,15 @@ // # define __cpp_lib_ranges_to_container 202202L // # define __cpp_lib_ranges_zip 202110L // # define __cpp_lib_reference_from_temporary 202202L +# ifndef _LIBCPP_FREESTANDING // # define __cpp_lib_spanstream 202106L // # define __cpp_lib_stacktrace 202011L +# endif # define __cpp_lib_stdatomic_h 202011L +# ifndef _LIBCPP_FREESTANDING # define __cpp_lib_string_contains 202011L # define __cpp_lib_string_resize_and_overwrite 202110L +# endif # define __cpp_lib_to_underlying 202102L # define __cpp_lib_unreachable 202202L #endif Index: libcxx/include/wchar.h =================================================================== --- libcxx/include/wchar.h +++ libcxx/include/wchar.h @@ -122,22 +122,31 @@ # if __has_include_next() # include_next +# else +# ifdef __cplusplus +extern "C" { +# 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 +183,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 @@ -14,7 +14,47 @@ #include <__config> -#if defined(FREESTANDING) != defined(_LIBCPP_FREESTANDING) -#error _LIBCPP_FREESTANDING should be defined in freestanding mode and not \ - defined in non-freestanding mode +#ifdef _LIBCPP_FREESTANDING +# 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 +/* + * libc++ Extensions + * just like libstdc++ do + */ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif