LLVM 22.0.0git
raw_ostream.cpp
Go to the documentation of this file.
1//===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements support for bulk buffered stream output.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/Config/config.h"
21#include "llvm/Support/Format.h"
28#include <algorithm>
29#include <cerrno>
30#include <cstdio>
31#include <sys/stat.h>
32
33// <fcntl.h> may provide O_BINARY.
34# include <fcntl.h>
35
36#if defined(HAVE_UNISTD_H)
37# include <unistd.h>
38#endif
39
40#if defined(__CYGWIN__)
41#include <io.h>
42#endif
43
44#if defined(_MSC_VER)
45#include <io.h>
46#ifndef STDIN_FILENO
47# define STDIN_FILENO 0
48#endif
49#ifndef STDOUT_FILENO
50# define STDOUT_FILENO 1
51#endif
52#ifndef STDERR_FILENO
53# define STDERR_FILENO 2
54#endif
55#endif
56
57#ifdef _WIN32
61#endif
62
63using namespace llvm;
64
66 // raw_ostream's subclasses should take care to flush the buffer
67 // in their destructors.
68 assert(OutBufCur == OutBufStart &&
69 "raw_ostream destructor called with non-empty buffer!");
70
71 if (BufferMode == BufferKind::InternalBuffer)
72 delete [] OutBufStart;
73}
74
76#ifdef _WIN32
77 // On Windows BUFSIZ is only 512 which results in more calls to write. This
78 // overhead can cause significant performance degradation. Therefore use a
79 // better default.
80 return (16 * 1024);
81#else
82 // BUFSIZ is intended to be a reasonable default.
83 return BUFSIZ;
84#endif
85}
86
88 // Ask the subclass to determine an appropriate buffer size.
89 if (size_t Size = preferred_buffer_size())
91 else
92 // It may return 0, meaning this stream should be unbuffered.
94}
95
96void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
97 BufferKind Mode) {
98 assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
99 (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
100 "stream must be unbuffered or have at least one byte");
101 // Make sure the current buffer is free of content (we can't flush here; the
102 // child buffer management logic will be in write_impl).
103 assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
104
105 if (BufferMode == BufferKind::InternalBuffer)
106 delete [] OutBufStart;
107 OutBufStart = BufferStart;
108 OutBufEnd = OutBufStart+Size;
109 OutBufCur = OutBufStart;
110 BufferMode = Mode;
111
112 assert(OutBufStart <= OutBufEnd && "Invalid size!");
113}
114
116 write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
117 return *this;
118}
119
121 write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
122 return *this;
123}
124
126 write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
127 return *this;
128}
129
131 write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
132 return *this;
133}
134
137 return *this;
138}
139
141 if (C == Colors::RESET)
142 resetColor();
143 else
144 changeColor(C);
145 return *this;
146}
147
149 for (int Idx = 0; Idx < 16; ++Idx) {
150 *this << format("%02" PRIX32, UUID[Idx]);
151 if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
152 *this << "-";
153 }
154 return *this;
155}
156
157
159 bool UseHexEscapes) {
160 for (unsigned char c : Str) {
161 switch (c) {
162 case '\\':
163 *this << '\\' << '\\';
164 break;
165 case '\t':
166 *this << '\\' << 't';
167 break;
168 case '\n':
169 *this << '\\' << 'n';
170 break;
171 case '"':
172 *this << '\\' << '"';
173 break;
174 default:
175 if (isPrint(c)) {
176 *this << c;
177 break;
178 }
179
180 // Write out the escaped representation.
181 if (UseHexEscapes) {
182 *this << '\\' << 'x';
183 *this << hexdigit((c >> 4) & 0xF);
184 *this << hexdigit((c >> 0) & 0xF);
185 } else {
186 // Always use a full 3-character octal escape.
187 *this << '\\';
188 *this << char('0' + ((c >> 6) & 7));
189 *this << char('0' + ((c >> 3) & 7));
190 *this << char('0' + ((c >> 0) & 7));
191 }
192 }
193 }
194
195 return *this;
196}
197
199 llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
200 return *this;
201}
202
205 return *this;
206}
207
208void raw_ostream::flush_nonempty() {
209 assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
210 size_t Length = OutBufCur - OutBufStart;
211 OutBufCur = OutBufStart;
212 write_impl(OutBufStart, Length);
213}
214
216 // Group exceptional cases into a single branch.
217 if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
218 if (LLVM_UNLIKELY(!OutBufStart)) {
219 if (BufferMode == BufferKind::Unbuffered) {
220 write_impl(reinterpret_cast<char *>(&C), 1);
221 return *this;
222 }
223 // Set up a buffer and start over.
224 SetBuffered();
225 return write(C);
226 }
227
228 flush_nonempty();
229 }
230
231 *OutBufCur++ = C;
232 return *this;
233}
234
235raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
236 // Group exceptional cases into a single branch.
237 if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
238 if (LLVM_UNLIKELY(!OutBufStart)) {
239 if (BufferMode == BufferKind::Unbuffered) {
240 write_impl(Ptr, Size);
241 return *this;
242 }
243 // Set up a buffer and start over.
244 SetBuffered();
245 return write(Ptr, Size);
246 }
247
248 size_t NumBytes = OutBufEnd - OutBufCur;
249
250 // If the buffer is empty at this point we have a string that is larger
251 // than the buffer. Directly write the chunk that is a multiple of the
252 // preferred buffer size and put the remainder in the buffer.
253 if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
254 assert(NumBytes != 0 && "undefined behavior");
255 size_t BytesToWrite = Size - (Size % NumBytes);
256 write_impl(Ptr, BytesToWrite);
257 size_t BytesRemaining = Size - BytesToWrite;
258 if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
259 // Too much left over to copy into our buffer.
260 return write(Ptr + BytesToWrite, BytesRemaining);
261 }
262 copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
263 return *this;
264 }
265
266 // We don't have enough space in the buffer to fit the string in. Insert as
267 // much as possible, flush and start over with the remainder.
268 copy_to_buffer(Ptr, NumBytes);
269 flush_nonempty();
270 return write(Ptr + NumBytes, Size - NumBytes);
271 }
272
273 copy_to_buffer(Ptr, Size);
274
275 return *this;
276}
277
278void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
279 assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
280
281 // Handle short strings specially, memcpy isn't very good at very short
282 // strings.
283 switch (Size) {
284 case 4: OutBufCur[3] = Ptr[3]; [[fallthrough]];
285 case 3: OutBufCur[2] = Ptr[2]; [[fallthrough]];
286 case 2: OutBufCur[1] = Ptr[1]; [[fallthrough]];
287 case 1: OutBufCur[0] = Ptr[0]; [[fallthrough]];
288 case 0: break;
289 default:
290 memcpy(OutBufCur, Ptr, Size);
291 break;
292 }
293
294 OutBufCur += Size;
295}
296
297// Formatted output.
299 // If we have more than a few bytes left in our output buffer, try
300 // formatting directly onto its end.
301 size_t NextBufferSize = 127;
302 size_t BufferBytesLeft = OutBufEnd - OutBufCur;
303 if (BufferBytesLeft > 3) {
304 size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
305
306 // Common case is that we have plenty of space.
307 if (BytesUsed <= BufferBytesLeft) {
308 OutBufCur += BytesUsed;
309 return *this;
310 }
311
312 // Otherwise, we overflowed and the return value tells us the size to try
313 // again with.
314 NextBufferSize = BytesUsed;
315 }
316
317 // If we got here, we didn't have enough space in the output buffer for the
318 // string. Try printing into a SmallVector that is resized to have enough
319 // space. Iterate until we win.
321
322 while (true) {
323 V.resize(NextBufferSize);
324
325 // Try formatting into the SmallVector.
326 size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
327
328 // If BytesUsed fit into the vector, we win.
329 if (BytesUsed <= NextBufferSize)
330 return write(V.data(), BytesUsed);
331
332 // Otherwise, try again with a new size.
333 assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
334 NextBufferSize = BytesUsed;
335 }
336}
337
339 Obj.format(*this);
340 return *this;
341}
342
344 unsigned LeftIndent = 0;
345 unsigned RightIndent = 0;
346 const ssize_t Difference = FS.Width - FS.Str.size();
347 if (Difference > 0) {
348 switch (FS.Justify) {
350 break;
352 RightIndent = Difference;
353 break;
355 LeftIndent = Difference;
356 break;
358 LeftIndent = Difference / 2;
359 RightIndent = Difference - LeftIndent;
360 break;
361 }
362 }
363 indent(LeftIndent);
364 (*this) << FS.Str;
365 indent(RightIndent);
366 return *this;
367}
368
370 if (FN.Hex) {
371 HexPrintStyle Style;
372 if (FN.Upper && FN.HexPrefix)
374 else if (FN.Upper && !FN.HexPrefix)
375 Style = HexPrintStyle::Upper;
376 else if (!FN.Upper && FN.HexPrefix)
378 else
379 Style = HexPrintStyle::Lower;
380 llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
381 } else {
383 llvm::raw_svector_ostream Stream(Buffer);
384 llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
385 if (Buffer.size() < FN.Width)
386 indent(FN.Width - Buffer.size());
387 (*this) << Buffer;
388 }
389 return *this;
390}
391
393 if (FB.Bytes.empty())
394 return *this;
395
396 size_t LineIndex = 0;
397 auto Bytes = FB.Bytes;
398 const size_t Size = Bytes.size();
400 uint64_t OffsetWidth = 0;
401 if (FB.FirstByteOffset) {
402 // Figure out how many nibbles are needed to print the largest offset
403 // represented by this data set, so that we can align the offset field
404 // to the right width.
405 size_t Lines = Size / FB.NumPerLine;
406 uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
407 unsigned Power = 0;
408 if (MaxOffset > 0)
409 Power = llvm::Log2_64_Ceil(MaxOffset);
410 OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
411 }
412
413 // The width of a block of data including all spaces for group separators.
414 unsigned NumByteGroups =
415 alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
416 unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
417
418 while (!Bytes.empty()) {
419 indent(FB.IndentLevel);
420
421 if (FB.FirstByteOffset) {
422 uint64_t Offset = *FB.FirstByteOffset;
423 llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
424 *this << ": ";
425 }
426
427 auto Line = Bytes.take_front(FB.NumPerLine);
428
429 size_t CharsPrinted = 0;
430 // Print the hex bytes for this line in groups
431 for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
432 if (I && (I % FB.ByteGroupSize) == 0) {
433 ++CharsPrinted;
434 *this << " ";
435 }
436 llvm::write_hex(*this, Line[I], HPS, 2);
437 }
438
439 if (FB.ASCII) {
440 // Print any spaces needed for any bytes that we didn't print on this
441 // line so that the ASCII bytes are correctly aligned.
442 assert(BlockCharWidth >= CharsPrinted);
443 indent(BlockCharWidth - CharsPrinted + 2);
444 *this << "|";
445
446 // Print the ASCII char values for each byte on this line
447 for (uint8_t Byte : Line) {
448 if (isPrint(Byte))
449 *this << static_cast<char>(Byte);
450 else
451 *this << '.';
452 }
453 *this << '|';
454 }
455
456 Bytes = Bytes.drop_front(Line.size());
457 LineIndex += Line.size();
458 if (LineIndex < Size)
459 *this << '\n';
460 }
461 return *this;
462}
463
464template <char C>
465static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
466 static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
467 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
468 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
469 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
470 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
471
472 // Usually the indentation is small, handle it with a fastpath.
473 if (NumChars < std::size(Chars))
474 return OS.write(Chars, NumChars);
475
476 while (NumChars) {
477 unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1);
478 OS.write(Chars, NumToWrite);
479 NumChars -= NumToWrite;
480 }
481 return OS;
482}
483
484/// indent - Insert 'NumSpaces' spaces.
485raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
486 return write_padding<' '>(*this, NumSpaces);
487}
488
489/// write_zeros - Insert 'NumZeros' nulls.
491 return write_padding<'\0'>(*this, NumZeros);
492}
493
494bool raw_ostream::prepare_colors() {
495 // Colors were explicitly disabled.
496 if (!ColorEnabled)
497 return false;
498
499 // Colors require changing the terminal but this stream is not going to a
500 // terminal.
502 return false;
503
505 flush();
506
507 return true;
508}
509
510raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
511 if (!prepare_colors())
512 return *this;
513
514 const char *colorcode =
515 (colors == SAVEDCOLOR)
517 : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
518 if (colorcode)
519 write(colorcode, strlen(colorcode));
520 return *this;
521}
522
524 if (!prepare_colors())
525 return *this;
526
527 if (const char *colorcode = sys::Process::ResetColor())
528 write(colorcode, strlen(colorcode));
529 return *this;
530}
531
533 if (!prepare_colors())
534 return *this;
535
536 if (const char *colorcode = sys::Process::OutputReverse())
537 write(colorcode, strlen(colorcode));
538 return *this;
539}
540
541void raw_ostream::anchor() {}
542
543//===----------------------------------------------------------------------===//
544// Formatted Output
545//===----------------------------------------------------------------------===//
546
547// Out of line virtual method.
550
551//===----------------------------------------------------------------------===//
552// raw_fd_ostream
553//===----------------------------------------------------------------------===//
554
555static int getFD(StringRef Filename, std::error_code &EC,
557 sys::fs::OpenFlags Flags) {
558 // FIXME(sandboxing): Remove this by adopting `llvm::vfs::OutputBackend`.
559 auto BypassSandbox = sys::sandbox::scopedDisable();
560
562 "Cannot make a raw_ostream from a read-only descriptor!");
563
564 // Handle "-" as stdout. Note that when we do this, we consider ourself
565 // the owner of stdout and may set the "binary" flag globally based on Flags.
566 if (Filename == "-") {
567 EC = std::error_code();
568 // Change stdout's text/binary mode based on the Flags.
570 return STDOUT_FILENO;
571 }
572
573 int FD;
575 EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
576 else
577 EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
578 if (EC)
579 return -1;
580
581 return FD;
582}
583
584raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
585 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
586 sys::fs::OF_None) {}
587
588raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
590 : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
591
592raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
594 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
595 sys::fs::OF_None) {}
596
597raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
598 sys::fs::OpenFlags Flags)
599 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
600 Flags) {}
601
602raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
605 sys::fs::OpenFlags Flags)
606 : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
607
608/// FD is the file descriptor that this writes to. If ShouldClose is true, this
609/// closes the file when the stream is destroyed.
610raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
611 OStreamKind K)
612 : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
613 // FIXME(sandboxing): Remove this by adopting `llvm::vfs::OutputBackend`.
614 auto BypassSandbox = sys::sandbox::scopedDisable();
615
616 if (FD < 0 ) {
617 ShouldClose = false;
618 return;
619 }
620
621 enable_colors(true);
622
623 // Do not attempt to close stdout or stderr. We used to try to maintain the
624 // property that tools that support writing file to stdout should not also
625 // write informational output to stdout, but in practice we were never able to
626 // maintain this invariant. Many features have been added to LLVM and clang
627 // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
628 // users must simply be aware that mixed output and remarks is a possibility.
629 if (FD <= STDERR_FILENO)
630 ShouldClose = false;
631
632#ifdef _WIN32
633 // Check if this is a console device. This is not equivalent to isatty.
634 IsWindowsConsole =
635 ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
636#endif
637
638 // Get the starting position.
639 off_t loc = ::lseek(FD, 0, SEEK_CUR);
641 std::error_code EC = status(FD, Status);
642 IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
643#ifdef _WIN32
644 // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
645 SupportsSeeking = !EC && IsRegularFile;
646#else
647 SupportsSeeking = !EC && loc != (off_t)-1;
648#endif
649 if (!SupportsSeeking)
650 pos = 0;
651 else
652 pos = static_cast<uint64_t>(loc);
653}
654
656 if (FD >= 0) {
657 flush();
658 if (ShouldClose) {
660 error_detected(EC);
661 }
662 }
663
664#ifdef __MINGW32__
665 // On mingw, global dtors should not call exit().
666 // report_fatal_error() invokes exit(). We know report_fatal_error()
667 // might not write messages to stderr when any errors were detected
668 // on FD == 2.
669 if (FD == 2) return;
670#endif
671
672 // If there are any pending errors, report them now. Clients wishing
673 // to avoid report_fatal_error calls should check for errors with
674 // has_error() and clear the error flag with clear_error() before
675 // destructing raw_ostream objects which may have errors.
676 if (has_error())
677 reportFatalUsageError(Twine("IO failure on output stream: ") +
678 error().message());
679}
680
681#if defined(_WIN32)
682// The most reliable way to print unicode in a Windows console is with
683// WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
684// assumes that LLVM programs always print valid UTF-8 to the console. The data
685// might not be UTF-8 for two major reasons:
686// 1. The program is printing binary (-filetype=obj -o -), in which case it
687// would have been gibberish anyway.
688// 2. The program is printing text in a semi-ascii compatible codepage like
689// shift-jis or cp1252.
690//
691// Most LLVM programs don't produce non-ascii text unless they are quoting
692// user source input. A well-behaved LLVM program should either validate that
693// the input is UTF-8 or transcode from the local codepage to UTF-8 before
694// quoting it. If they don't, this may mess up the encoding, but this is still
695// probably the best compromise we can make.
696static bool write_console_impl(int FD, StringRef Data) {
698
699 // Fall back to ::write if it wasn't valid UTF-8.
700 if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
701 return false;
702
703 // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
704 // that can be written to the console at a time.
705 size_t MaxWriteSize = WideText.size();
707 MaxWriteSize = 32767;
708
709 size_t WCharsWritten = 0;
710 do {
711 size_t WCharsToWrite =
712 std::min(MaxWriteSize, WideText.size() - WCharsWritten);
713 DWORD ActuallyWritten;
714 bool Success =
715 ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
716 WCharsToWrite, &ActuallyWritten,
717 /*Reserved=*/nullptr);
718
719 // The most likely reason for WriteConsoleW to fail is that FD no longer
720 // points to a console. Fall back to ::write. If this isn't the first loop
721 // iteration, something is truly wrong.
722 if (!Success)
723 return false;
724
725 WCharsWritten += ActuallyWritten;
726 } while (WCharsWritten != WideText.size());
727 return true;
728}
729#endif
730
731void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
732 if (TiedStream)
733 TiedStream->flush();
734
735 assert(FD >= 0 && "File already closed.");
736 pos += Size;
737
738#if defined(_WIN32)
739 // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
740 // and using WriteConsoleW. If that fails, fall back to plain write().
741 if (IsWindowsConsole)
742 if (write_console_impl(FD, StringRef(Ptr, Size)))
743 return;
744#endif
745
746 // The maximum write size is limited to INT32_MAX. A write
747 // greater than SSIZE_MAX is implementation-defined in POSIX,
748 // and Windows _write requires 32 bit input.
749 size_t MaxWriteSize = INT32_MAX;
750
751#if defined(__linux__)
752 // It is observed that Linux returns EINVAL for a very large write (>2G).
753 // Make it a reasonably small value.
754 MaxWriteSize = 1024 * 1024 * 1024;
755#endif
756
757 do {
758 size_t ChunkSize = std::min(Size, MaxWriteSize);
759 ssize_t ret = ::write(FD, Ptr, ChunkSize);
760
761 if (ret < 0) {
762 // If it's a recoverable error, swallow it and retry the write.
763 //
764 // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
765 // raw_ostream isn't designed to do non-blocking I/O. However, some
766 // programs, such as old versions of bjam, have mistakenly used
767 // O_NONBLOCK. For compatibility, emulate blocking semantics by
768 // spinning until the write succeeds. If you don't want spinning,
769 // don't use O_NONBLOCK file descriptors with raw_ostream.
770 if (errno == EINTR || errno == EAGAIN
771#ifdef EWOULDBLOCK
772 || errno == EWOULDBLOCK
773#endif
774 )
775 continue;
776
777#ifdef _WIN32
778 // Windows equivalents of SIGPIPE/EPIPE.
779 DWORD WinLastError = GetLastError();
780 if (WinLastError == ERROR_BROKEN_PIPE ||
781 (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
782 llvm::sys::CallOneShotPipeSignalHandler();
783 errno = EPIPE;
784 }
785#endif
786 // Otherwise it's a non-recoverable error. Note it and quit.
788 break;
789 }
790
791 // The write may have written some or all of the data. Update the
792 // size and buffer pointer to reflect the remainder that needs
793 // to be written. If there are no bytes left, we're done.
794 Ptr += ret;
795 Size -= ret;
796 } while (Size > 0);
797}
798
800 assert(ShouldClose);
801 ShouldClose = false;
802 flush();
804 error_detected(EC);
805 FD = -1;
806}
807
809 assert(SupportsSeeking && "Stream does not support seeking!");
810 flush();
811#ifdef _WIN32
812 pos = ::_lseeki64(FD, off, SEEK_SET);
813#else
814 pos = ::lseek(FD, off, SEEK_SET);
815#endif
816 if (pos == (uint64_t)-1)
818 return pos;
819}
820
821void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
823 uint64_t Pos = tell();
824 seek(Offset);
825 write(Ptr, Size);
826 seek(Pos);
827}
828
830#if defined(_WIN32)
831 // Disable buffering for console devices. Console output is re-encoded from
832 // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
833 // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
834 // below on most other OSs, so do the same thing on Windows and avoid that
835 // complexity.
836 if (IsWindowsConsole)
837 return 0;
839#elif defined(__MVS__)
840 // The buffer size on z/OS is defined with macro BUFSIZ, which can be
841 // retrieved by invoking function raw_ostream::preferred_buffer_size().
843#else
844 assert(FD >= 0 && "File not yet open!");
845 struct stat statbuf;
846 if (fstat(FD, &statbuf) != 0)
847 return 0;
848
849 // If this is a terminal, don't use buffering. Line buffering
850 // would be a more traditional thing to do, but it's not worth
851 // the complexity.
852 if (S_ISCHR(statbuf.st_mode) && is_displayed())
853 return 0;
854 // Return the preferred block size.
855 return statbuf.st_blksize;
856#endif
857}
858
862
864 if (!HasColors)
866 return *HasColors;
867}
868
870 std::error_code EC = sys::fs::lockFile(FD);
871 if (!EC)
872 return sys::fs::FileLocker(FD);
873 return errorCodeToError(EC);
874}
875
878 std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
879 if (!EC)
880 return sys::fs::FileLocker(FD);
881 return errorCodeToError(EC);
882}
883
884void raw_fd_ostream::anchor() {}
885
886//===----------------------------------------------------------------------===//
887// outs(), errs(), nulls()
888//===----------------------------------------------------------------------===//
889
891 // Set buffer settings to model stdout behavior.
892 std::error_code EC;
893
894 // On z/OS we need to enable auto conversion
895 static std::error_code EC1 = enableAutoConversion(STDOUT_FILENO);
896 assert(!EC1);
897 (void)EC1;
898
899 static raw_fd_ostream S("-", EC, sys::fs::OF_None);
900 assert(!EC);
901 return S;
902}
903
905 // On z/OS we need to enable auto conversion
906 static std::error_code EC = enableAutoConversion(STDERR_FILENO);
907 assert(!EC);
908 (void)EC;
909
910 // Set standard error to be unbuffered.
911 static raw_fd_ostream S(STDERR_FILENO, false, true);
912 return S;
913}
914
915/// nulls() - This returns a reference to a raw_ostream which discards output.
917 static raw_null_ostream S;
918 return S;
919}
920
921//===----------------------------------------------------------------------===//
922// File Streams
923//===----------------------------------------------------------------------===//
924
925raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
926 : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
927 sys::fs::FA_Write | sys::fs::FA_Read,
928 sys::fs::OF_None),
930 if (EC)
931 return;
932
933 if (!isRegularFile())
934 EC = std::make_error_code(std::errc::invalid_argument);
935}
936
937raw_fd_stream::raw_fd_stream(int fd, bool shouldClose)
938 : raw_fd_ostream(fd, shouldClose, false, OStreamKind::OK_FDStream) {}
939
940ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
941 assert(get_fd() >= 0 && "File already closed.");
942 ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
943 if (Ret >= 0)
944 inc_pos(Ret);
945 else
947 return Ret;
948}
949
951 return OS->get_kind() == OStreamKind::OK_FDStream;
952}
953
954//===----------------------------------------------------------------------===//
955// raw_string_ostream
956//===----------------------------------------------------------------------===//
957
958void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
959 OS.append(Ptr, Size);
960}
961
962//===----------------------------------------------------------------------===//
963// raw_svector_ostream
964//===----------------------------------------------------------------------===//
965
966uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
967
968void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
969 OS.append(Ptr, Ptr + Size);
970}
971
972void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
973 uint64_t Offset) {
974 memcpy(OS.data() + Offset, Ptr, Size);
975}
976
978 return OS->get_kind() == OStreamKind::OK_SVecStream;
979}
980
981//===----------------------------------------------------------------------===//
982// raw_null_ostream
983//===----------------------------------------------------------------------===//
984
986#ifndef NDEBUG
987 // ~raw_ostream asserts that the buffer is empty. This isn't necessary
988 // with raw_null_ostream, but it's better to have raw_null_ostream follow
989 // the rules than to change the rules just for raw_null_ostream.
990 flush();
991#endif
992}
993
994void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
995}
996
997uint64_t raw_null_ostream::current_pos() const {
998 return 0;
999}
1000
1001void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
1002 uint64_t Offset) {}
1003
1004void raw_pwrite_stream::anchor() {}
1005
1006void buffer_ostream::anchor() {}
1007
1008void buffer_unique_ostream::anchor() {}
1009
1011 std::function<Error(raw_ostream &)> Write) {
1012 if (OutputFileName == "-")
1013 return Write(outs());
1014
1015 if (OutputFileName == "/dev/null") {
1016 raw_null_ostream Out;
1017 return Write(Out);
1018 }
1019
1020 unsigned Mode = sys::fs::all_read | sys::fs::all_write;
1022 sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
1023 if (!Temp)
1024 return createFileError(OutputFileName, Temp.takeError());
1025
1026 raw_fd_ostream Out(Temp->FD, false);
1027
1028 if (Error E = Write(Out)) {
1029 if (Error DiscardError = Temp->discard())
1030 return joinErrors(std::move(E), std::move(DiscardError));
1031 return E;
1032 }
1033 Out.flush();
1034
1035 return Temp->keep(OutputFileName);
1036}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
DXIL Resource Access
#define STDOUT_FILENO
Definition InitLLVM.cpp:28
#define STDERR_FILENO
Definition InitLLVM.cpp:31
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
Provides a library for accessing information about this process and other processes on the operating ...
This file contains some functions that are useful when dealing with strings.
std::pair< llvm::MachO::Target, std::string > UUID
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
This is a helper class used for format_hex() and format_decimal().
Definition Format.h:169
This is a helper class for left_justify, right_justify, and center_justify.
Definition Format.h:134
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This is a helper class used for handling formatted output.
Definition Format.h:40
unsigned print(char *Buffer, unsigned BufferSize) const
Format the object into the specified buffer.
Definition Format.h:56
A raw_ostream that writes to a file descriptor.
bool is_displayed() const override
This function determines if this stream is connected to a "tty" or "console" window.
bool has_error() const
Return the value of the flag in this raw_fd_ostream indicating whether an output error has been encou...
std::error_code error() const
void close()
Manually flush the stream and close the file.
void inc_pos(uint64_t Delta)
Expected< sys::fs::FileLocker > lock()
Locks the underlying file.
bool has_colors() const override
This function determines if this stream is displayed and supports colors.
bool isRegularFile() const
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
int get_fd() const
Return the file descriptor.
Expected< sys::fs::FileLocker > tryLockFor(Duration const &Timeout)
Tries to lock the underlying file within the specified period.
raw_fd_ostream(StringRef Filename, std::error_code &EC)
Open the specified file for writing.
void error_detected(std::error_code EC)
Set the flag indicating that an output error has been encountered.
static LLVM_ABI bool classof(const raw_ostream *OS)
Check if OS is a pointer of type raw_fd_stream*.
LLVM_ABI raw_fd_stream(StringRef Filename, std::error_code &EC)
Open the specified file for reading/writing/seeking.
LLVM_ABI ssize_t read(char *Ptr, size_t Size)
This reads the Size bytes into a buffer pointed by Ptr.
A raw_ostream that discards all output.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
raw_ostream(bool unbuffered=false, OStreamKind K=OStreamKind::OK_OStream)
uint64_t tell() const
tell - Return the current offset with the file.
void SetBufferSize(size_t Size)
Set the stream to be buffered, using the specified buffer size.
virtual raw_ostream & changeColor(enum Colors Color, bool Bold=false, bool BG=false)
Changes the foreground color of text that will be output from this point forward.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
virtual raw_ostream & resetColor()
Resets the colors to terminal defaults.
raw_ostream & write_uuid(const uuid_t UUID)
raw_ostream & operator<<(char C)
virtual ~raw_ostream()
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
virtual raw_ostream & reverseColor()
Reverses the foreground and background colors.
virtual size_t preferred_buffer_size() const
Return an efficient buffer size for the underlying output mechanism.
raw_ostream & write(unsigned char C)
void SetUnbuffered()
Set the stream to be unbuffered.
virtual bool is_displayed() const
This function determines if this stream is connected to a "tty" or "console" window.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
static constexpr Colors SAVEDCOLOR
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
virtual void enable_colors(bool enable)
size_t GetNumBytesInBuffer() const
OStreamKind get_kind() const
void SetBuffered()
Set the stream to be buffered, with an automatically determined buffer size.
raw_pwrite_stream(bool Unbuffered=false, OStreamKind K=OStreamKind::OK_OStream)
A raw_ostream that writes to an SmallVector or SmallString.
static bool classof(const raw_ostream *OS)
static LLVM_ABI std::error_code SafelyCloseFileDescriptor(int FD)
static LLVM_ABI bool ColorNeedsFlush()
Whether changing colors requires the output to be flushed.
static LLVM_ABI const char * ResetColor()
Resets the terminals colors, or returns an escape sequence to do so.
static LLVM_ABI bool FileDescriptorIsDisplayed(int fd)
This function determines if the given file descriptor is connected to a "tty" or "console" window.
static LLVM_ABI const char * OutputColor(char c, bool bold, bool bg)
This function returns the colorcode escape sequences.
static LLVM_ABI const char * OutputBold(bool bg)
Same as OutputColor, but only enables the bold attribute.
static LLVM_ABI bool FileDescriptorHasColors(int fd)
This function determines if the given file descriptor is displayd and supports colors.
static LLVM_ABI const char * OutputReverse()
This function returns the escape sequence to reverse forground and background colors.
RAII class that facilitates file locking.
static LLVM_ABI Expected< TempFile > create(const Twine &Model, unsigned Mode=all_read|all_write, OpenFlags ExtraFlags=OF_None)
This creates a temporary file with createUniqueFile and schedules it for deletion with sys::RemoveFil...
Represents the result of a call to sys::fs::status().
Definition FileSystem.h:222
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
LLVM_ABI std::error_code lockFile(int FD, LockKind Kind=LockKind::Exclusive)
Lock the file.
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
LLVM_ABI std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout=std::chrono::milliseconds(0), LockKind Kind=LockKind::Exclusive)
Try to locks the file during the specified time.
ScopedSetting scopedDisable()
Definition IOSandbox.h:36
LLVM_ABI std::error_code ChangeStdoutMode(fs::OpenFlags Flags)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
LLVM_ABI bool RunningWindows8OrGreater()
Determines if the program is running on Windows 8 or newer.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1399
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
Definition MathExtras.h:350
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI void write_integer(raw_ostream &S, unsigned int N, size_t MinDigits, IntegerStyle Style)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition Error.h:442
char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
LLVM_ABI Error writeToOutput(StringRef OutputFileName, std::function< Error(raw_ostream &)> Write)
This helper creates an output stream and then passes it to Write.
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
@ Success
The lock was released successfully.
@ Timeout
Reached timeout while waiting for the owner to release the lock.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
LLVM_ABI void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
LLVM_ABI void write_double(raw_ostream &S, double D, FloatStyle Style, std::optional< size_t > Precision=std::nullopt)
bool isPrint(char C)
Checks whether character C is printable.
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)
Definition DWP.cpp:677
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:111
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
Definition Error.h:1240
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:180
static int getFD(StringRef Filename, std::error_code &EC, sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags)
static raw_ostream & write_padding(raw_ostream &OS, unsigned NumChars)
#define N