Files
allwpilib/upstream_utils/llvm_patches/0011-raw_ostream-add-vector-support.patch
2026-05-26 21:55:50 -07:00

215 lines
7.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PJ Reiniger <pj.reiniger@gmail.com>
Date: Sun, 8 May 2022 13:48:59 -0400
Subject: [PATCH 11/34] raw_ostream: add vector support
---
llvm/include/llvm/Support/raw_ostream.h | 115 ++++++++++++++++++++++++
llvm/lib/Support/raw_ostream.cpp | 47 ++++++++++
2 files changed, 162 insertions(+)
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index f346d36ca7a36ab2d9bcddc205db0abf50c2a136..991ede221d8c265a384ede4d4b037dbbb61d6afd 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -25,6 +25,7 @@
#include <string_view>
#include <system_error>
#include <type_traits>
+#include <vector>
namespace llvm {
@@ -275,12 +276,24 @@ public:
return write(Str.data(), Str.size());
}
+ raw_ostream &operator<<(const std::vector<uint8_t> &Arr) {
+ // Avoid the fast path, it would only increase code size for a marginal win.
+ return write(Arr.data(), Arr.size());
+ }
+
+ raw_ostream &operator<<(const SmallVectorImpl<uint8_t> &Arr) {
+ return write(Arr.data(), Arr.size());
+ }
+
/// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
/// satisfy llvm::isPrint into an escape sequence.
raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false);
raw_ostream &write(unsigned char C);
raw_ostream &write(const char *Ptr, size_t Size);
+ raw_ostream &write(const uint8_t *Ptr, size_t Size) {
+ return write(reinterpret_cast<const char *>(Ptr), Size);
+ }
/// indent - Insert 'NumSpaces' spaces.
raw_ostream &indent(unsigned NumSpaces);
@@ -642,6 +655,108 @@ public:
static bool classof(const raw_ostream *OS);
};
+/// A raw_ostream that writes to a vector. This is a
+/// simple adaptor class. This class does not encounter output errors.
+/// raw_vector_ostream operates without a buffer, delegating all memory
+/// management to the vector. Thus the vector is always up-to-date,
+/// may be used directly and there is no need to call flush().
+class LLVM_ABI raw_vector_ostream : public raw_pwrite_stream {
+ std::vector<char> &OS;
+
+ /// See raw_ostream::write_impl.
+ void write_impl(const char *Ptr, size_t Size) override;
+
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Return the current position within the stream.
+ uint64_t current_pos() const override;
+
+public:
+ /// Construct a new raw_svector_ostream.
+ ///
+ /// \param O The vector to write to; this should generally have at least 128
+ /// bytes free to avoid any extraneous memory overhead.
+ explicit raw_vector_ostream(std::vector<char> &O) : OS(O) {
+ SetUnbuffered();
+ }
+
+ ~raw_vector_ostream() override = default;
+
+ void flush() = delete;
+
+ /// Return a std::string_view for the vector contents.
+ std::string_view str() { return std::string_view(OS.data(), OS.size()); }
+};
+
+/// A raw_ostream that writes to an SmallVector or SmallString. This is a
+/// simple adaptor class. This class does not encounter output errors.
+/// raw_svector_ostream operates without a buffer, delegating all memory
+/// management to the SmallString. Thus the SmallString is always up-to-date,
+/// may be used directly and there is no need to call flush().
+class LLVM_ABI raw_usvector_ostream : public raw_pwrite_stream {
+ SmallVectorImpl<uint8_t> &OS;
+
+ /// See raw_ostream::write_impl.
+ void write_impl(const char *Ptr, size_t Size) override;
+
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Return the current position within the stream.
+ uint64_t current_pos() const override;
+
+public:
+ /// Construct a new raw_svector_ostream.
+ ///
+ /// \param O The vector to write to; this should generally have at least 128
+ /// bytes free to avoid any extraneous memory overhead.
+ explicit raw_usvector_ostream(SmallVectorImpl<uint8_t> &O) : OS(O) {
+ SetUnbuffered();
+ }
+
+ ~raw_usvector_ostream() override = default;
+
+ void flush() = delete;
+
+ /// Return an span for the vector contents.
+ span<uint8_t> array() { return {OS.data(), OS.size()}; }
+ span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
+};
+
+/// A raw_ostream that writes to a vector. This is a
+/// simple adaptor class. This class does not encounter output errors.
+/// raw_vector_ostream operates without a buffer, delegating all memory
+/// management to the vector. Thus the vector is always up-to-date,
+/// may be used directly and there is no need to call flush().
+class LLVM_ABI raw_uvector_ostream : public raw_pwrite_stream {
+ std::vector<uint8_t> &OS;
+
+ /// See raw_ostream::write_impl.
+ void write_impl(const char *Ptr, size_t Size) override;
+
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Return the current position within the stream.
+ uint64_t current_pos() const override;
+
+public:
+ /// Construct a new raw_svector_ostream.
+ ///
+ /// \param O The vector to write to; this should generally have at least 128
+ /// bytes free to avoid any extraneous memory overhead.
+ explicit raw_uvector_ostream(std::vector<uint8_t> &O) : OS(O) {
+ SetUnbuffered();
+ }
+
+ ~raw_uvector_ostream() override = default;
+
+ void flush() = delete;
+
+ /// Return a span for the vector contents.
+ span<uint8_t> array() { return {OS.data(), OS.size()}; }
+ span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
+};
+
+
/// A raw_ostream that discards all output.
class LLVM_ABI raw_null_ostream : public raw_pwrite_stream {
/// See raw_ostream::write_impl.
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 32f5d5fb78b1a9e4288b875c64ded0040d6fdce6..dd1ce4a784d096949681e297103c50aa002d636d 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -677,6 +677,53 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) {
return OS->get_kind() == OStreamKind::OK_SVecStream;
}
+//===----------------------------------------------------------------------===//
+// raw_vector_ostream
+//===----------------------------------------------------------------------===//
+
+uint64_t raw_vector_ostream::current_pos() const { return OS.size(); }
+
+void raw_vector_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.insert(OS.end(), Ptr, Ptr + Size);
+}
+
+void raw_vector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {
+ memcpy(OS.data() + Offset, Ptr, Size);
+}
+
+//===----------------------------------------------------------------------===//
+// raw_usvector_ostream
+//===----------------------------------------------------------------------===//
+
+uint64_t raw_usvector_ostream::current_pos() const { return OS.size(); }
+
+void raw_usvector_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.append(reinterpret_cast<const uint8_t *>(Ptr),
+ reinterpret_cast<const uint8_t *>(Ptr) + Size);
+}
+
+void raw_usvector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {
+ memcpy(OS.data() + Offset, Ptr, Size);
+}
+
+//===----------------------------------------------------------------------===//
+// raw_uvector_ostream
+//===----------------------------------------------------------------------===//
+
+uint64_t raw_uvector_ostream::current_pos() const { return OS.size(); }
+
+void raw_uvector_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.insert(OS.end(), reinterpret_cast<const uint8_t *>(Ptr),
+ reinterpret_cast<const uint8_t *>(Ptr) + Size);
+}
+
+void raw_uvector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {
+ memcpy(OS.data() + Offset, Ptr, Size);
+}
+
//===----------------------------------------------------------------------===//
// raw_null_ostream
//===----------------------------------------------------------------------===//