Skip to content

Commit 5cc9d99

Browse files
committed
[libc++] Refactor iostream.cpp
1 parent 8e965d8 commit 5cc9d99

File tree

2 files changed

+53
-76
lines changed

2 files changed

+53
-76
lines changed

libcxx/include/__utility/no_destroy.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ struct __no_destroy {
4545
_LIBCPP_HIDE_FROM_ABI _Tp& __get() { return *reinterpret_cast<_Tp*>(__obj_); }
4646
_LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return *reinterpret_cast<const _Tp*>(__obj_); }
4747

48+
_LIBCPP_HIDE_FROM_ABI _Tp* operator&() { return &__get(); }
49+
_LIBCPP_HIDE_FROM_ABI const _Tp* operator&() const { return &__get(); }
50+
4851
private:
4952
_ALIGNAS_TYPE(_Tp) char __obj_[sizeof(_Tp)];
5053
};

libcxx/src/iostream.cpp

Lines changed: 50 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -9,90 +9,64 @@
99
#include "std_stream.h"
1010
#include <__locale>
1111
#include <new>
12-
#include <string>
1312

1413
#define _str(s) #s
1514
#define str(s) _str(s)
1615
#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
1716

1817
_LIBCPP_BEGIN_NAMESPACE_STD
1918

20-
alignas(istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
21-
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
22-
__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
23-
"@std@@@12@A")
24-
#endif
25-
;
26-
alignas(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];
2719
static mbstate_t mb_cin;
20+
static mbstate_t mb_cout;
21+
static mbstate_t mb_cerr;
2822

2923
#if _LIBCPP_HAS_WIDE_CHARACTERS
30-
alignas(wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
31-
# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
32-
__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
33-
"@std@@@12@A")
34-
# endif
35-
;
36-
alignas(__stdinbuf<wchar_t>) static char __wcin[sizeof(__stdinbuf<wchar_t>)];
3724
static mbstate_t mb_wcin;
38-
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
39-
40-
alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
41-
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
42-
__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
43-
"@std@@@12@A")
25+
static mbstate_t mb_wcout;
26+
static mbstate_t mb_wcerr;
4427
#endif
45-
;
46-
alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
47-
static mbstate_t mb_cout;
4828

49-
#if _LIBCPP_HAS_WIDE_CHARACTERS
50-
alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
51-
# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
52-
__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
53-
"@std@@@12@A")
54-
# endif
55-
;
56-
alignas(__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
57-
static mbstate_t mb_wcout;
58-
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
29+
#if __has_cpp_attribute(clang::no_destroy)
30+
template <class T>
31+
using no_destroy_t = T;
32+
33+
# define STREAM_ATTRS [[clang::no_destroy]] _LIBCPP_INIT_PRIORITY_MAX
34+
#else
35+
template <class T>
36+
using no_destroy_t = __no_destroy<T>;
5937

60-
alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
61-
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
62-
__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
63-
"@std@@@12@A")
38+
# define STREAM_ATTRS _LIBCPP_INIT_PRIORITY_MAX
6439
#endif
65-
;
66-
alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
67-
static mbstate_t mb_cerr;
6840

69-
#if _LIBCPP_HAS_WIDE_CHARACTERS
70-
alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
71-
# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
72-
__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
73-
"@std@@@12@A")
74-
# endif
75-
;
76-
alignas(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
77-
static mbstate_t mb_wcerr;
78-
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
41+
# 41 __FILE__ 3 // FIXME: Remove this (and the one below) once https://llvm.org/PR121108 is fixed.
7942

80-
alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
81-
#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
82-
__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
83-
"@std@@@12@A")
84-
#endif
85-
;
43+
STREAM_ATTRS static no_destroy_t<__stdinbuf<char>> cin_stdbuf(stdin, &mb_cin);
44+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<istream> cin(&cin_stdbuf);
45+
46+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cout_stdbuf(stdout, &mb_cout);
47+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cout(&cout_stdbuf);
48+
49+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cerr_stdbuf(stderr, &mb_cerr);
50+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cerr(&cerr_stdbuf);
51+
52+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> clog(&cerr_stdbuf);
8653

8754
#if _LIBCPP_HAS_WIDE_CHARACTERS
88-
alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
89-
# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
90-
__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
91-
"@std@@@12@A")
92-
# endif
93-
;
55+
STREAM_ATTRS static __stdinbuf<wchar_t> wcin_stdbuf(stdin, &mb_wcin);
56+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI wistream wcin(&wcin_stdbuf);
57+
58+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcout_stdbuf(stdout, &mb_wcout);
59+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcout(&wcout_stdbuf);
60+
61+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcerr_stdbuf(stderr, &mb_wcerr);
62+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcerr(&wcerr_stdbuf);
63+
64+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wclog(&wcerr_stdbuf);
65+
9466
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
9567

68+
# 68 __FILE__ 1
69+
9670
// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
9771
// attribute with a value that's reserved for the implementation (we're the implementation).
9872
#include "iostream_init.h"
@@ -124,36 +98,36 @@ class DoIOSInit {
12498
DoIOSInit::DoIOSInit() {
12599
force_locale_initialization();
126100

127-
istream* cin_ptr = ::new (cin) istream(::new (__cin) __stdinbuf<char>(stdin, &mb_cin));
128-
ostream* cout_ptr = ::new (cout) ostream(::new (__cout) __stdoutbuf<char>(stdout, &mb_cout));
129-
ostream* cerr_ptr = ::new (cerr) ostream(::new (__cerr) __stdoutbuf<char>(stderr, &mb_cerr));
130-
::new (clog) ostream(cerr_ptr->rdbuf());
101+
auto cin_ptr = &cin;
102+
auto cout_ptr = &cout;
103+
auto cerr_ptr = &cerr;
104+
#if _LIBCPP_HAS_WIDE_CHARACTERS
105+
auto wcin_ptr = &wcin;
106+
auto wcout_ptr = &wcout;
107+
auto wcerr_ptr = &wcerr;
108+
#endif
109+
131110
cin_ptr->tie(cout_ptr);
132111
std::unitbuf(*cerr_ptr);
133112
cerr_ptr->tie(cout_ptr);
134113

135114
#if _LIBCPP_HAS_WIDE_CHARACTERS
136-
wistream* wcin_ptr = ::new (wcin) wistream(::new (__wcin) __stdinbuf<wchar_t>(stdin, &mb_wcin));
137-
wostream* wcout_ptr = ::new (wcout) wostream(::new (__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout));
138-
wostream* wcerr_ptr = ::new (wcerr) wostream(::new (__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));
139-
::new (wclog) wostream(wcerr_ptr->rdbuf());
140-
141115
wcin_ptr->tie(wcout_ptr);
142116
std::unitbuf(*wcerr_ptr);
143117
wcerr_ptr->tie(wcout_ptr);
144118
#endif
145119
}
146120

147121
DoIOSInit::~DoIOSInit() {
148-
ostream* cout_ptr = reinterpret_cast<ostream*>(cout);
122+
ostream* cout_ptr = &cout;
149123
cout_ptr->flush();
150-
ostream* clog_ptr = reinterpret_cast<ostream*>(clog);
124+
ostream* clog_ptr = &clog;
151125
clog_ptr->flush();
152126

153127
#if _LIBCPP_HAS_WIDE_CHARACTERS
154-
wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);
128+
wostream* wcout_ptr = &wcout;
155129
wcout_ptr->flush();
156-
wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);
130+
wostream* wclog_ptr = &wclog;
157131
wclog_ptr->flush();
158132
#endif
159133
}

0 commit comments

Comments
 (0)