[libcxx-commits] [libcxx] 9c3a7ad - [libc++] Cleanly implement the base locale API for BSD-like platforms (#115176)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 11 10:11:26 PST 2024


Author: Louis Dionne
Date: 2024-11-11T13:11:23-05:00
New Revision: 9c3a7ad7faab0e172d08e5873b88141ab9866985

URL: https://github.com/llvm/llvm-project/commit/9c3a7ad7faab0e172d08e5873b88141ab9866985
DIFF: https://github.com/llvm/llvm-project/commit/9c3a7ad7faab0e172d08e5873b88141ab9866985.diff

LOG: [libc++] Cleanly implement the base locale API for BSD-like platforms (#115176)

Instead of going through the old locale entry points, define the base
localization API for BSD-like platforms (Apple and FreeBSD) from
scratch, using <xlocale.h> as a basis. This doesn't actually change how
that functionality is implemented, it only avoids going through a maze
to do so.

This clean new support is implemented in a separate __locale_dir/support
directory, which mirrors what we do for the threading support API.
Eventually, everything under __locale_dir/locale_base_api will go away.

rdar://131476632

Added: 
    libcxx/include/__locale_dir/support/apple.h
    libcxx/include/__locale_dir/support/bsd_like.h
    libcxx/include/__locale_dir/support/freebsd.h

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/__locale_dir/locale_base_api.h
    libcxx/include/iomanip
    libcxx/include/module.modulemap
    libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/member_swap.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/move_assign.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/move.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/streambuf.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/tellg.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/member_swap.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/move_assign.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/move.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/streambuf.pass.cpp
    libcxx/test/std/input.output/iostream.format/input.streams/istream/istream_sentry/ctor.pass.cpp

Removed: 
    libcxx/include/__locale_dir/locale_base_api/apple.h
    libcxx/include/__locale_dir/locale_base_api/freebsd.h


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a4b97b1d7658cc..6dd392685c18ee 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -495,16 +495,17 @@ set(files
   __locale
   __locale_dir/locale_base_api.h
   __locale_dir/locale_base_api/android.h
-  __locale_dir/locale_base_api/apple.h
   __locale_dir/locale_base_api/bsd_locale_defaults.h
   __locale_dir/locale_base_api/bsd_locale_fallbacks.h
-  __locale_dir/locale_base_api/freebsd.h
   __locale_dir/locale_base_api/fuchsia.h
   __locale_dir/locale_base_api/ibm.h
   __locale_dir/locale_base_api/musl.h
   __locale_dir/locale_base_api/openbsd.h
   __locale_dir/locale_base_api/win32.h
   __locale_dir/locale_guard.h
+  __locale_dir/support/apple.h
+  __locale_dir/support/bsd_like.h
+  __locale_dir/support/freebsd.h
   __math/abs.h
   __math/copysign.h
   __math/error_functions.h

diff  --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index e798a006625b59..5cbe91207ca74e 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -94,42 +94,44 @@
 //  int     __sscanf(const char*, __locale_t, const char*, ...);
 // }
 
+#if defined(__APPLE__)
+#  include <__locale_dir/support/apple.h>
+#elif defined(__FreeBSD__)
+#  include <__locale_dir/support/freebsd.h>
+#else
+
 // TODO: This is a temporary definition to bridge between the old way we defined the locale base API
 //       (by providing global non-reserved names) and the new API. As we move individual platforms
 //       towards the new way of defining the locale base API, this should disappear since each platform
 //       will define those directly.
-#if defined(_LIBCPP_MSVCRT_LIKE)
-#  include <__locale_dir/locale_base_api/win32.h>
-#elif defined(_AIX) || defined(__MVS__)
-#  include <__locale_dir/locale_base_api/ibm.h>
-#elif defined(__ANDROID__)
-#  include <__locale_dir/locale_base_api/android.h>
-#elif defined(__OpenBSD__)
-#  include <__locale_dir/locale_base_api/openbsd.h>
-#elif defined(__Fuchsia__)
-#  include <__locale_dir/locale_base_api/fuchsia.h>
-#elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC
-#  include <__locale_dir/locale_base_api/musl.h>
-#elif defined(__APPLE__)
-#  include <__locale_dir/locale_base_api/apple.h>
-#elif defined(__FreeBSD__)
-#  include <__locale_dir/locale_base_api/freebsd.h>
-#endif
+#  if defined(_LIBCPP_MSVCRT_LIKE)
+#    include <__locale_dir/locale_base_api/win32.h>
+#  elif defined(_AIX) || defined(__MVS__)
+#    include <__locale_dir/locale_base_api/ibm.h>
+#  elif defined(__ANDROID__)
+#    include <__locale_dir/locale_base_api/android.h>
+#  elif defined(__OpenBSD__)
+#    include <__locale_dir/locale_base_api/openbsd.h>
+#  elif defined(__Fuchsia__)
+#    include <__locale_dir/locale_base_api/fuchsia.h>
+#  elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC
+#    include <__locale_dir/locale_base_api/musl.h>
+#  endif
 
-#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-#  include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
-#else
-#  include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
-#endif
+#  ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+#    include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
+#  else
+#    include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
+#  endif
 
-#include <__cstddef/size_t.h>
-#include <__utility/forward.h>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#if _LIBCPP_HAS_WIDE_CHARACTERS
-#  include <wctype.h>
-#endif
+#  include <__cstddef/size_t.h>
+#  include <__utility/forward.h>
+#  include <ctype.h>
+#  include <string.h>
+#  include <time.h>
+#  if _LIBCPP_HAS_WIDE_CHARACTERS
+#    include <wctype.h>
+#  endif
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 //
@@ -137,9 +139,9 @@ namespace __locale {
 //
 using __locale_t = locale_t;
 
-#ifndef _LIBCPP_MSVCRT_LIKE
+#  ifndef _LIBCPP_MSVCRT_LIKE
 inline _LIBCPP_HIDE_FROM_ABI __locale_t __uselocale(__locale_t __loc) { return uselocale(__loc); }
-#endif
+#  endif
 
 inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
   return newlocale(__category_mask, __name, __loc);
@@ -189,7 +191,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, s
 inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); }
 
-#if _LIBCPP_HAS_WIDE_CHARACTERS
+#  if _LIBCPP_HAS_WIDE_CHARACTERS
 inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) {
   return wcscoll_l(__s1, __s2, __loc);
 }
@@ -208,7 +210,7 @@ inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __ch, __locale_t __loc) { ret
 inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); }
-#endif
+#  endif
 
 inline _LIBCPP_HIDE_FROM_ABI size_t
 __strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) {
@@ -221,7 +223,7 @@ __strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __loca
 inline _LIBCPP_HIDE_FROM_ABI decltype(__libcpp_mb_cur_max_l(__locale_t())) __mb_len_max(__locale_t __loc) {
   return __libcpp_mb_cur_max_l(__loc);
 }
-#if _LIBCPP_HAS_WIDE_CHARACTERS
+#  if _LIBCPP_HAS_WIDE_CHARACTERS
 inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __ch, __locale_t __loc) { return __libcpp_btowc_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __ch, __locale_t __loc) { return __libcpp_wctob_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI size_t
@@ -249,16 +251,16 @@ inline _LIBCPP_HIDE_FROM_ABI size_t
 __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
   return __libcpp_mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
 }
-#endif
+#  endif
 
 _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
+#  ifdef _LIBCPP_COMPILER_CLANG_BASED
+#    define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__)
+#  else
+#    define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */
+#  endif
 
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
@@ -276,9 +278,11 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __s
   return __libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
 }
 _LIBCPP_DIAGNOSTIC_POP
-#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
+#  undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
 
 } // namespace __locale
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // Compatibility definition of locale base APIs
+
 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H

diff  --git a/libcxx/include/__locale_dir/locale_base_api/apple.h b/libcxx/include/__locale_dir/support/apple.h
similarity index 56%
rename from libcxx/include/__locale_dir/locale_base_api/apple.h
rename to libcxx/include/__locale_dir/support/apple.h
index 69faa260be2190..62eb79c30d4358 100644
--- a/libcxx/include/__locale_dir/locale_base_api/apple.h
+++ b/libcxx/include/__locale_dir/support/apple.h
@@ -1,4 +1,3 @@
-// -*- C++ -*-
 //===-----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,17 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_APPLE_H
-#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_APPLE_H
+#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_APPLE_H
+#define _LIBCPP___LOCALE_DIR_SUPPORT_APPLE_H
 
 #include <__config>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#if _LIBCPP_HAS_WIDE_CHARACTERS
-#  include <wctype.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
 #endif
 
-#include <xlocale.h>
+#include <__locale_dir/support/bsd_like.h>
 
-#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_APPLE_H
+#endif // _LIBCPP___LOCALE_DIR_SUPPORT_APPLE_H

diff  --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
new file mode 100644
index 00000000000000..cce6de64673b0e
--- /dev/null
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -0,0 +1,212 @@
+//===-----------------------------------------------------------------------===//
+//
+// 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_BSD_LIKE_H
+#define _LIBCPP___LOCALE_DIR_SUPPORT_BSD_LIKE_H
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__std_mbstate_t.h>
+#include <__utility/forward.h>
+#include <clocale> // std::lconv
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+#  include <wchar.h>
+#  include <wctype.h>
+#endif
+
+#include <xlocale.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __locale {
+
+//
+// Locale management
+//
+using __locale_t = ::locale_t;
+
+inline _LIBCPP_HIDE_FROM_ABI __locale_t __uselocale(__locale_t __loc) { return ::uselocale(__loc); }
+
+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 lconv* __localeconv(__locale_t& __loc) { return ::localeconv_l(__loc); }
+
+//
+// Strtonum functions
+//
+inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
+  return ::strtof_l(__nptr, __endptr, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
+  return ::strtod_l(__nptr, __endptr, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
+  return ::strtold_l(__nptr, __endptr, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+  return ::strtoll_l(__nptr, __endptr, __base, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI unsigned long long
+__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+  return ::strtoull_l(__nptr, __endptr, __base, __loc);
+}
+
+//
+// Character manipulation functions
+//
+inline _LIBCPP_HIDE_FROM_ABI int __islower(int __c, __locale_t __loc) { return ::islower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __c, __locale_t __loc) { return ::isupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return ::tolower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
+  return ::strcoll_l(__s1, __s2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
+  return ::strxfrm_l(__dest, __src, __n, __loc);
+}
+
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __c, __locale_t __loc) { return ::iswspace_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __c, __locale_t __loc) { return ::iswprint_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __c, __locale_t __loc) { return ::iswcntrl_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __c, __locale_t __loc) { return ::iswupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __c, __locale_t __loc) { return ::iswlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __c, __locale_t __loc) { return ::iswalpha_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __c, __locale_t __loc) { return ::iswblank_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __c, __locale_t __loc) { return ::iswdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __c, __locale_t __loc) { return ::iswpunct_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __c, __locale_t __loc) { return ::iswxdigit_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __c, __locale_t __loc) { return ::towupper_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __c, __locale_t __loc) { return ::towlower_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t* __ws2, __locale_t __loc) {
+  return ::wcscoll_l(__ws1, __ws2, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
+  return ::wcsxfrm_l(__dest, __src, __n, __loc);
+}
+#endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
+  return ::strftime_l(__s, __max, __format, __tm, __loc);
+}
+
+//
+// Other functions
+//
+inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) { return MB_CUR_MAX_L(__loc); }
+
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) { return ::btowc_l(__c, __loc); }
+
+inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) { return ::wctob_l(__c, __loc); }
+
+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 __loc) {
+  return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
+  return ::wcrtomb_l(__s, __wc, __ps, __loc);
+}
+
+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 __loc) {
+  return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+  return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) {
+  return ::mbtowc_l(__pwc, __pmb, __max, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
+  return ::mbrlen_l(__s, __n, __ps, __loc);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI size_t
+__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
+  return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
+}
+#endif
+
+_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 <class... _Args>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf(
+    char* __s, size_t __n, __locale_t __loc, const char* __format, _Args&&... __args) {
+  return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
+    char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
+  return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+}
+
+template <class... _Args>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf(
+    const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) {
+  return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
+}
+_LIBCPP_DIAGNOSTIC_POP
+#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
+
+} // namespace __locale
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOCALE_DIR_SUPPORT_BSD_LIKE_H

diff  --git a/libcxx/include/__locale_dir/locale_base_api/freebsd.h b/libcxx/include/__locale_dir/support/freebsd.h
similarity index 56%
rename from libcxx/include/__locale_dir/locale_base_api/freebsd.h
rename to libcxx/include/__locale_dir/support/freebsd.h
index cf683d14d16880..5c6e21e3872716 100644
--- a/libcxx/include/__locale_dir/locale_base_api/freebsd.h
+++ b/libcxx/include/__locale_dir/support/freebsd.h
@@ -1,4 +1,3 @@
-// -*- C++ -*-
 //===-----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,17 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_FREEBSD_H
-#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_FREEBSD_H
+#ifndef _LIBCPP___LOCALE_DIR_SUPPORT_FREEBSD_H
+#define _LIBCPP___LOCALE_DIR_SUPPORT_FREEBSD_H
 
 #include <__config>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#if _LIBCPP_HAS_WIDE_CHARACTERS
-#  include <wctype.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
 #endif
 
-#include <xlocale.h>
+#include <__locale_dir/support/bsd_like.h>
 
-#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_FREEBSD_H
+#endif // _LIBCPP___LOCALE_DIR_SUPPORT_FREEBSD_H

diff  --git a/libcxx/include/iomanip b/libcxx/include/iomanip
index bc3f860bd7a7d2..8c711c94f11762 100644
--- a/libcxx/include/iomanip
+++ b/libcxx/include/iomanip
@@ -49,6 +49,7 @@ template <class charT, class traits, class Allocator>
 #  include <__ostream/basic_ostream.h>
 #  include <ios>
 #  include <istream>
+#  include <locale>
 #  include <version>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 5465d603b2c4d0..2a4b9de436eab6 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1460,14 +1460,23 @@ module std [system] {
 
   module locale {
     header "locale"
-    header "__locale_dir/locale_base_api.h"
     header "__locale_dir/locale_guard.h"
+
+    module support {
+      header "__locale_dir/locale_base_api.h"
+      export *
+    }
+
+    module support_impl {
+      textual header "__locale_dir/support/apple.h"
+      textual header "__locale_dir/support/bsd_like.h"
+      textual header "__locale_dir/support/freebsd.h"
+    }
+
     module locale_base_api {
       textual header "__locale_dir/locale_base_api/android.h"
-      textual header "__locale_dir/locale_base_api/apple.h"
       textual header "__locale_dir/locale_base_api/bsd_locale_defaults.h"
       textual header "__locale_dir/locale_base_api/bsd_locale_fallbacks.h"
-      textual header "__locale_dir/locale_base_api/freebsd.h"
       textual header "__locale_dir/locale_base_api/fuchsia.h"
       textual header "__locale_dir/locale_base_api/ibm.h"
       textual header "__locale_dir/locale_base_api/musl.h"

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/member_swap.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/member_swap.pass.cpp
index a1fbc7dd065177..10eadb3e0a9d88 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/member_swap.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/member_swap.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/move_assign.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/move_assign.pass.cpp
index b8b2f013cf6e9e..b46909b9ae444b 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/move_assign.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.assign/move_assign.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/move.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/move.pass.cpp
index c1761fce3146c3..f6bb0255f6159a 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/move.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/streambuf.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/streambuf.pass.cpp
index e30560e440fda8..420ea71948e971 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/streambuf.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/iostreamclass/iostream.cons/streambuf.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp
index 0e71f254954bd8..1a249654a1debe 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp
index 4776299c235c50..0c5644546d98dc 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp
index 9b84a69c9ae10c..a5eacca4a1311c 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
index 00e335795dc6aa..0049509e6ee5f6 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
@@ -19,6 +19,8 @@
 #include <istream>
 #include <limits>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp
index 4d9b1181a1b70a..e166529a5630f2 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp
index 3d0f0035a3d6de..5c01af026adde0 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp
index 7e19304c4942d6..23745dafe992e6 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp
index 0a94762b0082b0..dfedc8425b1ca3 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
index cd0955f8bf3498..c748ee43936e75 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
@@ -19,6 +19,8 @@
 #include <istream>
 #include <limits>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp
index 87aadac1181f6f..ad51cd1b68ce52 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp
index 189a79dae9e53f..23681273b7455a 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp
index 7ca4224d098b5d..0c915928d71b39 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp
index ba231c47a7fe58..6d8b760ec874b9 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp
@@ -18,6 +18,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp
index ca7df067086ee8..7ad409ed86a2c9 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp
index d5ae9098213270..bdf070b9d5438d 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
index 64ff48d297384b..40509e46e194e8 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp
index 7eaf6f5a68ec9a..ce9603da8815f1 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp
@@ -18,6 +18,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp
index 8d86d11c1aeecf..68b8dfec4df218 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
index 7e4bf41c966432..b15ef18e0ea668 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
index 736849b7f0d9c0..e858d07ad0ddf6 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
@@ -13,6 +13,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp
index 2cd2fcb8b818a3..9314b9f8f634b3 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp
@@ -14,6 +14,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
index b9279d92f83f01..412fac8f7ed292 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
@@ -15,6 +15,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
index deb186c179760f..546dc31421a839 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
@@ -15,6 +15,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
index 7556d1b65020f8..a0575724928c93 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
@@ -17,6 +17,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
index b833d231be79b5..5db8a5ed49d857 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
@@ -17,6 +17,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp
index 49e7556d467207..7988b2f42cb242 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp
index 9e117c84d77cea..14f317ca606ce3 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp
@@ -16,6 +16,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
index 348464a9c7fd6a..533970837b025c 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
@@ -17,6 +17,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
index 9a02dd8c41be3d..e52ca720b4ebb0 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
@@ -17,6 +17,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp
index 646bd9f0feee0e..a9274aab3af409 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp
@@ -16,6 +16,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
index cf39982115399a..f862d9173ad0ff 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
@@ -15,6 +15,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp
index cb57b89a45cbef..e21cd7d93cdde0 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
index c30ccb46c04cfa..c7cca7bf7b4175 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
@@ -15,6 +15,8 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
+
 #include "test_macros.h"
 
 template <class CharT>

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
index 3c523bb2bfb55a..07261518416897 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/readsome.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
index 7bbbf94089cecb..b4f5922d914f5b 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
index 8126fe4401af3c..a0c5dd1dbdc0ab 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/seekg_off.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
index 3608b99dea972c..79d20ce68d11b0 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
@@ -17,6 +17,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/tellg.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/tellg.pass.cpp
index 816e400287cf53..dfc030905029fe 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/tellg.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/tellg.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp
index eddfaa8848f0e5..1b3ed2a169a31b 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/member_swap.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/member_swap.pass.cpp
index 64ddcf2fe8d1a9..838a564c19f742 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/member_swap.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/member_swap.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/move_assign.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/move_assign.pass.cpp
index fd79726d6b394a..5c88ca26e292d1 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/move_assign.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.assign/move_assign.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/move.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/move.pass.cpp
index 4f46ff509ef0e1..9eb4a502ecca8b 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/move.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/streambuf.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/streambuf.pass.cpp
index b2b428ede516dc..d8518f380dbb0a 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/streambuf.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream.cons/streambuf.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream_sentry/ctor.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream_sentry/ctor.pass.cpp
index fa094d79074aae..6af1de3294a225 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream_sentry/ctor.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream/istream_sentry/ctor.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include <streambuf>
 
 #include "test_macros.h"
 


        


More information about the libcxx-commits mailing list