1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "std_stream.h"
14 #ifdef _LIBCPP_MSVCRT_LIKE
15 # include <__locale_dir/locale_guard.h>
19 #define str(s) _str(s)
20 #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
22 _LIBCPP_BEGIN_NAMESPACE_STD
24 alignas(istream
) _LIBCPP_EXPORTED_FROM_ABI
char cin
[sizeof(istream
)]
25 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
26 __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
30 alignas(__stdinbuf
<char>) static char __cin
[sizeof(__stdinbuf
<char>)];
31 static mbstate_t mb_cin
;
33 #if _LIBCPP_HAS_WIDE_CHARACTERS
34 alignas(wistream
) _LIBCPP_EXPORTED_FROM_ABI
char wcin
[sizeof(wistream
)]
35 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
36 __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
40 alignas(__stdinbuf
<wchar_t>) static char __wcin
[sizeof(__stdinbuf
<wchar_t>)];
41 static mbstate_t mb_wcin
;
42 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
44 alignas(ostream
) _LIBCPP_EXPORTED_FROM_ABI
char cout
[sizeof(ostream
)]
45 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
46 __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
50 alignas(__stdoutbuf
<char>) static char __cout
[sizeof(__stdoutbuf
<char>)];
51 static mbstate_t mb_cout
;
53 #if _LIBCPP_HAS_WIDE_CHARACTERS
54 alignas(wostream
) _LIBCPP_EXPORTED_FROM_ABI
char wcout
[sizeof(wostream
)]
55 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
56 __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
60 alignas(__stdoutbuf
<wchar_t>) static char __wcout
[sizeof(__stdoutbuf
<wchar_t>)];
61 static mbstate_t mb_wcout
;
62 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
64 alignas(ostream
) _LIBCPP_EXPORTED_FROM_ABI
char cerr
[sizeof(ostream
)]
65 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
66 __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
70 alignas(__stdoutbuf
<char>) static char __cerr
[sizeof(__stdoutbuf
<char>)];
71 static mbstate_t mb_cerr
;
73 #if _LIBCPP_HAS_WIDE_CHARACTERS
74 alignas(wostream
) _LIBCPP_EXPORTED_FROM_ABI
char wcerr
[sizeof(wostream
)]
75 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
76 __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
80 alignas(__stdoutbuf
<wchar_t>) static char __wcerr
[sizeof(__stdoutbuf
<wchar_t>)];
81 static mbstate_t mb_wcerr
;
82 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
84 alignas(ostream
) _LIBCPP_EXPORTED_FROM_ABI
char clog
[sizeof(ostream
)]
85 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
86 __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
91 #if _LIBCPP_HAS_WIDE_CHARACTERS
92 alignas(wostream
) _LIBCPP_EXPORTED_FROM_ABI
char wclog
[sizeof(wostream
)]
93 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
94 __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
98 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
100 // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
101 // attribute with a value that's reserved for the implementation (we're the implementation).
102 #include "iostream_init.h"
104 // On Windows the TLS storage for locales needs to be initialized before we create
105 // the standard streams, otherwise it may not be alive during program termination
106 // when we flush the streams.
107 static void force_locale_initialization() {
108 #if defined(_LIBCPP_MSVCRT_LIKE)
109 static bool once
= []() {
110 auto loc
= __locale::__newlocale(LC_ALL_MASK
, "C", 0);
112 __locale_guard
g(loc
); // forces initialization of locale TLS
115 __locale::__freelocale(loc
);
128 DoIOSInit::DoIOSInit() {
129 force_locale_initialization();
131 istream
* cin_ptr
= ::new (cin
) istream(::new (__cin
) __stdinbuf
<char>(stdin
, &mb_cin
));
132 ostream
* cout_ptr
= ::new (cout
) ostream(::new (__cout
) __stdoutbuf
<char>(stdout
, &mb_cout
));
133 ostream
* cerr_ptr
= ::new (cerr
) ostream(::new (__cerr
) __stdoutbuf
<char>(stderr
, &mb_cerr
));
134 ::new (clog
) ostream(cerr_ptr
->rdbuf());
135 cin_ptr
->tie(cout_ptr
);
136 std::unitbuf(*cerr_ptr
);
137 cerr_ptr
->tie(cout_ptr
);
139 #if _LIBCPP_HAS_WIDE_CHARACTERS
140 wistream
* wcin_ptr
= ::new (wcin
) wistream(::new (__wcin
) __stdinbuf
<wchar_t>(stdin
, &mb_wcin
));
141 wostream
* wcout_ptr
= ::new (wcout
) wostream(::new (__wcout
) __stdoutbuf
<wchar_t>(stdout
, &mb_wcout
));
142 wostream
* wcerr_ptr
= ::new (wcerr
) wostream(::new (__wcerr
) __stdoutbuf
<wchar_t>(stderr
, &mb_wcerr
));
143 ::new (wclog
) wostream(wcerr_ptr
->rdbuf());
145 wcin_ptr
->tie(wcout_ptr
);
146 std::unitbuf(*wcerr_ptr
);
147 wcerr_ptr
->tie(wcout_ptr
);
151 DoIOSInit::~DoIOSInit() {
152 ostream
* cout_ptr
= reinterpret_cast<ostream
*>(cout
);
154 ostream
* clog_ptr
= reinterpret_cast<ostream
*>(clog
);
157 #if _LIBCPP_HAS_WIDE_CHARACTERS
158 wostream
* wcout_ptr
= reinterpret_cast<wostream
*>(wcout
);
160 wostream
* wclog_ptr
= reinterpret_cast<wostream
*>(wclog
);
165 ios_base::Init::Init() {
166 static DoIOSInit init_the_streams
; // gets initialized once
169 ios_base::Init::~Init() {}
171 _LIBCPP_END_NAMESPACE_STD