xref: /aosp_15_r20/external/swiftshader/third_party/llvm-16.0/llvm/lib/Support/raw_ostream.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 //===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
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 // This implements support for bulk buffered stream output.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/Support/raw_ostream.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/Config/config.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Duration.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/FormatVariadic.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/NativeFormatting.h"
24 #include "llvm/Support/Process.h"
25 #include "llvm/Support/Program.h"
26 #include <algorithm>
27 #include <cerrno>
28 #include <cstdio>
29 #include <sys/stat.h>
30 
31 // <fcntl.h> may provide O_BINARY.
32 #if defined(HAVE_FCNTL_H)
33 # include <fcntl.h>
34 #endif
35 
36 #if defined(HAVE_UNISTD_H)
37 # include <unistd.h>
38 #endif
39 
40 #if defined(__CYGWIN__)
41 #include <io.h>
42 #endif
43 
44 #if defined(_MSC_VER)
45 #include <io.h>
46 #ifndef STDIN_FILENO
47 # define STDIN_FILENO 0
48 #endif
49 #ifndef STDOUT_FILENO
50 # define STDOUT_FILENO 1
51 #endif
52 #ifndef STDERR_FILENO
53 # define STDERR_FILENO 2
54 #endif
55 #endif
56 
57 #ifdef _WIN32
58 #include "llvm/Support/ConvertUTF.h"
59 #include "llvm/Support/Signals.h"
60 #include "llvm/Support/Windows/WindowsSupport.h"
61 #endif
62 
63 using namespace llvm;
64 
65 constexpr raw_ostream::Colors raw_ostream::BLACK;
66 constexpr raw_ostream::Colors raw_ostream::RED;
67 constexpr raw_ostream::Colors raw_ostream::GREEN;
68 constexpr raw_ostream::Colors raw_ostream::YELLOW;
69 constexpr raw_ostream::Colors raw_ostream::BLUE;
70 constexpr raw_ostream::Colors raw_ostream::MAGENTA;
71 constexpr raw_ostream::Colors raw_ostream::CYAN;
72 constexpr raw_ostream::Colors raw_ostream::WHITE;
73 constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
74 constexpr raw_ostream::Colors raw_ostream::RESET;
75 
~raw_ostream()76 raw_ostream::~raw_ostream() {
77   // raw_ostream's subclasses should take care to flush the buffer
78   // in their destructors.
79   assert(OutBufCur == OutBufStart &&
80          "raw_ostream destructor called with non-empty buffer!");
81 
82   if (BufferMode == BufferKind::InternalBuffer)
83     delete [] OutBufStart;
84 }
85 
preferred_buffer_size() const86 size_t raw_ostream::preferred_buffer_size() const {
87   // BUFSIZ is intended to be a reasonable default.
88   return BUFSIZ;
89 }
90 
SetBuffered()91 void raw_ostream::SetBuffered() {
92   // Ask the subclass to determine an appropriate buffer size.
93   if (size_t Size = preferred_buffer_size())
94     SetBufferSize(Size);
95   else
96     // It may return 0, meaning this stream should be unbuffered.
97     SetUnbuffered();
98 }
99 
SetBufferAndMode(char * BufferStart,size_t Size,BufferKind Mode)100 void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
101                                    BufferKind Mode) {
102   assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
103           (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
104          "stream must be unbuffered or have at least one byte");
105   // Make sure the current buffer is free of content (we can't flush here; the
106   // child buffer management logic will be in write_impl).
107   assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
108 
109   if (BufferMode == BufferKind::InternalBuffer)
110     delete [] OutBufStart;
111   OutBufStart = BufferStart;
112   OutBufEnd = OutBufStart+Size;
113   OutBufCur = OutBufStart;
114   BufferMode = Mode;
115 
116   assert(OutBufStart <= OutBufEnd && "Invalid size!");
117 }
118 
operator <<(unsigned long N)119 raw_ostream &raw_ostream::operator<<(unsigned long N) {
120   write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
121   return *this;
122 }
123 
operator <<(long N)124 raw_ostream &raw_ostream::operator<<(long N) {
125   write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
126   return *this;
127 }
128 
operator <<(unsigned long long N)129 raw_ostream &raw_ostream::operator<<(unsigned long long N) {
130   write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
131   return *this;
132 }
133 
operator <<(long long N)134 raw_ostream &raw_ostream::operator<<(long long N) {
135   write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
136   return *this;
137 }
138 
write_hex(unsigned long long N)139 raw_ostream &raw_ostream::write_hex(unsigned long long N) {
140   llvm::write_hex(*this, N, HexPrintStyle::Lower);
141   return *this;
142 }
143 
operator <<(Colors C)144 raw_ostream &raw_ostream::operator<<(Colors C) {
145   if (C == Colors::RESET)
146     resetColor();
147   else
148     changeColor(C);
149   return *this;
150 }
151 
write_uuid(const uuid_t UUID)152 raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
153   for (int Idx = 0; Idx < 16; ++Idx) {
154     *this << format("%02" PRIX32, UUID[Idx]);
155     if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
156       *this << "-";
157   }
158   return *this;
159 }
160 
161 
write_escaped(StringRef Str,bool UseHexEscapes)162 raw_ostream &raw_ostream::write_escaped(StringRef Str,
163                                         bool UseHexEscapes) {
164   for (unsigned char c : Str) {
165     switch (c) {
166     case '\\':
167       *this << '\\' << '\\';
168       break;
169     case '\t':
170       *this << '\\' << 't';
171       break;
172     case '\n':
173       *this << '\\' << 'n';
174       break;
175     case '"':
176       *this << '\\' << '"';
177       break;
178     default:
179       if (isPrint(c)) {
180         *this << c;
181         break;
182       }
183 
184       // Write out the escaped representation.
185       if (UseHexEscapes) {
186         *this << '\\' << 'x';
187         *this << hexdigit((c >> 4) & 0xF);
188         *this << hexdigit((c >> 0) & 0xF);
189       } else {
190         // Always use a full 3-character octal escape.
191         *this << '\\';
192         *this << char('0' + ((c >> 6) & 7));
193         *this << char('0' + ((c >> 3) & 7));
194         *this << char('0' + ((c >> 0) & 7));
195       }
196     }
197   }
198 
199   return *this;
200 }
201 
operator <<(const void * P)202 raw_ostream &raw_ostream::operator<<(const void *P) {
203   llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
204   return *this;
205 }
206 
operator <<(double N)207 raw_ostream &raw_ostream::operator<<(double N) {
208   llvm::write_double(*this, N, FloatStyle::Exponent);
209   return *this;
210 }
211 
flush_nonempty()212 void raw_ostream::flush_nonempty() {
213   assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
214   size_t Length = OutBufCur - OutBufStart;
215   OutBufCur = OutBufStart;
216   flush_tied_then_write(OutBufStart, Length);
217 }
218 
write(unsigned char C)219 raw_ostream &raw_ostream::write(unsigned char C) {
220   // Group exceptional cases into a single branch.
221   if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
222     if (LLVM_UNLIKELY(!OutBufStart)) {
223       if (BufferMode == BufferKind::Unbuffered) {
224         flush_tied_then_write(reinterpret_cast<char *>(&C), 1);
225         return *this;
226       }
227       // Set up a buffer and start over.
228       SetBuffered();
229       return write(C);
230     }
231 
232     flush_nonempty();
233   }
234 
235   *OutBufCur++ = C;
236   return *this;
237 }
238 
write(const char * Ptr,size_t Size)239 raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
240   // Group exceptional cases into a single branch.
241   if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
242     if (LLVM_UNLIKELY(!OutBufStart)) {
243       if (BufferMode == BufferKind::Unbuffered) {
244         flush_tied_then_write(Ptr, Size);
245         return *this;
246       }
247       // Set up a buffer and start over.
248       SetBuffered();
249       return write(Ptr, Size);
250     }
251 
252     size_t NumBytes = OutBufEnd - OutBufCur;
253 
254     // If the buffer is empty at this point we have a string that is larger
255     // than the buffer. Directly write the chunk that is a multiple of the
256     // preferred buffer size and put the remainder in the buffer.
257     if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
258       assert(NumBytes != 0 && "undefined behavior");
259       size_t BytesToWrite = Size - (Size % NumBytes);
260       flush_tied_then_write(Ptr, BytesToWrite);
261       size_t BytesRemaining = Size - BytesToWrite;
262       if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
263         // Too much left over to copy into our buffer.
264         return write(Ptr + BytesToWrite, BytesRemaining);
265       }
266       copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
267       return *this;
268     }
269 
270     // We don't have enough space in the buffer to fit the string in. Insert as
271     // much as possible, flush and start over with the remainder.
272     copy_to_buffer(Ptr, NumBytes);
273     flush_nonempty();
274     return write(Ptr + NumBytes, Size - NumBytes);
275   }
276 
277   copy_to_buffer(Ptr, Size);
278 
279   return *this;
280 }
281 
copy_to_buffer(const char * Ptr,size_t Size)282 void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
283   assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
284 
285   // Handle short strings specially, memcpy isn't very good at very short
286   // strings.
287   switch (Size) {
288   case 4: OutBufCur[3] = Ptr[3]; [[fallthrough]];
289   case 3: OutBufCur[2] = Ptr[2]; [[fallthrough]];
290   case 2: OutBufCur[1] = Ptr[1]; [[fallthrough]];
291   case 1: OutBufCur[0] = Ptr[0]; [[fallthrough]];
292   case 0: break;
293   default:
294     memcpy(OutBufCur, Ptr, Size);
295     break;
296   }
297 
298   OutBufCur += Size;
299 }
300 
flush_tied_then_write(const char * Ptr,size_t Size)301 void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) {
302   if (TiedStream)
303     TiedStream->flush();
304   write_impl(Ptr, Size);
305 }
306 
307 // Formatted output.
operator <<(const format_object_base & Fmt)308 raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
309   // If we have more than a few bytes left in our output buffer, try
310   // formatting directly onto its end.
311   size_t NextBufferSize = 127;
312   size_t BufferBytesLeft = OutBufEnd - OutBufCur;
313   if (BufferBytesLeft > 3) {
314     size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
315 
316     // Common case is that we have plenty of space.
317     if (BytesUsed <= BufferBytesLeft) {
318       OutBufCur += BytesUsed;
319       return *this;
320     }
321 
322     // Otherwise, we overflowed and the return value tells us the size to try
323     // again with.
324     NextBufferSize = BytesUsed;
325   }
326 
327   // If we got here, we didn't have enough space in the output buffer for the
328   // string.  Try printing into a SmallVector that is resized to have enough
329   // space.  Iterate until we win.
330   SmallVector<char, 128> V;
331 
332   while (true) {
333     V.resize(NextBufferSize);
334 
335     // Try formatting into the SmallVector.
336     size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
337 
338     // If BytesUsed fit into the vector, we win.
339     if (BytesUsed <= NextBufferSize)
340       return write(V.data(), BytesUsed);
341 
342     // Otherwise, try again with a new size.
343     assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
344     NextBufferSize = BytesUsed;
345   }
346 }
347 
operator <<(const formatv_object_base & Obj)348 raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
349   Obj.format(*this);
350   return *this;
351 }
352 
operator <<(const FormattedString & FS)353 raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
354   unsigned LeftIndent = 0;
355   unsigned RightIndent = 0;
356   const ssize_t Difference = FS.Width - FS.Str.size();
357   if (Difference > 0) {
358     switch (FS.Justify) {
359     case FormattedString::JustifyNone:
360       break;
361     case FormattedString::JustifyLeft:
362       RightIndent = Difference;
363       break;
364     case FormattedString::JustifyRight:
365       LeftIndent = Difference;
366       break;
367     case FormattedString::JustifyCenter:
368       LeftIndent = Difference / 2;
369       RightIndent = Difference - LeftIndent;
370       break;
371     }
372   }
373   indent(LeftIndent);
374   (*this) << FS.Str;
375   indent(RightIndent);
376   return *this;
377 }
378 
operator <<(const FormattedNumber & FN)379 raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
380   if (FN.Hex) {
381     HexPrintStyle Style;
382     if (FN.Upper && FN.HexPrefix)
383       Style = HexPrintStyle::PrefixUpper;
384     else if (FN.Upper && !FN.HexPrefix)
385       Style = HexPrintStyle::Upper;
386     else if (!FN.Upper && FN.HexPrefix)
387       Style = HexPrintStyle::PrefixLower;
388     else
389       Style = HexPrintStyle::Lower;
390     llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
391   } else {
392     llvm::SmallString<16> Buffer;
393     llvm::raw_svector_ostream Stream(Buffer);
394     llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
395     if (Buffer.size() < FN.Width)
396       indent(FN.Width - Buffer.size());
397     (*this) << Buffer;
398   }
399   return *this;
400 }
401 
operator <<(const FormattedBytes & FB)402 raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
403   if (FB.Bytes.empty())
404     return *this;
405 
406   size_t LineIndex = 0;
407   auto Bytes = FB.Bytes;
408   const size_t Size = Bytes.size();
409   HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
410   uint64_t OffsetWidth = 0;
411   if (FB.FirstByteOffset) {
412     // Figure out how many nibbles are needed to print the largest offset
413     // represented by this data set, so that we can align the offset field
414     // to the right width.
415     size_t Lines = Size / FB.NumPerLine;
416     uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
417     unsigned Power = 0;
418     if (MaxOffset > 0)
419       Power = llvm::Log2_64_Ceil(MaxOffset);
420     OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
421   }
422 
423   // The width of a block of data including all spaces for group separators.
424   unsigned NumByteGroups =
425       alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
426   unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
427 
428   while (!Bytes.empty()) {
429     indent(FB.IndentLevel);
430 
431     if (FB.FirstByteOffset) {
432       uint64_t Offset = *FB.FirstByteOffset;
433       llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
434       *this << ": ";
435     }
436 
437     auto Line = Bytes.take_front(FB.NumPerLine);
438 
439     size_t CharsPrinted = 0;
440     // Print the hex bytes for this line in groups
441     for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
442       if (I && (I % FB.ByteGroupSize) == 0) {
443         ++CharsPrinted;
444         *this << " ";
445       }
446       llvm::write_hex(*this, Line[I], HPS, 2);
447     }
448 
449     if (FB.ASCII) {
450       // Print any spaces needed for any bytes that we didn't print on this
451       // line so that the ASCII bytes are correctly aligned.
452       assert(BlockCharWidth >= CharsPrinted);
453       indent(BlockCharWidth - CharsPrinted + 2);
454       *this << "|";
455 
456       // Print the ASCII char values for each byte on this line
457       for (uint8_t Byte : Line) {
458         if (isPrint(Byte))
459           *this << static_cast<char>(Byte);
460         else
461           *this << '.';
462       }
463       *this << '|';
464     }
465 
466     Bytes = Bytes.drop_front(Line.size());
467     LineIndex += Line.size();
468     if (LineIndex < Size)
469       *this << '\n';
470   }
471   return *this;
472 }
473 
474 template <char C>
write_padding(raw_ostream & OS,unsigned NumChars)475 static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
476   static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
477                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
478                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
479                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
480                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
481 
482   // Usually the indentation is small, handle it with a fastpath.
483   if (NumChars < std::size(Chars))
484     return OS.write(Chars, NumChars);
485 
486   while (NumChars) {
487     unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1);
488     OS.write(Chars, NumToWrite);
489     NumChars -= NumToWrite;
490   }
491   return OS;
492 }
493 
494 /// indent - Insert 'NumSpaces' spaces.
indent(unsigned NumSpaces)495 raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
496   return write_padding<' '>(*this, NumSpaces);
497 }
498 
499 /// write_zeros - Insert 'NumZeros' nulls.
write_zeros(unsigned NumZeros)500 raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
501   return write_padding<'\0'>(*this, NumZeros);
502 }
503 
prepare_colors()504 bool raw_ostream::prepare_colors() {
505   // Colors were explicitly disabled.
506   if (!ColorEnabled)
507     return false;
508 
509   // Colors require changing the terminal but this stream is not going to a
510   // terminal.
511   if (sys::Process::ColorNeedsFlush() && !is_displayed())
512     return false;
513 
514   if (sys::Process::ColorNeedsFlush())
515     flush();
516 
517   return true;
518 }
519 
changeColor(enum Colors colors,bool bold,bool bg)520 raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
521   if (!prepare_colors())
522     return *this;
523 
524   const char *colorcode =
525       (colors == SAVEDCOLOR)
526           ? sys::Process::OutputBold(bg)
527           : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
528   if (colorcode)
529     write(colorcode, strlen(colorcode));
530   return *this;
531 }
532 
resetColor()533 raw_ostream &raw_ostream::resetColor() {
534   if (!prepare_colors())
535     return *this;
536 
537   if (const char *colorcode = sys::Process::ResetColor())
538     write(colorcode, strlen(colorcode));
539   return *this;
540 }
541 
reverseColor()542 raw_ostream &raw_ostream::reverseColor() {
543   if (!prepare_colors())
544     return *this;
545 
546   if (const char *colorcode = sys::Process::OutputReverse())
547     write(colorcode, strlen(colorcode));
548   return *this;
549 }
550 
anchor()551 void raw_ostream::anchor() {}
552 
553 //===----------------------------------------------------------------------===//
554 //  Formatted Output
555 //===----------------------------------------------------------------------===//
556 
557 // Out of line virtual method.
home()558 void format_object_base::home() {
559 }
560 
561 //===----------------------------------------------------------------------===//
562 //  raw_fd_ostream
563 //===----------------------------------------------------------------------===//
564 
getFD(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)565 static int getFD(StringRef Filename, std::error_code &EC,
566                  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
567                  sys::fs::OpenFlags Flags) {
568   assert((Access & sys::fs::FA_Write) &&
569          "Cannot make a raw_ostream from a read-only descriptor!");
570 
571   // Handle "-" as stdout. Note that when we do this, we consider ourself
572   // the owner of stdout and may set the "binary" flag globally based on Flags.
573   if (Filename == "-") {
574     EC = std::error_code();
575     // Change stdout's text/binary mode based on the Flags.
576     sys::ChangeStdoutMode(Flags);
577     return STDOUT_FILENO;
578   }
579 
580   int FD;
581   if (Access & sys::fs::FA_Read)
582     EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
583   else
584     EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
585   if (EC)
586     return -1;
587 
588   return FD;
589 }
590 
raw_fd_ostream(StringRef Filename,std::error_code & EC)591 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
592     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
593                      sys::fs::OF_None) {}
594 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp)595 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
596                                sys::fs::CreationDisposition Disp)
597     : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
598 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::FileAccess Access)599 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
600                                sys::fs::FileAccess Access)
601     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
602                      sys::fs::OF_None) {}
603 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::OpenFlags Flags)604 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
605                                sys::fs::OpenFlags Flags)
606     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
607                      Flags) {}
608 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)609 raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
610                                sys::fs::CreationDisposition Disp,
611                                sys::fs::FileAccess Access,
612                                sys::fs::OpenFlags Flags)
613     : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
614 
615 /// FD is the file descriptor that this writes to.  If ShouldClose is true, this
616 /// closes the file when the stream is destroyed.
raw_fd_ostream(int fd,bool shouldClose,bool unbuffered,OStreamKind K)617 raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
618                                OStreamKind K)
619     : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
620   if (FD < 0 ) {
621     ShouldClose = false;
622     return;
623   }
624 
625   enable_colors(true);
626 
627   // Do not attempt to close stdout or stderr. We used to try to maintain the
628   // property that tools that support writing file to stdout should not also
629   // write informational output to stdout, but in practice we were never able to
630   // maintain this invariant. Many features have been added to LLVM and clang
631   // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
632   // users must simply be aware that mixed output and remarks is a possibility.
633   if (FD <= STDERR_FILENO)
634     ShouldClose = false;
635 
636 #ifdef _WIN32
637   // Check if this is a console device. This is not equivalent to isatty.
638   IsWindowsConsole =
639       ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
640 #endif
641 
642   // Get the starting position.
643   off_t loc = ::lseek(FD, 0, SEEK_CUR);
644   sys::fs::file_status Status;
645   std::error_code EC = status(FD, Status);
646   IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
647 #ifdef _WIN32
648   // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
649   SupportsSeeking = !EC && IsRegularFile;
650 #else
651   SupportsSeeking = !EC && loc != (off_t)-1;
652 #endif
653   if (!SupportsSeeking)
654     pos = 0;
655   else
656     pos = static_cast<uint64_t>(loc);
657 }
658 
~raw_fd_ostream()659 raw_fd_ostream::~raw_fd_ostream() {
660   if (FD >= 0) {
661     flush();
662     if (ShouldClose) {
663       if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
664         error_detected(EC);
665     }
666   }
667 
668 #ifdef __MINGW32__
669   // On mingw, global dtors should not call exit().
670   // report_fatal_error() invokes exit(). We know report_fatal_error()
671   // might not write messages to stderr when any errors were detected
672   // on FD == 2.
673   if (FD == 2) return;
674 #endif
675 
676   // If there are any pending errors, report them now. Clients wishing
677   // to avoid report_fatal_error calls should check for errors with
678   // has_error() and clear the error flag with clear_error() before
679   // destructing raw_ostream objects which may have errors.
680   if (has_error())
681     report_fatal_error(Twine("IO failure on output stream: ") +
682                            error().message(),
683                        /*gen_crash_diag=*/false);
684 }
685 
686 #if defined(_WIN32)
687 // The most reliable way to print unicode in a Windows console is with
688 // WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
689 // assumes that LLVM programs always print valid UTF-8 to the console. The data
690 // might not be UTF-8 for two major reasons:
691 // 1. The program is printing binary (-filetype=obj -o -), in which case it
692 // would have been gibberish anyway.
693 // 2. The program is printing text in a semi-ascii compatible codepage like
694 // shift-jis or cp1252.
695 //
696 // Most LLVM programs don't produce non-ascii text unless they are quoting
697 // user source input. A well-behaved LLVM program should either validate that
698 // the input is UTF-8 or transcode from the local codepage to UTF-8 before
699 // quoting it. If they don't, this may mess up the encoding, but this is still
700 // probably the best compromise we can make.
write_console_impl(int FD,StringRef Data)701 static bool write_console_impl(int FD, StringRef Data) {
702   SmallVector<wchar_t, 256> WideText;
703 
704   // Fall back to ::write if it wasn't valid UTF-8.
705   if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
706     return false;
707 
708   // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
709   // that can be written to the console at a time.
710   size_t MaxWriteSize = WideText.size();
711   if (!RunningWindows8OrGreater())
712     MaxWriteSize = 32767;
713 
714   size_t WCharsWritten = 0;
715   do {
716     size_t WCharsToWrite =
717         std::min(MaxWriteSize, WideText.size() - WCharsWritten);
718     DWORD ActuallyWritten;
719     bool Success =
720         ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
721                         WCharsToWrite, &ActuallyWritten,
722                         /*Reserved=*/nullptr);
723 
724     // The most likely reason for WriteConsoleW to fail is that FD no longer
725     // points to a console. Fall back to ::write. If this isn't the first loop
726     // iteration, something is truly wrong.
727     if (!Success)
728       return false;
729 
730     WCharsWritten += ActuallyWritten;
731   } while (WCharsWritten != WideText.size());
732   return true;
733 }
734 #endif
735 
write_impl(const char * Ptr,size_t Size)736 void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
737   assert(FD >= 0 && "File already closed.");
738   pos += Size;
739 
740 #if defined(_WIN32)
741   // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
742   // and using WriteConsoleW. If that fails, fall back to plain write().
743   if (IsWindowsConsole)
744     if (write_console_impl(FD, StringRef(Ptr, Size)))
745       return;
746 #endif
747 
748   // The maximum write size is limited to INT32_MAX. A write
749   // greater than SSIZE_MAX is implementation-defined in POSIX,
750   // and Windows _write requires 32 bit input.
751   size_t MaxWriteSize = INT32_MAX;
752 
753 #if defined(__linux__)
754   // It is observed that Linux returns EINVAL for a very large write (>2G).
755   // Make it a reasonably small value.
756   MaxWriteSize = 1024 * 1024 * 1024;
757 #endif
758 
759   do {
760     size_t ChunkSize = std::min(Size, MaxWriteSize);
761     ssize_t ret = ::write(FD, Ptr, ChunkSize);
762 
763     if (ret < 0) {
764       // If it's a recoverable error, swallow it and retry the write.
765       //
766       // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
767       // raw_ostream isn't designed to do non-blocking I/O. However, some
768       // programs, such as old versions of bjam, have mistakenly used
769       // O_NONBLOCK. For compatibility, emulate blocking semantics by
770       // spinning until the write succeeds. If you don't want spinning,
771       // don't use O_NONBLOCK file descriptors with raw_ostream.
772       if (errno == EINTR || errno == EAGAIN
773 #ifdef EWOULDBLOCK
774           || errno == EWOULDBLOCK
775 #endif
776           )
777         continue;
778 
779 #ifdef _WIN32
780       // Windows equivalents of SIGPIPE/EPIPE.
781       DWORD WinLastError = GetLastError();
782       if (WinLastError == ERROR_BROKEN_PIPE ||
783           (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
784         llvm::sys::CallOneShotPipeSignalHandler();
785         errno = EPIPE;
786       }
787 #endif
788       // Otherwise it's a non-recoverable error. Note it and quit.
789       error_detected(std::error_code(errno, std::generic_category()));
790       break;
791     }
792 
793     // The write may have written some or all of the data. Update the
794     // size and buffer pointer to reflect the remainder that needs
795     // to be written. If there are no bytes left, we're done.
796     Ptr += ret;
797     Size -= ret;
798   } while (Size > 0);
799 }
800 
close()801 void raw_fd_ostream::close() {
802   assert(ShouldClose);
803   ShouldClose = false;
804   flush();
805   if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
806     error_detected(EC);
807   FD = -1;
808 }
809 
seek(uint64_t off)810 uint64_t raw_fd_ostream::seek(uint64_t off) {
811   assert(SupportsSeeking && "Stream does not support seeking!");
812   flush();
813 #ifdef _WIN32
814   pos = ::_lseeki64(FD, off, SEEK_SET);
815 #else
816   pos = ::lseek(FD, off, SEEK_SET);
817 #endif
818   if (pos == (uint64_t)-1)
819     error_detected(std::error_code(errno, std::generic_category()));
820   return pos;
821 }
822 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)823 void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
824                                  uint64_t Offset) {
825   uint64_t Pos = tell();
826   seek(Offset);
827   write(Ptr, Size);
828   seek(Pos);
829 }
830 
preferred_buffer_size() const831 size_t raw_fd_ostream::preferred_buffer_size() const {
832 #if defined(_WIN32)
833   // Disable buffering for console devices. Console output is re-encoded from
834   // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
835   // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
836   // below on most other OSs, so do the same thing on Windows and avoid that
837   // complexity.
838   if (IsWindowsConsole)
839     return 0;
840   return raw_ostream::preferred_buffer_size();
841 #elif !defined(__minix)
842   // Minix has no st_blksize.
843   assert(FD >= 0 && "File not yet open!");
844   struct stat statbuf;
845   if (fstat(FD, &statbuf) != 0)
846     return 0;
847 
848   // If this is a terminal, don't use buffering. Line buffering
849   // would be a more traditional thing to do, but it's not worth
850   // the complexity.
851   if (S_ISCHR(statbuf.st_mode) && is_displayed())
852     return 0;
853   // Return the preferred block size.
854   return statbuf.st_blksize;
855 #else
856   return raw_ostream::preferred_buffer_size();
857 #endif
858 }
859 
is_displayed() const860 bool raw_fd_ostream::is_displayed() const {
861   return sys::Process::FileDescriptorIsDisplayed(FD);
862 }
863 
has_colors() const864 bool raw_fd_ostream::has_colors() const {
865   if (!HasColors)
866     HasColors = sys::Process::FileDescriptorHasColors(FD);
867   return *HasColors;
868 }
869 
lock()870 Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
871   std::error_code EC = sys::fs::lockFile(FD);
872   if (!EC)
873     return sys::fs::FileLocker(FD);
874   return errorCodeToError(EC);
875 }
876 
877 Expected<sys::fs::FileLocker>
tryLockFor(Duration const & Timeout)878 raw_fd_ostream::tryLockFor(Duration const& Timeout) {
879   std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
880   if (!EC)
881     return sys::fs::FileLocker(FD);
882   return errorCodeToError(EC);
883 }
884 
anchor()885 void raw_fd_ostream::anchor() {}
886 
887 //===----------------------------------------------------------------------===//
888 //  outs(), errs(), nulls()
889 //===----------------------------------------------------------------------===//
890 
outs()891 raw_fd_ostream &llvm::outs() {
892   // Set buffer settings to model stdout behavior.
893   std::error_code EC;
894   static raw_fd_ostream S("-", EC, sys::fs::OF_None);
895   assert(!EC);
896   return S;
897 }
898 
errs()899 raw_fd_ostream &llvm::errs() {
900   // Set standard error to be unbuffered and tied to outs() by default.
901   static raw_fd_ostream S(STDERR_FILENO, false, true);
902   return S;
903 }
904 
905 /// nulls() - This returns a reference to a raw_ostream which discards output.
nulls()906 raw_ostream &llvm::nulls() {
907   static raw_null_ostream S;
908   return S;
909 }
910 
911 //===----------------------------------------------------------------------===//
912 // File Streams
913 //===----------------------------------------------------------------------===//
914 
raw_fd_stream(StringRef Filename,std::error_code & EC)915 raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
916     : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
917                            sys::fs::FA_Write | sys::fs::FA_Read,
918                            sys::fs::OF_None),
919                      true, false, OStreamKind::OK_FDStream) {
920   if (EC)
921     return;
922 
923   if (!isRegularFile())
924     EC = std::make_error_code(std::errc::invalid_argument);
925 }
926 
read(char * Ptr,size_t Size)927 ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
928   assert(get_fd() >= 0 && "File already closed.");
929   ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
930   if (Ret >= 0)
931     inc_pos(Ret);
932   else
933     error_detected(std::error_code(errno, std::generic_category()));
934   return Ret;
935 }
936 
classof(const raw_ostream * OS)937 bool raw_fd_stream::classof(const raw_ostream *OS) {
938   return OS->get_kind() == OStreamKind::OK_FDStream;
939 }
940 
941 //===----------------------------------------------------------------------===//
942 //  raw_string_ostream
943 //===----------------------------------------------------------------------===//
944 
write_impl(const char * Ptr,size_t Size)945 void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
946   OS.append(Ptr, Size);
947 }
948 
949 //===----------------------------------------------------------------------===//
950 //  raw_svector_ostream
951 //===----------------------------------------------------------------------===//
952 
current_pos() const953 uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
954 
write_impl(const char * Ptr,size_t Size)955 void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
956   OS.append(Ptr, Ptr + Size);
957 }
958 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)959 void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
960                                       uint64_t Offset) {
961   memcpy(OS.data() + Offset, Ptr, Size);
962 }
963 
964 //===----------------------------------------------------------------------===//
965 //  raw_null_ostream
966 //===----------------------------------------------------------------------===//
967 
~raw_null_ostream()968 raw_null_ostream::~raw_null_ostream() {
969 #ifndef NDEBUG
970   // ~raw_ostream asserts that the buffer is empty. This isn't necessary
971   // with raw_null_ostream, but it's better to have raw_null_ostream follow
972   // the rules than to change the rules just for raw_null_ostream.
973   flush();
974 #endif
975 }
976 
write_impl(const char * Ptr,size_t Size)977 void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
978 }
979 
current_pos() const980 uint64_t raw_null_ostream::current_pos() const {
981   return 0;
982 }
983 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)984 void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
985                                    uint64_t Offset) {}
986 
anchor()987 void raw_pwrite_stream::anchor() {}
988 
anchor()989 void buffer_ostream::anchor() {}
990 
anchor()991 void buffer_unique_ostream::anchor() {}
992 
writeToOutput(StringRef OutputFileName,std::function<Error (raw_ostream &)> Write)993 Error llvm::writeToOutput(StringRef OutputFileName,
994                           std::function<Error(raw_ostream &)> Write) {
995   if (OutputFileName == "-")
996     return Write(outs());
997 
998   if (OutputFileName == "/dev/null") {
999     raw_null_ostream Out;
1000     return Write(Out);
1001   }
1002 
1003   unsigned Mode = sys::fs::all_read | sys::fs::all_write | sys::fs::all_exe;
1004   Expected<sys::fs::TempFile> Temp =
1005       sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
1006   if (!Temp)
1007     return createFileError(OutputFileName, Temp.takeError());
1008 
1009   raw_fd_ostream Out(Temp->FD, false);
1010 
1011   if (Error E = Write(Out)) {
1012     if (Error DiscardError = Temp->discard())
1013       return joinErrors(std::move(E), std::move(DiscardError));
1014     return E;
1015   }
1016   Out.flush();
1017 
1018   return Temp->keep(OutputFileName);
1019 }
1020