llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Sergei Druzhkov (DrSergei) <details> <summary>Changes</summary> This patch introduces general summary provider for `std::string_view` and simial types. I tried to remove copy-paste between different stl implementations. I cannot check now how it works on Windows machine, but I hope it works as expected (I used msvc stl implementation as a base). --- Patch is 27.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/171854.diff 10 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+49-46) - (modified) lldb/source/Plugins/Language/CPlusPlus/Generic.h (+8) - (added) lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp (+131) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (+2-94) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (-16) - (modified) lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp (-63) - (modified) lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h (-9) - (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py (+5) - (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py (-2) ``````````diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt index c52d3bdb31284..940737068fd47 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -17,6 +17,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN GenericInitializerList.cpp GenericList.cpp GenericOptional.cpp + GenericStringView.cpp LibCxx.cpp LibCxxAtomic.cpp LibCxxMap.cpp diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index ae6086ff89d71..bd58abca7ab04 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -54,6 +54,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +using StringElementType = StringPrinter::StringElementType; + LLDB_PLUGIN_DEFINE(CPlusPlusLanguage) void CPlusPlusLanguage::Initialize() { @@ -799,42 +801,47 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { stl_summary_flags, true); AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, + GenericStringViewSummaryProvider<StringElementType::ASCII>, "std::string_view summary provider", "^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, + GenericStringViewSummaryProvider<StringElementType::ASCII>, "std::string_view summary provider", "^std::__[[:alnum:]]+::basic_string_view<char, " "std::__[[:alnum:]]+::char_traits<char> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, + GenericStringViewSummaryProvider<StringElementType::ASCII>, "std::string_view summary provider", "^std::__[[:alnum:]]+::basic_string_view<unsigned char, " "std::__[[:alnum:]]+::char_traits<unsigned char> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16, + GenericStringViewSummaryProvider<StringElementType::UTF8>, + "std::u8string_view summary provider", + "^std::__[[:alnum:]]+::basic_string_view<char8_t, " + "std::__[[:alnum:]]+::char_traits<char8_t> >$", + stl_summary_flags, true); + + AddCXXSummary(cpp_category_sp, + GenericStringViewSummaryProvider<StringElementType::UTF16>, "std::u16string_view summary provider", "^std::__[[:alnum:]]+::basic_string_view<char16_t, " "std::__[[:alnum:]]+::char_traits<char16_t> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32, + GenericStringViewSummaryProvider<StringElementType::UTF32>, "std::u32string_view summary provider", "^std::__[[:alnum:]]+::basic_string_view<char32_t, " "std::__[[:alnum:]]+::char_traits<char32_t> >$", stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxWStringViewSummaryProvider, + AddCXXSummary(cpp_category_sp, GenericWStringViewSummaryProvider, "std::wstring_view summary provider", "^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxWStringViewSummaryProvider, + AddCXXSummary(cpp_category_sp, GenericWStringViewSummaryProvider, "std::wstring_view summary provider", "^std::__[[:alnum:]]+::basic_string_view<wchar_t, " "std::__[[:alnum:]]+::char_traits<wchar_t> >$", @@ -1696,8 +1703,6 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( false); - using StringElementType = StringPrinter::StringElementType; - RegisterStdStringSummaryProvider( cpp_category_sp, "std::string", "char", std::make_shared<CXXFunctionSummaryFormat>( @@ -1722,9 +1727,39 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { }, "MSVC STL/libstdc++ std::wstring summary provider")); - // NOTE: it is loaded as a common formatter because the libc++ version is not - // in the `__1` namespace, hence we need to dispatch based on the class - // layout. + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::string_view", "char", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + GenericStringViewSummaryProvider<StringElementType::ASCII>, + "MSVC STL/libstdc++ std::string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u8string_view", "char8_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + GenericStringViewSummaryProvider<StringElementType::UTF8>, + "MSVC STL/libstdc++ std::u8string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u16string_view", "char16_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + GenericStringViewSummaryProvider<StringElementType::UTF16>, + "MSVC STL/libstdc++ std::u16string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u32string_view", "char32_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + GenericStringViewSummaryProvider<StringElementType::UTF32>, + "MSVC STL/libstdc++ std::u32string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::wstring_view", "wchar_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, GenericWStringViewSummaryProvider, + "MSVC STL/libstdc++ std::wstring_view summary provider")); + + // NOTE: it is loaded as a common formatter because the libc++ version is + // not in the `__1` namespace, hence we need to dispatch based on the + // class layout. AddCXXSynthetic(cpp_category_sp, GenericInitializerListSyntheticFrontEndCreator, "std::initializer_list synthetic children", @@ -1837,8 +1872,6 @@ static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( false); - using StringElementType = StringPrinter::StringElementType; - RegisterStdStringSummaryProvider( cpp_category_sp, "std::u8string", "char8_t", std::make_shared<CXXFunctionSummaryFormat>( @@ -1858,36 +1891,6 @@ static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { MsvcStlStringSummaryProvider<StringElementType::UTF32>, "MSVC STL std::u32string summary provider")); - RegisterStdStringViewSummaryProvider( - cpp_category_sp, "std::string_view", "char", - std::make_shared<CXXFunctionSummaryFormat>( - stl_summary_flags, - MsvcStlStringViewSummaryProvider<StringElementType::ASCII>, - "MSVC STL std::string_view summary provider")); - RegisterStdStringViewSummaryProvider( - cpp_category_sp, "std::u8string_view", "char8_t", - std::make_shared<CXXFunctionSummaryFormat>( - stl_summary_flags, - MsvcStlStringViewSummaryProvider<StringElementType::UTF8>, - "MSVC STL std::u8string_view summary provider")); - RegisterStdStringViewSummaryProvider( - cpp_category_sp, "std::u16string_view", "char16_t", - std::make_shared<CXXFunctionSummaryFormat>( - stl_summary_flags, - MsvcStlStringViewSummaryProvider<StringElementType::UTF16>, - "MSVC STL std::u16string_view summary provider")); - RegisterStdStringViewSummaryProvider( - cpp_category_sp, "std::u32string_view", "char32_t", - std::make_shared<CXXFunctionSummaryFormat>( - stl_summary_flags, - MsvcStlStringViewSummaryProvider<StringElementType::UTF32>, - "MSVC STL std::u32string_view summary provider")); - RegisterStdStringViewSummaryProvider( - cpp_category_sp, "std::wstring_view", "wchar_t", - std::make_shared<CXXFunctionSummaryFormat>( - stl_summary_flags, MsvcStlWStringViewSummaryProvider, - "MSVC STL std::wstring_view summary provider")); - stl_summary_flags.SetDontShowChildren(false); AddCXXSynthetic(cpp_category_sp, MsvcStlAtomicSyntheticFrontEndCreator, diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h index 539eddd3d3e78..9283875852cf1 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/Generic.h +++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h @@ -9,6 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H #define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H +#include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Utility/Stream.h" #include "lldb/ValueObject/ValueObject.h" @@ -19,6 +20,13 @@ namespace formatters { bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); +template <StringPrinter::StringElementType element_type> +bool GenericStringViewSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); + +bool GenericWStringViewSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); + /// Return the ValueObjectSP of the underlying pointer member whose type /// is a desugared 'std::shared_ptr::element_type *'. lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr, diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp new file mode 100644 index 0000000000000..f566ef210489b --- /dev/null +++ b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp @@ -0,0 +1,131 @@ +//===-- GenericStringView.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "Generic.h" +#include "LibCxx.h" + +#include "lldb/ValueObject/ValueObject.h" +#include "lldb/lldb-forward.h" + +#include "Plugins/Language/CPlusPlus/CxxStringTypes.h" +#include <tuple> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +using StringElementType = StringPrinter::StringElementType; + +enum class StlType { + LibCxx, + LibStdcpp, + MsvcStl, +}; + +std::tuple<StlType, lldb::ValueObjectSP, lldb::ValueObjectSP> +extractStringViewData(ValueObject &valobj) { + auto data_sp = valobj.GetChildMemberWithName("_Mydata"); + if (data_sp) + return std::make_tuple(StlType::MsvcStl, data_sp, + valobj.GetChildMemberWithName("_Mysize")); + data_sp = valobj.GetChildMemberWithName("_M_str"); + if (data_sp) + return std::make_tuple(StlType::LibStdcpp, data_sp, + valobj.GetChildMemberWithName("_M_len")); + return std::make_tuple( + StlType::LibCxx, + GetChildMemberWithName(valobj, + {ConstString("__data_"), ConstString("__data")}), + GetChildMemberWithName(valobj, + {ConstString("__size_"), ConstString("__size")})); +} + +template <StringPrinter::StringElementType element_type> +static bool formatStringViewImpl(lldb::ValueObjectSP data_sp, + lldb::ValueObjectSP size_sp, Stream &stream, + const TypeSummaryOptions &summary_options, + std::string prefix_token) { + if (!data_sp || !size_sp) + return false; + + bool success = false; + uint64_t size = size_sp->GetValueAsUnsigned(0, &success); + if (!success) { + stream << "Summary Unavailable"; + return true; + } + + StreamString scratch_stream; + success = StringBufferSummaryProvider<element_type>( + scratch_stream, summary_options, data_sp, size, prefix_token); + + if (success) + stream << scratch_stream.GetData(); + else + stream << "Summary Unavailable"; + return true; +} + +template <StringElementType element_type> +static constexpr const char *getPrefixToken() { + if constexpr (element_type == StringElementType::ASCII) + return ""; + if constexpr (element_type == StringElementType::UTF8) + return "u8"; + if constexpr (element_type == StringElementType::UTF16) + return "u"; + if constexpr (element_type == StringElementType::UTF32) + return "U"; + llvm_unreachable("invalid element type"); +} + +template <StringPrinter::StringElementType element_type> +bool lldb_private::formatters::GenericStringViewSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + auto [_, data_sp, size_sp] = extractStringViewData(valobj); + return formatStringViewImpl<element_type>(data_sp, size_sp, stream, options, + getPrefixToken<element_type>()); +} + +template bool lldb_private::formatters::GenericStringViewSummaryProvider< + StringElementType::ASCII>(ValueObject &, Stream &, + const TypeSummaryOptions &); +template bool lldb_private::formatters::GenericStringViewSummaryProvider< + StringElementType::UTF8>(ValueObject &, Stream &, + const TypeSummaryOptions &); +template bool lldb_private::formatters::GenericStringViewSummaryProvider< + StringElementType::UTF16>(ValueObject &, Stream &, + const TypeSummaryOptions &); +template bool lldb_private::formatters::GenericStringViewSummaryProvider< + StringElementType::UTF32>(ValueObject &, Stream &, + const TypeSummaryOptions &); + +bool lldb_private::formatters::GenericWStringViewSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + auto [stl, data_sp, size_sp] = extractStringViewData(valobj); + if (stl == StlType::LibStdcpp) + return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp, + stream, options, "L"); + + auto wchar_t_size = GetWCharByteSize(valobj); + if (!wchar_t_size) + return false; + + switch (*wchar_t_size) { + case 1: + return formatStringViewImpl<StringElementType::UTF8>(data_sp, size_sp, + stream, options, "L"); + case 2: + return formatStringViewImpl<StringElementType::UTF16>(data_sp, size_sp, + stream, options, "L"); + case 4: + return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp, + stream, options, "L"); + } + return false; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 141c5c9a2caf9..a68c9f0fdc963 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -495,8 +495,8 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { StringLayout layout = *index_or_err == 0 ? StringLayout::DSC : StringLayout::CSD; - bool short_mode = false; // this means the string is in short-mode and the - // data is stored inline + bool short_mode = false; // this means the string is in short-mode and the + // data is stored inline bool using_bitmasks = true; // Whether the class uses bitmasks for the mode // flag (pre-D123580). uint64_t size; @@ -638,98 +638,6 @@ bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( valobj, stream, summary_options, "U"); } -static std::tuple<bool, ValueObjectSP, size_t> -LibcxxExtractStringViewData(ValueObject& valobj) { - auto dataobj = GetChildMemberWithName( - valobj, {ConstString("__data_"), ConstString("__data")}); - auto sizeobj = GetChildMemberWithName( - valobj, {ConstString("__size_"), ConstString("__size")}); - if (!dataobj || !sizeobj) - return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {}); - - if (!dataobj->GetError().Success() || !sizeobj->GetError().Success()) - return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {}); - - bool success{false}; - uint64_t size = sizeobj->GetValueAsUnsigned(0, &success); - if (!success) - return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {}); - - return std::make_tuple(true,dataobj,size); -} - -template <StringPrinter::StringElementType element_type> -static bool formatStringViewImpl(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options, - std::string prefix_token) { - - bool success; - ValueObjectSP dataobj; - size_t size; - std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj); - - if (!success) { - stream << "Summary Unavailable"; - return true; - } - - return StringBufferSummaryProvider<element_type>(stream, summary_options, - dataobj, size, prefix_token); -} - -bool lldb_private::formatters::LibcxxStringViewSummaryProviderASCII( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options) { - return formatStringViewImpl<StringPrinter::StringElementType::ASCII>( - valobj, stream, summary_options, ""); -} - -bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options) { - return formatStringViewImpl<StringPrinter::StringElementType::UTF16>( - valobj, stream, summary_options, "u"); -} - -bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options) { - return formatStringViewImpl<StringPrinter::StringElementType::UTF32>( - valobj, stream, summary_options, "U"); -} - -bool lldb_private::formatters::LibcxxWStringViewSummaryProvider( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options) { - - bool success; - ValueObjectSP dataobj; - size_t size; - std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj); - - if (!success) { - stream << "Summary Unavailable"; - return true; - } - - auto wchar_t_size = GetWCharByteSize(valobj); - if (!wchar_t_size) - return false; - - switch (*wchar_t_size) { - case 1: - return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF8>( - stream, summary_options, dataobj, size, "L"); - case 2: - return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF16>( - stream, summary_options, dataobj, size, "L"); - case 4: - return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF32>( - stream, summary_options, dataobj, size, "L"); - } - return false; -} - static bool LibcxxChronoTimePointSecondsSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options, diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plug... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/171854 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
