[llvm-branch-commits] [libcxx] [libc++][format] Implements P3107R5 in <print>. (PR #130500)

Mark de Wever via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Mar 10 11:48:57 PDT 2025


https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/130500

>From f3b052aa1bbc633655108e6e3a432c820169d96f Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 30 Mar 2024 17:35:56 +0100
Subject: [PATCH] [libc++][format] Implements P3107R5 in <print>.

The followup paper P3235R3 which is voted in as a DR changes the names
foo_locking to foo_buffered. These changes have been applied in this
patch.

Before
-------------------------------------------------------
Benchmark             Time             CPU   Iterations
-------------------------------------------------------
printf             71.3 ns         71.3 ns      9525175
print_string        226 ns          226 ns      3105850
print_stack         232 ns          232 ns      3026498
print_direct        530 ns          530 ns      1318447

After
-------------------------------------------------------
Benchmark             Time             CPU   Iterations
-------------------------------------------------------
printf             70.6 ns         70.6 ns      9789585
print_string        222 ns          222 ns      3147678
print_stack         227 ns          227 ns      3084767
print_direct        474 ns          474 ns      1472786

Note: The performance of libc++'s std::print is still extemely slow
compared to printf. Based on P3107R5 std::print should outperform
printf. The main culprit is the call to isatty, which is resolved
after implementing
LWG4044  Confusing requirements for std::print on POSIX platforms

Implements
- P3107R5 - Permit an efficient implementation of ``std::print``

Implements parts of
- P3235R3 std::print more types faster with less memory

Fixes: #105435
---
 libcxx/docs/ReleaseNotes/21.rst               |   1 +
 libcxx/include/__format/buffer.h              |   3 +
 libcxx/include/print                          | 249 +++++++++++++++++-
 libcxx/modules/std/print.inc                  |   1 +
 .../test/libcxx/transitive_includes/cxx03.csv |   5 +
 .../test/libcxx/transitive_includes/cxx11.csv |   5 +
 .../test/libcxx/transitive_includes/cxx14.csv |   5 +
 .../test/libcxx/transitive_includes/cxx17.csv |   5 +
 .../test/libcxx/transitive_includes/cxx23.csv |   5 +-
 .../test/libcxx/transitive_includes/cxx26.csv |   4 +
 10 files changed, 270 insertions(+), 13 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index e7cfa625a132c..a1f30b26c5a1d 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -40,6 +40,7 @@ Implemented Papers
 
 - N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
 - P1361R2: Integration of chrono with text formatting (`Github <https://github.com/llvm/llvm-project/issues/100014>`__)
+- P3107R5 - Permit an efficient implementation of ``std::print`` (`Github <https://github.com/llvm/llvm-project/issues/105435>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h
index c88b7f3222010..d6e4ddc840e2d 100644
--- a/libcxx/include/__format/buffer.h
+++ b/libcxx/include/__format/buffer.h
@@ -12,6 +12,7 @@
 
 #include <__algorithm/copy_n.h>
 #include <__algorithm/fill_n.h>
+#include <__algorithm/for_each.h>
 #include <__algorithm/max.h>
 #include <__algorithm/min.h>
 #include <__algorithm/ranges_copy.h>
@@ -34,11 +35,13 @@
 #include <__memory/construct_at.h>
 #include <__memory/destroy.h>
 #include <__memory/uninitialized_algorithms.h>
+#include <__system_error/system_error.h>
 #include <__type_traits/add_pointer.h>
 #include <__type_traits/conditional.h>
 #include <__utility/exception_guard.h>
 #include <__utility/move.h>
 #include <stdexcept>
+#include <stdio.h> // Uses the POSIX/Windows unlocked stream I/O
 #include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/print b/libcxx/include/print
index 1794d6014efcd..5489b993b03a3 100644
--- a/libcxx/include/print
+++ b/libcxx/include/print
@@ -27,9 +27,11 @@ namespace std {
 
   void vprint_unicode(string_view fmt, format_args args);
   void vprint_unicode(FILE* stream, string_view fmt, format_args args);
+  void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args);
 
   void vprint_nonunicode(string_view fmt, format_args args);
   void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
+  void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args);
 }
 */
 
@@ -213,6 +215,107 @@ _LIBCPP_HIDE_FROM_ABI inline bool __is_terminal([[maybe_unused]] FILE* __stream)
 #    endif
 }
 
+_LIBCPP_HIDE_FROM_ABI inline void __flockfile(FILE* __stream) {
+#    if defined(_LIBCPP_WIN32API)
+  ::_lock_file(__stream);
+#    elif __has_include(<unistd.h>)
+  ::flockfile(__stream);
+#    else
+#      error "Provide a way to do unlocked stream I/O operations"
+#    endif
+}
+_LIBCPP_HIDE_FROM_ABI inline void __funlockfile(FILE* __stream) {
+#    if defined(_LIBCPP_WIN32API)
+  ::_unlock_file(__stream);
+#    elif __has_include(<unistd.h>)
+  ::funlockfile(__stream);
+#    else
+#      error "Provide a way to do unlocked stream I/O operations"
+#    endif
+}
+
+_LIBCPP_HIDE_FROM_ABI inline int __fflush_unlocked(FILE* __stream) {
+#    if defined(_LIBCPP_WIN32API)
+  return ::_fflush_nolock(__stream);
+#    elif __has_include(<unistd.h>)
+  return ::fflush_unlocked(__stream);
+#    else
+#      error "Provide a way to do unlocked stream I/O operations"
+#    endif
+}
+
+_LIBCPP_HIDE_FROM_ABI inline size_t __fwrite_unlocked(const void* __buffer, size_t __size, size_t __n, FILE* __stream) {
+#    if defined(_LIBCPP_WIN32API)
+  return ::_fwrite_nolock(__buffer, __size, __n, __stream);
+#    elif __has_include(<unistd.h>)
+  return ::fwrite_unlocked(__buffer, __size, __n, __stream);
+#    else
+#      error "Provide a way to do unlocked stream I/O operations"
+#    endif
+}
+
+// This "buffer" is not a typical buffer but an adaptor for FILE*
+//
+// This adaptor locks the file stream, allowing it to use unlocked I/O.
+// This is used by the *_buffered functions in <print>. The print functions have
+// no wchar_t support so char is hard-coded. Since the underlaying I/O functions
+// encode narrow or wide in their name this avoids some `if constexpr` branches.
+//
+// The underlying functions for unlocked I/O are not in the C Standard, and
+// their names differ between POSIX and Windows, therefore the functions are
+// wrapped in this class.
+class __file_stream_buffer : public __format::__output_buffer<char> {
+public:
+  using value_type = char;
+
+  __file_stream_buffer(const __file_stream_buffer&)           = delete;
+  __file_stream_buffer operator=(const __file_stream_buffer&) = delete;
+
+  _LIBCPP_HIDE_FROM_ABI explicit __file_stream_buffer(FILE* __stream)
+      : __output_buffer<char>{__small_buffer_, __buffer_size, __prepare_write, nullptr}, __stream_(__stream) {
+    __print::__flockfile(__stream_);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI ~__file_stream_buffer() { __print::__funlockfile(__stream_); }
+
+  // In order to ensure all data is written this function needs to be called.
+  //
+  // The class wraps C based APIs that never throw. However the Standard
+  // requires exceptions to be throw when a write operation fails. Therefore
+  // this function should be called before the class is destroyed.
+  _LIBCPP_HIDE_FROM_ABI void __write_internal_buffer() && { __write_buffer(); }
+
+private:
+  FILE* __stream_;
+
+  // This class uses a fixed size buffer and appends the elements in
+  // __buffer_size chunks. An alternative would be to use an allocating buffer
+  // and append the output in a single write operation. Benchmarking showed no
+  // performance difference.
+  static constexpr size_t __buffer_size = 256;
+  char __small_buffer_[__buffer_size];
+
+  _LIBCPP_HIDE_FROM_ABI void __write_buffer() {
+    size_t __n    = this->__size();
+    size_t __size = __print::__fwrite_unlocked(__small_buffer_, 1, __n, __stream_);
+    if (__size < __n) {
+      if (std::feof(__stream_))
+        std::__throw_system_error(EIO, "EOF while writing the formatted output");
+      std::__throw_system_error(std::ferror(__stream_), "failed to write formatted output");
+    }
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void __prepare_write() {
+    __write_buffer();
+    this->__buffer_flushed();
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static void
+  __prepare_write(__output_buffer<char>& __buffer, [[maybe_unused]] size_t __size_hint) {
+    static_cast<__file_stream_buffer&>(__buffer).__prepare_write();
+  }
+};
+
 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
 _LIBCPP_HIDE_FROM_ABI inline void
 __vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) {
@@ -229,6 +332,26 @@ __vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool
   }
 }
 
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void __vprint_nonunicode_buffered(
+    __print::__file_stream_buffer& __buffer, string_view __fmt, format_args __args, bool __write_nl) {
+  std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
+                              std::__format_context_create(__buffer.__make_output_iterator(), __args));
+  if (__write_nl)
+    __buffer.push_back('\n');
+}
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void __vprint_nonunicode_buffered(
+FILE* __stream    , string_view __fmt, format_args __args, bool __write_nl) {
+  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
+  __print::__file_stream_buffer __buffer(__stream);
+
+  __print::__vprint_nonunicode_buffered(__buffer, __fmt, __args, __write_nl);
+
+  std::move(__buffer).__write_internal_buffer();
+}
+
 #    if _LIBCPP_HAS_UNICODE
 
 // Note these helper functions are mainly used to aid testing.
@@ -246,10 +369,27 @@ __vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bo
   __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
 }
 
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void __vprint_unicode_buffered_posix(
+    FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
+  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
+  __print::__file_stream_buffer __buffer(__stream);
+
+  // TODO PRINT Should flush errors throw too?
+  if (__is_terminal)
+    __print::__fflush_unlocked(__stream);
+
+  __print::__vprint_nonunicode_buffered(__buffer, __fmt, __args, __write_nl);
+
+  std::move(__buffer).__write_internal_buffer();
+}
 #      if _LIBCPP_HAS_WIDE_CHARACTERS
+
 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
 _LIBCPP_HIDE_FROM_ABI inline void
 __vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
+  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
+
   if (!__is_terminal)
     return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
 
@@ -284,6 +424,49 @@ __vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args,
                              "__write_to_windows_console is not available.");
 #        endif
 }
+
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void
+__vprint_unicode_buffered_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
+  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
+
+  if (!__is_terminal)
+    return __print::__vprint_nonunicode_buffered(__stream, __fmt, __args, __write_nl);
+
+  [[maybe_unused]] __print::__file_stream_buffer __unused(__stream);
+
+  // TODO PRINT Should flush errors throw too?
+  __print::__fflush_unlocked(__stream);
+
+  string __str = std::vformat(__fmt, __args);
+  // UTF-16 uses the same number or less code units than UTF-8.
+  // However the size of the code unit is 16 bits instead of 8 bits.
+  //
+  // The buffer uses the worst-case estimate and should never resize.
+  // However when the string is large this could lead to OOM. Using a
+  // smaller size might work, but since the buffer uses a grow factor
+  // the final size might be larger when the estimate is wrong.
+  //
+  // TODO PRINT profile and improve the speed of this code.
+  __format::__retarget_buffer<wchar_t> __buffer{__str.size()};
+  __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator());
+  if (__write_nl)
+    __buffer.push_back(L'\n');
+
+  [[maybe_unused]] wstring_view __view = __buffer.__view();
+
+  // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change
+  // the behavior in the test. This is not part of the public API.
+#        ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
+  _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view);
+#        elif defined(_LIBCPP_WIN32API)
+  std::__write_to_windows_console(__stream, __view);
+#        else
+  std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and "
+                             "__write_to_windows_console is not available.");
+#        endif
+}
+
 #      endif // _LIBCPP_HAS_WIDE_CHARACTERS
 
 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
@@ -324,6 +507,23 @@ __vprint_unicode([[maybe_unused]] FILE* __stream,
 #      endif
 }
 
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void __vprint_unicode_buffered(
+    [[maybe_unused]] FILE* __stream,
+    [[maybe_unused]] string_view __fmt,
+    [[maybe_unused]] format_args __args,
+    [[maybe_unused]] bool __write_nl) {
+  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
+
+#      ifndef _LIBCPP_WIN32API
+  __print::__vprint_unicode_buffered_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
+#      elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+  __print::__vprint_unicode_buffered_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
+#      else
+#        error "Windows builds with wchar_t disabled are not supported."
+#      endif
+}
+
 #    endif // _LIBCPP_HAS_UNICODE
 
 } // namespace __print
@@ -331,13 +531,23 @@ __vprint_unicode([[maybe_unused]] FILE* __stream,
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
 #    if _LIBCPP_HAS_UNICODE
-  if constexpr (__print::__use_unicode_execution_charset)
-    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
-  else
-    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+  constexpr bool __use_unicode = __print::__use_unicode_execution_charset;
 #    else  // _LIBCPP_HAS_UNICODE
-  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+  constexpr bool __use_unicode = false;
 #    endif // _LIBCPP_HAS_UNICODE
+  constexpr bool __locksafe = (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
+
+  if constexpr (__use_unicode) {
+    if constexpr (__locksafe)
+      __print::__vprint_unicode_buffered(__stream, __fmt.get(), std::make_format_args(__args...), false);
+    else
+      __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+  } else {
+    if constexpr (__locksafe)
+      __print::__vprint_nonunicode_buffered(__stream, __fmt.get(), std::make_format_args(__args...), false);
+    else
+      __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
+  }
 }
 
 template <class... _Args>
@@ -348,16 +558,26 @@ _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __arg
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
 #    if _LIBCPP_HAS_UNICODE
+  constexpr bool __use_unicode = __print::__use_unicode_execution_charset;
+#    else  // _LIBCPP_HAS_UNICODE
+  constexpr bool __use_unicode = false;
+#    endif // _LIBCPP_HAS_UNICODE
+  constexpr bool __locksafe = (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
+
   // Note the wording in the Standard is inefficient. The output of
   // std::format is a std::string which is then copied. This solution
   // just appends a newline at the end of the output.
-  if constexpr (__print::__use_unicode_execution_charset)
-    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
-  else
-    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
-#    else  // _LIBCPP_HAS_UNICODE
-  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
-#    endif // _LIBCPP_HAS_UNICODE
+  if constexpr (__use_unicode) {
+    if constexpr (__locksafe)
+      __print::__vprint_unicode_buffered(__stream, __fmt.get(), std::make_format_args(__args...), true);
+    else
+      __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
+  } else {
+    if constexpr (__locksafe)
+      __print::__vprint_nonunicode_buffered(__stream, __fmt.get(), std::make_format_args(__args...), true);
+    else
+      __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
+  }
 }
 
 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
@@ -381,6 +601,11 @@ _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __f
   __print::__vprint_unicode(__stream, __fmt, __args, false);
 }
 
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
+_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode_buffered(FILE* __stream, string_view __fmt, format_args __args) {
+  __print::__vprint_unicode_buffered(__stream, __fmt, __args, false);
+}
+
 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
 _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) {
   std::vprint_unicode(stdout, __fmt, __args);
diff --git a/libcxx/modules/std/print.inc b/libcxx/modules/std/print.inc
index 5354025ca8bd8..9c6d8b20a22d8 100644
--- a/libcxx/modules/std/print.inc
+++ b/libcxx/modules/std/print.inc
@@ -16,6 +16,7 @@ export namespace std {
   using std::vprint_nonunicode;
 #  if _LIBCPP_HAS_UNICODE
   using std::vprint_unicode;
+  using std::vprint_unicode_buffered;
 #  endif // _LIBCPP_HAS_UNICODE
 #endif   // _LIBCPP_STD_VER >= 23
 } // namespace std
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index ec5db90597d92..7d52c9fe13594 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2024,6 +2028,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index ec5db90597d92..7d52c9fe13594 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2024,6 +2028,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 95024df0590b8..951a785cf077b 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -125,15 +125,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2064,6 +2068,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index a3518f7f62ecb..7742c23b796f7 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -122,15 +122,19 @@ atomic ratio
 atomic type_traits
 atomic version
 barrier atomic
+barrier cctype
 barrier climits
 barrier cmath
 barrier compare
 barrier concepts
 barrier cstddef
 barrier cstdint
+barrier cstdio
 barrier cstdlib
 barrier cstring
 barrier ctime
+barrier cwchar
+barrier cwctype
 barrier exception
 barrier initializer_list
 barrier iosfwd
@@ -2077,6 +2081,7 @@ stdexcept new
 stdexcept type_traits
 stdexcept typeinfo
 stdexcept version
+stop_token cstddef
 stop_token iosfwd
 stop_token version
 streambuf algorithm
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index 17972b8453743..167c79130bfbf 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -556,7 +556,6 @@ istream ios
 istream iosfwd
 istream limits
 istream locale
-
 istream ratio
 istream stdexcept
 istream streambuf
@@ -765,6 +764,7 @@ queue deque
 queue initializer_list
 queue iosfwd
 queue limits
+queue optional
 queue stdexcept
 queue string
 queue string_view
@@ -831,6 +831,7 @@ regex deque
 regex initializer_list
 regex iosfwd
 regex limits
+regex optional
 regex stdexcept
 regex string
 regex string_view
@@ -1075,6 +1076,7 @@ thread iosfwd
 thread istream
 thread limits
 thread locale
+thread optional
 thread ratio
 thread sstream
 thread stdexcept
@@ -1146,6 +1148,7 @@ vector cwctype
 vector initializer_list
 vector iosfwd
 vector limits
+vector optional
 vector stdexcept
 vector string
 vector string_view
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 00ab78e61a457..2bc61974a2ad8 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -763,6 +763,7 @@ queue deque
 queue initializer_list
 queue iosfwd
 queue limits
+queue optional
 queue stdexcept
 queue string
 queue string_view
@@ -829,6 +830,7 @@ regex deque
 regex initializer_list
 regex iosfwd
 regex limits
+regex optional
 regex stdexcept
 regex string
 regex string_view
@@ -1073,6 +1075,7 @@ thread iosfwd
 thread istream
 thread limits
 thread locale
+thread optional
 thread ratio
 thread sstream
 thread stdexcept
@@ -1144,6 +1147,7 @@ vector cwctype
 vector initializer_list
 vector iosfwd
 vector limits
+vector optional
 vector stdexcept
 vector string
 vector string_view



More information about the llvm-branch-commits mailing list