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