1 | //===------------------------ iostream.cpp --------------------------------===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "__std_stream" |
10 | #include "__locale" |
11 | #include "string" |
12 | #include "new" |
13 | |
14 | #define _str(s) #s |
15 | #define str(s) _str(s) |
16 | #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE) |
17 | |
18 | _LIBCPP_BEGIN_NAMESPACE_STD |
19 | |
20 | #ifndef _LIBCPP_HAS_NO_STDIN |
21 | _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] |
22 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
23 | __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
24 | #endif |
25 | ; |
26 | _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)]; |
27 | static mbstate_t mb_cin; |
28 | _ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)] |
29 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
30 | __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
31 | #endif |
32 | ; |
33 | _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar_t>)]; |
34 | static mbstate_t mb_wcin; |
35 | #endif |
36 | |
37 | #ifndef _LIBCPP_HAS_NO_STDOUT |
38 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)] |
39 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
40 | __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
41 | #endif |
42 | ; |
43 | _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; |
44 | static mbstate_t mb_cout; |
45 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)] |
46 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
47 | __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
48 | #endif |
49 | ; |
50 | _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)]; |
51 | static mbstate_t mb_wcout; |
52 | #endif |
53 | |
54 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)] |
55 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
56 | __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
57 | #endif |
58 | ; |
59 | _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; |
60 | static mbstate_t mb_cerr; |
61 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)] |
62 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
63 | __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
64 | #endif |
65 | ; |
66 | _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)]; |
67 | static mbstate_t mb_wcerr; |
68 | |
69 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)] |
70 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
71 | __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
72 | #endif |
73 | ; |
74 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)] |
75 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
76 | __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A" ) |
77 | #endif |
78 | ; |
79 | |
80 | _LIBCPP_HIDDEN ios_base::Init __start_std_streams; |
81 | |
82 | // On Windows the TLS storage for locales needs to be initialized before we create |
83 | // the standard streams, otherwise it may not be alive during program termination |
84 | // when we flush the streams. |
85 | static void force_locale_initialization() { |
86 | #if defined(_LIBCPP_MSVCRT_LIKE) |
87 | static bool once = []() { |
88 | auto loc = newlocale(LC_ALL_MASK, "C" , 0); |
89 | { |
90 | __libcpp_locale_guard g(loc); // forces initialization of locale TLS |
91 | ((void)g); |
92 | } |
93 | freelocale(loc); |
94 | return true; |
95 | }(); |
96 | ((void)once); |
97 | #endif |
98 | } |
99 | |
100 | class DoIOSInit { |
101 | public: |
102 | DoIOSInit(); |
103 | ~DoIOSInit(); |
104 | }; |
105 | |
106 | DoIOSInit::DoIOSInit() |
107 | { |
108 | force_locale_initialization(); |
109 | |
110 | #ifndef _LIBCPP_HAS_NO_STDIN |
111 | istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, &mb_cin)); |
112 | wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, &mb_wcin)); |
113 | #endif |
114 | #ifndef _LIBCPP_HAS_NO_STDOUT |
115 | ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, &mb_cout)); |
116 | wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout)); |
117 | #endif |
118 | ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, &mb_cerr)); |
119 | ::new(clog) ostream(cerr_ptr->rdbuf()); |
120 | wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr)); |
121 | ::new(wclog) wostream(wcerr_ptr->rdbuf()); |
122 | |
123 | #if !defined(_LIBCPP_HAS_NO_STDIN) && !defined(_LIBCPP_HAS_NO_STDOUT) |
124 | cin_ptr->tie(cout_ptr); |
125 | wcin_ptr->tie(wcout_ptr); |
126 | #endif |
127 | _VSTD::unitbuf(*cerr_ptr); |
128 | _VSTD::unitbuf(*wcerr_ptr); |
129 | #ifndef _LIBCPP_HAS_NO_STDOUT |
130 | cerr_ptr->tie(cout_ptr); |
131 | wcerr_ptr->tie(wcout_ptr); |
132 | #endif |
133 | } |
134 | |
135 | DoIOSInit::~DoIOSInit() |
136 | { |
137 | #ifndef _LIBCPP_HAS_NO_STDOUT |
138 | ostream* cout_ptr = reinterpret_cast<ostream*>(cout); |
139 | wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout); |
140 | cout_ptr->flush(); |
141 | wcout_ptr->flush(); |
142 | #endif |
143 | |
144 | ostream* clog_ptr = reinterpret_cast<ostream*>(clog); |
145 | wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog); |
146 | clog_ptr->flush(); |
147 | wclog_ptr->flush(); |
148 | } |
149 | |
150 | ios_base::Init::Init() |
151 | { |
152 | static DoIOSInit init_the_streams; // gets initialized once |
153 | } |
154 | |
155 | ios_base::Init::~Init() |
156 | { |
157 | } |
158 | |
159 | _LIBCPP_END_NAMESPACE_STD |
160 | |