[libcxx-commits] [libcxx] [libc++] Refactor iostream.cpp (PR #121116)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 2 09:34:08 PST 2025


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/121116

>From 762bab95bf22c1d8cd418bd9c7290ab74604224f Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 25 Dec 2024 23:23:34 +0100
Subject: [PATCH] [libc++] Refactor iostream.cpp

---
 libcxx/src/iostream.cpp | 140 ++++++++++++++++------------------------
 1 file changed, 54 insertions(+), 86 deletions(-)

diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp
index 6db02d56037947..0d309979e216e0 100644
--- a/libcxx/src/iostream.cpp
+++ b/libcxx/src/iostream.cpp
@@ -9,7 +9,6 @@
 #include "std_stream.h"
 #include <__locale>
 #include <new>
-#include <string>
 
 #define _str(s) #s
 #define str(s) _str(s)
@@ -17,82 +16,57 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-alignas(istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
-#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream at DU?$char_traits at D@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#endif
-        ;
-alignas(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];
 static mbstate_t mb_cin;
+static mbstate_t mb_cout;
+static mbstate_t mb_cerr;
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-alignas(wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
-#  if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream at _WU?$char_traits at _W@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#  endif
-        ;
-alignas(__stdinbuf<wchar_t>) static char __wcin[sizeof(__stdinbuf<wchar_t>)];
 static mbstate_t mb_wcin;
-#endif // _LIBCPP_HAS_WIDE_CHARACTERS
-
-alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
-#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at DU?$char_traits at D@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
+static mbstate_t mb_wcout;
+static mbstate_t mb_wcerr;
 #endif
-        ;
-alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
-static mbstate_t mb_cout;
 
-#if _LIBCPP_HAS_WIDE_CHARACTERS
-alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
-#  if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at _WU?$char_traits at _W@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#  endif
-        ;
-alignas(__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
-static mbstate_t mb_wcout;
-#endif // _LIBCPP_HAS_WIDE_CHARACTERS
+#if __has_cpp_attribute(clang::no_destroy)
+template <class T>
+using no_destroy_t = T;
 
-alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
-#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at DU?$char_traits at D@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
+#  define STREAM_ATTRS [[clang::no_destroy]] _LIBCPP_INIT_PRIORITY_MAX
+#else
+template <class T>
+using no_destroy_t = __no_destroy<T>;
+
+#  define STREAM_ATTRS _LIBCPP_INIT_PRIORITY_MAX
 #endif
-        ;
-alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
-static mbstate_t mb_cerr;
 
-#if _LIBCPP_HAS_WIDE_CHARACTERS
-alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
-#  if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at _WU?$char_traits at _W@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#  endif
-        ;
-alignas(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
-static mbstate_t mb_wcerr;
-#endif // _LIBCPP_HAS_WIDE_CHARACTERS
+# 41 __FILE__ 3 // FIXME: Remove this (and the one below) once https://llvm.org/PR121108 is fixed.
 
-alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
-#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at DU?$char_traits at D@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#endif
-        ;
+STREAM_ATTRS static no_destroy_t<__stdinbuf<char>> cin_stdbuf(stdin, &mb_cin);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<istream> cin(&cin_stdbuf);
+
+STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cout_stdbuf(stdout, &mb_cout);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cout(&cout_stdbuf);
+
+STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cerr_stdbuf(stderr, &mb_cerr);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cerr(&cerr_stdbuf);
+
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> clog(&cerr_stdbuf);
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
-#  if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
-    __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream at _WU?$char_traits at _W@" _LIBCPP_ABI_NAMESPACE_STR
-            "@std@@@12 at A")
-#  endif
-        ;
+STREAM_ATTRS static __stdinbuf<wchar_t> wcin_stdbuf(stdin, &mb_wcin);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI wistream wcin(&wcin_stdbuf);
+
+STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcout_stdbuf(stdout, &mb_wcout);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcout(&wcout_stdbuf);
+
+STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcerr_stdbuf(stderr, &mb_wcerr);
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcerr(&wcerr_stdbuf);
+
+STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wclog(&wcerr_stdbuf);
+
 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
 
+# 68 __FILE__ 1
+
 // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
 // attribute with a value that's reserved for the implementation (we're the implementation).
 #include "iostream_init.h"
@@ -121,40 +95,34 @@ class DoIOSInit {
   ~DoIOSInit();
 };
 
+auto&& unwrap(auto& val) { return val; }
+
+template <class T>
+auto&& unwrap(__no_destroy<T>& val) {
+  return val.__get();
+}
+
 DoIOSInit::DoIOSInit() {
   force_locale_initialization();
 
-  istream* cin_ptr  = ::new (cin) istream(::new (__cin) __stdinbuf<char>(stdin, &mb_cin));
-  ostream* cout_ptr = ::new (cout) ostream(::new (__cout) __stdoutbuf<char>(stdout, &mb_cout));
-  ostream* cerr_ptr = ::new (cerr) ostream(::new (__cerr) __stdoutbuf<char>(stderr, &mb_cerr));
-  ::new (clog) ostream(cerr_ptr->rdbuf());
-  cin_ptr->tie(cout_ptr);
-  std::unitbuf(*cerr_ptr);
-  cerr_ptr->tie(cout_ptr);
+  unwrap(cin).tie(&unwrap(cout));
+  std::unitbuf(unwrap(cerr));
+  unwrap(cerr).tie(&unwrap(cout));
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-  wistream* wcin_ptr  = ::new (wcin) wistream(::new (__wcin) __stdinbuf<wchar_t>(stdin, &mb_wcin));
-  wostream* wcout_ptr = ::new (wcout) wostream(::new (__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout));
-  wostream* wcerr_ptr = ::new (wcerr) wostream(::new (__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));
-  ::new (wclog) wostream(wcerr_ptr->rdbuf());
-
-  wcin_ptr->tie(wcout_ptr);
-  std::unitbuf(*wcerr_ptr);
-  wcerr_ptr->tie(wcout_ptr);
+  unwrap(wcin).tie(&unwrap(wcout));
+  std::unitbuf(unwrap(wcerr));
+  unwrap(wcerr).tie(&unwrap(wcout));
 #endif
 }
 
 DoIOSInit::~DoIOSInit() {
-  ostream* cout_ptr = reinterpret_cast<ostream*>(cout);
-  cout_ptr->flush();
-  ostream* clog_ptr = reinterpret_cast<ostream*>(clog);
-  clog_ptr->flush();
+  unwrap(cout).flush();
+  unwrap(clog).flush();
 
 #if _LIBCPP_HAS_WIDE_CHARACTERS
-  wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);
-  wcout_ptr->flush();
-  wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);
-  wclog_ptr->flush();
+  unwrap(wcout).flush();
+  unwrap(wclog).flush();
 #endif
 }
 



More information about the libcxx-commits mailing list