Index: libcxx/CMakeLists.txt =================================================================== --- libcxx/CMakeLists.txt +++ libcxx/CMakeLists.txt @@ -101,59 +101,71 @@ 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) - -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") -elseif(MINGW) - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-mingw.cfg.in") -elseif(WIN32) # clang-cl - if (LIBCXX_ENABLE_SHARED) - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-clangcl.cfg.in") - else() - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static-clangcl.cfg.in") - endif() +option(LIBCXX_FREESTANDING OFF + "Build libc++ with freestanding headers. This toggle allows the libc to work for + freestanding environments like operating systems kernels or embedded systems.") + +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) else() - if (LIBCXX_ENABLE_SHARED) - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared.cfg.in") + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") + elseif(MINGW) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-mingw.cfg.in") + elseif(WIN32) # clang-cl + if (LIBCXX_ENABLE_SHARED) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-clangcl.cfg.in") + else() + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static-clangcl.cfg.in") + endif() else() - set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static.cfg.in") + if (LIBCXX_ENABLE_SHARED) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared.cfg.in") + else() + 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'.") -if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}") - set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}") -endif() -message(STATUS "Using libc++ testing configuration: ${LIBCXX_TEST_CONFIG}") -set(LIBCXX_TEST_PARAMS "" CACHE STRING - "A list of parameters to run the Lit test suite with.") - -# Benchmark options ----------------------------------------------------------- -option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON) - -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") - -set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING - "Build the benchmarks against the specified native STL. - The value must be one of libc++/libstdc++") -set(LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN "" CACHE STRING - "Use alternate GCC toolchain when building the native benchmarks") - -if (LIBCXX_BENCHMARK_NATIVE_STDLIB) - if (NOT (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++" - OR LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")) - message(FATAL_ERROR "Invalid value for LIBCXX_BENCHMARK_NATIVE_STDLIB: " - "'${LIBCXX_BENCHMARK_NATIVE_STDLIB}'") + 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'.") + if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}") + set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}") + endif() + message(STATUS "Using libc++ testing configuration: ${LIBCXX_TEST_CONFIG}") + set(LIBCXX_TEST_PARAMS "" CACHE STRING + "A list of parameters to run the Lit test suite with.") + + # Benchmark options ----------------------------------------------------------- + option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON) + + 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") + + set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING + "Build the benchmarks against the specified native STL. + The value must be one of libc++/libstdc++") + set(LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN "" CACHE STRING + "Use alternate GCC toolchain when building the native benchmarks") + + if (LIBCXX_BENCHMARK_NATIVE_STDLIB) + if (NOT (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++" + OR LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")) + message(FATAL_ERROR "Invalid value for LIBCXX_BENCHMARK_NATIVE_STDLIB: " + "'${LIBCXX_BENCHMARK_NATIVE_STDLIB}'") + endif() endif() endif() - option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS}) set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) +if(NOT LIBCXX_FREESTANDING) option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON) cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY "Install the static libc++ library." ON @@ -161,6 +173,7 @@ cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY "Install the shared libc++ library." ON "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF) +endif() option(LIBCXX_ABI_UNSTABLE "Use the unstable ABI of libc++. This is equivalent to specifying LIBCXX_ABI_VERSION=n, where n is the not-yet-stable version." OFF) if (LIBCXX_ABI_UNSTABLE) @@ -299,6 +312,11 @@ set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING "The Profile-rt library used to build with code coverage") +if (LIBCXX_FREESTANDING) +set(LIBCXX_ENABLE_THREADS OFF) +set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF) +endif() + set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF) if (XCODE OR MSVC_IDE) set(LIBCXX_CONFIGURE_IDE_DEFAULT ON) @@ -319,6 +337,7 @@ # Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when # LIBCXX_ENABLE_THREADS is on. +if (NOT LIBCXX_FREESTANDING) 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.") @@ -341,7 +360,6 @@ message(FATAL_ERROR "LIBCXX_HAS_WIN32_THREAD_API can only be set to ON" " when LIBCXX_ENABLE_THREADS is also set to ON.") endif() - endif() if (LIBCXX_HAS_EXTERNAL_THREAD_API) @@ -394,7 +412,7 @@ if (LIBCXX_ABI_FORCE_ITANIUM AND LIBCXX_ABI_FORCE_MICROSOFT) message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.") endif () - +endif () #=============================================================================== # Configure System #=============================================================================== @@ -745,7 +763,7 @@ # default libunwind (which may be missing still). target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none") endif() - + if (NOT LIBCXX_FREESTANDING) if (LIBCXX_HAS_SYSTEM_LIB) target_link_libraries(${target} PRIVATE System) endif() @@ -799,12 +817,12 @@ # Required for standards-complaint wide character formatting functions # (e.g. `printfw`/`scanfw`) target_link_libraries(${target} PRIVATE iso_stdio_wide_specifiers) - endif() - + endif() if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21) target_link_libraries(${target} PUBLIC android_support) endif() target_link_libraries(${target} PUBLIC "${LIBCXX_ADDITIONAL_LIBRARIES}") + endif() endfunction() # Windows-related flags ======================================================= @@ -870,6 +888,10 @@ 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) foreach (abi_define ${LIBCXX_ABI_DEFINES}) @@ -922,6 +944,7 @@ # Setup Source Code And Tests #=============================================================================== add_subdirectory(include) +if (NOT LIBCXX_FREESTANDING) add_subdirectory(src) add_subdirectory(utils) @@ -939,6 +962,7 @@ add_subdirectory(test) add_subdirectory(lib/abi) endif() +endif() if (LIBCXX_INCLUDE_DOCS) add_subdirectory(docs) 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> +#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> +#ifndef _LIBCPP_FREESTANDING #include +#endif #include #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -37,6 +39,7 @@ -> 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,6 +67,7 @@ } } } +#endif template requires is_same_v, decay_t<_Up>> Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -32,6 +32,11 @@ # define _LIBCPP_COMPILER_GCC #endif +# if __STDC_HOSTED__ == 0 +# undef _LIBCPP_FREESTANDING +# define _LIBCPP_FREESTANDING +# endif + #ifdef __cplusplus // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. @@ -46,10 +51,6 @@ // generate identifiers that must be unique for every released libc++ version. # define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION) -# if __STDC_HOSTED__ == 0 -# define _LIBCPP_FREESTANDING -# endif - # ifndef _LIBCPP_STD_VER # if __cplusplus <= 201103L # define _LIBCPP_STD_VER 11 @@ -253,16 +254,20 @@ // Need to detect which libc we're using if we're on Linux. # if defined(__linux__) -# include -# if defined(__GLIBC_PREREQ) -# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) -# else -# define _LIBCPP_GLIBC_PREREQ(a, b) 0 -# endif // defined(__GLIBC_PREREQ) +# if __has_include() +# include +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) +# endif # endif // defined(__linux__) # if defined(__MVS__) -# include // for __NATIVE_ASCII_F +# if __has_include() +# include // for __NATIVE_ASCII_F +# endif # endif # ifdef __LITTLE_ENDIAN__ @@ -286,22 +291,26 @@ # endif // __BYTE_ORDER__ # ifdef __FreeBSD__ -# include -# include -# if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# if __has_include() && __has_include() +# include +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# endif # endif // __FreeBSD__ # if defined(__NetBSD__) || defined(__OpenBSD__) -# include -# if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# if __has_include() +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# endif # endif // defined(__NetBSD__) || defined(__OpenBSD__) # if defined(_WIN32) @@ -322,11 +331,13 @@ # endif // defined(_WIN32) # ifdef __sun__ +# if __has_include() # include -# ifdef _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else -# define _LIBCPP_BIG_ENDIAN +# ifdef _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else +# define _LIBCPP_BIG_ENDIAN +# endif # endif # endif // __sun__ Index: libcxx/include/__config_site.in =================================================================== --- libcxx/include/__config_site.in +++ libcxx/include/__config_site.in @@ -31,6 +31,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 +#ifndef _LIBCPP_FREESTANDING #include +#endif #include #include @@ -254,6 +256,8 @@ return static_cast(__u + __p.a()); } +#ifndef _LIBCPP_FREESTANDING + template _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, @@ -285,6 +289,7 @@ __x.param(param_type(__a, __b)); return __is; } +#endif _LIBCPP_END_NAMESPACE_STD Index: libcxx/include/__string/char_traits.h =================================================================== --- libcxx/include/__string/char_traits.h +++ libcxx/include/__string/char_traits.h @@ -21,10 +21,12 @@ #include <__type_traits/is_constant_evaluated.h> #include #include +#ifndef _LIBCPP_FREESTANDING #include +#endif #include -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && !defined(_LIBCPP_FREESTANDING) # include // for wmemcpy #endif @@ -42,10 +44,11 @@ { using char_type = _CharT; using int_type = int; +#ifndef _LIBCPP_FREESTANDING using off_type = streamoff; using pos_type = streampos; using state_type = mbstate_t; - +#endif static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17 assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT @@ -67,17 +70,20 @@ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type* assign(char_type* __s, size_t __n, char_type __a); - +#if defined(EOF) static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} +#endif static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {return char_type(__c);} static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {return int_type(__c);} static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {return __c1 == __c2;} +#if defined(EOF) static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT {return int_type(EOF);} +#endif }; template @@ -191,9 +197,11 @@ { using char_type = char; using int_type = int; +#ifndef _LIBCPP_FREESTANDING using off_type = streamoff; using pos_type = streampos; using state_type = mbstate_t; +#endif #if _LIBCPP_STD_VER > 17 using comparison_category = strong_ordering; #endif @@ -243,17 +251,20 @@ std::fill_n(__s, __n, __a); return __s; } - +#if defined(EOF) static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} +#endif static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {return char_type(__c);} static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {return int_type((unsigned char)__c);} static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {return __c1 == __c2;} +#if defined(EOF) static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT {return int_type(EOF);} +#endif }; inline _LIBCPP_CONSTEXPR_SINCE_CXX17 @@ -307,10 +318,12 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { using char_type = wchar_t; +#if defined(WEOF) using int_type = wint_t; using off_type = streamoff; using pos_type = streampos; using state_type = mbstate_t; +#endif #if _LIBCPP_STD_VER > 17 using comparison_category = strong_ordering; #endif @@ -347,17 +360,19 @@ std::fill_n(__s, __n, __a); return __s; } - +#if defined(WEOF) static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {return char_type(__c);} static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {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);} +#endif }; inline _LIBCPP_CONSTEXPR_SINCE_CXX17 @@ -368,7 +383,7 @@ return 0; #if __has_feature(cxx_constexpr_string_builtins) return __builtin_wmemcmp(__s1, __s2, __n); -#elif _LIBCPP_STD_VER <= 14 +#elif _LIBCPP_STD_VER <= 14 && !defined(_LIBCPP_FREESTANDING) return _VSTD::wmemcmp(__s1, __s2, __n); #else for (; __n; --__n, ++__s1, ++__s2) @@ -406,7 +421,7 @@ return nullptr; #if __has_feature(cxx_constexpr_string_builtins) return __builtin_wmemchr(__s, __a, __n); -#elif _LIBCPP_STD_VER <= 14 +#elif _LIBCPP_STD_VER <= 14 && !defined(_LIBCPP_FREESTANDING) return _VSTD::wmemchr(__s, __a, __n); #else for (; __n; --__n) @@ -427,9 +442,11 @@ { using char_type = char8_t; using int_type = unsigned int; +#ifndef _LIBCPP_FREESTANDING using off_type = streamoff; using pos_type = u8streampos; using state_type = mbstate_t; +#endif #if _LIBCPP_STD_VER > 17 using comparison_category = strong_ordering; #endif @@ -468,17 +485,20 @@ std::fill_n(__s, __n, __a); return __s; } - +#if defined(EOF) static inline constexpr int_type not_eof(int_type __c) noexcept {return eq_int_type(__c, eof()) ? ~eof() : __c;} +#endif static inline constexpr char_type to_char_type(int_type __c) noexcept {return char_type(__c);} static inline constexpr int_type to_int_type(char_type __c) noexcept {return int_type(__c);} static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept {return __c1 == __c2;} +#if defined(EOF) static inline constexpr int_type eof() noexcept {return int_type(EOF);} +#endif }; // TODO use '__builtin_strlen' if it ever supports char8_t ?? @@ -531,9 +551,11 @@ { using char_type = char16_t; using int_type = uint_least16_t; +#ifndef _LIBCPP_FREESTANDING using off_type = streamoff; using pos_type = u16streampos; using state_type = mbstate_t; +#endif #if _LIBCPP_STD_VER > 17 using comparison_category = strong_ordering; #endif @@ -625,9 +647,11 @@ { using char_type = char32_t; using int_type = uint_least32_t; +#ifndef _LIBCPP_FREESTANDING using off_type = streamoff; using pos_type = u32streampos; using state_type = mbstate_t; +#endif #if _LIBCPP_STD_VER > 17 using comparison_category = strong_ordering; #endif Index: libcxx/include/__thread/poll_with_backoff.h =================================================================== --- libcxx/include/__thread/poll_with_backoff.h +++ libcxx/include/__thread/poll_with_backoff.h @@ -9,13 +9,16 @@ #ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H #define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H +#include <__config> + +#ifndef _LIBCPP_FREESTANDING #include <__availability> #include <__chrono/duration.h> #include <__chrono/high_resolution_clock.h> #include <__chrono/steady_clock.h> #include <__chrono/time_point.h> -#include <__config> #include <__filesystem/file_time_type.h> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,6 +26,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_INLINE_VISIBILITY +bool __libcpp_thread_poll_with_backoff_freestanding(_Fn&& __f) { + for (;;) { + if (__f()) + return true; // _Fn completion means success + } +} + +#ifndef _LIBCPP_FREESTANDING 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 @@ -55,6 +69,7 @@ } } + // A trivial backoff policy that always immediately returns the control to // the polling loop. // @@ -67,7 +82,7 @@ return false; } }; - +#endif _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___THREAD_POLL_WITH_BACKOFF_H Index: libcxx/include/atomic =================================================================== --- libcxx/include/atomic +++ libcxx/include/atomic @@ -523,14 +523,16 @@ #include <__chrono/duration.h> #include <__config> #include <__thread/poll_with_backoff.h> +#ifndef _LIBCPP_FREESTANDING #include <__thread/timed_backoff_policy.h> +#endif #include #include #include #include #include -#ifndef _LIBCPP_HAS_NO_THREADS +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_FREESTANDING) # include <__threading_support> #endif @@ -1431,7 +1433,7 @@ using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; -#ifndef _LIBCPP_HAS_NO_THREADS +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_FREESTANDING) _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); @@ -1482,7 +1484,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/bitset =================================================================== --- libcxx/include/bitset +++ libcxx/include/bitset @@ -127,8 +127,10 @@ // standard-mandated includes // [bitset.syn] +#ifndef _LIBCPP_FREESTANDING #include #include +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -691,11 +693,17 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : base(__v) {} + template::value> > _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(const _CharT* __str, +#ifndef _LIBCPP_FREESTANDING typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos, +#else + ::std::size_t __n = ::std::size_t(-1), +#endif _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); +#ifndef _LIBCPP_FREESTANDING template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, @@ -703,7 +711,7 @@ typename basic_string<_CharT,_Traits,_Allocator>::size_type __n = (basic_string<_CharT,_Traits,_Allocator>::npos), _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); - +#endif // 23.3.5.2 bitset operations: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator&=(const bitset& __rhs) _NOEXCEPT; @@ -741,6 +749,7 @@ unsigned long to_ulong() const; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const; +#ifndef _LIBCPP_FREESTANDING template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'), @@ -756,6 +765,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string, allocator > to_string(char __zero = '0', char __one = '1') const; +#endif _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;} @@ -787,7 +797,11 @@ template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>::bitset(const _CharT* __str, +#ifdef _LIBCPP_FREESTANDING + _VSTD::size_t __n, +#else typename basic_string<_CharT>::size_type __n, +#endif _CharT __zero, _CharT __one) { size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str)); @@ -804,7 +818,7 @@ } _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); } - +#ifndef _LIBCPP_FREESTANDING template template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 @@ -830,6 +844,7 @@ } _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); } +#endif template inline @@ -979,6 +994,7 @@ return base::to_ullong(); } +#ifndef _LIBCPP_FREESTANDING template template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 @@ -1022,6 +1038,7 @@ { return to_string, allocator >(__zero, __one); } +#endif template inline @@ -1140,6 +1157,7 @@ {return __bs.__hash_code();} }; +#ifndef _LIBCPP_FREESTANDING template _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x); @@ -1147,6 +1165,7 @@ template _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x); +#endif _LIBCPP_END_NAMESPACE_STD Index: libcxx/include/compare =================================================================== --- libcxx/include/compare +++ libcxx/include/compare @@ -141,6 +141,7 @@ */ #include <__assert> // all public C++ headers provide the assertion handler +#include <__config> #include <__compare/common_comparison_category.h> #include <__compare/compare_partial_order_fallback.h> #include <__compare/compare_strong_order_fallback.h> Index: libcxx/include/cstdlib =================================================================== --- libcxx/include/cstdlib +++ libcxx/include/cstdlib @@ -84,6 +84,34 @@ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if defined(_LIBCPP_FREESTANDING) + +// Referenced from GNU libstdc++ +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +extern "C" _LIBCPP_NORETURN void abort(void) _NOEXCEPT; +extern "C" int atexit(void (*)(void)) _NOEXCEPT; +extern "C" _LIBCPP_NORETURN void exit(int) _NOEXCEPT; +#if __cplusplus >= 201103L +extern "C" int at_quick_exit(void (*)(void)) _NOEXCEPT; +extern "C" _LIBCPP_NORETURN void quick_exit(int) _NOEXCEPT; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#else + #include #ifndef _LIBCPP_STDLIB_H @@ -94,10 +122,6 @@ not be the case. #endif -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - _LIBCPP_BEGIN_NAMESPACE_STD using ::size_t _LIBCPP_USING_IF_EXISTS; @@ -149,5 +173,6 @@ #endif _LIBCPP_END_NAMESPACE_STD +#endif #endif // _LIBCPP_CSTDLIB Index: libcxx/include/functional =================================================================== --- libcxx/include/functional +++ libcxx/include/functional @@ -512,10 +512,14 @@ #include <__functional/bind_front.h> #include <__functional/binder1st.h> #include <__functional/binder2nd.h> +#ifndef _LIBCPP_FREESTANDING #include <__functional/boyer_moore_searcher.h> +#endif #include <__functional/compose.h> #include <__functional/default_searcher.h> +#ifndef _LIBCPP_FREESTANDING #include <__functional/function.h> +#endif #include <__functional/hash.h> #include <__functional/identity.h> #include <__functional/invoke.h> Index: libcxx/include/iosfwd =================================================================== --- libcxx/include/iosfwd +++ libcxx/include/iosfwd @@ -96,7 +96,9 @@ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#ifndef _LIBCPP_FREESTANDING #include <__mbstate_t.h> +#endif #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -105,7 +107,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#ifndef _LIBCPP_FREESTANDING class _LIBCPP_TYPE_VIS ios_base; +#endif template struct _LIBCPP_TEMPLATE_VIS char_traits; template<> struct char_traits; @@ -118,6 +122,8 @@ template<> struct char_traits; #endif + +#ifndef _LIBCPP_FREESTANDING template class _LIBCPP_TEMPLATE_VIS allocator; template > @@ -285,6 +291,8 @@ } }; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_IOSFWD Index: libcxx/include/iterator =================================================================== --- libcxx/include/iterator +++ libcxx/include/iterator @@ -693,8 +693,10 @@ #include <__iterator/incrementable_traits.h> #include <__iterator/indirectly_comparable.h> #include <__iterator/insert_iterator.h> +#ifndef _LIBCPP_FREESTANDING #include <__iterator/istream_iterator.h> #include <__iterator/istreambuf_iterator.h> +#endif #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> #include <__iterator/iterator.h> @@ -703,8 +705,10 @@ #include <__iterator/move_iterator.h> #include <__iterator/move_sentinel.h> #include <__iterator/next.h> +#ifndef _LIBCPP_FREESTANDING #include <__iterator/ostream_iterator.h> #include <__iterator/ostreambuf_iterator.h> +#endif #include <__iterator/permutable.h> #include <__iterator/prev.h> #include <__iterator/projected.h> Index: libcxx/include/memory =================================================================== --- libcxx/include/memory +++ libcxx/include/memory @@ -866,11 +866,15 @@ #include <__memory/align.h> #include <__memory/allocate_at_least.h> #include <__memory/allocation_guard.h> +#ifndef _LIBCPP_FREESTANDING #include <__memory/allocator.h> +#endif #include <__memory/allocator_arg_t.h> #include <__memory/allocator_traits.h> #include <__memory/assume_aligned.h> +#ifndef _LIBCPP_FREESTANDING #include <__memory/auto_ptr.h> +#endif #include <__memory/compressed_pair.h> #include <__memory/concepts.h> #include <__memory/construct_at.h> @@ -878,7 +882,9 @@ #include <__memory/ranges_construct_at.h> #include <__memory/ranges_uninitialized_algorithms.h> #include <__memory/raw_storage_iterator.h> +#ifndef _LIBCPP_FREESTANDING #include <__memory/shared_ptr.h> +#endif #include <__memory/temporary_buffer.h> #include <__memory/uninitialized_algorithms.h> #include <__memory/unique_ptr.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/stdexcept =================================================================== --- libcxx/include/stdexcept +++ libcxx/include/stdexcept @@ -43,14 +43,18 @@ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> -#include -#include -#include // for string forward decl #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif + +#if !defined(_LIBCPP_FREESTANDING) + +#include +#include +#include // for string forward decl + _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_ABI_VCRUNTIME @@ -211,16 +215,22 @@ }; } // namespace std +#endif _LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_FREESTANDING +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_runtime_error(const char*){} +#else // in the dylib _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); +#endif _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_logic_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw logic_error(__msg); #else ((void)__msg); @@ -231,7 +241,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_domain_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw domain_error(__msg); #else ((void)__msg); @@ -242,7 +252,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_invalid_argument(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw invalid_argument(__msg); #else ((void)__msg); @@ -253,7 +263,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_length_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw length_error(__msg); #else ((void)__msg); @@ -264,7 +274,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_out_of_range(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw out_of_range(__msg); #else ((void)__msg); @@ -275,7 +285,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_range_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw range_error(__msg); #else ((void)__msg); @@ -286,7 +296,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_overflow_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw overflow_error(__msg); #else ((void)__msg); @@ -297,7 +307,7 @@ _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_underflow_error(const char*__msg) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#if !defined(_LIBCPP_NO_EXCEPTIONS) && !defined(_LIBCPP_FREESTANDING) throw underflow_error(__msg); #else ((void)__msg); Index: libcxx/include/stdlib.h =================================================================== --- libcxx/include/stdlib.h +++ libcxx/include/stdlib.h @@ -90,6 +90,18 @@ # pragma GCC system_header #endif +#if defined(_LIBCPP_FREESTANDING) +#include + +using std::abort; +using std::atexit; +using std::exit; +#if __cplusplus >= 201103L + using std::at_quick_exit; + using std::quick_exit; +#endif + +#else #include_next #ifdef __cplusplus @@ -157,5 +169,6 @@ #endif // _LIBCPP_MSVCRT / __sun__ } // extern "C++" #endif // __cplusplus +#endif #endif // _LIBCPP_STDLIB_H Index: libcxx/include/string.h =================================================================== --- libcxx/include/string.h +++ libcxx/include/string.h @@ -56,7 +56,26 @@ #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +#ifdef _LIBCPP_FREESTANDING +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void* memcpy(void*,void const*,size_t); +void* memmove(void*,void const*,size_t); +int memcmp(void const*, void const*, size_t); +int memset(void const*, int, size_t); +size_t strlen(void const*); + +#ifdef __cplusplus +} +#endif + + +#else #include_next // MSVCRT, GNU libc and its derivates may already have the correct prototype in @@ -105,5 +124,5 @@ char* strstr( char* __s1, const char* __s2) {return __libcpp_strstr(__s1, __s2);} } #endif - +#endif #endif // _LIBCPP_STRING_H Index: libcxx/include/string_view =================================================================== --- libcxx/include/string_view +++ libcxx/include/string_view @@ -950,10 +950,12 @@ #endif // _LIBCPP_STD_VER > 17 +#ifndef _LIBCPP_FREESTANDING template _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str); +#endif // [string.view.hash] template