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