Skip to content

[libc++] Refactor iostream.cpp #121116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 54 additions & 91 deletions libcxx/src/iostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,91 +8,67 @@

#include "std_stream.h"
#include <__locale>
#include <new>
#include <string>

#define _str(s) #s
#define str(s) _str(s)
#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)

_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@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
#endif
;
alignas(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];
static mbstate_t mb_cin;
static mbstate_t mb_cout;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constinit?

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@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@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@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@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@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@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@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@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@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
# endif
;
alignas(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
static mbstate_t mb_wcerr;
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
auto&& unwrap(auto& val) { return val; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto&& unwrap(auto& val) { return val; }
inline auto&& unwrap(auto& val) { return val; }

If you decide to write this as an auto function, let's make the linkage clear by using inline.


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@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
#endif
;
template <class T>
auto&& unwrap(__no_destroy<T>& val) {
return val.__get();
}

# 43 __FILE__ 3 // FIXME: Remove this (and the one below) once https://llvm.org/PR121108 is fixed.

STREAM_ATTRS static no_destroy_t<__stdinbuf<char>> cin_stdbuf(stdin, &mb_cin);
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<istream> cin(&unwrap(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(&unwrap(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(&unwrap(cerr_stdbuf));

STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> clog(&unwrap(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@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
# endif
;
STREAM_ATTRS static __stdinbuf<wchar_t> wcin_stdbuf(stdin, &mb_wcin);
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI wistream wcin(&unwrap(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(&unwrap(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(&unwrap(wcerr_stdbuf));

STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wclog(&unwrap(wcerr_stdbuf));

#endif // _LIBCPP_HAS_WIDE_CHARACTERS

# 70 __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"
Comment on lines 72 to 74
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could move the contents of that file inside the # __FILE__ directive and get rid of the header.

_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX;

# 70 __FILE__ 1

Expand Down Expand Up @@ -124,37 +100,24 @@ class DoIOSInit {
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
}

Expand Down
Loading