xref: /freebsd/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This implements support for bulk buffered stream output.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
150b57cec5SDimitry Andric #include "llvm/Config/config.h"
165f757f3fSDimitry Andric #include "llvm/Support/AutoConvert.h"
170b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
1804eeddc0SDimitry Andric #include "llvm/Support/Duration.h"
190b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
200b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
210b57cec5SDimitry Andric #include "llvm/Support/Format.h"
220b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h"
230b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
240b57cec5SDimitry Andric #include "llvm/Support/NativeFormatting.h"
250b57cec5SDimitry Andric #include "llvm/Support/Process.h"
260b57cec5SDimitry Andric #include "llvm/Support/Program.h"
270b57cec5SDimitry Andric #include <algorithm>
280b57cec5SDimitry Andric #include <cerrno>
290b57cec5SDimitry Andric #include <cstdio>
300b57cec5SDimitry Andric #include <sys/stat.h>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric // <fcntl.h> may provide O_BINARY.
330b57cec5SDimitry Andric #if defined(HAVE_FCNTL_H)
340b57cec5SDimitry Andric # include <fcntl.h>
350b57cec5SDimitry Andric #endif
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric #if defined(HAVE_UNISTD_H)
380b57cec5SDimitry Andric # include <unistd.h>
390b57cec5SDimitry Andric #endif
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric #if defined(__CYGWIN__)
420b57cec5SDimitry Andric #include <io.h>
430b57cec5SDimitry Andric #endif
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric #if defined(_MSC_VER)
460b57cec5SDimitry Andric #include <io.h>
470b57cec5SDimitry Andric #ifndef STDIN_FILENO
480b57cec5SDimitry Andric # define STDIN_FILENO 0
490b57cec5SDimitry Andric #endif
500b57cec5SDimitry Andric #ifndef STDOUT_FILENO
510b57cec5SDimitry Andric # define STDOUT_FILENO 1
520b57cec5SDimitry Andric #endif
530b57cec5SDimitry Andric #ifndef STDERR_FILENO
540b57cec5SDimitry Andric # define STDERR_FILENO 2
550b57cec5SDimitry Andric #endif
560b57cec5SDimitry Andric #endif
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric #ifdef _WIN32
590b57cec5SDimitry Andric #include "llvm/Support/ConvertUTF.h"
601ac55f4cSDimitry Andric #include "llvm/Support/Signals.h"
618c27c554SDimitry Andric #include "llvm/Support/Windows/WindowsSupport.h"
620b57cec5SDimitry Andric #endif
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric using namespace llvm;
650b57cec5SDimitry Andric 
665ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::BLACK;
675ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::RED;
685ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::GREEN;
695ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::YELLOW;
705ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::BLUE;
715ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::MAGENTA;
725ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::CYAN;
735ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::WHITE;
745ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
755ffd83dbSDimitry Andric constexpr raw_ostream::Colors raw_ostream::RESET;
768bcb0991SDimitry Andric 
~raw_ostream()770b57cec5SDimitry Andric raw_ostream::~raw_ostream() {
780b57cec5SDimitry Andric   // raw_ostream's subclasses should take care to flush the buffer
790b57cec5SDimitry Andric   // in their destructors.
800b57cec5SDimitry Andric   assert(OutBufCur == OutBufStart &&
810b57cec5SDimitry Andric          "raw_ostream destructor called with non-empty buffer!");
820b57cec5SDimitry Andric 
83480093f4SDimitry Andric   if (BufferMode == BufferKind::InternalBuffer)
840b57cec5SDimitry Andric     delete [] OutBufStart;
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
preferred_buffer_size() const870b57cec5SDimitry Andric size_t raw_ostream::preferred_buffer_size() const {
889e7101a8SDimitry Andric #ifdef _WIN32
899e7101a8SDimitry Andric   // On Windows BUFSIZ is only 512 which results in more calls to write. This
909e7101a8SDimitry Andric   // overhead can cause significant performance degradation. Therefore use a
919e7101a8SDimitry Andric   // better default.
929e7101a8SDimitry Andric   return (16 * 1024);
939e7101a8SDimitry Andric #else
940b57cec5SDimitry Andric   // BUFSIZ is intended to be a reasonable default.
950b57cec5SDimitry Andric   return BUFSIZ;
969e7101a8SDimitry Andric #endif
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
SetBuffered()990b57cec5SDimitry Andric void raw_ostream::SetBuffered() {
1000b57cec5SDimitry Andric   // Ask the subclass to determine an appropriate buffer size.
1010b57cec5SDimitry Andric   if (size_t Size = preferred_buffer_size())
1020b57cec5SDimitry Andric     SetBufferSize(Size);
1030b57cec5SDimitry Andric   else
1040b57cec5SDimitry Andric     // It may return 0, meaning this stream should be unbuffered.
1050b57cec5SDimitry Andric     SetUnbuffered();
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
SetBufferAndMode(char * BufferStart,size_t Size,BufferKind Mode)1080b57cec5SDimitry Andric void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
1090b57cec5SDimitry Andric                                    BufferKind Mode) {
110480093f4SDimitry Andric   assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
111480093f4SDimitry Andric           (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
1120b57cec5SDimitry Andric          "stream must be unbuffered or have at least one byte");
1130b57cec5SDimitry Andric   // Make sure the current buffer is free of content (we can't flush here; the
1140b57cec5SDimitry Andric   // child buffer management logic will be in write_impl).
1150b57cec5SDimitry Andric   assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
1160b57cec5SDimitry Andric 
117480093f4SDimitry Andric   if (BufferMode == BufferKind::InternalBuffer)
1180b57cec5SDimitry Andric     delete [] OutBufStart;
1190b57cec5SDimitry Andric   OutBufStart = BufferStart;
1200b57cec5SDimitry Andric   OutBufEnd = OutBufStart+Size;
1210b57cec5SDimitry Andric   OutBufCur = OutBufStart;
1220b57cec5SDimitry Andric   BufferMode = Mode;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   assert(OutBufStart <= OutBufEnd && "Invalid size!");
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
operator <<(unsigned long N)1270b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(unsigned long N) {
1280b57cec5SDimitry Andric   write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
1290b57cec5SDimitry Andric   return *this;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
operator <<(long N)1320b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(long N) {
1330b57cec5SDimitry Andric   write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
1340b57cec5SDimitry Andric   return *this;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric 
operator <<(unsigned long long N)1370b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(unsigned long long N) {
1380b57cec5SDimitry Andric   write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
1390b57cec5SDimitry Andric   return *this;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
operator <<(long long N)1420b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(long long N) {
1430b57cec5SDimitry Andric   write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
1440b57cec5SDimitry Andric   return *this;
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
write_hex(unsigned long long N)1470b57cec5SDimitry Andric raw_ostream &raw_ostream::write_hex(unsigned long long N) {
1480b57cec5SDimitry Andric   llvm::write_hex(*this, N, HexPrintStyle::Lower);
1490b57cec5SDimitry Andric   return *this;
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
operator <<(Colors C)1528bcb0991SDimitry Andric raw_ostream &raw_ostream::operator<<(Colors C) {
1538bcb0991SDimitry Andric   if (C == Colors::RESET)
1548bcb0991SDimitry Andric     resetColor();
1558bcb0991SDimitry Andric   else
1568bcb0991SDimitry Andric     changeColor(C);
1578bcb0991SDimitry Andric   return *this;
1588bcb0991SDimitry Andric }
1598bcb0991SDimitry Andric 
write_uuid(const uuid_t UUID)1600b57cec5SDimitry Andric raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
1610b57cec5SDimitry Andric   for (int Idx = 0; Idx < 16; ++Idx) {
1620b57cec5SDimitry Andric     *this << format("%02" PRIX32, UUID[Idx]);
1630b57cec5SDimitry Andric     if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
1640b57cec5SDimitry Andric       *this << "-";
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric   return *this;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric 
write_escaped(StringRef Str,bool UseHexEscapes)1700b57cec5SDimitry Andric raw_ostream &raw_ostream::write_escaped(StringRef Str,
1710b57cec5SDimitry Andric                                         bool UseHexEscapes) {
1720b57cec5SDimitry Andric   for (unsigned char c : Str) {
1730b57cec5SDimitry Andric     switch (c) {
1740b57cec5SDimitry Andric     case '\\':
1750b57cec5SDimitry Andric       *this << '\\' << '\\';
1760b57cec5SDimitry Andric       break;
1770b57cec5SDimitry Andric     case '\t':
1780b57cec5SDimitry Andric       *this << '\\' << 't';
1790b57cec5SDimitry Andric       break;
1800b57cec5SDimitry Andric     case '\n':
1810b57cec5SDimitry Andric       *this << '\\' << 'n';
1820b57cec5SDimitry Andric       break;
1830b57cec5SDimitry Andric     case '"':
1840b57cec5SDimitry Andric       *this << '\\' << '"';
1850b57cec5SDimitry Andric       break;
1860b57cec5SDimitry Andric     default:
1870b57cec5SDimitry Andric       if (isPrint(c)) {
1880b57cec5SDimitry Andric         *this << c;
1890b57cec5SDimitry Andric         break;
1900b57cec5SDimitry Andric       }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric       // Write out the escaped representation.
1930b57cec5SDimitry Andric       if (UseHexEscapes) {
1940b57cec5SDimitry Andric         *this << '\\' << 'x';
195349cc55cSDimitry Andric         *this << hexdigit((c >> 4) & 0xF);
1960b57cec5SDimitry Andric         *this << hexdigit((c >> 0) & 0xF);
1970b57cec5SDimitry Andric       } else {
1980b57cec5SDimitry Andric         // Always use a full 3-character octal escape.
1990b57cec5SDimitry Andric         *this << '\\';
2000b57cec5SDimitry Andric         *this << char('0' + ((c >> 6) & 7));
2010b57cec5SDimitry Andric         *this << char('0' + ((c >> 3) & 7));
2020b57cec5SDimitry Andric         *this << char('0' + ((c >> 0) & 7));
2030b57cec5SDimitry Andric       }
2040b57cec5SDimitry Andric     }
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric   return *this;
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
operator <<(const void * P)2100b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const void *P) {
2110b57cec5SDimitry Andric   llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
2120b57cec5SDimitry Andric   return *this;
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
operator <<(double N)2150b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(double N) {
2160b57cec5SDimitry Andric   llvm::write_double(*this, N, FloatStyle::Exponent);
2170b57cec5SDimitry Andric   return *this;
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
flush_nonempty()2200b57cec5SDimitry Andric void raw_ostream::flush_nonempty() {
2210b57cec5SDimitry Andric   assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
2220b57cec5SDimitry Andric   size_t Length = OutBufCur - OutBufStart;
2230b57cec5SDimitry Andric   OutBufCur = OutBufStart;
224*0fca6ea1SDimitry Andric   write_impl(OutBufStart, Length);
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric 
write(unsigned char C)2270b57cec5SDimitry Andric raw_ostream &raw_ostream::write(unsigned char C) {
2280b57cec5SDimitry Andric   // Group exceptional cases into a single branch.
2290b57cec5SDimitry Andric   if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
2300b57cec5SDimitry Andric     if (LLVM_UNLIKELY(!OutBufStart)) {
231480093f4SDimitry Andric       if (BufferMode == BufferKind::Unbuffered) {
232*0fca6ea1SDimitry Andric         write_impl(reinterpret_cast<char *>(&C), 1);
2330b57cec5SDimitry Andric         return *this;
2340b57cec5SDimitry Andric       }
2350b57cec5SDimitry Andric       // Set up a buffer and start over.
2360b57cec5SDimitry Andric       SetBuffered();
2370b57cec5SDimitry Andric       return write(C);
2380b57cec5SDimitry Andric     }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric     flush_nonempty();
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   *OutBufCur++ = C;
2440b57cec5SDimitry Andric   return *this;
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric 
write(const char * Ptr,size_t Size)2470b57cec5SDimitry Andric raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
2480b57cec5SDimitry Andric   // Group exceptional cases into a single branch.
2490b57cec5SDimitry Andric   if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
2500b57cec5SDimitry Andric     if (LLVM_UNLIKELY(!OutBufStart)) {
251480093f4SDimitry Andric       if (BufferMode == BufferKind::Unbuffered) {
252*0fca6ea1SDimitry Andric         write_impl(Ptr, Size);
2530b57cec5SDimitry Andric         return *this;
2540b57cec5SDimitry Andric       }
2550b57cec5SDimitry Andric       // Set up a buffer and start over.
2560b57cec5SDimitry Andric       SetBuffered();
2570b57cec5SDimitry Andric       return write(Ptr, Size);
2580b57cec5SDimitry Andric     }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric     size_t NumBytes = OutBufEnd - OutBufCur;
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric     // If the buffer is empty at this point we have a string that is larger
2630b57cec5SDimitry Andric     // than the buffer. Directly write the chunk that is a multiple of the
2640b57cec5SDimitry Andric     // preferred buffer size and put the remainder in the buffer.
2650b57cec5SDimitry Andric     if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
2660b57cec5SDimitry Andric       assert(NumBytes != 0 && "undefined behavior");
2670b57cec5SDimitry Andric       size_t BytesToWrite = Size - (Size % NumBytes);
268*0fca6ea1SDimitry Andric       write_impl(Ptr, BytesToWrite);
2690b57cec5SDimitry Andric       size_t BytesRemaining = Size - BytesToWrite;
2700b57cec5SDimitry Andric       if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
2710b57cec5SDimitry Andric         // Too much left over to copy into our buffer.
2720b57cec5SDimitry Andric         return write(Ptr + BytesToWrite, BytesRemaining);
2730b57cec5SDimitry Andric       }
2740b57cec5SDimitry Andric       copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
2750b57cec5SDimitry Andric       return *this;
2760b57cec5SDimitry Andric     }
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric     // We don't have enough space in the buffer to fit the string in. Insert as
2790b57cec5SDimitry Andric     // much as possible, flush and start over with the remainder.
2800b57cec5SDimitry Andric     copy_to_buffer(Ptr, NumBytes);
2810b57cec5SDimitry Andric     flush_nonempty();
2820b57cec5SDimitry Andric     return write(Ptr + NumBytes, Size - NumBytes);
2830b57cec5SDimitry Andric   }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   copy_to_buffer(Ptr, Size);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   return *this;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
copy_to_buffer(const char * Ptr,size_t Size)2900b57cec5SDimitry Andric void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
2910b57cec5SDimitry Andric   assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   // Handle short strings specially, memcpy isn't very good at very short
2940b57cec5SDimitry Andric   // strings.
2950b57cec5SDimitry Andric   switch (Size) {
296bdd1243dSDimitry Andric   case 4: OutBufCur[3] = Ptr[3]; [[fallthrough]];
297bdd1243dSDimitry Andric   case 3: OutBufCur[2] = Ptr[2]; [[fallthrough]];
298bdd1243dSDimitry Andric   case 2: OutBufCur[1] = Ptr[1]; [[fallthrough]];
299bdd1243dSDimitry Andric   case 1: OutBufCur[0] = Ptr[0]; [[fallthrough]];
3000b57cec5SDimitry Andric   case 0: break;
3010b57cec5SDimitry Andric   default:
3020b57cec5SDimitry Andric     memcpy(OutBufCur, Ptr, Size);
3030b57cec5SDimitry Andric     break;
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   OutBufCur += Size;
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric // Formatted output.
operator <<(const format_object_base & Fmt)3100b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
3110b57cec5SDimitry Andric   // If we have more than a few bytes left in our output buffer, try
3120b57cec5SDimitry Andric   // formatting directly onto its end.
3130b57cec5SDimitry Andric   size_t NextBufferSize = 127;
3140b57cec5SDimitry Andric   size_t BufferBytesLeft = OutBufEnd - OutBufCur;
3150b57cec5SDimitry Andric   if (BufferBytesLeft > 3) {
3160b57cec5SDimitry Andric     size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric     // Common case is that we have plenty of space.
3190b57cec5SDimitry Andric     if (BytesUsed <= BufferBytesLeft) {
3200b57cec5SDimitry Andric       OutBufCur += BytesUsed;
3210b57cec5SDimitry Andric       return *this;
3220b57cec5SDimitry Andric     }
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric     // Otherwise, we overflowed and the return value tells us the size to try
3250b57cec5SDimitry Andric     // again with.
3260b57cec5SDimitry Andric     NextBufferSize = BytesUsed;
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   // If we got here, we didn't have enough space in the output buffer for the
3300b57cec5SDimitry Andric   // string.  Try printing into a SmallVector that is resized to have enough
3310b57cec5SDimitry Andric   // space.  Iterate until we win.
3320b57cec5SDimitry Andric   SmallVector<char, 128> V;
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   while (true) {
3350b57cec5SDimitry Andric     V.resize(NextBufferSize);
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric     // Try formatting into the SmallVector.
3380b57cec5SDimitry Andric     size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric     // If BytesUsed fit into the vector, we win.
3410b57cec5SDimitry Andric     if (BytesUsed <= NextBufferSize)
3420b57cec5SDimitry Andric       return write(V.data(), BytesUsed);
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric     // Otherwise, try again with a new size.
3450b57cec5SDimitry Andric     assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
3460b57cec5SDimitry Andric     NextBufferSize = BytesUsed;
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
operator <<(const formatv_object_base & Obj)3500b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
3510b57cec5SDimitry Andric   Obj.format(*this);
3520b57cec5SDimitry Andric   return *this;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
operator <<(const FormattedString & FS)3550b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
3565ffd83dbSDimitry Andric   unsigned LeftIndent = 0;
3575ffd83dbSDimitry Andric   unsigned RightIndent = 0;
3585ffd83dbSDimitry Andric   const ssize_t Difference = FS.Width - FS.Str.size();
3595ffd83dbSDimitry Andric   if (Difference > 0) {
3600b57cec5SDimitry Andric     switch (FS.Justify) {
3615ffd83dbSDimitry Andric     case FormattedString::JustifyNone:
3625ffd83dbSDimitry Andric       break;
3630b57cec5SDimitry Andric     case FormattedString::JustifyLeft:
3645ffd83dbSDimitry Andric       RightIndent = Difference;
3650b57cec5SDimitry Andric       break;
3660b57cec5SDimitry Andric     case FormattedString::JustifyRight:
3675ffd83dbSDimitry Andric       LeftIndent = Difference;
3680b57cec5SDimitry Andric       break;
3695ffd83dbSDimitry Andric     case FormattedString::JustifyCenter:
3705ffd83dbSDimitry Andric       LeftIndent = Difference / 2;
3715ffd83dbSDimitry Andric       RightIndent = Difference - LeftIndent;
3720b57cec5SDimitry Andric       break;
3730b57cec5SDimitry Andric     }
3740b57cec5SDimitry Andric   }
3755ffd83dbSDimitry Andric   indent(LeftIndent);
3765ffd83dbSDimitry Andric   (*this) << FS.Str;
3775ffd83dbSDimitry Andric   indent(RightIndent);
3780b57cec5SDimitry Andric   return *this;
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric 
operator <<(const FormattedNumber & FN)3810b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
3820b57cec5SDimitry Andric   if (FN.Hex) {
3830b57cec5SDimitry Andric     HexPrintStyle Style;
3840b57cec5SDimitry Andric     if (FN.Upper && FN.HexPrefix)
3850b57cec5SDimitry Andric       Style = HexPrintStyle::PrefixUpper;
3860b57cec5SDimitry Andric     else if (FN.Upper && !FN.HexPrefix)
3870b57cec5SDimitry Andric       Style = HexPrintStyle::Upper;
3880b57cec5SDimitry Andric     else if (!FN.Upper && FN.HexPrefix)
3890b57cec5SDimitry Andric       Style = HexPrintStyle::PrefixLower;
3900b57cec5SDimitry Andric     else
3910b57cec5SDimitry Andric       Style = HexPrintStyle::Lower;
3920b57cec5SDimitry Andric     llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
3930b57cec5SDimitry Andric   } else {
3940b57cec5SDimitry Andric     llvm::SmallString<16> Buffer;
3950b57cec5SDimitry Andric     llvm::raw_svector_ostream Stream(Buffer);
3960b57cec5SDimitry Andric     llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
3970b57cec5SDimitry Andric     if (Buffer.size() < FN.Width)
3980b57cec5SDimitry Andric       indent(FN.Width - Buffer.size());
3990b57cec5SDimitry Andric     (*this) << Buffer;
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric   return *this;
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric 
operator <<(const FormattedBytes & FB)4040b57cec5SDimitry Andric raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
4050b57cec5SDimitry Andric   if (FB.Bytes.empty())
4060b57cec5SDimitry Andric     return *this;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   size_t LineIndex = 0;
4090b57cec5SDimitry Andric   auto Bytes = FB.Bytes;
4100b57cec5SDimitry Andric   const size_t Size = Bytes.size();
4110b57cec5SDimitry Andric   HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
4120b57cec5SDimitry Andric   uint64_t OffsetWidth = 0;
41381ad6265SDimitry Andric   if (FB.FirstByteOffset) {
4140b57cec5SDimitry Andric     // Figure out how many nibbles are needed to print the largest offset
4150b57cec5SDimitry Andric     // represented by this data set, so that we can align the offset field
4160b57cec5SDimitry Andric     // to the right width.
4170b57cec5SDimitry Andric     size_t Lines = Size / FB.NumPerLine;
4180b57cec5SDimitry Andric     uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
4190b57cec5SDimitry Andric     unsigned Power = 0;
4200b57cec5SDimitry Andric     if (MaxOffset > 0)
4210b57cec5SDimitry Andric       Power = llvm::Log2_64_Ceil(MaxOffset);
4220b57cec5SDimitry Andric     OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
4230b57cec5SDimitry Andric   }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   // The width of a block of data including all spaces for group separators.
4260b57cec5SDimitry Andric   unsigned NumByteGroups =
4270b57cec5SDimitry Andric       alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
4280b57cec5SDimitry Andric   unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   while (!Bytes.empty()) {
4310b57cec5SDimitry Andric     indent(FB.IndentLevel);
4320b57cec5SDimitry Andric 
43381ad6265SDimitry Andric     if (FB.FirstByteOffset) {
434bdd1243dSDimitry Andric       uint64_t Offset = *FB.FirstByteOffset;
4350b57cec5SDimitry Andric       llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
4360b57cec5SDimitry Andric       *this << ": ";
4370b57cec5SDimitry Andric     }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric     auto Line = Bytes.take_front(FB.NumPerLine);
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric     size_t CharsPrinted = 0;
4420b57cec5SDimitry Andric     // Print the hex bytes for this line in groups
4430b57cec5SDimitry Andric     for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
4440b57cec5SDimitry Andric       if (I && (I % FB.ByteGroupSize) == 0) {
4450b57cec5SDimitry Andric         ++CharsPrinted;
4460b57cec5SDimitry Andric         *this << " ";
4470b57cec5SDimitry Andric       }
4480b57cec5SDimitry Andric       llvm::write_hex(*this, Line[I], HPS, 2);
4490b57cec5SDimitry Andric     }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric     if (FB.ASCII) {
4520b57cec5SDimitry Andric       // Print any spaces needed for any bytes that we didn't print on this
4530b57cec5SDimitry Andric       // line so that the ASCII bytes are correctly aligned.
4540b57cec5SDimitry Andric       assert(BlockCharWidth >= CharsPrinted);
4550b57cec5SDimitry Andric       indent(BlockCharWidth - CharsPrinted + 2);
4560b57cec5SDimitry Andric       *this << "|";
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric       // Print the ASCII char values for each byte on this line
4590b57cec5SDimitry Andric       for (uint8_t Byte : Line) {
4600b57cec5SDimitry Andric         if (isPrint(Byte))
4610b57cec5SDimitry Andric           *this << static_cast<char>(Byte);
4620b57cec5SDimitry Andric         else
4630b57cec5SDimitry Andric           *this << '.';
4640b57cec5SDimitry Andric       }
4650b57cec5SDimitry Andric       *this << '|';
4660b57cec5SDimitry Andric     }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric     Bytes = Bytes.drop_front(Line.size());
4690b57cec5SDimitry Andric     LineIndex += Line.size();
4700b57cec5SDimitry Andric     if (LineIndex < Size)
4710b57cec5SDimitry Andric       *this << '\n';
4720b57cec5SDimitry Andric   }
4730b57cec5SDimitry Andric   return *this;
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric template <char C>
write_padding(raw_ostream & OS,unsigned NumChars)4770b57cec5SDimitry Andric static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
4780b57cec5SDimitry Andric   static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
4790b57cec5SDimitry Andric                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
4800b57cec5SDimitry Andric                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
4810b57cec5SDimitry Andric                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
4820b57cec5SDimitry Andric                                C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   // Usually the indentation is small, handle it with a fastpath.
485bdd1243dSDimitry Andric   if (NumChars < std::size(Chars))
4860b57cec5SDimitry Andric     return OS.write(Chars, NumChars);
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   while (NumChars) {
489bdd1243dSDimitry Andric     unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1);
4900b57cec5SDimitry Andric     OS.write(Chars, NumToWrite);
4910b57cec5SDimitry Andric     NumChars -= NumToWrite;
4920b57cec5SDimitry Andric   }
4930b57cec5SDimitry Andric   return OS;
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric /// indent - Insert 'NumSpaces' spaces.
indent(unsigned NumSpaces)4970b57cec5SDimitry Andric raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
4980b57cec5SDimitry Andric   return write_padding<' '>(*this, NumSpaces);
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric /// write_zeros - Insert 'NumZeros' nulls.
write_zeros(unsigned NumZeros)5020b57cec5SDimitry Andric raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
5030b57cec5SDimitry Andric   return write_padding<'\0'>(*this, NumZeros);
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
prepare_colors()5065ffd83dbSDimitry Andric bool raw_ostream::prepare_colors() {
5075ffd83dbSDimitry Andric   // Colors were explicitly disabled.
5085ffd83dbSDimitry Andric   if (!ColorEnabled)
5095ffd83dbSDimitry Andric     return false;
5105ffd83dbSDimitry Andric 
5115ffd83dbSDimitry Andric   // Colors require changing the terminal but this stream is not going to a
5125ffd83dbSDimitry Andric   // terminal.
5135ffd83dbSDimitry Andric   if (sys::Process::ColorNeedsFlush() && !is_displayed())
5145ffd83dbSDimitry Andric     return false;
5155ffd83dbSDimitry Andric 
5165ffd83dbSDimitry Andric   if (sys::Process::ColorNeedsFlush())
5175ffd83dbSDimitry Andric     flush();
5185ffd83dbSDimitry Andric 
5195ffd83dbSDimitry Andric   return true;
5205ffd83dbSDimitry Andric }
5215ffd83dbSDimitry Andric 
changeColor(enum Colors colors,bool bold,bool bg)5225ffd83dbSDimitry Andric raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
5235ffd83dbSDimitry Andric   if (!prepare_colors())
5245ffd83dbSDimitry Andric     return *this;
5255ffd83dbSDimitry Andric 
5265ffd83dbSDimitry Andric   const char *colorcode =
5275ffd83dbSDimitry Andric       (colors == SAVEDCOLOR)
5285ffd83dbSDimitry Andric           ? sys::Process::OutputBold(bg)
5295ffd83dbSDimitry Andric           : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
5305ffd83dbSDimitry Andric   if (colorcode)
5315ffd83dbSDimitry Andric     write(colorcode, strlen(colorcode));
5325ffd83dbSDimitry Andric   return *this;
5335ffd83dbSDimitry Andric }
5345ffd83dbSDimitry Andric 
resetColor()5355ffd83dbSDimitry Andric raw_ostream &raw_ostream::resetColor() {
5365ffd83dbSDimitry Andric   if (!prepare_colors())
5375ffd83dbSDimitry Andric     return *this;
5385ffd83dbSDimitry Andric 
5395ffd83dbSDimitry Andric   if (const char *colorcode = sys::Process::ResetColor())
5405ffd83dbSDimitry Andric     write(colorcode, strlen(colorcode));
5415ffd83dbSDimitry Andric   return *this;
5425ffd83dbSDimitry Andric }
5435ffd83dbSDimitry Andric 
reverseColor()5445ffd83dbSDimitry Andric raw_ostream &raw_ostream::reverseColor() {
5455ffd83dbSDimitry Andric   if (!prepare_colors())
5465ffd83dbSDimitry Andric     return *this;
5475ffd83dbSDimitry Andric 
5485ffd83dbSDimitry Andric   if (const char *colorcode = sys::Process::OutputReverse())
5495ffd83dbSDimitry Andric     write(colorcode, strlen(colorcode));
5505ffd83dbSDimitry Andric   return *this;
5515ffd83dbSDimitry Andric }
5525ffd83dbSDimitry Andric 
anchor()5530b57cec5SDimitry Andric void raw_ostream::anchor() {}
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5560b57cec5SDimitry Andric //  Formatted Output
5570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric // Out of line virtual method.
home()5600b57cec5SDimitry Andric void format_object_base::home() {
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5640b57cec5SDimitry Andric //  raw_fd_ostream
5650b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5660b57cec5SDimitry Andric 
getFD(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)5670b57cec5SDimitry Andric static int getFD(StringRef Filename, std::error_code &EC,
5680b57cec5SDimitry Andric                  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
5690b57cec5SDimitry Andric                  sys::fs::OpenFlags Flags) {
5700b57cec5SDimitry Andric   assert((Access & sys::fs::FA_Write) &&
5710b57cec5SDimitry Andric          "Cannot make a raw_ostream from a read-only descriptor!");
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric   // Handle "-" as stdout. Note that when we do this, we consider ourself
5740b57cec5SDimitry Andric   // the owner of stdout and may set the "binary" flag globally based on Flags.
5750b57cec5SDimitry Andric   if (Filename == "-") {
5760b57cec5SDimitry Andric     EC = std::error_code();
577fe6060f1SDimitry Andric     // Change stdout's text/binary mode based on the Flags.
578fe6060f1SDimitry Andric     sys::ChangeStdoutMode(Flags);
5790b57cec5SDimitry Andric     return STDOUT_FILENO;
5800b57cec5SDimitry Andric   }
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric   int FD;
5830b57cec5SDimitry Andric   if (Access & sys::fs::FA_Read)
5840b57cec5SDimitry Andric     EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
5850b57cec5SDimitry Andric   else
5860b57cec5SDimitry Andric     EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
5870b57cec5SDimitry Andric   if (EC)
5880b57cec5SDimitry Andric     return -1;
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric   return FD;
5910b57cec5SDimitry Andric }
5920b57cec5SDimitry Andric 
raw_fd_ostream(StringRef Filename,std::error_code & EC)5930b57cec5SDimitry Andric raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
5940b57cec5SDimitry Andric     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
5950b57cec5SDimitry Andric                      sys::fs::OF_None) {}
5960b57cec5SDimitry Andric 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp)5970b57cec5SDimitry Andric raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
5980b57cec5SDimitry Andric                                sys::fs::CreationDisposition Disp)
5990b57cec5SDimitry Andric     : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
6000b57cec5SDimitry Andric 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::FileAccess Access)6010b57cec5SDimitry Andric raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
6020b57cec5SDimitry Andric                                sys::fs::FileAccess Access)
6030b57cec5SDimitry Andric     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
6040b57cec5SDimitry Andric                      sys::fs::OF_None) {}
6050b57cec5SDimitry Andric 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::OpenFlags Flags)6060b57cec5SDimitry Andric raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
6070b57cec5SDimitry Andric                                sys::fs::OpenFlags Flags)
6080b57cec5SDimitry Andric     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
6090b57cec5SDimitry Andric                      Flags) {}
6100b57cec5SDimitry Andric 
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)6110b57cec5SDimitry Andric raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
6120b57cec5SDimitry Andric                                sys::fs::CreationDisposition Disp,
6130b57cec5SDimitry Andric                                sys::fs::FileAccess Access,
6140b57cec5SDimitry Andric                                sys::fs::OpenFlags Flags)
6150b57cec5SDimitry Andric     : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric /// FD is the file descriptor that this writes to.  If ShouldClose is true, this
6180b57cec5SDimitry Andric /// closes the file when the stream is destroyed.
raw_fd_ostream(int fd,bool shouldClose,bool unbuffered,OStreamKind K)619e8d8bef9SDimitry Andric raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
620e8d8bef9SDimitry Andric                                OStreamKind K)
621e8d8bef9SDimitry Andric     : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
6220b57cec5SDimitry Andric   if (FD < 0 ) {
6230b57cec5SDimitry Andric     ShouldClose = false;
6240b57cec5SDimitry Andric     return;
6250b57cec5SDimitry Andric   }
6260b57cec5SDimitry Andric 
6275ffd83dbSDimitry Andric   enable_colors(true);
6285ffd83dbSDimitry Andric 
6290b57cec5SDimitry Andric   // Do not attempt to close stdout or stderr. We used to try to maintain the
6300b57cec5SDimitry Andric   // property that tools that support writing file to stdout should not also
6310b57cec5SDimitry Andric   // write informational output to stdout, but in practice we were never able to
6320b57cec5SDimitry Andric   // maintain this invariant. Many features have been added to LLVM and clang
6330b57cec5SDimitry Andric   // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
6340b57cec5SDimitry Andric   // users must simply be aware that mixed output and remarks is a possibility.
6350b57cec5SDimitry Andric   if (FD <= STDERR_FILENO)
6360b57cec5SDimitry Andric     ShouldClose = false;
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric #ifdef _WIN32
6390b57cec5SDimitry Andric   // Check if this is a console device. This is not equivalent to isatty.
6400b57cec5SDimitry Andric   IsWindowsConsole =
6410b57cec5SDimitry Andric       ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
642cb14a3feSDimitry Andric #endif
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   // Get the starting position.
6450b57cec5SDimitry Andric   off_t loc = ::lseek(FD, 0, SEEK_CUR);
6460b57cec5SDimitry Andric   sys::fs::file_status Status;
6470b57cec5SDimitry Andric   std::error_code EC = status(FD, Status);
64804eeddc0SDimitry Andric   IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
64904eeddc0SDimitry Andric #ifdef _WIN32
65004eeddc0SDimitry Andric   // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
65104eeddc0SDimitry Andric   SupportsSeeking = !EC && IsRegularFile;
6520b57cec5SDimitry Andric #else
65304eeddc0SDimitry Andric   SupportsSeeking = !EC && loc != (off_t)-1;
6540b57cec5SDimitry Andric #endif
6550b57cec5SDimitry Andric   if (!SupportsSeeking)
6560b57cec5SDimitry Andric     pos = 0;
6570b57cec5SDimitry Andric   else
6580b57cec5SDimitry Andric     pos = static_cast<uint64_t>(loc);
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric 
~raw_fd_ostream()6610b57cec5SDimitry Andric raw_fd_ostream::~raw_fd_ostream() {
6620b57cec5SDimitry Andric   if (FD >= 0) {
6630b57cec5SDimitry Andric     flush();
6640b57cec5SDimitry Andric     if (ShouldClose) {
6650b57cec5SDimitry Andric       if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
6660b57cec5SDimitry Andric         error_detected(EC);
6670b57cec5SDimitry Andric     }
6680b57cec5SDimitry Andric   }
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric #ifdef __MINGW32__
6710b57cec5SDimitry Andric   // On mingw, global dtors should not call exit().
6720b57cec5SDimitry Andric   // report_fatal_error() invokes exit(). We know report_fatal_error()
6730b57cec5SDimitry Andric   // might not write messages to stderr when any errors were detected
6740b57cec5SDimitry Andric   // on FD == 2.
6750b57cec5SDimitry Andric   if (FD == 2) return;
6760b57cec5SDimitry Andric #endif
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric   // If there are any pending errors, report them now. Clients wishing
6790b57cec5SDimitry Andric   // to avoid report_fatal_error calls should check for errors with
6800b57cec5SDimitry Andric   // has_error() and clear the error flag with clear_error() before
6810b57cec5SDimitry Andric   // destructing raw_ostream objects which may have errors.
6820b57cec5SDimitry Andric   if (has_error())
683349cc55cSDimitry Andric     report_fatal_error(Twine("IO failure on output stream: ") +
684349cc55cSDimitry Andric                            error().message(),
6850b57cec5SDimitry Andric                        /*gen_crash_diag=*/false);
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric #if defined(_WIN32)
6890b57cec5SDimitry Andric // The most reliable way to print unicode in a Windows console is with
6900b57cec5SDimitry Andric // WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
6910b57cec5SDimitry Andric // assumes that LLVM programs always print valid UTF-8 to the console. The data
6920b57cec5SDimitry Andric // might not be UTF-8 for two major reasons:
6930b57cec5SDimitry Andric // 1. The program is printing binary (-filetype=obj -o -), in which case it
6940b57cec5SDimitry Andric // would have been gibberish anyway.
6950b57cec5SDimitry Andric // 2. The program is printing text in a semi-ascii compatible codepage like
6960b57cec5SDimitry Andric // shift-jis or cp1252.
6970b57cec5SDimitry Andric //
6980b57cec5SDimitry Andric // Most LLVM programs don't produce non-ascii text unless they are quoting
6990b57cec5SDimitry Andric // user source input. A well-behaved LLVM program should either validate that
7000b57cec5SDimitry Andric // the input is UTF-8 or transcode from the local codepage to UTF-8 before
7010b57cec5SDimitry Andric // quoting it. If they don't, this may mess up the encoding, but this is still
7020b57cec5SDimitry Andric // probably the best compromise we can make.
write_console_impl(int FD,StringRef Data)7030b57cec5SDimitry Andric static bool write_console_impl(int FD, StringRef Data) {
7040b57cec5SDimitry Andric   SmallVector<wchar_t, 256> WideText;
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric   // Fall back to ::write if it wasn't valid UTF-8.
7070b57cec5SDimitry Andric   if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
7080b57cec5SDimitry Andric     return false;
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric   // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
7110b57cec5SDimitry Andric   // that can be written to the console at a time.
7120b57cec5SDimitry Andric   size_t MaxWriteSize = WideText.size();
7130b57cec5SDimitry Andric   if (!RunningWindows8OrGreater())
7140b57cec5SDimitry Andric     MaxWriteSize = 32767;
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   size_t WCharsWritten = 0;
7170b57cec5SDimitry Andric   do {
7180b57cec5SDimitry Andric     size_t WCharsToWrite =
7190b57cec5SDimitry Andric         std::min(MaxWriteSize, WideText.size() - WCharsWritten);
7200b57cec5SDimitry Andric     DWORD ActuallyWritten;
7210b57cec5SDimitry Andric     bool Success =
7220b57cec5SDimitry Andric         ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
7230b57cec5SDimitry Andric                         WCharsToWrite, &ActuallyWritten,
7240b57cec5SDimitry Andric                         /*Reserved=*/nullptr);
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric     // The most likely reason for WriteConsoleW to fail is that FD no longer
7270b57cec5SDimitry Andric     // points to a console. Fall back to ::write. If this isn't the first loop
7280b57cec5SDimitry Andric     // iteration, something is truly wrong.
7290b57cec5SDimitry Andric     if (!Success)
7300b57cec5SDimitry Andric       return false;
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric     WCharsWritten += ActuallyWritten;
7330b57cec5SDimitry Andric   } while (WCharsWritten != WideText.size());
7340b57cec5SDimitry Andric   return true;
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric #endif
7370b57cec5SDimitry Andric 
write_impl(const char * Ptr,size_t Size)7380b57cec5SDimitry Andric void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
739*0fca6ea1SDimitry Andric   if (TiedStream)
740*0fca6ea1SDimitry Andric     TiedStream->flush();
741*0fca6ea1SDimitry Andric 
7420b57cec5SDimitry Andric   assert(FD >= 0 && "File already closed.");
7430b57cec5SDimitry Andric   pos += Size;
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric #if defined(_WIN32)
7460b57cec5SDimitry Andric   // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
7470b57cec5SDimitry Andric   // and using WriteConsoleW. If that fails, fall back to plain write().
7480b57cec5SDimitry Andric   if (IsWindowsConsole)
7490b57cec5SDimitry Andric     if (write_console_impl(FD, StringRef(Ptr, Size)))
7500b57cec5SDimitry Andric       return;
7510b57cec5SDimitry Andric #endif
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric   // The maximum write size is limited to INT32_MAX. A write
7540b57cec5SDimitry Andric   // greater than SSIZE_MAX is implementation-defined in POSIX,
7550b57cec5SDimitry Andric   // and Windows _write requires 32 bit input.
7560b57cec5SDimitry Andric   size_t MaxWriteSize = INT32_MAX;
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric #if defined(__linux__)
7590b57cec5SDimitry Andric   // It is observed that Linux returns EINVAL for a very large write (>2G).
7600b57cec5SDimitry Andric   // Make it a reasonably small value.
7610b57cec5SDimitry Andric   MaxWriteSize = 1024 * 1024 * 1024;
7620b57cec5SDimitry Andric #endif
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   do {
7650b57cec5SDimitry Andric     size_t ChunkSize = std::min(Size, MaxWriteSize);
7660b57cec5SDimitry Andric     ssize_t ret = ::write(FD, Ptr, ChunkSize);
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric     if (ret < 0) {
7690b57cec5SDimitry Andric       // If it's a recoverable error, swallow it and retry the write.
7700b57cec5SDimitry Andric       //
7710b57cec5SDimitry Andric       // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
7720b57cec5SDimitry Andric       // raw_ostream isn't designed to do non-blocking I/O. However, some
7730b57cec5SDimitry Andric       // programs, such as old versions of bjam, have mistakenly used
7740b57cec5SDimitry Andric       // O_NONBLOCK. For compatibility, emulate blocking semantics by
7750b57cec5SDimitry Andric       // spinning until the write succeeds. If you don't want spinning,
7760b57cec5SDimitry Andric       // don't use O_NONBLOCK file descriptors with raw_ostream.
7770b57cec5SDimitry Andric       if (errno == EINTR || errno == EAGAIN
7780b57cec5SDimitry Andric #ifdef EWOULDBLOCK
7790b57cec5SDimitry Andric           || errno == EWOULDBLOCK
7800b57cec5SDimitry Andric #endif
7810b57cec5SDimitry Andric           )
7820b57cec5SDimitry Andric         continue;
7830b57cec5SDimitry Andric 
7841ac55f4cSDimitry Andric #ifdef _WIN32
7851ac55f4cSDimitry Andric       // Windows equivalents of SIGPIPE/EPIPE.
7861ac55f4cSDimitry Andric       DWORD WinLastError = GetLastError();
7871ac55f4cSDimitry Andric       if (WinLastError == ERROR_BROKEN_PIPE ||
7881ac55f4cSDimitry Andric           (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
7891ac55f4cSDimitry Andric         llvm::sys::CallOneShotPipeSignalHandler();
7901ac55f4cSDimitry Andric         errno = EPIPE;
7911ac55f4cSDimitry Andric       }
7921ac55f4cSDimitry Andric #endif
7930b57cec5SDimitry Andric       // Otherwise it's a non-recoverable error. Note it and quit.
794*0fca6ea1SDimitry Andric       error_detected(errnoAsErrorCode());
7950b57cec5SDimitry Andric       break;
7960b57cec5SDimitry Andric     }
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric     // The write may have written some or all of the data. Update the
7990b57cec5SDimitry Andric     // size and buffer pointer to reflect the remainder that needs
8000b57cec5SDimitry Andric     // to be written. If there are no bytes left, we're done.
8010b57cec5SDimitry Andric     Ptr += ret;
8020b57cec5SDimitry Andric     Size -= ret;
8030b57cec5SDimitry Andric   } while (Size > 0);
8040b57cec5SDimitry Andric }
8050b57cec5SDimitry Andric 
close()8060b57cec5SDimitry Andric void raw_fd_ostream::close() {
8070b57cec5SDimitry Andric   assert(ShouldClose);
8080b57cec5SDimitry Andric   ShouldClose = false;
8090b57cec5SDimitry Andric   flush();
8100b57cec5SDimitry Andric   if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
8110b57cec5SDimitry Andric     error_detected(EC);
8120b57cec5SDimitry Andric   FD = -1;
8130b57cec5SDimitry Andric }
8140b57cec5SDimitry Andric 
seek(uint64_t off)8150b57cec5SDimitry Andric uint64_t raw_fd_ostream::seek(uint64_t off) {
8160b57cec5SDimitry Andric   assert(SupportsSeeking && "Stream does not support seeking!");
8170b57cec5SDimitry Andric   flush();
8180b57cec5SDimitry Andric #ifdef _WIN32
8190b57cec5SDimitry Andric   pos = ::_lseeki64(FD, off, SEEK_SET);
8200b57cec5SDimitry Andric #else
8210b57cec5SDimitry Andric   pos = ::lseek(FD, off, SEEK_SET);
8220b57cec5SDimitry Andric #endif
8230b57cec5SDimitry Andric   if (pos == (uint64_t)-1)
824*0fca6ea1SDimitry Andric     error_detected(errnoAsErrorCode());
8250b57cec5SDimitry Andric   return pos;
8260b57cec5SDimitry Andric }
8270b57cec5SDimitry Andric 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)8280b57cec5SDimitry Andric void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
8290b57cec5SDimitry Andric                                  uint64_t Offset) {
8300b57cec5SDimitry Andric   uint64_t Pos = tell();
8310b57cec5SDimitry Andric   seek(Offset);
8320b57cec5SDimitry Andric   write(Ptr, Size);
8330b57cec5SDimitry Andric   seek(Pos);
8340b57cec5SDimitry Andric }
8350b57cec5SDimitry Andric 
preferred_buffer_size() const8360b57cec5SDimitry Andric size_t raw_fd_ostream::preferred_buffer_size() const {
8370b57cec5SDimitry Andric #if defined(_WIN32)
8380b57cec5SDimitry Andric   // Disable buffering for console devices. Console output is re-encoded from
8390b57cec5SDimitry Andric   // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
8400b57cec5SDimitry Andric   // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
8410b57cec5SDimitry Andric   // below on most other OSs, so do the same thing on Windows and avoid that
8420b57cec5SDimitry Andric   // complexity.
8430b57cec5SDimitry Andric   if (IsWindowsConsole)
8440b57cec5SDimitry Andric     return 0;
8450b57cec5SDimitry Andric   return raw_ostream::preferred_buffer_size();
8465f757f3fSDimitry Andric #else
8470b57cec5SDimitry Andric   assert(FD >= 0 && "File not yet open!");
8480b57cec5SDimitry Andric   struct stat statbuf;
8490b57cec5SDimitry Andric   if (fstat(FD, &statbuf) != 0)
8500b57cec5SDimitry Andric     return 0;
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric   // If this is a terminal, don't use buffering. Line buffering
8530b57cec5SDimitry Andric   // would be a more traditional thing to do, but it's not worth
8540b57cec5SDimitry Andric   // the complexity.
8555ffd83dbSDimitry Andric   if (S_ISCHR(statbuf.st_mode) && is_displayed())
8560b57cec5SDimitry Andric     return 0;
8570b57cec5SDimitry Andric   // Return the preferred block size.
8580b57cec5SDimitry Andric   return statbuf.st_blksize;
8590b57cec5SDimitry Andric #endif
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric 
is_displayed() const8620b57cec5SDimitry Andric bool raw_fd_ostream::is_displayed() const {
8630b57cec5SDimitry Andric   return sys::Process::FileDescriptorIsDisplayed(FD);
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric 
has_colors() const8660b57cec5SDimitry Andric bool raw_fd_ostream::has_colors() const {
867e8d8bef9SDimitry Andric   if (!HasColors)
868e8d8bef9SDimitry Andric     HasColors = sys::Process::FileDescriptorHasColors(FD);
869e8d8bef9SDimitry Andric   return *HasColors;
870e8d8bef9SDimitry Andric }
871e8d8bef9SDimitry Andric 
lock()872e8d8bef9SDimitry Andric Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
873e8d8bef9SDimitry Andric   std::error_code EC = sys::fs::lockFile(FD);
874e8d8bef9SDimitry Andric   if (!EC)
875e8d8bef9SDimitry Andric     return sys::fs::FileLocker(FD);
876e8d8bef9SDimitry Andric   return errorCodeToError(EC);
877e8d8bef9SDimitry Andric }
878e8d8bef9SDimitry Andric 
879e8d8bef9SDimitry Andric Expected<sys::fs::FileLocker>
tryLockFor(Duration const & Timeout)88004eeddc0SDimitry Andric raw_fd_ostream::tryLockFor(Duration const& Timeout) {
88104eeddc0SDimitry Andric   std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
882e8d8bef9SDimitry Andric   if (!EC)
883e8d8bef9SDimitry Andric     return sys::fs::FileLocker(FD);
884e8d8bef9SDimitry Andric   return errorCodeToError(EC);
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric 
anchor()8870b57cec5SDimitry Andric void raw_fd_ostream::anchor() {}
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8900b57cec5SDimitry Andric //  outs(), errs(), nulls()
8910b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8920b57cec5SDimitry Andric 
outs()8935ffd83dbSDimitry Andric raw_fd_ostream &llvm::outs() {
8940b57cec5SDimitry Andric   // Set buffer settings to model stdout behavior.
8950b57cec5SDimitry Andric   std::error_code EC;
8965f757f3fSDimitry Andric #ifdef __MVS__
8975f757f3fSDimitry Andric   EC = enableAutoConversion(STDOUT_FILENO);
8985f757f3fSDimitry Andric   assert(!EC);
8995f757f3fSDimitry Andric #endif
9008bcb0991SDimitry Andric   static raw_fd_ostream S("-", EC, sys::fs::OF_None);
9010b57cec5SDimitry Andric   assert(!EC);
9020b57cec5SDimitry Andric   return S;
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric 
errs()9055ffd83dbSDimitry Andric raw_fd_ostream &llvm::errs() {
906*0fca6ea1SDimitry Andric   // Set standard error to be unbuffered.
9075f757f3fSDimitry Andric #ifdef __MVS__
9085f757f3fSDimitry Andric   std::error_code EC = enableAutoConversion(STDERR_FILENO);
9095f757f3fSDimitry Andric   assert(!EC);
9105f757f3fSDimitry Andric #endif
9110b57cec5SDimitry Andric   static raw_fd_ostream S(STDERR_FILENO, false, true);
9120b57cec5SDimitry Andric   return S;
9130b57cec5SDimitry Andric }
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric /// nulls() - This returns a reference to a raw_ostream which discards output.
nulls()9160b57cec5SDimitry Andric raw_ostream &llvm::nulls() {
9170b57cec5SDimitry Andric   static raw_null_ostream S;
9180b57cec5SDimitry Andric   return S;
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
922e8d8bef9SDimitry Andric // File Streams
923e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
924e8d8bef9SDimitry Andric 
raw_fd_stream(StringRef Filename,std::error_code & EC)925e8d8bef9SDimitry Andric raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
926e8d8bef9SDimitry Andric     : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
927e8d8bef9SDimitry Andric                            sys::fs::FA_Write | sys::fs::FA_Read,
928e8d8bef9SDimitry Andric                            sys::fs::OF_None),
929e8d8bef9SDimitry Andric                      true, false, OStreamKind::OK_FDStream) {
930e8d8bef9SDimitry Andric   if (EC)
931e8d8bef9SDimitry Andric     return;
932e8d8bef9SDimitry Andric 
93304eeddc0SDimitry Andric   if (!isRegularFile())
934e8d8bef9SDimitry Andric     EC = std::make_error_code(std::errc::invalid_argument);
935e8d8bef9SDimitry Andric }
936e8d8bef9SDimitry Andric 
raw_fd_stream(int fd,bool shouldClose)9375f757f3fSDimitry Andric raw_fd_stream::raw_fd_stream(int fd, bool shouldClose)
9385f757f3fSDimitry Andric     : raw_fd_ostream(fd, shouldClose, false, OStreamKind::OK_FDStream) {}
9395f757f3fSDimitry Andric 
read(char * Ptr,size_t Size)940e8d8bef9SDimitry Andric ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
941e8d8bef9SDimitry Andric   assert(get_fd() >= 0 && "File already closed.");
942e8d8bef9SDimitry Andric   ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
943e8d8bef9SDimitry Andric   if (Ret >= 0)
944e8d8bef9SDimitry Andric     inc_pos(Ret);
945e8d8bef9SDimitry Andric   else
946*0fca6ea1SDimitry Andric     error_detected(errnoAsErrorCode());
947e8d8bef9SDimitry Andric   return Ret;
948e8d8bef9SDimitry Andric }
949e8d8bef9SDimitry Andric 
classof(const raw_ostream * OS)950e8d8bef9SDimitry Andric bool raw_fd_stream::classof(const raw_ostream *OS) {
951e8d8bef9SDimitry Andric   return OS->get_kind() == OStreamKind::OK_FDStream;
952e8d8bef9SDimitry Andric }
953e8d8bef9SDimitry Andric 
954e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
955*0fca6ea1SDimitry Andric //  raw_string_ostream
956*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
957*0fca6ea1SDimitry Andric 
write_impl(const char * Ptr,size_t Size)958*0fca6ea1SDimitry Andric void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
959*0fca6ea1SDimitry Andric   OS.append(Ptr, Size);
960*0fca6ea1SDimitry Andric }
961*0fca6ea1SDimitry Andric 
962*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
9630b57cec5SDimitry Andric //  raw_svector_ostream
9640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9650b57cec5SDimitry Andric 
current_pos() const9660b57cec5SDimitry Andric uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
9670b57cec5SDimitry Andric 
write_impl(const char * Ptr,size_t Size)9680b57cec5SDimitry Andric void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
9690b57cec5SDimitry Andric   OS.append(Ptr, Ptr + Size);
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)9720b57cec5SDimitry Andric void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
9730b57cec5SDimitry Andric                                       uint64_t Offset) {
9740b57cec5SDimitry Andric   memcpy(OS.data() + Offset, Ptr, Size);
9750b57cec5SDimitry Andric }
9760b57cec5SDimitry Andric 
classof(const raw_ostream * OS)977*0fca6ea1SDimitry Andric bool raw_svector_ostream::classof(const raw_ostream *OS) {
978*0fca6ea1SDimitry Andric   return OS->get_kind() == OStreamKind::OK_SVecStream;
979*0fca6ea1SDimitry Andric }
980*0fca6ea1SDimitry Andric 
9810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9820b57cec5SDimitry Andric //  raw_null_ostream
9830b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9840b57cec5SDimitry Andric 
~raw_null_ostream()9850b57cec5SDimitry Andric raw_null_ostream::~raw_null_ostream() {
9860b57cec5SDimitry Andric #ifndef NDEBUG
9870b57cec5SDimitry Andric   // ~raw_ostream asserts that the buffer is empty. This isn't necessary
9880b57cec5SDimitry Andric   // with raw_null_ostream, but it's better to have raw_null_ostream follow
9890b57cec5SDimitry Andric   // the rules than to change the rules just for raw_null_ostream.
9900b57cec5SDimitry Andric   flush();
9910b57cec5SDimitry Andric #endif
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
write_impl(const char * Ptr,size_t Size)9940b57cec5SDimitry Andric void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
9950b57cec5SDimitry Andric }
9960b57cec5SDimitry Andric 
current_pos() const9970b57cec5SDimitry Andric uint64_t raw_null_ostream::current_pos() const {
9980b57cec5SDimitry Andric   return 0;
9990b57cec5SDimitry Andric }
10000b57cec5SDimitry Andric 
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)10010b57cec5SDimitry Andric void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
10020b57cec5SDimitry Andric                                    uint64_t Offset) {}
10030b57cec5SDimitry Andric 
anchor()10040b57cec5SDimitry Andric void raw_pwrite_stream::anchor() {}
10050b57cec5SDimitry Andric 
anchor()10060b57cec5SDimitry Andric void buffer_ostream::anchor() {}
1007e8d8bef9SDimitry Andric 
anchor()1008e8d8bef9SDimitry Andric void buffer_unique_ostream::anchor() {}
1009fe6060f1SDimitry Andric 
writeToOutput(StringRef OutputFileName,std::function<Error (raw_ostream &)> Write)1010fe6060f1SDimitry Andric Error llvm::writeToOutput(StringRef OutputFileName,
1011fe6060f1SDimitry Andric                           std::function<Error(raw_ostream &)> Write) {
1012fe6060f1SDimitry Andric   if (OutputFileName == "-")
1013fe6060f1SDimitry Andric     return Write(outs());
1014fe6060f1SDimitry Andric 
1015fe6060f1SDimitry Andric   if (OutputFileName == "/dev/null") {
1016fe6060f1SDimitry Andric     raw_null_ostream Out;
1017fe6060f1SDimitry Andric     return Write(Out);
1018fe6060f1SDimitry Andric   }
1019fe6060f1SDimitry Andric 
102006c3fb27SDimitry Andric   unsigned Mode = sys::fs::all_read | sys::fs::all_write;
1021fe6060f1SDimitry Andric   Expected<sys::fs::TempFile> Temp =
1022fe6060f1SDimitry Andric       sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
1023fe6060f1SDimitry Andric   if (!Temp)
1024fe6060f1SDimitry Andric     return createFileError(OutputFileName, Temp.takeError());
1025fe6060f1SDimitry Andric 
1026fe6060f1SDimitry Andric   raw_fd_ostream Out(Temp->FD, false);
1027fe6060f1SDimitry Andric 
1028fe6060f1SDimitry Andric   if (Error E = Write(Out)) {
1029fe6060f1SDimitry Andric     if (Error DiscardError = Temp->discard())
1030fe6060f1SDimitry Andric       return joinErrors(std::move(E), std::move(DiscardError));
1031fe6060f1SDimitry Andric     return E;
1032fe6060f1SDimitry Andric   }
1033fe6060f1SDimitry Andric   Out.flush();
1034fe6060f1SDimitry Andric 
1035fe6060f1SDimitry Andric   return Temp->keep(OutputFileName);
1036fe6060f1SDimitry Andric }
1037