Index: include/lldb/Utility/Stream.h =================================================================== --- include/lldb/Utility/Stream.h +++ include/lldb/Utility/Stream.h @@ -15,6 +15,7 @@ #include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderInvalid #include "llvm/ADT/StringRef.h" // for StringRef #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" #include #include // for size_t @@ -52,6 +53,17 @@ //------------------------------------------------------------------ Stream(); + // FIXME: Streams should not be copyable. + Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } + + Stream &operator=(const Stream &rhs) { + m_flags = rhs.m_flags; + m_addr_size = rhs.m_addr_size; + m_byte_order = rhs.m_byte_order; + m_indent_level = rhs.m_indent_level; + return *this; + } + //------------------------------------------------------------------ /// Destructor //------------------------------------------------------------------ @@ -520,6 +532,13 @@ //------------------------------------------------------------------ size_t PutULEB128(uint64_t uval); + //------------------------------------------------------------------ + /// Returns a raw_ostream that forwards the data to this Stream object. + //------------------------------------------------------------------ + llvm::raw_ostream &AsRawOstream() { + return m_forwarder; + } + protected: //------------------------------------------------------------------ // Member variables @@ -548,6 +567,34 @@ /// The number of bytes that were appended to the stream. //------------------------------------------------------------------ virtual size_t WriteImpl(const void *src, size_t src_len) = 0; + + //---------------------------------------------------------------------- + /// @class RawOstreamForward Stream.h "lldb/Utility/Stream.h" + /// This is a wrapper class that exposes a raw_ostream interface that just + /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take + /// a raw_ostream within the LLDB code base. + //---------------------------------------------------------------------- + class RawOstreamForward : public llvm::raw_ostream { + // Note: This stream must *not* maintain its own buffer, but instead + // directly write everything to the internal Stream class. Without this, + // we would run into the problem that the Stream written byte count would + // differ from the actually written bytes by the size of the internal + // raw_ostream buffer. + + Stream &m_target; + void write_impl(const char *Ptr, size_t Size) override { + m_target.Write(Ptr, Size); + } + + uint64_t current_pos() const override { + return m_target.GetWrittenBytes(); + } + + public: + RawOstreamForward(Stream &target) + : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {} + }; + RawOstreamForward m_forwarder; }; } // namespace lldb_private Index: source/Utility/Stream.cpp =================================================================== --- source/Utility/Stream.cpp +++ source/Utility/Stream.cpp @@ -23,11 +23,11 @@ Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0) {} + m_indent_level(0), m_forwarder(*this) {} Stream::Stream() : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0) {} + m_indent_level(0), m_forwarder(*this) {} //------------------------------------------------------------------ // Destructor