File indexing completed on 2026-05-10 08:44:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_SUPPORT_RAW_OSTREAM_H
0014 #define LLVM_SUPPORT_RAW_OSTREAM_H
0015
0016 #include "llvm/ADT/SmallVector.h"
0017 #include "llvm/ADT/StringRef.h"
0018 #include "llvm/Support/DataTypes.h"
0019 #include <cassert>
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <cstring>
0023 #include <optional>
0024 #include <string>
0025 #include <string_view>
0026 #include <system_error>
0027 #include <type_traits>
0028
0029 namespace llvm {
0030
0031 class Duration;
0032 class formatv_object_base;
0033 class format_object_base;
0034 class FormattedString;
0035 class FormattedNumber;
0036 class FormattedBytes;
0037 template <class T> class [[nodiscard]] Expected;
0038
0039 namespace sys {
0040 namespace fs {
0041 enum FileAccess : unsigned;
0042 enum OpenFlags : unsigned;
0043 enum CreationDisposition : unsigned;
0044 class FileLocker;
0045 }
0046 }
0047
0048
0049
0050
0051
0052 class raw_ostream {
0053 public:
0054
0055 enum class OStreamKind {
0056 OK_OStream,
0057 OK_FDStream,
0058 OK_SVecStream,
0059 };
0060
0061 private:
0062 OStreamKind Kind;
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 char *OutBufStart, *OutBufEnd, *OutBufCur;
0083 bool ColorEnabled = false;
0084
0085 enum class BufferKind {
0086 Unbuffered = 0,
0087 InternalBuffer,
0088 ExternalBuffer
0089 } BufferMode;
0090
0091 public:
0092
0093 enum class Colors {
0094 BLACK = 0,
0095 RED,
0096 GREEN,
0097 YELLOW,
0098 BLUE,
0099 MAGENTA,
0100 CYAN,
0101 WHITE,
0102 BRIGHT_BLACK,
0103 BRIGHT_RED,
0104 BRIGHT_GREEN,
0105 BRIGHT_YELLOW,
0106 BRIGHT_BLUE,
0107 BRIGHT_MAGENTA,
0108 BRIGHT_CYAN,
0109 BRIGHT_WHITE,
0110 SAVEDCOLOR,
0111 RESET,
0112 };
0113
0114 static constexpr Colors BLACK = Colors::BLACK;
0115 static constexpr Colors RED = Colors::RED;
0116 static constexpr Colors GREEN = Colors::GREEN;
0117 static constexpr Colors YELLOW = Colors::YELLOW;
0118 static constexpr Colors BLUE = Colors::BLUE;
0119 static constexpr Colors MAGENTA = Colors::MAGENTA;
0120 static constexpr Colors CYAN = Colors::CYAN;
0121 static constexpr Colors WHITE = Colors::WHITE;
0122 static constexpr Colors BRIGHT_BLACK = Colors::BRIGHT_BLACK;
0123 static constexpr Colors BRIGHT_RED = Colors::BRIGHT_RED;
0124 static constexpr Colors BRIGHT_GREEN = Colors::BRIGHT_GREEN;
0125 static constexpr Colors BRIGHT_YELLOW = Colors::BRIGHT_YELLOW;
0126 static constexpr Colors BRIGHT_BLUE = Colors::BRIGHT_BLUE;
0127 static constexpr Colors BRIGHT_MAGENTA = Colors::BRIGHT_MAGENTA;
0128 static constexpr Colors BRIGHT_CYAN = Colors::BRIGHT_CYAN;
0129 static constexpr Colors BRIGHT_WHITE = Colors::BRIGHT_WHITE;
0130 static constexpr Colors SAVEDCOLOR = Colors::SAVEDCOLOR;
0131 static constexpr Colors RESET = Colors::RESET;
0132
0133 explicit raw_ostream(bool unbuffered = false,
0134 OStreamKind K = OStreamKind::OK_OStream)
0135 : Kind(K), BufferMode(unbuffered ? BufferKind::Unbuffered
0136 : BufferKind::InternalBuffer) {
0137
0138 OutBufStart = OutBufEnd = OutBufCur = nullptr;
0139 }
0140
0141 raw_ostream(const raw_ostream &) = delete;
0142 void operator=(const raw_ostream &) = delete;
0143
0144 virtual ~raw_ostream();
0145
0146
0147 uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
0148
0149 OStreamKind get_kind() const { return Kind; }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 virtual void reserveExtraSpace(uint64_t ExtraSize) { (void)ExtraSize; }
0161
0162
0163
0164 void SetBuffered();
0165
0166
0167 void SetBufferSize(size_t Size) {
0168 flush();
0169 SetBufferAndMode(new char[Size], Size, BufferKind::InternalBuffer);
0170 }
0171
0172 size_t GetBufferSize() const {
0173
0174
0175 if (BufferMode != BufferKind::Unbuffered && OutBufStart == nullptr)
0176 return preferred_buffer_size();
0177
0178
0179 return OutBufEnd - OutBufStart;
0180 }
0181
0182
0183
0184
0185 void SetUnbuffered() {
0186 flush();
0187 SetBufferAndMode(nullptr, 0, BufferKind::Unbuffered);
0188 }
0189
0190 size_t GetNumBytesInBuffer() const {
0191 return OutBufCur - OutBufStart;
0192 }
0193
0194
0195
0196
0197
0198 void flush() {
0199 if (OutBufCur != OutBufStart)
0200 flush_nonempty();
0201 }
0202
0203 raw_ostream &operator<<(char C) {
0204 if (OutBufCur >= OutBufEnd)
0205 return write(C);
0206 *OutBufCur++ = C;
0207 return *this;
0208 }
0209
0210 raw_ostream &operator<<(unsigned char C) {
0211 if (OutBufCur >= OutBufEnd)
0212 return write(C);
0213 *OutBufCur++ = C;
0214 return *this;
0215 }
0216
0217 raw_ostream &operator<<(signed char C) {
0218 if (OutBufCur >= OutBufEnd)
0219 return write(C);
0220 *OutBufCur++ = C;
0221 return *this;
0222 }
0223
0224 raw_ostream &operator<<(StringRef Str) {
0225
0226 size_t Size = Str.size();
0227
0228
0229 if (Size > (size_t)(OutBufEnd - OutBufCur))
0230 return write(Str.data(), Size);
0231
0232 if (Size) {
0233 memcpy(OutBufCur, Str.data(), Size);
0234 OutBufCur += Size;
0235 }
0236 return *this;
0237 }
0238
0239 #if defined(__cpp_char8_t)
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 raw_ostream &operator<<(const char8_t *Str) = delete;
0251 #endif
0252
0253 raw_ostream &operator<<(const char *Str) {
0254
0255
0256
0257 return this->operator<<(StringRef(Str));
0258 }
0259
0260 raw_ostream &operator<<(const std::string &Str) {
0261
0262 return write(Str.data(), Str.length());
0263 }
0264
0265 raw_ostream &operator<<(const std::string_view &Str) {
0266 return write(Str.data(), Str.length());
0267 }
0268
0269 raw_ostream &operator<<(const SmallVectorImpl<char> &Str) {
0270 return write(Str.data(), Str.size());
0271 }
0272
0273 raw_ostream &operator<<(unsigned long N);
0274 raw_ostream &operator<<(long N);
0275 raw_ostream &operator<<(unsigned long long N);
0276 raw_ostream &operator<<(long long N);
0277 raw_ostream &operator<<(const void *P);
0278
0279 raw_ostream &operator<<(unsigned int N) {
0280 return this->operator<<(static_cast<unsigned long>(N));
0281 }
0282
0283 raw_ostream &operator<<(int N) {
0284 return this->operator<<(static_cast<long>(N));
0285 }
0286
0287 raw_ostream &operator<<(double N);
0288
0289
0290 raw_ostream &write_hex(unsigned long long N);
0291
0292
0293 raw_ostream &operator<<(Colors C);
0294
0295
0296 using uuid_t = uint8_t[16];
0297 raw_ostream &write_uuid(const uuid_t UUID);
0298
0299
0300
0301 raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
0302
0303 raw_ostream &write(unsigned char C);
0304 raw_ostream &write(const char *Ptr, size_t Size);
0305
0306
0307 raw_ostream &operator<<(const format_object_base &Fmt);
0308
0309
0310 raw_ostream &operator<<(const FormattedString &);
0311
0312
0313 raw_ostream &operator<<(const FormattedNumber &);
0314
0315
0316 raw_ostream &operator<<(const formatv_object_base &);
0317
0318
0319 raw_ostream &operator<<(const FormattedBytes &);
0320
0321
0322 raw_ostream &indent(unsigned NumSpaces);
0323
0324
0325 raw_ostream &write_zeros(unsigned NumZeros);
0326
0327
0328
0329
0330
0331
0332
0333
0334 virtual raw_ostream &changeColor(enum Colors Color, bool Bold = false,
0335 bool BG = false);
0336
0337
0338
0339 virtual raw_ostream &resetColor();
0340
0341
0342 virtual raw_ostream &reverseColor();
0343
0344
0345
0346
0347 virtual bool is_displayed() const { return false; }
0348
0349
0350
0351 virtual bool has_colors() const { return is_displayed(); }
0352
0353
0354
0355 virtual void enable_colors(bool enable) { ColorEnabled = enable; }
0356
0357 bool colors_enabled() const { return ColorEnabled; }
0358
0359
0360
0361
0362
0363 private:
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 virtual void write_impl(const char *Ptr, size_t Size) = 0;
0378
0379
0380
0381 virtual uint64_t current_pos() const = 0;
0382
0383 protected:
0384
0385
0386
0387 void SetBuffer(char *BufferStart, size_t Size) {
0388 SetBufferAndMode(BufferStart, Size, BufferKind::ExternalBuffer);
0389 }
0390
0391
0392 virtual size_t preferred_buffer_size() const;
0393
0394
0395
0396 const char *getBufferStart() const { return OutBufStart; }
0397
0398
0399
0400
0401 private:
0402
0403 void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
0404
0405
0406
0407 void flush_nonempty();
0408
0409
0410
0411 void copy_to_buffer(const char *Ptr, size_t Size);
0412
0413
0414
0415 bool prepare_colors();
0416
0417 virtual void anchor();
0418 };
0419
0420
0421
0422 template <typename OStream, typename T>
0423 std::enable_if_t<!std::is_reference_v<OStream> &&
0424 std::is_base_of_v<raw_ostream, OStream>,
0425 OStream &&>
0426 operator<<(OStream &&OS, const T &Value) {
0427 OS << Value;
0428 return std::move(OS);
0429 }
0430
0431
0432
0433
0434 class raw_pwrite_stream : public raw_ostream {
0435 virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0;
0436 void anchor() override;
0437
0438 public:
0439 explicit raw_pwrite_stream(bool Unbuffered = false,
0440 OStreamKind K = OStreamKind::OK_OStream)
0441 : raw_ostream(Unbuffered, K) {}
0442 void pwrite(const char *Ptr, size_t Size, uint64_t Offset) {
0443 #ifndef NDEBUG
0444 uint64_t Pos = tell();
0445
0446
0447 if (Pos)
0448 assert(Size + Offset <= Pos && "We don't support extending the stream");
0449 #endif
0450 pwrite_impl(Ptr, Size, Offset);
0451 }
0452 };
0453
0454
0455
0456
0457
0458
0459
0460 class raw_fd_ostream : public raw_pwrite_stream {
0461 int FD;
0462 bool ShouldClose;
0463 bool SupportsSeeking = false;
0464 bool IsRegularFile = false;
0465 mutable std::optional<bool> HasColors;
0466
0467
0468
0469 raw_ostream *TiedStream = nullptr;
0470
0471 #ifdef _WIN32
0472
0473
0474 bool IsWindowsConsole = false;
0475 #endif
0476
0477 std::error_code EC;
0478
0479 uint64_t pos = 0;
0480
0481
0482 void write_impl(const char *Ptr, size_t Size) override;
0483
0484 void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
0485
0486
0487
0488 uint64_t current_pos() const override { return pos; }
0489
0490
0491 size_t preferred_buffer_size() const override;
0492
0493 void anchor() override;
0494
0495 protected:
0496
0497 void error_detected(std::error_code EC) { this->EC = EC; }
0498
0499
0500 int get_fd() const { return FD; }
0501
0502
0503 void inc_pos(uint64_t Delta) { pos += Delta; }
0504
0505 public:
0506
0507
0508
0509
0510
0511
0512
0513
0514 raw_fd_ostream(StringRef Filename, std::error_code &EC);
0515 raw_fd_ostream(StringRef Filename, std::error_code &EC,
0516 sys::fs::CreationDisposition Disp);
0517 raw_fd_ostream(StringRef Filename, std::error_code &EC,
0518 sys::fs::FileAccess Access);
0519 raw_fd_ostream(StringRef Filename, std::error_code &EC,
0520 sys::fs::OpenFlags Flags);
0521 raw_fd_ostream(StringRef Filename, std::error_code &EC,
0522 sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
0523 sys::fs::OpenFlags Flags);
0524
0525
0526
0527
0528 raw_fd_ostream(int fd, bool shouldClose, bool unbuffered = false,
0529 OStreamKind K = OStreamKind::OK_OStream);
0530
0531 ~raw_fd_ostream() override;
0532
0533
0534
0535 void close();
0536
0537 bool supportsSeeking() const { return SupportsSeeking; }
0538
0539 bool isRegularFile() const { return IsRegularFile; }
0540
0541
0542
0543 uint64_t seek(uint64_t off);
0544
0545 bool is_displayed() const override;
0546
0547 bool has_colors() const override;
0548
0549
0550
0551
0552
0553
0554 void tie(raw_ostream *TieTo) { TiedStream = TieTo; }
0555
0556 std::error_code error() const { return EC; }
0557
0558
0559
0560
0561
0562 bool has_error() const { return bool(EC); }
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573 void clear_error() { EC = std::error_code(); }
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595 [[nodiscard]] Expected<sys::fs::FileLocker> lock();
0596
0597
0598
0599
0600
0601
0602
0603
0604 [[nodiscard]] Expected<sys::fs::FileLocker>
0605 tryLockFor(Duration const &Timeout);
0606 };
0607
0608
0609
0610 raw_fd_ostream &outs();
0611
0612
0613
0614
0615
0616
0617 raw_fd_ostream &errs();
0618
0619
0620 raw_ostream &nulls();
0621
0622
0623
0624
0625
0626
0627
0628 class raw_fd_stream : public raw_fd_ostream {
0629 public:
0630
0631
0632
0633 raw_fd_stream(StringRef Filename, std::error_code &EC);
0634
0635 raw_fd_stream(int fd, bool shouldClose);
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646 ssize_t read(char *Ptr, size_t Size);
0647
0648
0649 static bool classof(const raw_ostream *OS);
0650 };
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 class raw_string_ostream : public raw_ostream {
0662 std::string &OS;
0663
0664
0665 void write_impl(const char *Ptr, size_t Size) override;
0666
0667
0668
0669 uint64_t current_pos() const override { return OS.size(); }
0670
0671 public:
0672 explicit raw_string_ostream(std::string &O) : OS(O) {
0673 SetUnbuffered();
0674 }
0675
0676
0677
0678
0679 std::string &str() { return OS; }
0680
0681 void reserveExtraSpace(uint64_t ExtraSize) override {
0682 OS.reserve(tell() + ExtraSize);
0683 }
0684 };
0685
0686
0687
0688
0689
0690
0691 class raw_svector_ostream : public raw_pwrite_stream {
0692 SmallVectorImpl<char> &OS;
0693
0694
0695 void write_impl(const char *Ptr, size_t Size) override;
0696
0697 void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
0698
0699
0700 uint64_t current_pos() const override;
0701
0702 public:
0703
0704
0705
0706
0707 explicit raw_svector_ostream(SmallVectorImpl<char> &O)
0708 : raw_pwrite_stream(false, raw_ostream::OStreamKind::OK_SVecStream),
0709 OS(O) {
0710
0711
0712 SetUnbuffered();
0713 }
0714
0715 ~raw_svector_ostream() override = default;
0716
0717 void flush() = delete;
0718
0719
0720 StringRef str() const { return StringRef(OS.data(), OS.size()); }
0721 SmallVectorImpl<char> &buffer() { return OS; }
0722
0723 void reserveExtraSpace(uint64_t ExtraSize) override {
0724 OS.reserve(tell() + ExtraSize);
0725 }
0726
0727 static bool classof(const raw_ostream *OS);
0728 };
0729
0730
0731 class raw_null_ostream : public raw_pwrite_stream {
0732
0733 void write_impl(const char *Ptr, size_t size) override;
0734 void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
0735
0736
0737
0738 uint64_t current_pos() const override;
0739
0740 public:
0741 explicit raw_null_ostream() = default;
0742 ~raw_null_ostream() override;
0743 };
0744
0745 class buffer_ostream : public raw_svector_ostream {
0746 raw_ostream &OS;
0747 SmallVector<char, 0> Buffer;
0748
0749 void anchor() override;
0750
0751 public:
0752 buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {}
0753 ~buffer_ostream() override { OS << str(); }
0754 };
0755
0756 class buffer_unique_ostream : public raw_svector_ostream {
0757 std::unique_ptr<raw_ostream> OS;
0758 SmallVector<char, 0> Buffer;
0759
0760 void anchor() override;
0761
0762 public:
0763 buffer_unique_ostream(std::unique_ptr<raw_ostream> OS)
0764 : raw_svector_ostream(Buffer), OS(std::move(OS)) {
0765
0766
0767 this->OS->SetUnbuffered();
0768 }
0769 ~buffer_unique_ostream() override { *OS << str(); }
0770 };
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781 struct indent {
0782
0783 unsigned NumIndents;
0784 unsigned Scale;
0785
0786 explicit indent(unsigned NumIndents, unsigned Scale = 1)
0787 : NumIndents(NumIndents), Scale(Scale) {}
0788
0789
0790 void operator+=(unsigned N) { NumIndents += N; }
0791 void operator-=(unsigned N) {
0792 assert(NumIndents >= N && "Indentation underflow");
0793 NumIndents -= N;
0794 }
0795 indent operator+(unsigned N) const { return indent(NumIndents + N, Scale); }
0796 indent operator-(unsigned N) const {
0797 assert(NumIndents >= N && "Indentation undeflow");
0798 return indent(NumIndents - N, Scale);
0799 }
0800 indent &operator++() {
0801 ++NumIndents;
0802 return *this;
0803 }
0804 indent operator++(int) {
0805 indent Old = *this;
0806 ++NumIndents;
0807 return Old;
0808 }
0809 indent &operator--() {
0810 assert(NumIndents >= 1);
0811 --NumIndents;
0812 return *this;
0813 }
0814 indent operator--(int) {
0815 indent Old = *this;
0816 assert(NumIndents >= 1);
0817 --NumIndents;
0818 return Old;
0819 }
0820 indent &operator=(unsigned N) {
0821 NumIndents = N;
0822 return *this;
0823 }
0824 };
0825
0826 inline raw_ostream &operator<<(raw_ostream &OS, const indent &Indent) {
0827 return OS.indent(Indent.NumIndents * Indent.Scale);
0828 }
0829
0830 class Error;
0831
0832
0833
0834
0835
0836
0837
0838 Error writeToOutput(StringRef OutputFileName,
0839 std::function<Error(raw_ostream &)> Write);
0840
0841 raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
0842
0843 template <typename T, typename = decltype(std::declval<raw_ostream &>()
0844 << std::declval<const T &>())>
0845 raw_ostream &operator<<(raw_ostream &OS, const std::optional<T> &O) {
0846 if (O)
0847 OS << *O;
0848 else
0849 OS << std::nullopt;
0850 return OS;
0851 }
0852
0853 }
0854
0855 #endif