diff --git a/lldb/include/lldb/DataFormatters/StringPrinter.h b/lldb/include/lldb/DataFormatters/StringPrinter.h index a41a2ae8335b..934e440d4da1 100644 --- a/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -14,6 +14,8 @@ #include "lldb/Core/DataExtractor.h" +#include + namespace lldb_private { namespace formatters { @@ -308,13 +310,99 @@ namespace lldb_private { bool m_zero_is_terminator; }; - template - bool - ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options); - - template - bool - ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options); + class StringPrinter + { + public: + // I can't use a std::unique_ptr for this because the Deleter is a template argument there + // and I want the same type to represent both pointers I want to free and pointers I don't need + // to free - which is what this class essentially is + // It's very specialized to the needs of this file, and not suggested for general use + template + struct StringPrinterBufferPointer + { + public: + + typedef std::function Deleter; + + StringPrinterBufferPointer (std::nullptr_t ptr) : + m_data(nullptr), + m_size(0), + m_deleter() + {} + + StringPrinterBufferPointer(const T* bytes, S size, Deleter deleter = nullptr) : + m_data(bytes), + m_size(size), + m_deleter(deleter) + {} + + StringPrinterBufferPointer(const U* bytes, S size, Deleter deleter = nullptr) : + m_data((T*)bytes), + m_size(size), + m_deleter(deleter) + {} + + StringPrinterBufferPointer(StringPrinterBufferPointer&& rhs) : + m_data(rhs.m_data), + m_size(rhs.m_size), + m_deleter(rhs.m_deleter) + { + rhs.m_data = nullptr; + } + + StringPrinterBufferPointer(const StringPrinterBufferPointer& rhs) : + m_data(rhs.m_data), + m_size(rhs.m_size), + m_deleter(rhs.m_deleter) + { + rhs.m_data = nullptr; // this is why m_data has to be mutable + } + + const T* + GetBytes () const + { + return m_data; + } + + const S + GetSize () const + { + return m_size; + } + + ~StringPrinterBufferPointer () + { + if (m_data && m_deleter) + m_deleter(m_data); + m_data = nullptr; + } + + StringPrinterBufferPointer& + operator = (const StringPrinterBufferPointer& rhs) + { + if (m_data && m_deleter) + m_deleter(m_data); + m_data = rhs.m_data; + m_size = rhs.m_size; + m_deleter = rhs.m_deleter; + rhs.m_data = nullptr; + return *this; + } + + private: + mutable const T* m_data; + size_t m_size; + Deleter m_deleter; + }; + + template + static bool + ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options); + + template + static bool + ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options); + }; } // namespace formatters } // namespace lldb_private diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 85305a00ae7b..3efb28088d60 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -1601,7 +1601,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s, options.SetPrefixToken(0); options.SetQuote('"'); options.SetSourceSize(buffer_sp->GetByteSize()); - lldb_private::formatters::ReadBufferAndDumpToStream(options); + formatters::StringPrinter::ReadBufferAndDumpToStream(options); return !error.Fail(); } diff --git a/lldb/source/DataFormatters/Cocoa.cpp b/lldb/source/DataFormatters/Cocoa.cpp index d89c3e354699..0942c8da2a32 100644 --- a/lldb/source/DataFormatters/Cocoa.cpp +++ b/lldb/source/DataFormatters/Cocoa.cpp @@ -876,7 +876,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); } else { @@ -889,7 +889,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); } } else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable) @@ -904,7 +904,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetQuote('"'); options.SetSourceSize(explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - return ReadStringAndDumpToStream (options); + return StringPrinter::ReadStringAndDumpToStream (options); } else if (is_unicode) { @@ -935,7 +935,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetNeedsZeroTermination(has_explicit_length == false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(has_explicit_length == false); - return ReadStringAndDumpToStream (options); + return StringPrinter::ReadStringAndDumpToStream (options); } else if (is_path_store) { @@ -953,7 +953,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetNeedsZeroTermination(has_explicit_length == false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(has_explicit_length == false); - return ReadStringAndDumpToStream (options); + return StringPrinter::ReadStringAndDumpToStream (options); } else if (is_inline) { @@ -980,9 +980,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); if (has_explicit_length) - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); else - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); } else { @@ -999,7 +999,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& options.SetStream(&stream); options.SetSourceSize(explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); } } diff --git a/lldb/source/DataFormatters/StringPrinter.cpp b/lldb/source/DataFormatters/StringPrinter.cpp index 27f5b51f7d2c..a5ed7e45cdfd 100644 --- a/lldb/source/DataFormatters/StringPrinter.cpp +++ b/lldb/source/DataFormatters/StringPrinter.cpp @@ -19,99 +19,16 @@ #include "llvm/Support/ConvertUTF.h" #include -#include #include using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; -// I can't use a std::unique_ptr for this because the Deleter is a template argument there -// and I want the same type to represent both pointers I want to free and pointers I don't need -// to free - which is what this class essentially is -// It's very specialized to the needs of this file, and not suggested for general use -template -struct StringPrinterBufferPointer -{ -public: - - typedef std::function Deleter; - - StringPrinterBufferPointer (std::nullptr_t ptr) : - m_data(nullptr), - m_size(0), - m_deleter() - {} - - StringPrinterBufferPointer(const T* bytes, S size, Deleter deleter = nullptr) : - m_data(bytes), - m_size(size), - m_deleter(deleter) - {} - - StringPrinterBufferPointer(const U* bytes, S size, Deleter deleter = nullptr) : - m_data((T*)bytes), - m_size(size), - m_deleter(deleter) - {} - - StringPrinterBufferPointer(StringPrinterBufferPointer&& rhs) : - m_data(rhs.m_data), - m_size(rhs.m_size), - m_deleter(rhs.m_deleter) - { - rhs.m_data = nullptr; - } - - StringPrinterBufferPointer(const StringPrinterBufferPointer& rhs) : - m_data(rhs.m_data), - m_size(rhs.m_size), - m_deleter(rhs.m_deleter) - { - rhs.m_data = nullptr; // this is why m_data has to be mutable - } - - const T* - GetBytes () const - { - return m_data; - } - - const S - GetSize () const - { - return m_size; - } - - ~StringPrinterBufferPointer () - { - if (m_data && m_deleter) - m_deleter(m_data); - m_data = nullptr; - } - - StringPrinterBufferPointer& - operator = (const StringPrinterBufferPointer& rhs) - { - if (m_data && m_deleter) - m_deleter(m_data); - m_data = rhs.m_data; - m_size = rhs.m_size; - m_deleter = rhs.m_deleter; - rhs.m_data = nullptr; - return *this; - } - -private: - mutable const T* m_data; - size_t m_size; - Deleter m_deleter; -}; - // we define this for all values of type but only implement it for those we care about // that's good because we get linker errors for any unsupported type template -static StringPrinterBufferPointer<> +static StringPrinter::StringPrinterBufferPointer<> GetPrintableImpl(uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next); // mimic isprint() for Unicode codepoints @@ -142,10 +59,10 @@ isprint(char32_t codepoint) } template <> -StringPrinterBufferPointer<> +StringPrinter::StringPrinterBufferPointer<> GetPrintableImpl (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { - StringPrinterBufferPointer<> retval = {nullptr}; + StringPrinter::StringPrinterBufferPointer<> retval = {nullptr}; switch (*buffer) { @@ -212,10 +129,10 @@ ConvertUTF8ToCodePoint (unsigned char c0, unsigned char c1, unsigned char c2, un } template <> -StringPrinterBufferPointer<> +StringPrinter::StringPrinterBufferPointer<> GetPrintableImpl (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { - StringPrinterBufferPointer<> retval {nullptr}; + StringPrinter::StringPrinterBufferPointer<> retval {nullptr}; unsigned utf8_encoded_len = getNumBytesForUTF8(*buffer); @@ -309,7 +226,7 @@ GetPrintableImpl (uint8_t* buffer, uint8_t* buffer_end, // Given a sequence of bytes, this function returns: // a sequence of bytes to actually print out + a length // the following unscanned position of the buffer is in next -static StringPrinterBufferPointer<> +static StringPrinter::StringPrinterBufferPointer<> GetPrintable(StringElementType type, uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { if (!buffer) @@ -464,7 +381,7 @@ namespace formatters template <> bool -ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); Error my_error; @@ -608,7 +525,7 @@ ReadUTFBufferAndDumpToStream (const ReadStringAndDumpToStreamOptions& options, template <> bool -ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream(options, nullptr); @@ -616,7 +533,7 @@ ReadStringAndDumpToStream (const ReadStringAndDumpToStr template <> bool -ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream(options, ConvertUTF16toUTF8); @@ -624,7 +541,7 @@ ReadStringAndDumpToStream (const ReadStringAndDumpToSt template <> bool -ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream(options, ConvertUTF32toUTF8); @@ -632,7 +549,7 @@ ReadStringAndDumpToStream (const ReadStringAndDumpToSt template <> bool -ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); @@ -641,7 +558,7 @@ ReadBufferAndDumpToStream (const ReadBufferAndDumpToStr template <> bool -ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) { // treat ASCII the same as UTF8 // FIXME: can we optimize ASCII some more? @@ -650,7 +567,7 @@ ReadBufferAndDumpToStream (const ReadBufferAndDumpToSt template <> bool -ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); @@ -659,7 +576,7 @@ ReadBufferAndDumpToStream (const ReadBufferAndDumpToSt template <> bool -ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 660704337cbb..3ea0bcc091db 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -55,7 +55,7 @@ lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stre options.SetStream(&stream); options.SetPrefixToken('u'); - if (!ReadStringAndDumpToStream(options)) + if (!StringPrinter::ReadStringAndDumpToStream(options)) { stream.Printf("Summary Unavailable"); return true; @@ -82,7 +82,7 @@ lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stre options.SetStream(&stream); options.SetPrefixToken('U'); - if (!ReadStringAndDumpToStream(options)) + if (!StringPrinter::ReadStringAndDumpToStream(options)) { stream.Printf("Summary Unavailable"); return true; @@ -125,11 +125,11 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea switch (wchar_size) { case 8: - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); case 16: - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); case 32: - return ReadStringAndDumpToStream(options); + return StringPrinter::ReadStringAndDumpToStream(options); default: stream.Printf("size for wchar_t is not valid"); return true; @@ -160,7 +160,7 @@ lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& st options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return ReadBufferAndDumpToStream(options); + return StringPrinter::ReadBufferAndDumpToStream(options); } bool @@ -186,7 +186,7 @@ lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& st options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return ReadBufferAndDumpToStream(options); + return StringPrinter::ReadBufferAndDumpToStream(options); } bool @@ -207,5 +207,5 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return ReadBufferAndDumpToStream(options); + return StringPrinter::ReadBufferAndDumpToStream(options); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 392e812c8c12..7d7156858a3f 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -581,15 +581,15 @@ lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Str switch (wchar_t_size) { case 1: - lldb_private::formatters::ReadBufferAndDumpToStream(options); + StringPrinter::ReadBufferAndDumpToStream(options); break; case 2: - lldb_private::formatters::ReadBufferAndDumpToStream(options); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream(options); break; case 4: - lldb_private::formatters::ReadBufferAndDumpToStream(options); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream(options); break; default: @@ -630,7 +630,7 @@ lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stre options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - lldb_private::formatters::ReadBufferAndDumpToStream(options); + StringPrinter::ReadBufferAndDumpToStream(options); return true; }