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_base_api/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_TYPE(istream
)
25 _LIBCPP_EXPORTED_FROM_ABI
char cin
[sizeof(istream
)]
26 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
27 __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
31 _ALIGNAS_TYPE(__stdinbuf
<char>) static char __cin
[sizeof(__stdinbuf
<char>)];
32 static mbstate_t mb_cin
;
34 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
35 _ALIGNAS_TYPE(wistream
)
36 _LIBCPP_EXPORTED_FROM_ABI
char wcin
[sizeof(wistream
)]
37 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
38 __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
42 _ALIGNAS_TYPE(__stdinbuf
<wchar_t>) static char __wcin
[sizeof(__stdinbuf
<wchar_t>)];
43 static mbstate_t mb_wcin
;
44 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
46 _ALIGNAS_TYPE(ostream
)
47 _LIBCPP_EXPORTED_FROM_ABI
char cout
[sizeof(ostream
)]
48 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
49 __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
53 _ALIGNAS_TYPE(__stdoutbuf
<char>) static char __cout
[sizeof(__stdoutbuf
<char>)];
54 static mbstate_t mb_cout
;
56 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
57 _ALIGNAS_TYPE(wostream
)
58 _LIBCPP_EXPORTED_FROM_ABI
char wcout
[sizeof(wostream
)]
59 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
60 __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
64 _ALIGNAS_TYPE(__stdoutbuf
<wchar_t>) static char __wcout
[sizeof(__stdoutbuf
<wchar_t>)];
65 static mbstate_t mb_wcout
;
66 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
68 _ALIGNAS_TYPE(ostream
)
69 _LIBCPP_EXPORTED_FROM_ABI
char cerr
[sizeof(ostream
)]
70 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
71 __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
75 _ALIGNAS_TYPE(__stdoutbuf
<char>) static char __cerr
[sizeof(__stdoutbuf
<char>)];
76 static mbstate_t mb_cerr
;
78 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
79 _ALIGNAS_TYPE(wostream
)
80 _LIBCPP_EXPORTED_FROM_ABI
char wcerr
[sizeof(wostream
)]
81 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
82 __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
86 _ALIGNAS_TYPE(__stdoutbuf
<wchar_t>) static char __wcerr
[sizeof(__stdoutbuf
<wchar_t>)];
87 static mbstate_t mb_wcerr
;
88 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
90 _ALIGNAS_TYPE(ostream
)
91 _LIBCPP_EXPORTED_FROM_ABI
char clog
[sizeof(ostream
)]
92 #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
93 __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
98 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
99 _ALIGNAS_TYPE(wostream
)
100 _LIBCPP_EXPORTED_FROM_ABI
char wclog
[sizeof(wostream
)]
101 # if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
102 __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
106 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
108 // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
109 // attribute with a value that's reserved for the implementation (we're the implementation).
110 #include "iostream_init.h"
112 // On Windows the TLS storage for locales needs to be initialized before we create
113 // the standard streams, otherwise it may not be alive during program termination
114 // when we flush the streams.
115 static void force_locale_initialization() {
116 #if defined(_LIBCPP_MSVCRT_LIKE)
117 static bool once
= []() {
118 auto loc
= newlocale(LC_ALL_MASK
, "C", 0);
120 __libcpp_locale_guard
g(loc
); // forces initialization of locale TLS
136 DoIOSInit::DoIOSInit() {
137 force_locale_initialization();
139 istream
* cin_ptr
= ::new (cin
) istream(::new (__cin
) __stdinbuf
<char>(stdin
, &mb_cin
));
140 ostream
* cout_ptr
= ::new (cout
) ostream(::new (__cout
) __stdoutbuf
<char>(stdout
, &mb_cout
));
141 ostream
* cerr_ptr
= ::new (cerr
) ostream(::new (__cerr
) __stdoutbuf
<char>(stderr
, &mb_cerr
));
142 ::new (clog
) ostream(cerr_ptr
->rdbuf());
143 cin_ptr
->tie(cout_ptr
);
144 std::unitbuf(*cerr_ptr
);
145 cerr_ptr
->tie(cout_ptr
);
147 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
148 wistream
* wcin_ptr
= ::new (wcin
) wistream(::new (__wcin
) __stdinbuf
<wchar_t>(stdin
, &mb_wcin
));
149 wostream
* wcout_ptr
= ::new (wcout
) wostream(::new (__wcout
) __stdoutbuf
<wchar_t>(stdout
, &mb_wcout
));
150 wostream
* wcerr_ptr
= ::new (wcerr
) wostream(::new (__wcerr
) __stdoutbuf
<wchar_t>(stderr
, &mb_wcerr
));
151 ::new (wclog
) wostream(wcerr_ptr
->rdbuf());
153 wcin_ptr
->tie(wcout_ptr
);
154 std::unitbuf(*wcerr_ptr
);
155 wcerr_ptr
->tie(wcout_ptr
);
159 DoIOSInit::~DoIOSInit() {
160 ostream
* cout_ptr
= reinterpret_cast<ostream
*>(cout
);
162 ostream
* clog_ptr
= reinterpret_cast<ostream
*>(clog
);
165 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
166 wostream
* wcout_ptr
= reinterpret_cast<wostream
*>(wcout
);
168 wostream
* wclog_ptr
= reinterpret_cast<wostream
*>(wclog
);
173 ios_base::Init::Init() {
174 static DoIOSInit init_the_streams
; // gets initialized once
177 ios_base::Init::~Init() {}
179 _LIBCPP_END_NAMESPACE_STD