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