diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 85514cc7547a9..241dbbccd0600 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -285,6 +285,8 @@ endif() # Feature options ------------------------------------------------------------- option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF) +option(LIBCXX_HAS_NEWLIB_LIBC "Build libc++ with support for the Newlib C library" OFF) +option(LIBCXX_HAS_PICOLIBC "Build libc++ with support for the picolibc C library" OFF) option(LIBCXX_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF) option(LIBCXX_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF) option(LIBCXX_HAS_EXTERNAL_THREAD_API @@ -742,6 +744,8 @@ config_define(${LIBCXX_HAS_PTHREAD_API} _LIBCPP_HAS_THREAD_API_PTHREAD) config_define(${LIBCXX_HAS_EXTERNAL_THREAD_API} _LIBCPP_HAS_THREAD_API_EXTERNAL) config_define(${LIBCXX_HAS_WIN32_THREAD_API} _LIBCPP_HAS_THREAD_API_WIN32) config_define(${LIBCXX_HAS_MUSL_LIBC} _LIBCPP_HAS_MUSL_LIBC) +config_define(${LIBCXX_HAS_NEWLIB_LIBC} _LIBCPP_HAS_NEWLIB_LIBC) +config_define(${LIBCXX_HAS_PICOLIBC} _LIBCPP_HAS_PICOLIBC) config_define_if(LIBCXX_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME) config_define(${LIBCXX_ENABLE_FILESYSTEM} _LIBCPP_HAS_FILESYSTEM) config_define(${LIBCXX_ENABLE_RANDOM_DEVICE} _LIBCPP_HAS_RANDOM_DEVICE) diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h index f3c199dee172b..8d0f8f63f5213 100644 --- a/libcxx/include/__configuration/platform.h +++ b/libcxx/include/__configuration/platform.h @@ -42,13 +42,6 @@ # endif #endif -// This is required in order for _NEWLIB_VERSION to be defined in places where we use it. -// TODO: We shouldn't be including arbitrarily-named headers from libc++ since this can break valid -// user code. Move code paths that need _NEWLIB_VERSION to another customization mechanism. -#if __has_include() -# include -#endif - #ifndef __BYTE_ORDER__ # error \ "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform" diff --git a/libcxx/include/__cxx03/__fwd/ios.h b/libcxx/include/__cxx03/__fwd/ios.h index dc03e8c6bab2f..356eb18697cab 100644 --- a/libcxx/include/__cxx03/__fwd/ios.h +++ b/libcxx/include/__cxx03/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios; template class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in #else diff --git a/libcxx/include/__cxx03/__locale b/libcxx/include/__cxx03/__locale index d5faa89b99fc0..d16a0f2e7c981 100644 --- a/libcxx/include/__cxx03/__locale +++ b/libcxx/include/__cxx03/__locale @@ -384,7 +384,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h index a20f0952f52c3..8a223dc2f7a3c 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h @@ -17,7 +17,7 @@ # include <__cxx03/__locale_dir/locale_base_api/android.h> #elif defined(__sun__) # include <__cxx03/__locale_dir/locale_base_api/solaris.h> -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC # include <__cxx03/__locale_dir/locale_base_api/newlib.h> #elif defined(__OpenBSD__) # include <__cxx03/__locale_dir/locale_base_api/openbsd.h> diff --git a/libcxx/include/__cxx03/fstream b/libcxx/include/__cxx03/fstream index 44bdabc4602b5..8ccad9727b353 100644 --- a/libcxx/include/__cxx03/fstream +++ b/libcxx/include/__cxx03/fstream @@ -209,7 +209,7 @@ typedef basic_fstream wfstream; _LIBCPP_PUSH_MACROS #include <__cxx03/__undef_macros> -#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_MSVCRT) || _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS #endif diff --git a/libcxx/include/__cxx03/locale b/libcxx/include/__cxx03/locale index 64162f5a4ff2c..4e3c75afa450b 100644 --- a/libcxx/include/__cxx03/locale +++ b/libcxx/include/__cxx03/locale @@ -220,7 +220,7 @@ template class messages_byname; # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !_LIBCPP_HAS_NEWLIB_LIBC && !_LIBCPP_HAS_PICOLIBC && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include # endif diff --git a/libcxx/include/__cxx03/regex b/libcxx/include/__cxx03/regex index b96d59d3a252a..05775c517fd92 100644 --- a/libcxx/include/__cxx03/regex +++ b/libcxx/include/__cxx03/regex @@ -984,7 +984,7 @@ public: typedef _CharT char_type; typedef basic_string string_type; typedef locale locale_type; -#if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +#if defined(__BIONIC__) || _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -993,11 +993,10 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is - // often used for space constrained environments, so it makes sense not to - // duplicate the ctype table. + // + // We also use this logic for Newlib and picolibc. These are often used + // for space constrained environments, so it makes sense no to duplicate + // the ctype table. typedef uint16_t char_class_type; #else typedef ctype_base::mask char_class_type; diff --git a/libcxx/include/__fwd/ios.h b/libcxx/include/__fwd/ios.h index 831624f4b1c57..e2d7e3e82420d 100644 --- a/libcxx/include/__fwd/ios.h +++ b/libcxx/include/__fwd/ios.h @@ -31,7 +31,7 @@ using wios = basic_ios; template class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // On newlib, off_t is 'long int' using streamoff = long int; // for char_traits in #else diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 757a53951f66e..a3d3f6b257779 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -389,7 +389,7 @@ public: static const mask xdigit = _ISXDIGIT; static const mask blank = _ISBLANK; static const mask __regex_word = 0x8000; -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. typedef char mask; // In case char is signed, static_cast is needed to avoid warning on diff --git a/libcxx/include/__locale_dir/messages.h b/libcxx/include/__locale_dir/messages.h index c04bf04025ff0..efaf136e58dd3 100644 --- a/libcxx/include/__locale_dir/messages.h +++ b/libcxx/include/__locale_dir/messages.h @@ -22,7 +22,7 @@ # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__EMSCRIPTEN__) +# if !defined(__BIONIC__) && !_LIBCPP_HAS_NEWLIB_LIBC && !_LIBC_HAS_PICOLIBC && !defined(__EMSCRIPTEN__) # define _LIBCPP_HAS_CATOPEN 1 # include # else diff --git a/libcxx/include/fstream b/libcxx/include/fstream index 6d3f20fff688f..2f60ec56433fe 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -977,7 +977,7 @@ template int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) { # if defined(_LIBCPP_MSVCRT_LIKE) return _fseeki64(__file, __offset, __whence); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC return fseek(__file, __offset, __whence); # else return ::fseeko(__file, __offset, __whence); @@ -988,7 +988,7 @@ template typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) { # if defined(_LIBCPP_MSVCRT_LIKE) return _ftelli64(__file); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC return ftell(__file); # else return ftello(__file); diff --git a/libcxx/include/regex b/libcxx/include/regex index 9bbc3a69021b9..7a051272fd42e 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -1004,7 +1004,7 @@ public: typedef _CharT char_type; typedef basic_string string_type; typedef locale locale_type; -# if defined(__BIONIC__) || defined(_NEWLIB_VERSION) +# if defined(__BIONIC__) || _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // Originally bionic's ctype_base used its own ctype masks because the // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask // was only 8 bits wide and already saturated, so it used a wider type here @@ -1013,11 +1013,10 @@ public: // implementation, but this was not updated to match. Since then Android has // needed to maintain a stable libc++ ABI, and this can't be changed without // an ABI break. - // We also need this workaround for newlib since _NEWLIB_VERSION is not - // defined yet inside __config, so we can't set the - // _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE macro. Additionally, newlib is - // often used for space constrained environments, so it makes sense not to - // duplicate the ctype table. + // + // We also use this logic for Newlib and picolibc. These are often used + // for space constrained environments, so it makes sense no to duplicate + // the ctype table. typedef uint16_t char_class_type; # else typedef ctype_base::mask char_class_type; diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index 7edff2d9375d4..9102989a2a2f8 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -23,7 +23,7 @@ # define _LIBCPP_ELAST ELAST #elif defined(__LLVM_LIBC__) // No _LIBCPP_ELAST needed for LLVM libc -#elif defined(_NEWLIB_VERSION) +#elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC # define _LIBCPP_ELAST __ELASTERROR #elif defined(__NuttX__) // No _LIBCPP_ELAST needed on NuttX diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index da735865c322c..94747a05bc314 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -933,7 +933,7 @@ const ctype::mask* ctype::classic_table() noexcept { return __pctype_func(); # elif defined(__EMSCRIPTEN__) return *__ctype_b_loc(); -# elif defined(_NEWLIB_VERSION) +# elif _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. return _ctype_ + 1; # elif defined(_AIX) diff --git a/libcxx/test/libcxx/system_reserved_names.gen.py b/libcxx/test/libcxx/system_reserved_names.gen.py index a4f2928eda332..40fc482f728dc 100644 --- a/libcxx/test/libcxx/system_reserved_names.gen.py +++ b/libcxx/test/libcxx/system_reserved_names.gen.py @@ -78,7 +78,7 @@ // Test that libc++ doesn't use names that collide with FreeBSD system macros. // newlib and picolibc also define these macros -#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION) +#if !defined(__FreeBSD__) && !_LIBCPP_HAS_NEWLIB_LIBC && !_LIBCPP_HAS_PICOLIBC # define __null_sentinel SYSTEM_RESERVED_NAME # define __generic SYSTEM_RESERVED_NAME #endif @@ -117,7 +117,7 @@ #endif // Newlib & picolibc use __input as a parameter name of a64l & l64a -#ifndef _NEWLIB_VERSION +#if !_LIBCPP_HAS_NEWLIB_LIBC && !_LIBC_HAS_PICOLIBC # define __input SYSTEM_RESERVED_NAME #endif #define __output SYSTEM_RESERVED_NAME diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp index 5425203304014..fb3514416381a 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp @@ -48,7 +48,7 @@ int main(int, char**) // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index 255cbe75e2fa9..23ddceb4720ea 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -59,7 +59,7 @@ int main(int, char**) { // responds with an empty message, which we probably want to // treat as a failure code otherwise, but we can detect that // with the preprocessor. -#if defined(_NEWLIB_VERSION) +#if _LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC const bool is_newlib = true; #else const bool is_newlib = false; diff --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h index 99e60f60c5998..cfd5d048c72b0 100644 --- a/libcxx/test/support/platform_support.h +++ b/libcxx/test/support/platform_support.h @@ -48,7 +48,7 @@ # include // strverscmp #endif -#if defined(_NEWLIB_VERSION) && defined(__STRICT_ANSI__) +#if (_LIBCPP_HAS_NEWLIB_LIBC || _LIBC_HAS_PICOLIBC) && defined(__STRICT_ANSI__) // Newlib provides this, but in the header it's under __STRICT_ANSI__ extern "C" { int mkstemp(char*);