Skip to content

Commit 912fc97

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

File tree

1 file changed

+54
-91
lines changed

1 file changed

+54
-91
lines changed

libcxx/src/iostream.cpp

Lines changed: 54 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -8,91 +8,67 @@
88

99
#include "std_stream.h"
1010
#include <__locale>
11-
#include <new>
12-
#include <string>
13-
14-
#define _str(s) #s
15-
#define str(s) _str(s)
16-
#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
1711

1812
_LIBCPP_BEGIN_NAMESPACE_STD
1913

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>)];
2714
static mbstate_t mb_cin;
15+
static mbstate_t mb_cout;
16+
static mbstate_t mb_cerr;
2817

2918
#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>)];
3719
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")
20+
static mbstate_t mb_wcout;
21+
static mbstate_t mb_wcerr;
4422
#endif
45-
;
46-
alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
47-
static mbstate_t mb_cout;
4823

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
24+
#if __has_cpp_attribute(clang::no_destroy)
25+
template <class T>
26+
using no_destroy_t = T;
5927

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")
28+
# define STREAM_ATTRS [[clang::no_destroy]] _LIBCPP_INIT_PRIORITY_MAX
29+
#else
30+
template <class T>
31+
using no_destroy_t = __no_destroy<T>;
32+
33+
# define STREAM_ATTRS _LIBCPP_INIT_PRIORITY_MAX
6434
#endif
65-
;
66-
alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
67-
static mbstate_t mb_cerr;
6835

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
36+
auto&& unwrap(auto& val) { return val; }
7937

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-
;
38+
template <class T>
39+
auto&& unwrap(__no_destroy<T>& val) {
40+
return val.__get();
41+
}
42+
43+
# 43 __FILE__ 3 // FIXME: Remove this (and the one below) once https://llvm.org/PR121108 is fixed.
44+
45+
STREAM_ATTRS static no_destroy_t<__stdinbuf<char>> cin_stdbuf(stdin, &mb_cin);
46+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<istream> cin(&unwrap(cin_stdbuf));
47+
48+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cout_stdbuf(stdout, &mb_cout);
49+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cout(&unwrap(cout_stdbuf));
50+
51+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<char>> cerr_stdbuf(stderr, &mb_cerr);
52+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> cerr(&unwrap(cerr_stdbuf));
53+
54+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<ostream> clog(&unwrap(cerr_stdbuf));
8655

8756
#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-
;
57+
STREAM_ATTRS static __stdinbuf<wchar_t> wcin_stdbuf(stdin, &mb_wcin);
58+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI wistream wcin(&unwrap(wcin_stdbuf));
59+
60+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcout_stdbuf(stdout, &mb_wcout);
61+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcout(&unwrap(wcout_stdbuf));
62+
63+
STREAM_ATTRS static no_destroy_t<__stdoutbuf<wchar_t>> wcerr_stdbuf(stderr, &mb_wcerr);
64+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wcerr(&unwrap(wcerr_stdbuf));
65+
66+
STREAM_ATTRS _LIBCPP_EXPORTED_FROM_ABI no_destroy_t<wostream> wclog(&unwrap(wcerr_stdbuf));
67+
9468
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
9569

70+
# 70 __FILE__ 1
71+
9672
// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
9773
// attribute with a value that's reserved for the implementation (we're the implementation).
9874
#include "iostream_init.h"
@@ -124,37 +100,24 @@ class DoIOSInit {
124100
DoIOSInit::DoIOSInit() {
125101
force_locale_initialization();
126102

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());
131-
cin_ptr->tie(cout_ptr);
132-
std::unitbuf(*cerr_ptr);
133-
cerr_ptr->tie(cout_ptr);
103+
unwrap(cin).tie(&unwrap(cout));
104+
std::unitbuf(unwrap(cerr));
105+
unwrap(cerr).tie(&unwrap(cout));
134106

135107
#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-
141-
wcin_ptr->tie(wcout_ptr);
142-
std::unitbuf(*wcerr_ptr);
143-
wcerr_ptr->tie(wcout_ptr);
108+
unwrap(wcin).tie(&unwrap(wcout));
109+
std::unitbuf(unwrap(wcerr));
110+
unwrap(wcerr).tie(&unwrap(wcout));
144111
#endif
145112
}
146113

147114
DoIOSInit::~DoIOSInit() {
148-
ostream* cout_ptr = reinterpret_cast<ostream*>(cout);
149-
cout_ptr->flush();
150-
ostream* clog_ptr = reinterpret_cast<ostream*>(clog);
151-
clog_ptr->flush();
115+
unwrap(cout).flush();
116+
unwrap(clog).flush();
152117

153118
#if _LIBCPP_HAS_WIDE_CHARACTERS
154-
wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);
155-
wcout_ptr->flush();
156-
wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);
157-
wclog_ptr->flush();
119+
unwrap(wcout).flush();
120+
unwrap(wclog).flush();
158121
#endif
159122
}
160123

0 commit comments

Comments
 (0)