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