mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Semiwrap / meson / robotpy define `NDEBUG` when building their software in all modes, while `allwplib` only does it when building debug. This causes the size of `DenseMap` to differ between the shared libraries built here, and the extension modules built in `mostrobotpy`, causing segfaults when you try to execute code that uses `DenseMap`. This is not a problem with the robotpy code in `allwpilib`, because bazel uses the exact same compiler flags when building the shared libraries and pybind11 extensions.
215 lines
7.9 KiB
Diff
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/35] Add vectors to raw_ostream
|
|
|
|
---
|
|
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 fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82335b9913 100644
|
|
--- a/llvm/include/llvm/Support/raw_ostream.h
|
|
+++ b/llvm/include/llvm/Support/raw_ostream.h
|
|
@@ -24,6 +24,7 @@
|
|
#include <string_view>
|
|
#include <system_error>
|
|
#include <type_traits>
|
|
+#include <vector>
|
|
|
|
namespace llvm {
|
|
|
|
@@ -274,12 +275,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);
|
|
@@ -641,6 +654,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 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 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 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 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 e06253e8f3a16dc09573cdec74cf54e0e3fcf848..a74b6b00d616828a8e5ab25c1fd15f2528b4d76d 100644
|
|
--- a/llvm/lib/Support/raw_ostream.cpp
|
|
+++ b/llvm/lib/Support/raw_ostream.cpp
|
|
@@ -679,6 +679,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
|
|
//===----------------------------------------------------------------------===//
|