LLVM 20.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 write_impl(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 write_impl(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 write_impl(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 write_impl(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
309// Formatted output.
311 // If we have more than a few bytes left in our output buffer, try
312 // formatting directly onto its end.
313 size_t NextBufferSize = 127;
314 size_t BufferBytesLeft = OutBufEnd - OutBufCur;
315 if (BufferBytesLeft > 3) {
316 size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
317
318 // Common case is that we have plenty of space.
319 if (BytesUsed <= BufferBytesLeft) {
320 OutBufCur += BytesUsed;
321 return *this;
322 }
323
324 // Otherwise, we overflowed and the return value tells us the size to try
325 // again with.
326 NextBufferSize = BytesUsed;
327 }
328
329 // If we got here, we didn't have enough space in the output buffer for the
330 // string. Try printing into a SmallVector that is resized to have enough
331 // space. Iterate until we win.
333
334 while (true) {
335 V.resize(NextBufferSize);
336
337 // Try formatting into the SmallVector.
338 size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
339
340 // If BytesUsed fit into the vector, we win.
341 if (BytesUsed <= NextBufferSize)
342 return write(V.data(), BytesUsed);
343
344 // Otherwise, try again with a new size.
345 assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
346 NextBufferSize = BytesUsed;
347 }
348}
349
351 Obj.format(*this);
352 return *this;
353}
354
356 unsigned LeftIndent = 0;
357 unsigned RightIndent = 0;
358 const ssize_t Difference = FS.Width - FS.Str.size();
359 if (Difference > 0) {
360 switch (FS.Justify) {
362 break;
364 RightIndent = Difference;
365 break;
367 LeftIndent = Difference;
368 break;
370 LeftIndent = Difference / 2;
371 RightIndent = Difference - LeftIndent;
372 break;
373 }
374 }
375 indent(LeftIndent);
376 (*this) << FS.Str;
377 indent(RightIndent);
378 return *this;
379}
380
382 if (FN.Hex) {
383 HexPrintStyle Style;
384 if (FN.Upper && FN.HexPrefix)
386 else if (FN.Upper && !FN.HexPrefix)
387 Style = HexPrintStyle::Upper;
388 else if (!FN.Upper && FN.HexPrefix)
390 else
391 Style = HexPrintStyle::Lower;
392 llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
393 } else {
395 llvm::raw_svector_ostream Stream(Buffer);
396 llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
397 if (Buffer.size() < FN.Width)
398 indent(FN.Width - Buffer.size());
399 (*this) << Buffer;
400 }
401 return *this;
402}
403
405 if (FB.Bytes.empty())
406 return *this;
407
408 size_t LineIndex = 0;
409 auto Bytes = FB.Bytes;
410 const size_t Size = Bytes.size();
412 uint64_t OffsetWidth = 0;
413 if (FB.FirstByteOffset) {
414 // Figure out how many nibbles are needed to print the largest offset
415 // represented by this data set, so that we can align the offset field
416 // to the right width.
417 size_t Lines = Size / FB.NumPerLine;
418 uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
419 unsigned Power = 0;
420 if (MaxOffset > 0)
421 Power = llvm::Log2_64_Ceil(MaxOffset);
422 OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
423 }
424
425 // The width of a block of data including all spaces for group separators.
426 unsigned NumByteGroups =
427 alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
428 unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
429
430 while (!Bytes.empty()) {
431 indent(FB.IndentLevel);
432
433 if (FB.FirstByteOffset) {
434 uint64_t Offset = *FB.FirstByteOffset;
435 llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
436 *this << ": ";
437 }
438
439 auto Line = Bytes.take_front(FB.NumPerLine);
440
441 size_t CharsPrinted = 0;
442 // Print the hex bytes for this line in groups
443 for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
444 if (I && (I % FB.ByteGroupSize) == 0) {
445 ++CharsPrinted;
446 *this << " ";
447 }
448 llvm::write_hex(*this, Line[I], HPS, 2);
449 }
450
451 if (FB.ASCII) {
452 // Print any spaces needed for any bytes that we didn't print on this
453 // line so that the ASCII bytes are correctly aligned.
454 assert(BlockCharWidth >= CharsPrinted);
455 indent(BlockCharWidth - CharsPrinted + 2);
456 *this << "|";
457
458 // Print the ASCII char values for each byte on this line
459 for (uint8_t Byte : Line) {
460 if (isPrint(Byte))
461 *this << static_cast<char>(Byte);
462 else
463 *this << '.';
464 }
465 *this << '|';
466 }
467
468 Bytes = Bytes.drop_front(Line.size());
469 LineIndex += Line.size();
470 if (LineIndex < Size)
471 *this << '\n';
472 }
473 return *this;
474}
475
476template <char C>
477static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
478 static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
479 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
480 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
481 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
482 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
483
484 // Usually the indentation is small, handle it with a fastpath.
485 if (NumChars < std::size(Chars))
486 return OS.write(Chars, NumChars);
487
488 while (NumChars) {
489 unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1);
490 OS.write(Chars, NumToWrite);
491 NumChars -= NumToWrite;
492 }
493 return OS;
494}
495
496/// indent - Insert 'NumSpaces' spaces.
497raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
498 return write_padding<' '>(*this, NumSpaces);
499}
500
501/// write_zeros - Insert 'NumZeros' nulls.
503 return write_padding<'\0'>(*this, NumZeros);
504}
505
506bool raw_ostream::prepare_colors() {
507 // Colors were explicitly disabled.
508 if (!ColorEnabled)
509 return false;
510
511 // Colors require changing the terminal but this stream is not going to a
512 // terminal.
514 return false;
515
517 flush();
518
519 return true;
520}
521
522raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
523 if (!prepare_colors())
524 return *this;
525
526 const char *colorcode =
527 (colors == SAVEDCOLOR)
529 : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
530 if (colorcode)
531 write(colorcode, strlen(colorcode));
532 return *this;
533}
534
536 if (!prepare_colors())
537 return *this;
538
539 if (const char *colorcode = sys::Process::ResetColor())
540 write(colorcode, strlen(colorcode));
541 return *this;
542}
543
545 if (!prepare_colors())
546 return *this;
547
548 if (const char *colorcode = sys::Process::OutputReverse())
549 write(colorcode, strlen(colorcode));
550 return *this;
551}
552
553void raw_ostream::anchor() {}
554
555//===----------------------------------------------------------------------===//
556// Formatted Output
557//===----------------------------------------------------------------------===//
558
559// Out of line virtual method.
561}
562
563//===----------------------------------------------------------------------===//
564// raw_fd_ostream
565//===----------------------------------------------------------------------===//
566
567static int getFD(StringRef Filename, std::error_code &EC,
569 sys::fs::OpenFlags Flags) {
571 "Cannot make a raw_ostream from a read-only descriptor!");
572
573 // Handle "-" as stdout. Note that when we do this, we consider ourself
574 // the owner of stdout and may set the "binary" flag globally based on Flags.
575 if (Filename == "-") {
576 EC = std::error_code();
577 // Change stdout's text/binary mode based on the Flags.
579 return STDOUT_FILENO;
580 }
581
582 int FD;
584 EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
585 else
586 EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
587 if (EC)
588 return -1;
589
590 return FD;
591}
592
593raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
594 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
595 sys::fs::OF_None) {}
596
597raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
599 : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
600
601raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
603 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
604 sys::fs::OF_None) {}
605
606raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
607 sys::fs::OpenFlags Flags)
608 : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
609 Flags) {}
610
611raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
614 sys::fs::OpenFlags Flags)
615 : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
616
617/// FD is the file descriptor that this writes to. If ShouldClose is true, this
618/// closes the file when the stream is destroyed.
619raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
620 OStreamKind K)
621 : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
622 if (FD < 0 ) {
623 ShouldClose = false;
624 return;
625 }
626
627 enable_colors(true);
628
629 // Do not attempt to close stdout or stderr. We used to try to maintain the
630 // property that tools that support writing file to stdout should not also
631 // write informational output to stdout, but in practice we were never able to
632 // maintain this invariant. Many features have been added to LLVM and clang
633 // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
634 // users must simply be aware that mixed output and remarks is a possibility.
635 if (FD <= STDERR_FILENO)
636 ShouldClose = false;
637
638#ifdef _WIN32
639 // Check if this is a console device. This is not equivalent to isatty.
640 IsWindowsConsole =
641 ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
642#endif
643
644 // Get the starting position.
645 off_t loc = ::lseek(FD, 0, SEEK_CUR);
647 std::error_code EC = status(FD, Status);
648 IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
649#ifdef _WIN32
650 // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
651 SupportsSeeking = !EC && IsRegularFile;
652#else
653 SupportsSeeking = !EC && loc != (off_t)-1;
654#endif
655 if (!SupportsSeeking)
656 pos = 0;
657 else
658 pos = static_cast<uint64_t>(loc);
659}
660
662 if (FD >= 0) {
663 flush();
664 if (ShouldClose) {
666 error_detected(EC);
667 }
668 }
669
670#ifdef __MINGW32__
671 // On mingw, global dtors should not call exit().
672 // report_fatal_error() invokes exit(). We know report_fatal_error()
673 // might not write messages to stderr when any errors were detected
674 // on FD == 2.
675 if (FD == 2) return;
676#endif
677
678 // If there are any pending errors, report them now. Clients wishing
679 // to avoid report_fatal_error calls should check for errors with
680 // has_error() and clear the error flag with clear_error() before
681 // destructing raw_ostream objects which may have errors.
682 if (has_error())
683 report_fatal_error(Twine("IO failure on output stream: ") +
684 error().message(),
685 /*gen_crash_diag=*/false);
686}
687
688#if defined(_WIN32)
689// The most reliable way to print unicode in a Windows console is with
690// WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
691// assumes that LLVM programs always print valid UTF-8 to the console. The data
692// might not be UTF-8 for two major reasons:
693// 1. The program is printing binary (-filetype=obj -o -), in which case it
694// would have been gibberish anyway.
695// 2. The program is printing text in a semi-ascii compatible codepage like
696// shift-jis or cp1252.
697//
698// Most LLVM programs don't produce non-ascii text unless they are quoting
699// user source input. A well-behaved LLVM program should either validate that
700// the input is UTF-8 or transcode from the local codepage to UTF-8 before
701// quoting it. If they don't, this may mess up the encoding, but this is still
702// probably the best compromise we can make.
703static bool write_console_impl(int FD, StringRef Data) {
705
706 // Fall back to ::write if it wasn't valid UTF-8.
707 if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
708 return false;
709
710 // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
711 // that can be written to the console at a time.
712 size_t MaxWriteSize = WideText.size();
714 MaxWriteSize = 32767;
715
716 size_t WCharsWritten = 0;
717 do {
718 size_t WCharsToWrite =
719 std::min(MaxWriteSize, WideText.size() - WCharsWritten);
720 DWORD ActuallyWritten;
721 bool Success =
722 ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
723 WCharsToWrite, &ActuallyWritten,
724 /*Reserved=*/nullptr);
725
726 // The most likely reason for WriteConsoleW to fail is that FD no longer
727 // points to a console. Fall back to ::write. If this isn't the first loop
728 // iteration, something is truly wrong.
729 if (!Success)
730 return false;
731
732 WCharsWritten += ActuallyWritten;
733 } while (WCharsWritten != WideText.size());
734 return true;
735}
736#endif
737
738void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
739 if (TiedStream)
740 TiedStream->flush();
741
742 assert(FD >= 0 && "File already closed.");
743 pos += Size;
744
745#if defined(_WIN32)
746 // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
747 // and using WriteConsoleW. If that fails, fall back to plain write().
748 if (IsWindowsConsole)
749 if (write_console_impl(FD, StringRef(Ptr, Size)))
750 return;
751#endif
752
753 // The maximum write size is limited to INT32_MAX. A write
754 // greater than SSIZE_MAX is implementation-defined in POSIX,
755 // and Windows _write requires 32 bit input.
756 size_t MaxWriteSize = INT32_MAX;
757
758#if defined(__linux__)
759 // It is observed that Linux returns EINVAL for a very large write (>2G).
760 // Make it a reasonably small value.
761 MaxWriteSize = 1024 * 1024 * 1024;
762#endif
763
764 do {
765 size_t ChunkSize = std::min(Size, MaxWriteSize);
766 ssize_t ret = ::write(FD, Ptr, ChunkSize);
767
768 if (ret < 0) {
769 // If it's a recoverable error, swallow it and retry the write.
770 //
771 // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
772 // raw_ostream isn't designed to do non-blocking I/O. However, some
773 // programs, such as old versions of bjam, have mistakenly used
774 // O_NONBLOCK. For compatibility, emulate blocking semantics by
775 // spinning until the write succeeds. If you don't want spinning,
776 // don't use O_NONBLOCK file descriptors with raw_ostream.
777 if (errno == EINTR || errno == EAGAIN
778#ifdef EWOULDBLOCK
779 || errno == EWOULDBLOCK
780#endif
781 )
782 continue;
783
784#ifdef _WIN32
785 // Windows equivalents of SIGPIPE/EPIPE.
786 DWORD WinLastError = GetLastError();
787 if (WinLastError == ERROR_BROKEN_PIPE ||
788 (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
789 llvm::sys::CallOneShotPipeSignalHandler();
790 errno = EPIPE;
791 }
792#endif
793 // Otherwise it's a non-recoverable error. Note it and quit.
795 break;
796 }
797
798 // The write may have written some or all of the data. Update the
799 // size and buffer pointer to reflect the remainder that needs
800 // to be written. If there are no bytes left, we're done.
801 Ptr += ret;
802 Size -= ret;
803 } while (Size > 0);
804}
805
807 assert(ShouldClose);
808 ShouldClose = false;
809 flush();
811 error_detected(EC);
812 FD = -1;
813}
814
816 assert(SupportsSeeking && "Stream does not support seeking!");
817 flush();
818#ifdef _WIN32
819 pos = ::_lseeki64(FD, off, SEEK_SET);
820#else
821 pos = ::lseek(FD, off, SEEK_SET);
822#endif
823 if (pos == (uint64_t)-1)
825 return pos;
826}
827
828void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
830 uint64_t Pos = tell();
831 seek(Offset);
832 write(Ptr, Size);
833 seek(Pos);
834}
835
836size_t raw_fd_ostream::preferred_buffer_size() const {
837#if defined(_WIN32)
838 // Disable buffering for console devices. Console output is re-encoded from
839 // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
840 // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
841 // below on most other OSs, so do the same thing on Windows and avoid that
842 // complexity.
843 if (IsWindowsConsole)
844 return 0;
846#elif defined(__MVS__)
847 // The buffer size on z/OS is defined with macro BUFSIZ, which can be
848 // retrieved by invoking function raw_ostream::preferred_buffer_size().
850#else
851 assert(FD >= 0 && "File not yet open!");
852 struct stat statbuf;
853 if (fstat(FD, &statbuf) != 0)
854 return 0;
855
856 // If this is a terminal, don't use buffering. Line buffering
857 // would be a more traditional thing to do, but it's not worth
858 // the complexity.
859 if (S_ISCHR(statbuf.st_mode) && is_displayed())
860 return 0;
861 // Return the preferred block size.
862 return statbuf.st_blksize;
863#endif
864}
865
868}
869
871 if (!HasColors)
873 return *HasColors;
874}
875
877 std::error_code EC = sys::fs::lockFile(FD);
878 if (!EC)
879 return sys::fs::FileLocker(FD);
880 return errorCodeToError(EC);
881}
882
885 std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
886 if (!EC)
887 return sys::fs::FileLocker(FD);
888 return errorCodeToError(EC);
889}
890
891void raw_fd_ostream::anchor() {}
892
893//===----------------------------------------------------------------------===//
894// outs(), errs(), nulls()
895//===----------------------------------------------------------------------===//
896
898 // Set buffer settings to model stdout behavior.
899 std::error_code EC;
900#ifdef __MVS__
901 EC = enablezOSAutoConversion(STDOUT_FILENO);
902 assert(!EC);
903#endif
904 static raw_fd_ostream S("-", EC, sys::fs::OF_None);
905 assert(!EC);
906 return S;
907}
908
910 // Set standard error to be unbuffered.
911#ifdef __MVS__
912 std::error_code EC = enablezOSAutoConversion(STDERR_FILENO);
913 assert(!EC);
914#endif
915 static raw_fd_ostream S(STDERR_FILENO, false, true);
916 return S;
917}
918
919/// nulls() - This returns a reference to a raw_ostream which discards output.
921 static raw_null_ostream S;
922 return S;
923}
924
925//===----------------------------------------------------------------------===//
926// File Streams
927//===----------------------------------------------------------------------===//
928
929raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
930 : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
931 sys::fs::FA_Write | sys::fs::FA_Read,
932 sys::fs::OF_None),
933 true, false, OStreamKind::OK_FDStream) {
934 if (EC)
935 return;
936
937 if (!isRegularFile())
938 EC = std::make_error_code(std::errc::invalid_argument);
939}
940
941raw_fd_stream::raw_fd_stream(int fd, bool shouldClose)
942 : raw_fd_ostream(fd, shouldClose, false, OStreamKind::OK_FDStream) {}
943
944ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
945 assert(get_fd() >= 0 && "File already closed.");
946 ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
947 if (Ret >= 0)
948 inc_pos(Ret);
949 else
951 return Ret;
952}
953
956}
957
958//===----------------------------------------------------------------------===//
959// raw_string_ostream
960//===----------------------------------------------------------------------===//
961
962void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
963 OS.append(Ptr, Size);
964}
965
966//===----------------------------------------------------------------------===//
967// raw_svector_ostream
968//===----------------------------------------------------------------------===//
969
970uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
971
972void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
973 OS.append(Ptr, Ptr + Size);
974}
975
976void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
978 memcpy(OS.data() + Offset, Ptr, Size);
979}
980
983}
984
985//===----------------------------------------------------------------------===//
986// raw_null_ostream
987//===----------------------------------------------------------------------===//
988
990#ifndef NDEBUG
991 // ~raw_ostream asserts that the buffer is empty. This isn't necessary
992 // with raw_null_ostream, but it's better to have raw_null_ostream follow
993 // the rules than to change the rules just for raw_null_ostream.
994 flush();
995#endif
996}
997
998void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
999}
1000
1001uint64_t raw_null_ostream::current_pos() const {
1002 return 0;
1003}
1004
1005void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
1006 uint64_t Offset) {}
1007
1008void raw_pwrite_stream::anchor() {}
1009
1010void buffer_ostream::anchor() {}
1011
1012void buffer_unique_ostream::anchor() {}
1013
1015 std::function<Error(raw_ostream &)> Write) {
1016 if (OutputFileName == "-")
1017 return Write(outs());
1018
1019 if (OutputFileName == "/dev/null") {
1020 raw_null_ostream Out;
1021 return Write(Out);
1022 }
1023
1026 sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
1027 if (!Temp)
1028 return createFileError(OutputFileName, Temp.takeError());
1029
1030 raw_fd_ostream Out(Temp->FD, false);
1031
1032 if (Error E = Write(Out)) {
1033 if (Error DiscardError = Temp->discard())
1034 return joinErrors(std::move(E), std::move(DiscardError));
1035 return E;
1036 }
1037 Out.flush();
1038
1039 return Temp->keep(OutputFileName);
1040}
#define Success
basic Basic Alias true
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition: Compiler.h:320
DXIL Resource Access
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:163
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:78
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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:460
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:503
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:539
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:500
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:497
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:117
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:147
void SetBufferSize(size_t Size)
Set the stream to be buffered, using the specified buffer size.
Definition: raw_ostream.h:167
static constexpr Colors CYAN
Definition: raw_ostream.h:120
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:203
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:118
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:185
virtual bool is_displayed() const
This function determines if this stream is connected to a "tty" or "console" window.
Definition: raw_ostream.h:347
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
static constexpr Colors RESET
Definition: raw_ostream.h:131
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
Definition: raw_ostream.h:296
static constexpr Colors MAGENTA
Definition: raw_ostream.h:119
virtual void enable_colors(bool enable)
Definition: raw_ostream.h:355
static constexpr Colors SAVEDCOLOR
Definition: raw_ostream.h:130
size_t GetNumBytesInBuffer() const
Definition: raw_ostream.h:190
static constexpr Colors BLACK
Definition: raw_ostream.h:114
static constexpr Colors GREEN
Definition: raw_ostream.h:116
static constexpr Colors RED
Definition: raw_ostream.h:115
OStreamKind get_kind() const
Definition: raw_ostream.h:149
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:121
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:434
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:1325
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:480
@ Length
Definition: DWP.cpp:480
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1385
@ Write
Definition: CodeGenData.h:108
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:359
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:625
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:1226
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