xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===//
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 file defines the raw_ostream class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_SUPPORT_RAW_OSTREAM_H
140b57cec5SDimitry Andric #define LLVM_SUPPORT_RAW_OSTREAM_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
18e8d8bef9SDimitry Andric #include "llvm/Support/DataTypes.h"
190b57cec5SDimitry Andric #include <cassert>
200b57cec5SDimitry Andric #include <cstddef>
210b57cec5SDimitry Andric #include <cstdint>
220b57cec5SDimitry Andric #include <cstring>
23bdd1243dSDimitry Andric #include <optional>
240b57cec5SDimitry Andric #include <string>
25fe6060f1SDimitry Andric #include <string_view>
260b57cec5SDimitry Andric #include <system_error>
27480093f4SDimitry Andric #include <type_traits>
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace llvm {
300b57cec5SDimitry Andric 
3104eeddc0SDimitry Andric class Duration;
320b57cec5SDimitry Andric class formatv_object_base;
330b57cec5SDimitry Andric class format_object_base;
340b57cec5SDimitry Andric class FormattedString;
350b57cec5SDimitry Andric class FormattedNumber;
360b57cec5SDimitry Andric class FormattedBytes;
37bdd1243dSDimitry Andric template <class T> class [[nodiscard]] Expected;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace sys {
400b57cec5SDimitry Andric namespace fs {
410b57cec5SDimitry Andric enum FileAccess : unsigned;
420b57cec5SDimitry Andric enum OpenFlags : unsigned;
430b57cec5SDimitry Andric enum CreationDisposition : unsigned;
44e8d8bef9SDimitry Andric class FileLocker;
450b57cec5SDimitry Andric } // end namespace fs
460b57cec5SDimitry Andric } // end namespace sys
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric /// This class implements an extremely fast bulk output stream that can *only*
490b57cec5SDimitry Andric /// output to a stream.  It does not support seeking, reopening, rewinding, line
500b57cec5SDimitry Andric /// buffered disciplines etc. It is a simple buffer that outputs
510b57cec5SDimitry Andric /// a chunk at a time.
520b57cec5SDimitry Andric class raw_ostream {
53e8d8bef9SDimitry Andric public:
54e8d8bef9SDimitry Andric   // Class kinds to support LLVM-style RTTI.
55e8d8bef9SDimitry Andric   enum class OStreamKind {
56e8d8bef9SDimitry Andric     OK_OStream,
57e8d8bef9SDimitry Andric     OK_FDStream,
58*0fca6ea1SDimitry Andric     OK_SVecStream,
59e8d8bef9SDimitry Andric   };
60e8d8bef9SDimitry Andric 
610b57cec5SDimitry Andric private:
62e8d8bef9SDimitry Andric   OStreamKind Kind;
63e8d8bef9SDimitry Andric 
640b57cec5SDimitry Andric   /// The buffer is handled in such a way that the buffer is
650b57cec5SDimitry Andric   /// uninitialized, unbuffered, or out of space when OutBufCur >=
660b57cec5SDimitry Andric   /// OutBufEnd. Thus a single comparison suffices to determine if we
670b57cec5SDimitry Andric   /// need to take the slow path to write a single character.
680b57cec5SDimitry Andric   ///
690b57cec5SDimitry Andric   /// The buffer is in one of three states:
700b57cec5SDimitry Andric   ///  1. Unbuffered (BufferMode == Unbuffered)
710b57cec5SDimitry Andric   ///  1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0).
720b57cec5SDimitry Andric   ///  2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 &&
730b57cec5SDimitry Andric   ///               OutBufEnd - OutBufStart >= 1).
740b57cec5SDimitry Andric   ///
750b57cec5SDimitry Andric   /// If buffered, then the raw_ostream owns the buffer if (BufferMode ==
760b57cec5SDimitry Andric   /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is
770b57cec5SDimitry Andric   /// managed by the subclass.
780b57cec5SDimitry Andric   ///
790b57cec5SDimitry Andric   /// If a subclass installs an external buffer using SetBuffer then it can wait
800b57cec5SDimitry Andric   /// for a \see write_impl() call to handle the data which has been put into
810b57cec5SDimitry Andric   /// this buffer.
820b57cec5SDimitry Andric   char *OutBufStart, *OutBufEnd, *OutBufCur;
835ffd83dbSDimitry Andric   bool ColorEnabled = false;
845ffd83dbSDimitry Andric 
85480093f4SDimitry Andric   enum class BufferKind {
860b57cec5SDimitry Andric     Unbuffered = 0,
870b57cec5SDimitry Andric     InternalBuffer,
880b57cec5SDimitry Andric     ExternalBuffer
890b57cec5SDimitry Andric   } BufferMode;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric public:
920b57cec5SDimitry Andric   // color order matches ANSI escape sequence, don't change
938bcb0991SDimitry Andric   enum class Colors {
940b57cec5SDimitry Andric     BLACK = 0,
950b57cec5SDimitry Andric     RED,
960b57cec5SDimitry Andric     GREEN,
970b57cec5SDimitry Andric     YELLOW,
980b57cec5SDimitry Andric     BLUE,
990b57cec5SDimitry Andric     MAGENTA,
1000b57cec5SDimitry Andric     CYAN,
1010b57cec5SDimitry Andric     WHITE,
102*0fca6ea1SDimitry Andric     BRIGHT_BLACK,
103*0fca6ea1SDimitry Andric     BRIGHT_RED,
104*0fca6ea1SDimitry Andric     BRIGHT_GREEN,
105*0fca6ea1SDimitry Andric     BRIGHT_YELLOW,
106*0fca6ea1SDimitry Andric     BRIGHT_BLUE,
107*0fca6ea1SDimitry Andric     BRIGHT_MAGENTA,
108*0fca6ea1SDimitry Andric     BRIGHT_CYAN,
109*0fca6ea1SDimitry Andric     BRIGHT_WHITE,
1108bcb0991SDimitry Andric     SAVEDCOLOR,
1118bcb0991SDimitry Andric     RESET,
1120b57cec5SDimitry Andric   };
1130b57cec5SDimitry Andric 
1145ffd83dbSDimitry Andric   static constexpr Colors BLACK = Colors::BLACK;
1155ffd83dbSDimitry Andric   static constexpr Colors RED = Colors::RED;
1165ffd83dbSDimitry Andric   static constexpr Colors GREEN = Colors::GREEN;
1175ffd83dbSDimitry Andric   static constexpr Colors YELLOW = Colors::YELLOW;
1185ffd83dbSDimitry Andric   static constexpr Colors BLUE = Colors::BLUE;
1195ffd83dbSDimitry Andric   static constexpr Colors MAGENTA = Colors::MAGENTA;
1205ffd83dbSDimitry Andric   static constexpr Colors CYAN = Colors::CYAN;
1215ffd83dbSDimitry Andric   static constexpr Colors WHITE = Colors::WHITE;
122*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_BLACK = Colors::BRIGHT_BLACK;
123*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_RED = Colors::BRIGHT_RED;
124*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_GREEN = Colors::BRIGHT_GREEN;
125*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_YELLOW = Colors::BRIGHT_YELLOW;
126*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_BLUE = Colors::BRIGHT_BLUE;
127*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_MAGENTA = Colors::BRIGHT_MAGENTA;
128*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_CYAN = Colors::BRIGHT_CYAN;
129*0fca6ea1SDimitry Andric   static constexpr Colors BRIGHT_WHITE = Colors::BRIGHT_WHITE;
1305ffd83dbSDimitry Andric   static constexpr Colors SAVEDCOLOR = Colors::SAVEDCOLOR;
1315ffd83dbSDimitry Andric   static constexpr Colors RESET = Colors::RESET;
1328bcb0991SDimitry Andric 
133e8d8bef9SDimitry Andric   explicit raw_ostream(bool unbuffered = false,
134e8d8bef9SDimitry Andric                        OStreamKind K = OStreamKind::OK_OStream)
Kind(K)135e8d8bef9SDimitry Andric       : Kind(K), BufferMode(unbuffered ? BufferKind::Unbuffered
136480093f4SDimitry Andric                                        : BufferKind::InternalBuffer) {
1370b57cec5SDimitry Andric     // Start out ready to flush.
1380b57cec5SDimitry Andric     OutBufStart = OutBufEnd = OutBufCur = nullptr;
1390b57cec5SDimitry Andric   }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   raw_ostream(const raw_ostream &) = delete;
1420b57cec5SDimitry Andric   void operator=(const raw_ostream &) = delete;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   virtual ~raw_ostream();
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   /// tell - Return the current offset with the file.
tell()1470b57cec5SDimitry Andric   uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
1480b57cec5SDimitry Andric 
get_kind()149e8d8bef9SDimitry Andric   OStreamKind get_kind() const { return Kind; }
150e8d8bef9SDimitry Andric 
1510b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
1520b57cec5SDimitry Andric   // Configuration Interface
1530b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
1540b57cec5SDimitry Andric 
155fe6060f1SDimitry Andric   /// If possible, pre-allocate \p ExtraSize bytes for stream data.
156fe6060f1SDimitry Andric   /// i.e. it extends internal buffers to keep additional ExtraSize bytes.
157fe6060f1SDimitry Andric   /// So that the stream could keep at least tell() + ExtraSize bytes
158fe6060f1SDimitry Andric   /// without re-allocations. reserveExtraSpace() does not change
159fe6060f1SDimitry Andric   /// the size/data of the stream.
reserveExtraSpace(uint64_t ExtraSize)160fe6060f1SDimitry Andric   virtual void reserveExtraSpace(uint64_t ExtraSize) {}
161fe6060f1SDimitry Andric 
1620b57cec5SDimitry Andric   /// Set the stream to be buffered, with an automatically determined buffer
1630b57cec5SDimitry Andric   /// size.
1640b57cec5SDimitry Andric   void SetBuffered();
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   /// Set the stream to be buffered, using the specified buffer size.
SetBufferSize(size_t Size)1670b57cec5SDimitry Andric   void SetBufferSize(size_t Size) {
1680b57cec5SDimitry Andric     flush();
169480093f4SDimitry Andric     SetBufferAndMode(new char[Size], Size, BufferKind::InternalBuffer);
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
GetBufferSize()1720b57cec5SDimitry Andric   size_t GetBufferSize() const {
1730b57cec5SDimitry Andric     // If we're supposed to be buffered but haven't actually gotten around
1740b57cec5SDimitry Andric     // to allocating the buffer yet, return the value that would be used.
175480093f4SDimitry Andric     if (BufferMode != BufferKind::Unbuffered && OutBufStart == nullptr)
1760b57cec5SDimitry Andric       return preferred_buffer_size();
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric     // Otherwise just return the size of the allocated buffer.
1790b57cec5SDimitry Andric     return OutBufEnd - OutBufStart;
1800b57cec5SDimitry Andric   }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   /// Set the stream to be unbuffered. When unbuffered, the stream will flush
1830b57cec5SDimitry Andric   /// after every write. This routine will also flush the buffer immediately
1840b57cec5SDimitry Andric   /// when the stream is being set to unbuffered.
SetUnbuffered()1850b57cec5SDimitry Andric   void SetUnbuffered() {
1860b57cec5SDimitry Andric     flush();
187480093f4SDimitry Andric     SetBufferAndMode(nullptr, 0, BufferKind::Unbuffered);
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric 
GetNumBytesInBuffer()1900b57cec5SDimitry Andric   size_t GetNumBytesInBuffer() const {
1910b57cec5SDimitry Andric     return OutBufCur - OutBufStart;
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
1950b57cec5SDimitry Andric   // Data Output Interface
1960b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
1970b57cec5SDimitry Andric 
flush()1980b57cec5SDimitry Andric   void flush() {
1990b57cec5SDimitry Andric     if (OutBufCur != OutBufStart)
2000b57cec5SDimitry Andric       flush_nonempty();
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   raw_ostream &operator<<(char C) {
2040b57cec5SDimitry Andric     if (OutBufCur >= OutBufEnd)
2050b57cec5SDimitry Andric       return write(C);
2060b57cec5SDimitry Andric     *OutBufCur++ = C;
2070b57cec5SDimitry Andric     return *this;
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   raw_ostream &operator<<(unsigned char C) {
2110b57cec5SDimitry Andric     if (OutBufCur >= OutBufEnd)
2120b57cec5SDimitry Andric       return write(C);
2130b57cec5SDimitry Andric     *OutBufCur++ = C;
2140b57cec5SDimitry Andric     return *this;
2150b57cec5SDimitry Andric   }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   raw_ostream &operator<<(signed char C) {
2180b57cec5SDimitry Andric     if (OutBufCur >= OutBufEnd)
2190b57cec5SDimitry Andric       return write(C);
2200b57cec5SDimitry Andric     *OutBufCur++ = C;
2210b57cec5SDimitry Andric     return *this;
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   raw_ostream &operator<<(StringRef Str) {
2250b57cec5SDimitry Andric     // Inline fast path, particularly for strings with a known length.
2260b57cec5SDimitry Andric     size_t Size = Str.size();
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric     // Make sure we can use the fast path.
2290b57cec5SDimitry Andric     if (Size > (size_t)(OutBufEnd - OutBufCur))
2300b57cec5SDimitry Andric       return write(Str.data(), Size);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     if (Size) {
2330b57cec5SDimitry Andric       memcpy(OutBufCur, Str.data(), Size);
2340b57cec5SDimitry Andric       OutBufCur += Size;
2350b57cec5SDimitry Andric     }
2360b57cec5SDimitry Andric     return *this;
2370b57cec5SDimitry Andric   }
2380b57cec5SDimitry Andric 
239bdd1243dSDimitry Andric #if defined(__cpp_char8_t)
240bdd1243dSDimitry Andric   // When using `char8_t *` integers or pointers are written to the ostream
241bdd1243dSDimitry Andric   // instead of UTF-8 code as one might expect. This might lead to unexpected
242bdd1243dSDimitry Andric   // behavior, especially as `u8""` literals are of type `char8_t*` instead of
243bdd1243dSDimitry Andric   // type `char_t*` from C++20 onwards. Thus we disallow using them with
244bdd1243dSDimitry Andric   // raw_ostreams.
245bdd1243dSDimitry Andric   // If you have u8"" literals to stream, you can rewrite them as ordinary
246bdd1243dSDimitry Andric   // literals with escape sequences
247bdd1243dSDimitry Andric   // e.g.  replace `u8"\u00a0"` by `"\xc2\xa0"`
248bdd1243dSDimitry Andric   // or use `reinterpret_cast`:
249bdd1243dSDimitry Andric   // e.g. replace `u8"\u00a0"` by `reinterpret_cast<const char *>(u8"\u00a0")`
250bdd1243dSDimitry Andric   raw_ostream &operator<<(const char8_t *Str) = delete;
251bdd1243dSDimitry Andric #endif
252bdd1243dSDimitry Andric 
2530b57cec5SDimitry Andric   raw_ostream &operator<<(const char *Str) {
2540b57cec5SDimitry Andric     // Inline fast path, particularly for constant strings where a sufficiently
2550b57cec5SDimitry Andric     // smart compiler will simplify strlen.
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric     return this->operator<<(StringRef(Str));
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   raw_ostream &operator<<(const std::string &Str) {
2610b57cec5SDimitry Andric     // Avoid the fast path, it would only increase code size for a marginal win.
2620b57cec5SDimitry Andric     return write(Str.data(), Str.length());
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
265fe6060f1SDimitry Andric   raw_ostream &operator<<(const std::string_view &Str) {
266fe6060f1SDimitry Andric     return write(Str.data(), Str.length());
267fe6060f1SDimitry Andric   }
268fe6060f1SDimitry Andric 
2690b57cec5SDimitry Andric   raw_ostream &operator<<(const SmallVectorImpl<char> &Str) {
2700b57cec5SDimitry Andric     return write(Str.data(), Str.size());
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   raw_ostream &operator<<(unsigned long N);
2740b57cec5SDimitry Andric   raw_ostream &operator<<(long N);
2750b57cec5SDimitry Andric   raw_ostream &operator<<(unsigned long long N);
2760b57cec5SDimitry Andric   raw_ostream &operator<<(long long N);
2770b57cec5SDimitry Andric   raw_ostream &operator<<(const void *P);
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   raw_ostream &operator<<(unsigned int N) {
2800b57cec5SDimitry Andric     return this->operator<<(static_cast<unsigned long>(N));
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   raw_ostream &operator<<(int N) {
2840b57cec5SDimitry Andric     return this->operator<<(static_cast<long>(N));
2850b57cec5SDimitry Andric   }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   raw_ostream &operator<<(double N);
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   /// Output \p N in hexadecimal, without any prefix or padding.
2900b57cec5SDimitry Andric   raw_ostream &write_hex(unsigned long long N);
2910b57cec5SDimitry Andric 
2928bcb0991SDimitry Andric   // Change the foreground color of text.
2938bcb0991SDimitry Andric   raw_ostream &operator<<(Colors C);
2948bcb0991SDimitry Andric 
2950b57cec5SDimitry Andric   /// Output a formatted UUID with dash separators.
2960b57cec5SDimitry Andric   using uuid_t = uint8_t[16];
2970b57cec5SDimitry Andric   raw_ostream &write_uuid(const uuid_t UUID);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
3000b57cec5SDimitry Andric   /// satisfy llvm::isPrint into an escape sequence.
3010b57cec5SDimitry Andric   raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   raw_ostream &write(unsigned char C);
3040b57cec5SDimitry Andric   raw_ostream &write(const char *Ptr, size_t Size);
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   // Formatted output, see the format() function in Support/Format.h.
3070b57cec5SDimitry Andric   raw_ostream &operator<<(const format_object_base &Fmt);
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   // Formatted output, see the leftJustify() function in Support/Format.h.
3100b57cec5SDimitry Andric   raw_ostream &operator<<(const FormattedString &);
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   // Formatted output, see the formatHex() function in Support/Format.h.
3130b57cec5SDimitry Andric   raw_ostream &operator<<(const FormattedNumber &);
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   // Formatted output, see the formatv() function in Support/FormatVariadic.h.
3160b57cec5SDimitry Andric   raw_ostream &operator<<(const formatv_object_base &);
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric   // Formatted output, see the format_bytes() function in Support/Format.h.
3190b57cec5SDimitry Andric   raw_ostream &operator<<(const FormattedBytes &);
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   /// indent - Insert 'NumSpaces' spaces.
3220b57cec5SDimitry Andric   raw_ostream &indent(unsigned NumSpaces);
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   /// write_zeros - Insert 'NumZeros' nulls.
3250b57cec5SDimitry Andric   raw_ostream &write_zeros(unsigned NumZeros);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   /// Changes the foreground color of text that will be output from this point
3280b57cec5SDimitry Andric   /// forward.
3290b57cec5SDimitry Andric   /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
3300b57cec5SDimitry Andric   /// change only the bold attribute, and keep colors untouched
3310b57cec5SDimitry Andric   /// @param Bold bold/brighter text, default false
3320b57cec5SDimitry Andric   /// @param BG if true change the background, default: change foreground
3330b57cec5SDimitry Andric   /// @returns itself so it can be used within << invocations
3345ffd83dbSDimitry Andric   virtual raw_ostream &changeColor(enum Colors Color, bool Bold = false,
3355ffd83dbSDimitry Andric                                    bool BG = false);
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   /// Resets the colors to terminal defaults. Call this when you are done
3380b57cec5SDimitry Andric   /// outputting colored text, or before program exit.
3395ffd83dbSDimitry Andric   virtual raw_ostream &resetColor();
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   /// Reverses the foreground and background colors.
3425ffd83dbSDimitry Andric   virtual raw_ostream &reverseColor();
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   /// This function determines if this stream is connected to a "tty" or
3450b57cec5SDimitry Andric   /// "console" window. That is, the output would be displayed to the user
3460b57cec5SDimitry Andric   /// rather than being put on a pipe or stored in a file.
is_displayed()3470b57cec5SDimitry Andric   virtual bool is_displayed() const { return false; }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   /// This function determines if this stream is displayed and supports colors.
3505ffd83dbSDimitry Andric   /// The result is unaffected by calls to enable_color().
has_colors()3510b57cec5SDimitry Andric   virtual bool has_colors() const { return is_displayed(); }
3520b57cec5SDimitry Andric 
3535ffd83dbSDimitry Andric   // Enable or disable colors. Once enable_colors(false) is called,
3545ffd83dbSDimitry Andric   // changeColor() has no effect until enable_colors(true) is called.
enable_colors(bool enable)3555ffd83dbSDimitry Andric   virtual void enable_colors(bool enable) { ColorEnabled = enable; }
3565ffd83dbSDimitry Andric 
colors_enabled()357349cc55cSDimitry Andric   bool colors_enabled() const { return ColorEnabled; }
358349cc55cSDimitry Andric 
3590b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
3600b57cec5SDimitry Andric   // Subclass Interface
3610b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric private:
3640b57cec5SDimitry Andric   /// The is the piece of the class that is implemented by subclasses.  This
3650b57cec5SDimitry Andric   /// writes the \p Size bytes starting at
3660b57cec5SDimitry Andric   /// \p Ptr to the underlying stream.
3670b57cec5SDimitry Andric   ///
3680b57cec5SDimitry Andric   /// This function is guaranteed to only be called at a point at which it is
3690b57cec5SDimitry Andric   /// safe for the subclass to install a new buffer via SetBuffer.
3700b57cec5SDimitry Andric   ///
3710b57cec5SDimitry Andric   /// \param Ptr The start of the data to be written. For buffered streams this
3720b57cec5SDimitry Andric   /// is guaranteed to be the start of the buffer.
3730b57cec5SDimitry Andric   ///
3740b57cec5SDimitry Andric   /// \param Size The number of bytes to be written.
3750b57cec5SDimitry Andric   ///
3760b57cec5SDimitry Andric   /// \invariant { Size > 0 }
3770b57cec5SDimitry Andric   virtual void write_impl(const char *Ptr, size_t Size) = 0;
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   /// Return the current position within the stream, not counting the bytes
3800b57cec5SDimitry Andric   /// currently in the buffer.
3810b57cec5SDimitry Andric   virtual uint64_t current_pos() const = 0;
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric protected:
3840b57cec5SDimitry Andric   /// Use the provided buffer as the raw_ostream buffer. This is intended for
3850b57cec5SDimitry Andric   /// use only by subclasses which can arrange for the output to go directly
3860b57cec5SDimitry Andric   /// into the desired output buffer, instead of being copied on each flush.
SetBuffer(char * BufferStart,size_t Size)3870b57cec5SDimitry Andric   void SetBuffer(char *BufferStart, size_t Size) {
388480093f4SDimitry Andric     SetBufferAndMode(BufferStart, Size, BufferKind::ExternalBuffer);
3890b57cec5SDimitry Andric   }
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   /// Return an efficient buffer size for the underlying output mechanism.
3920b57cec5SDimitry Andric   virtual size_t preferred_buffer_size() const;
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   /// Return the beginning of the current stream buffer, or 0 if the stream is
3950b57cec5SDimitry Andric   /// unbuffered.
getBufferStart()3960b57cec5SDimitry Andric   const char *getBufferStart() const { return OutBufStart; }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
3990b57cec5SDimitry Andric   // Private Interface
4000b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
4010b57cec5SDimitry Andric private:
4020b57cec5SDimitry Andric   /// Install the given buffer and mode.
4030b57cec5SDimitry Andric   void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   /// Flush the current buffer, which is known to be non-empty. This outputs the
4060b57cec5SDimitry Andric   /// currently buffered data and resets the buffer to empty.
4070b57cec5SDimitry Andric   void flush_nonempty();
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   /// Copy data into the buffer. Size must not be greater than the number of
4100b57cec5SDimitry Andric   /// unused bytes in the buffer.
4110b57cec5SDimitry Andric   void copy_to_buffer(const char *Ptr, size_t Size);
4120b57cec5SDimitry Andric 
4135ffd83dbSDimitry Andric   /// Compute whether colors should be used and do the necessary work such as
4145ffd83dbSDimitry Andric   /// flushing. The result is affected by calls to enable_color().
4155ffd83dbSDimitry Andric   bool prepare_colors();
4165ffd83dbSDimitry Andric 
4170b57cec5SDimitry Andric   virtual void anchor();
4180b57cec5SDimitry Andric };
4190b57cec5SDimitry Andric 
420480093f4SDimitry Andric /// Call the appropriate insertion operator, given an rvalue reference to a
421480093f4SDimitry Andric /// raw_ostream object and return a stream of the same type as the argument.
422480093f4SDimitry Andric template <typename OStream, typename T>
42306c3fb27SDimitry Andric std::enable_if_t<!std::is_reference_v<OStream> &&
42406c3fb27SDimitry Andric                      std::is_base_of_v<raw_ostream, OStream>,
4255ffd83dbSDimitry Andric                  OStream &&>
426480093f4SDimitry Andric operator<<(OStream &&OS, const T &Value) {
427480093f4SDimitry Andric   OS << Value;
428480093f4SDimitry Andric   return std::move(OS);
429480093f4SDimitry Andric }
430480093f4SDimitry Andric 
4310b57cec5SDimitry Andric /// An abstract base class for streams implementations that also support a
4320b57cec5SDimitry Andric /// pwrite operation. This is useful for code that can mostly stream out data,
4330b57cec5SDimitry Andric /// but needs to patch in a header that needs to know the output size.
4340b57cec5SDimitry Andric class raw_pwrite_stream : public raw_ostream {
4350b57cec5SDimitry Andric   virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0;
4360b57cec5SDimitry Andric   void anchor() override;
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric public:
439e8d8bef9SDimitry Andric   explicit raw_pwrite_stream(bool Unbuffered = false,
440e8d8bef9SDimitry Andric                              OStreamKind K = OStreamKind::OK_OStream)
raw_ostream(Unbuffered,K)441e8d8bef9SDimitry Andric       : raw_ostream(Unbuffered, K) {}
pwrite(const char * Ptr,size_t Size,uint64_t Offset)4420b57cec5SDimitry Andric   void pwrite(const char *Ptr, size_t Size, uint64_t Offset) {
4430b57cec5SDimitry Andric #ifndef NDEBUG
4440b57cec5SDimitry Andric     uint64_t Pos = tell();
4450b57cec5SDimitry Andric     // /dev/null always reports a pos of 0, so we cannot perform this check
4460b57cec5SDimitry Andric     // in that case.
4470b57cec5SDimitry Andric     if (Pos)
4480b57cec5SDimitry Andric       assert(Size + Offset <= Pos && "We don't support extending the stream");
4490b57cec5SDimitry Andric #endif
4500b57cec5SDimitry Andric     pwrite_impl(Ptr, Size, Offset);
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric };
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4550b57cec5SDimitry Andric // File Output Streams
4560b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric /// A raw_ostream that writes to a file descriptor.
4590b57cec5SDimitry Andric ///
4600b57cec5SDimitry Andric class raw_fd_ostream : public raw_pwrite_stream {
4610b57cec5SDimitry Andric   int FD;
4620b57cec5SDimitry Andric   bool ShouldClose;
463480093f4SDimitry Andric   bool SupportsSeeking = false;
46404eeddc0SDimitry Andric   bool IsRegularFile = false;
465bdd1243dSDimitry Andric   mutable std::optional<bool> HasColors;
4660b57cec5SDimitry Andric 
467*0fca6ea1SDimitry Andric   /// Optional stream this stream is tied to. If this stream is written to, the
468*0fca6ea1SDimitry Andric   /// tied-to stream will be flushed first.
469*0fca6ea1SDimitry Andric   raw_ostream *TiedStream = nullptr;
470*0fca6ea1SDimitry Andric 
4710b57cec5SDimitry Andric #ifdef _WIN32
4720b57cec5SDimitry Andric   /// True if this fd refers to a Windows console device. Mintty and other
4730b57cec5SDimitry Andric   /// terminal emulators are TTYs, but they are not consoles.
4740b57cec5SDimitry Andric   bool IsWindowsConsole = false;
4750b57cec5SDimitry Andric #endif
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   std::error_code EC;
4780b57cec5SDimitry Andric 
479480093f4SDimitry Andric   uint64_t pos = 0;
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   /// See raw_ostream::write_impl.
4820b57cec5SDimitry Andric   void write_impl(const char *Ptr, size_t Size) override;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric   /// Return the current position within the stream, not counting the bytes
4870b57cec5SDimitry Andric   /// currently in the buffer.
current_pos()4880b57cec5SDimitry Andric   uint64_t current_pos() const override { return pos; }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   /// Determine an efficient buffer size.
4910b57cec5SDimitry Andric   size_t preferred_buffer_size() const override;
4920b57cec5SDimitry Andric 
493e8d8bef9SDimitry Andric   void anchor() override;
494e8d8bef9SDimitry Andric 
495e8d8bef9SDimitry Andric protected:
4960b57cec5SDimitry Andric   /// Set the flag indicating that an output error has been encountered.
error_detected(std::error_code EC)4970b57cec5SDimitry Andric   void error_detected(std::error_code EC) { this->EC = EC; }
4980b57cec5SDimitry Andric 
499e8d8bef9SDimitry Andric   /// Return the file descriptor.
get_fd()500e8d8bef9SDimitry Andric   int get_fd() const { return FD; }
501e8d8bef9SDimitry Andric 
502e8d8bef9SDimitry Andric   // Update the file position by increasing \p Delta.
inc_pos(uint64_t Delta)503e8d8bef9SDimitry Andric   void inc_pos(uint64_t Delta) { pos += Delta; }
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric public:
5060b57cec5SDimitry Andric   /// Open the specified file for writing. If an error occurs, information
5070b57cec5SDimitry Andric   /// about the error is put into EC, and the stream should be immediately
5080b57cec5SDimitry Andric   /// destroyed;
5090b57cec5SDimitry Andric   /// \p Flags allows optional flags to control how the file will be opened.
5100b57cec5SDimitry Andric   ///
5110b57cec5SDimitry Andric   /// As a special case, if Filename is "-", then the stream will use
5120b57cec5SDimitry Andric   /// STDOUT_FILENO instead of opening a file. This will not close the stdout
5130b57cec5SDimitry Andric   /// descriptor.
5140b57cec5SDimitry Andric   raw_fd_ostream(StringRef Filename, std::error_code &EC);
5150b57cec5SDimitry Andric   raw_fd_ostream(StringRef Filename, std::error_code &EC,
5160b57cec5SDimitry Andric                  sys::fs::CreationDisposition Disp);
5170b57cec5SDimitry Andric   raw_fd_ostream(StringRef Filename, std::error_code &EC,
5180b57cec5SDimitry Andric                  sys::fs::FileAccess Access);
5190b57cec5SDimitry Andric   raw_fd_ostream(StringRef Filename, std::error_code &EC,
5200b57cec5SDimitry Andric                  sys::fs::OpenFlags Flags);
5210b57cec5SDimitry Andric   raw_fd_ostream(StringRef Filename, std::error_code &EC,
5220b57cec5SDimitry Andric                  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
5230b57cec5SDimitry Andric                  sys::fs::OpenFlags Flags);
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric   /// FD is the file descriptor that this writes to.  If ShouldClose is true,
5260b57cec5SDimitry Andric   /// this closes the file when the stream is destroyed. If FD is for stdout or
5270b57cec5SDimitry Andric   /// stderr, it will not be closed.
528e8d8bef9SDimitry Andric   raw_fd_ostream(int fd, bool shouldClose, bool unbuffered = false,
529e8d8bef9SDimitry Andric                  OStreamKind K = OStreamKind::OK_OStream);
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   ~raw_fd_ostream() override;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   /// Manually flush the stream and close the file. Note that this does not call
5340b57cec5SDimitry Andric   /// fsync.
5350b57cec5SDimitry Andric   void close();
5360b57cec5SDimitry Andric 
supportsSeeking()537e8d8bef9SDimitry Andric   bool supportsSeeking() const { return SupportsSeeking; }
5380b57cec5SDimitry Andric 
isRegularFile()53904eeddc0SDimitry Andric   bool isRegularFile() const { return IsRegularFile; }
54004eeddc0SDimitry Andric 
5410b57cec5SDimitry Andric   /// Flushes the stream and repositions the underlying file descriptor position
5420b57cec5SDimitry Andric   /// to the offset specified from the beginning of the file.
5430b57cec5SDimitry Andric   uint64_t seek(uint64_t off);
5440b57cec5SDimitry Andric 
5450b57cec5SDimitry Andric   bool is_displayed() const override;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   bool has_colors() const override;
5480b57cec5SDimitry Andric 
549*0fca6ea1SDimitry Andric   /// Tie this stream to the specified stream. Replaces any existing tied-to
550*0fca6ea1SDimitry Andric   /// stream. Specifying a nullptr unties the stream. This is intended for to
551*0fca6ea1SDimitry Andric   /// tie errs() to outs(), so that outs() is flushed whenever something is
552*0fca6ea1SDimitry Andric   /// written to errs(), preventing weird and hard-to-test output when stderr
553*0fca6ea1SDimitry Andric   /// is redirected to stdout.
tie(raw_ostream * TieTo)554*0fca6ea1SDimitry Andric   void tie(raw_ostream *TieTo) { TiedStream = TieTo; }
555*0fca6ea1SDimitry Andric 
error()5560b57cec5SDimitry Andric   std::error_code error() const { return EC; }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   /// Return the value of the flag in this raw_fd_ostream indicating whether an
5590b57cec5SDimitry Andric   /// output error has been encountered.
5600b57cec5SDimitry Andric   /// This doesn't implicitly flush any pending output.  Also, it doesn't
5610b57cec5SDimitry Andric   /// guarantee to detect all errors unless the stream has been closed.
has_error()5620b57cec5SDimitry Andric   bool has_error() const { return bool(EC); }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   /// Set the flag read by has_error() to false. If the error flag is set at the
5650b57cec5SDimitry Andric   /// time when this raw_ostream's destructor is called, report_fatal_error is
5660b57cec5SDimitry Andric   /// called to report the error. Use clear_error() after handling the error to
5670b57cec5SDimitry Andric   /// avoid this behavior.
5680b57cec5SDimitry Andric   ///
5690b57cec5SDimitry Andric   ///   "Errors should never pass silently.
5700b57cec5SDimitry Andric   ///    Unless explicitly silenced."
5710b57cec5SDimitry Andric   ///      - from The Zen of Python, by Tim Peters
5720b57cec5SDimitry Andric   ///
clear_error()5730b57cec5SDimitry Andric   void clear_error() { EC = std::error_code(); }
574e8d8bef9SDimitry Andric 
575e8d8bef9SDimitry Andric   /// Locks the underlying file.
576e8d8bef9SDimitry Andric   ///
577e8d8bef9SDimitry Andric   /// @returns RAII object that releases the lock upon leaving the scope, if the
578e8d8bef9SDimitry Andric   ///          locking was successful. Otherwise returns corresponding
579e8d8bef9SDimitry Andric   ///          error code.
580e8d8bef9SDimitry Andric   ///
581e8d8bef9SDimitry Andric   /// The function blocks the current thread until the lock become available or
582e8d8bef9SDimitry Andric   /// error occurs.
583e8d8bef9SDimitry Andric   ///
584e8d8bef9SDimitry Andric   /// Possible use of this function may be as follows:
585e8d8bef9SDimitry Andric   ///
586e8d8bef9SDimitry Andric   ///   @code{.cpp}
587e8d8bef9SDimitry Andric   ///   if (auto L = stream.lock()) {
588e8d8bef9SDimitry Andric   ///     // ... do action that require file to be locked.
589e8d8bef9SDimitry Andric   ///   } else {
590e8d8bef9SDimitry Andric   ///     handleAllErrors(std::move(L.takeError()), [&](ErrorInfoBase &EIB) {
591e8d8bef9SDimitry Andric   ///       // ... handle lock error.
592e8d8bef9SDimitry Andric   ///     });
593e8d8bef9SDimitry Andric   ///   }
594e8d8bef9SDimitry Andric   ///   @endcode
595bdd1243dSDimitry Andric   [[nodiscard]] Expected<sys::fs::FileLocker> lock();
596e8d8bef9SDimitry Andric 
597e8d8bef9SDimitry Andric   /// Tries to lock the underlying file within the specified period.
598e8d8bef9SDimitry Andric   ///
599e8d8bef9SDimitry Andric   /// @returns RAII object that releases the lock upon leaving the scope, if the
600e8d8bef9SDimitry Andric   ///          locking was successful. Otherwise returns corresponding
601e8d8bef9SDimitry Andric   ///          error code.
602e8d8bef9SDimitry Andric   ///
603e8d8bef9SDimitry Andric   /// It is used as @ref lock.
604bdd1243dSDimitry Andric   [[nodiscard]] Expected<sys::fs::FileLocker>
605bdd1243dSDimitry Andric   tryLockFor(Duration const &Timeout);
6060b57cec5SDimitry Andric };
6070b57cec5SDimitry Andric 
6085ffd83dbSDimitry Andric /// This returns a reference to a raw_fd_ostream for standard output. Use it
6095ffd83dbSDimitry Andric /// like: outs() << "foo" << "bar";
6105ffd83dbSDimitry Andric raw_fd_ostream &outs();
6110b57cec5SDimitry Andric 
6125ffd83dbSDimitry Andric /// This returns a reference to a raw_ostream for standard error.
6135ffd83dbSDimitry Andric /// Use it like: errs() << "foo" << "bar";
6145ffd83dbSDimitry Andric /// By default, the stream is tied to stdout to ensure stdout is flushed before
6155ffd83dbSDimitry Andric /// stderr is written, to ensure the error messages are written in their
6165ffd83dbSDimitry Andric /// expected place.
6175ffd83dbSDimitry Andric raw_fd_ostream &errs();
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric /// This returns a reference to a raw_ostream which simply discards output.
6200b57cec5SDimitry Andric raw_ostream &nulls();
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
623e8d8bef9SDimitry Andric // File Streams
624e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
625e8d8bef9SDimitry Andric 
626e8d8bef9SDimitry Andric /// A raw_ostream of a file for reading/writing/seeking.
627e8d8bef9SDimitry Andric ///
628e8d8bef9SDimitry Andric class raw_fd_stream : public raw_fd_ostream {
629e8d8bef9SDimitry Andric public:
630e8d8bef9SDimitry Andric   /// Open the specified file for reading/writing/seeking. If an error occurs,
631e8d8bef9SDimitry Andric   /// information about the error is put into EC, and the stream should be
632e8d8bef9SDimitry Andric   /// immediately destroyed.
633e8d8bef9SDimitry Andric   raw_fd_stream(StringRef Filename, std::error_code &EC);
634e8d8bef9SDimitry Andric 
6355f757f3fSDimitry Andric   raw_fd_stream(int fd, bool shouldClose);
6365f757f3fSDimitry Andric 
637e8d8bef9SDimitry Andric   /// This reads the \p Size bytes into a buffer pointed by \p Ptr.
638e8d8bef9SDimitry Andric   ///
639e8d8bef9SDimitry Andric   /// \param Ptr The start of the buffer to hold data to be read.
640e8d8bef9SDimitry Andric   ///
641e8d8bef9SDimitry Andric   /// \param Size The number of bytes to be read.
642e8d8bef9SDimitry Andric   ///
643e8d8bef9SDimitry Andric   /// On success, the number of bytes read is returned, and the file position is
644e8d8bef9SDimitry Andric   /// advanced by this number. On error, -1 is returned, use error() to get the
645e8d8bef9SDimitry Andric   /// error code.
646e8d8bef9SDimitry Andric   ssize_t read(char *Ptr, size_t Size);
647e8d8bef9SDimitry Andric 
648e8d8bef9SDimitry Andric   /// Check if \p OS is a pointer of type raw_fd_stream*.
649e8d8bef9SDimitry Andric   static bool classof(const raw_ostream *OS);
650e8d8bef9SDimitry Andric };
651e8d8bef9SDimitry Andric 
652e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
6530b57cec5SDimitry Andric // Output Stream Adaptors
6540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric /// A raw_ostream that writes to an std::string.  This is a simple adaptor
6570b57cec5SDimitry Andric /// class. This class does not encounter output errors.
65804eeddc0SDimitry Andric /// raw_string_ostream operates without a buffer, delegating all memory
65904eeddc0SDimitry Andric /// management to the std::string. Thus the std::string is always up-to-date,
66004eeddc0SDimitry Andric /// may be used directly and there is no need to call flush().
6610b57cec5SDimitry Andric class raw_string_ostream : public raw_ostream {
6620b57cec5SDimitry Andric   std::string &OS;
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric   /// See raw_ostream::write_impl.
6650b57cec5SDimitry Andric   void write_impl(const char *Ptr, size_t Size) override;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   /// Return the current position within the stream, not counting the bytes
6680b57cec5SDimitry Andric   /// currently in the buffer.
current_pos()6690b57cec5SDimitry Andric   uint64_t current_pos() const override { return OS.size(); }
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric public:
raw_string_ostream(std::string & O)6725ffd83dbSDimitry Andric   explicit raw_string_ostream(std::string &O) : OS(O) {
6735ffd83dbSDimitry Andric     SetUnbuffered();
6745ffd83dbSDimitry Andric   }
6750b57cec5SDimitry Andric 
67604eeddc0SDimitry Andric   /// Returns the string's reference. In most cases it is better to simply use
67704eeddc0SDimitry Andric   /// the underlying std::string directly.
67804eeddc0SDimitry Andric   /// TODO: Consider removing this API.
str()67904eeddc0SDimitry Andric   std::string &str() { return OS; }
680fe6060f1SDimitry Andric 
reserveExtraSpace(uint64_t ExtraSize)681fe6060f1SDimitry Andric   void reserveExtraSpace(uint64_t ExtraSize) override {
682fe6060f1SDimitry Andric     OS.reserve(tell() + ExtraSize);
683fe6060f1SDimitry Andric   }
6840b57cec5SDimitry Andric };
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric /// A raw_ostream that writes to an SmallVector or SmallString.  This is a
6870b57cec5SDimitry Andric /// simple adaptor class. This class does not encounter output errors.
6880b57cec5SDimitry Andric /// raw_svector_ostream operates without a buffer, delegating all memory
6890b57cec5SDimitry Andric /// management to the SmallString. Thus the SmallString is always up-to-date,
6900b57cec5SDimitry Andric /// may be used directly and there is no need to call flush().
6910b57cec5SDimitry Andric class raw_svector_ostream : public raw_pwrite_stream {
6920b57cec5SDimitry Andric   SmallVectorImpl<char> &OS;
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   /// See raw_ostream::write_impl.
6950b57cec5SDimitry Andric   void write_impl(const char *Ptr, size_t Size) override;
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   /// Return the current position within the stream.
7000b57cec5SDimitry Andric   uint64_t current_pos() const override;
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric public:
7030b57cec5SDimitry Andric   /// Construct a new raw_svector_ostream.
7040b57cec5SDimitry Andric   ///
7050b57cec5SDimitry Andric   /// \param O The vector to write to; this should generally have at least 128
7060b57cec5SDimitry Andric   /// bytes free to avoid any extraneous memory overhead.
raw_svector_ostream(SmallVectorImpl<char> & O)707*0fca6ea1SDimitry Andric   explicit raw_svector_ostream(SmallVectorImpl<char> &O)
708*0fca6ea1SDimitry Andric       : raw_pwrite_stream(false, raw_ostream::OStreamKind::OK_SVecStream),
709*0fca6ea1SDimitry Andric         OS(O) {
710*0fca6ea1SDimitry Andric     // FIXME: here and in a few other places, set directly to unbuffered in the
711*0fca6ea1SDimitry Andric     // ctor.
7120b57cec5SDimitry Andric     SetUnbuffered();
7130b57cec5SDimitry Andric   }
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric   ~raw_svector_ostream() override = default;
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric   void flush() = delete;
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   /// Return a StringRef for the vector contents.
str()7205ffd83dbSDimitry Andric   StringRef str() const { return StringRef(OS.data(), OS.size()); }
buffer()721*0fca6ea1SDimitry Andric   SmallVectorImpl<char> &buffer() { return OS; }
722fe6060f1SDimitry Andric 
reserveExtraSpace(uint64_t ExtraSize)723fe6060f1SDimitry Andric   void reserveExtraSpace(uint64_t ExtraSize) override {
724fe6060f1SDimitry Andric     OS.reserve(tell() + ExtraSize);
725fe6060f1SDimitry Andric   }
726*0fca6ea1SDimitry Andric 
727*0fca6ea1SDimitry Andric   static bool classof(const raw_ostream *OS);
7280b57cec5SDimitry Andric };
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric /// A raw_ostream that discards all output.
7310b57cec5SDimitry Andric class raw_null_ostream : public raw_pwrite_stream {
7320b57cec5SDimitry Andric   /// See raw_ostream::write_impl.
7330b57cec5SDimitry Andric   void write_impl(const char *Ptr, size_t size) override;
7340b57cec5SDimitry Andric   void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   /// Return the current position within the stream, not counting the bytes
7370b57cec5SDimitry Andric   /// currently in the buffer.
7380b57cec5SDimitry Andric   uint64_t current_pos() const override;
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric public:
7410b57cec5SDimitry Andric   explicit raw_null_ostream() = default;
7420b57cec5SDimitry Andric   ~raw_null_ostream() override;
7430b57cec5SDimitry Andric };
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric class buffer_ostream : public raw_svector_ostream {
7460b57cec5SDimitry Andric   raw_ostream &OS;
7470b57cec5SDimitry Andric   SmallVector<char, 0> Buffer;
7480b57cec5SDimitry Andric 
749972a253aSDimitry Andric   void anchor() override;
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric public:
buffer_ostream(raw_ostream & OS)7520b57cec5SDimitry Andric   buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {}
~buffer_ostream()7530b57cec5SDimitry Andric   ~buffer_ostream() override { OS << str(); }
7540b57cec5SDimitry Andric };
7550b57cec5SDimitry Andric 
756e8d8bef9SDimitry Andric class buffer_unique_ostream : public raw_svector_ostream {
757e8d8bef9SDimitry Andric   std::unique_ptr<raw_ostream> OS;
758e8d8bef9SDimitry Andric   SmallVector<char, 0> Buffer;
759e8d8bef9SDimitry Andric 
760972a253aSDimitry Andric   void anchor() override;
761e8d8bef9SDimitry Andric 
762e8d8bef9SDimitry Andric public:
buffer_unique_ostream(std::unique_ptr<raw_ostream> OS)763e8d8bef9SDimitry Andric   buffer_unique_ostream(std::unique_ptr<raw_ostream> OS)
764349cc55cSDimitry Andric       : raw_svector_ostream(Buffer), OS(std::move(OS)) {
765349cc55cSDimitry Andric     // Turn off buffering on OS, which we now own, to avoid allocating a buffer
766349cc55cSDimitry Andric     // when the destructor writes only to be immediately flushed again.
767349cc55cSDimitry Andric     this->OS->SetUnbuffered();
768349cc55cSDimitry Andric   }
~buffer_unique_ostream()769e8d8bef9SDimitry Andric   ~buffer_unique_ostream() override { *OS << str(); }
770e8d8bef9SDimitry Andric };
771e8d8bef9SDimitry Andric 
772fe6060f1SDimitry Andric class Error;
773fe6060f1SDimitry Andric 
774fe6060f1SDimitry Andric /// This helper creates an output stream and then passes it to \p Write.
775fe6060f1SDimitry Andric /// The stream created is based on the specified \p OutputFileName:
776fe6060f1SDimitry Andric /// llvm::outs for "-", raw_null_ostream for "/dev/null", and raw_fd_ostream
777fe6060f1SDimitry Andric /// for other names. For raw_fd_ostream instances, the stream writes to
778fe6060f1SDimitry Andric /// a temporary file. The final output file is atomically replaced with the
779fe6060f1SDimitry Andric /// temporary file after the \p Write function is finished.
780fe6060f1SDimitry Andric Error writeToOutput(StringRef OutputFileName,
781fe6060f1SDimitry Andric                     std::function<Error(raw_ostream &)> Write);
782fe6060f1SDimitry Andric 
783bdd1243dSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
784bdd1243dSDimitry Andric 
785bdd1243dSDimitry Andric template <typename T, typename = decltype(std::declval<raw_ostream &>()
786bdd1243dSDimitry Andric                                           << std::declval<const T &>())>
787bdd1243dSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const std::optional<T> &O) {
788bdd1243dSDimitry Andric   if (O)
789bdd1243dSDimitry Andric     OS << *O;
790bdd1243dSDimitry Andric   else
791bdd1243dSDimitry Andric     OS << std::nullopt;
792bdd1243dSDimitry Andric   return OS;
793bdd1243dSDimitry Andric }
794bdd1243dSDimitry Andric 
7950b57cec5SDimitry Andric } // end namespace llvm
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric #endif // LLVM_SUPPORT_RAW_OSTREAM_H
798