[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