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