diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 9006757f9d6d..85f1bdf9b483 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -543,9 +543,12 @@ set(files __locale_dir/support/freebsd.h __locale_dir/support/fuchsia.h __locale_dir/support/linux.h + __locale_dir/support/llvm_libc.h __locale_dir/support/netbsd.h __locale_dir/support/newlib.h __locale_dir/support/no_locale/characters.h + __locale_dir/support/no_locale/conversions.h + __locale_dir/support/no_locale/formatting.h __locale_dir/support/no_locale/strtonum.h __locale_dir/support/windows.h __locale_dir/time.h diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index f956882403b5..615c404723a9 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -119,6 +119,8 @@ # include <__locale_dir/support/windows.h> # elif defined(__Fuchsia__) # include <__locale_dir/support/fuchsia.h> +# elif _LIBCPP_LIBC_LLVM_LIBC +# include <__locale_dir/support/llvm_libc.h> # elif defined(__linux__) # include <__locale_dir/support/linux.h> # elif _LIBCPP_LIBC_NEWLIB diff --git a/libcxx/include/__locale_dir/support/llvm_libc.h b/libcxx/include/__locale_dir/support/llvm_libc.h new file mode 100644 index 000000000000..1ce1c443d87e --- /dev/null +++ b/libcxx/include/__locale_dir/support/llvm_libc.h @@ -0,0 +1,60 @@ +//===-----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_LLVM_LIBC_H +#define _LIBCPP___LOCALE_DIR_SUPPORT_LLVM_LIBC_H + +#include <__config> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD +namespace __locale { + +using __locale_t _LIBCPP_NODEBUG = ::locale_t; + +#define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK +#define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK +#define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK +#define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK +#define _LIBCPP_TIME_MASK LC_TIME_MASK +#define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK +#define _LIBCPP_ALL_MASK LC_ALL_MASK +#define _LIBCPP_LC_ALL LC_ALL + +#if defined(_LIBCPP_BUILDING_LIBRARY) +using __lconv_t _LIBCPP_NODEBUG = std::lconv; + +inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) { + return ::newlocale(__category_mask, __locale, __base); +} + +inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::freelocale(__loc); } + +inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) { + return ::setlocale(__category, __locale); +} + +inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t&) { return std::localeconv(); } +#endif // _LIBCPP_BUILDING_LIBRARY + +} // namespace __locale +_LIBCPP_END_NAMESPACE_STD + +#include <__locale_dir/support/no_locale/characters.h> +#include <__locale_dir/support/no_locale/conversions.h> +#include <__locale_dir/support/no_locale/formatting.h> +#include <__locale_dir/support/no_locale/strtonum.h> + +#endif // _LIBCPP___LOCALE_DIR_SUPPORT_LLVM_LIBC_H diff --git a/libcxx/include/__locale_dir/support/no_locale/characters.h b/libcxx/include/__locale_dir/support/no_locale/characters.h index e0755d1a7152..52e842d8f494 100644 --- a/libcxx/include/__locale_dir/support/no_locale/characters.h +++ b/libcxx/include/__locale_dir/support/no_locale/characters.h @@ -16,6 +16,7 @@ #include #include #if _LIBCPP_HAS_WIDE_CHARACTERS +# include # include #endif diff --git a/libcxx/include/__locale_dir/support/no_locale/conversions.h b/libcxx/include/__locale_dir/support/no_locale/conversions.h new file mode 100644 index 000000000000..64a50df4a50b --- /dev/null +++ b/libcxx/include/__locale_dir/support/no_locale/conversions.h @@ -0,0 +1,72 @@ +//===-----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_CONVERSIONS_H +#define _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_CONVERSIONS_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__std_mbstate_t.h> +#include +#if _LIBCPP_HAS_WIDE_CHARACTERS +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD +namespace __locale { + +#if defined(_LIBCPP_BUILDING_LIBRARY) +inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t) { return MB_CUR_MAX; } + +# if _LIBCPP_HAS_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t) { return std::btowc(__c); } + +inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t) { return std::wctob(__c); } + +inline _LIBCPP_HIDE_FROM_ABI size_t +__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t) { + return ::wcsnrtombs(__dest, __src, __nwc, __len, __ps); // Non-standard +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t) { + return std::wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t) { + return ::mbsnrtowcs(__dest, __src, __nms, __len, __ps); // Non-standard +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t) { + return std::mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t) { + return std::mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t) { + return std::mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t) { + return std::mbsrtowcs(__dest, __src, __len, __ps); +} +# endif // _LIBCPP_HAS_WIDE_CHARACTERS +#endif // _LIBCPP_BUILDING_LIBRARY + +} // namespace __locale +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_CONVERSIONS_H diff --git a/libcxx/include/__locale_dir/support/no_locale/formatting.h b/libcxx/include/__locale_dir/support/no_locale/formatting.h new file mode 100644 index 000000000000..7185e9a4e600 --- /dev/null +++ b/libcxx/include/__locale_dir/support/no_locale/formatting.h @@ -0,0 +1,50 @@ +//===-----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_FORMATTING_H +#define _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_FORMATTING_H + +#include <__config> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD +namespace __locale { + +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates +#ifdef _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__) +#else +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */ +#endif + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf( + char* __s, size_t __n, __locale_t, const char* __format, _Args&&... __args) { + return std::snprintf(__s, __n, __format, std::forward<_Args>(__args)...); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf( + char** __s, __locale_t, const char* __format, _Args&&... __args) { + return ::asprintf(__s, __format, std::forward<_Args>(__args)...); // non-standard +} + +_LIBCPP_DIAGNOSTIC_POP +#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT + +} // namespace __locale +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LOCALE_DIR_SUPPORT_NO_LOCALE_FORMATTING_H diff --git a/libcxx/include/__mbstate_t.h b/libcxx/include/__mbstate_t.h index d331ba622d37..1ce5f0cd6da1 100644 --- a/libcxx/include/__mbstate_t.h +++ b/libcxx/include/__mbstate_t.h @@ -39,6 +39,8 @@ # define __NEED_mbstate_t # include # undef __NEED_mbstate_t +#elif _LIBCPP_LIBC_LLVM_LIBC +# include #elif __has_include() # include // works on most Unixes #elif __has_include() diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index b7c2ef91be55..015ac10e7394 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1606,7 +1606,10 @@ module std [system] { textual header "__locale_dir/support/freebsd.h" textual header "__locale_dir/support/fuchsia.h" textual header "__locale_dir/support/linux.h" + textual header "__locale_dir/support/llvm_libc.h" textual header "__locale_dir/support/netbsd.h" + textual header "__locale_dir/support/no_locale/conversions.h" + textual header "__locale_dir/support/no_locale/formatting.h" textual header "__locale_dir/support/newlib.h" textual header "__locale_dir/support/no_locale/characters.h" textual header "__locale_dir/support/no_locale/strtonum.h"