|
8 | 8 |
|
9 | 9 | #include "std_stream.h" |
10 | 10 | #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) |
17 | 11 |
|
18 | 12 | _LIBCPP_BEGIN_NAMESPACE_STD |
19 | 13 |
|
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>)]; |
27 | 14 | static mbstate_t mb_cin; |
| 15 | +static mbstate_t mb_cout; |
| 16 | +static mbstate_t mb_cerr; |
28 | 17 |
|
29 | 18 | #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>)]; |
37 | 19 | 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; |
44 | 22 | #endif |
45 | | - ; |
46 | | -alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; |
47 | | -static mbstate_t mb_cout; |
48 | 23 |
|
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; |
59 | 27 |
|
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 |
64 | 34 | #endif |
65 | | - ; |
66 | | -alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; |
67 | | -static mbstate_t mb_cerr; |
68 | 35 |
|
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; } |
79 | 37 |
|
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)); |
86 | 55 |
|
87 | 56 | #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 | + |
94 | 68 | #endif // _LIBCPP_HAS_WIDE_CHARACTERS |
95 | 69 |
|
| 70 | +# 70 __FILE__ 1 |
| 71 | + |
96 | 72 | // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority |
97 | 73 | // attribute with a value that's reserved for the implementation (we're the implementation). |
98 | 74 | #include "iostream_init.h" |
@@ -124,37 +100,24 @@ class DoIOSInit { |
124 | 100 | DoIOSInit::DoIOSInit() { |
125 | 101 | force_locale_initialization(); |
126 | 102 |
|
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)); |
134 | 106 |
|
135 | 107 | #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)); |
144 | 111 | #endif |
145 | 112 | } |
146 | 113 |
|
147 | 114 | 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(); |
152 | 117 |
|
153 | 118 | #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(); |
158 | 121 | #endif |
159 | 122 | } |
160 | 123 |
|
|
0 commit comments