llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Sergei Druzhkov (DrSergei) <details> <summary>Changes</summary> I want to propose adding summary providers for `std::*_ordering` types introduced in `C++20`. GDB already has pretty-printers for [them](https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L1788), so I think it will be useful. --- Full diff: https://github.com/llvm/llvm-project/pull/174195.diff 8 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+33) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (+93-7) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+12) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp (+88-1) - (modified) lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h (+12) - (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/Makefile (+4) - (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/TestDataFormatterStdOrdering.py (+42) - (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/main.cpp (+16) ``````````diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index dd3b84e47dec3..3c1464485bbe0 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1286,6 +1286,22 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { TypeSummaryImplSP(new StringSummaryFormat( eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__y_} ${var.__m_} ${var.__wdl_}"))); + + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxPartialOrderingSummaryProvider, + "libc++ std::partial_ordering summary provider", + "^std::__[[:alnum:]]+::partial_ordering$", + eTypeOptionHideChildren | eTypeOptionHideValue, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxWeakOrderingSummaryProvider, + "libc++ std::weak_ordering summary provider", + "^std::__[[:alnum:]]+::weak_ordering$", + eTypeOptionHideChildren | eTypeOptionHideValue, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxStrongOrderingSummaryProvider, + "libc++ std::strong_ordering summary provider", + "^std::__[[:alnum:]]+::strong_ordering$", + eTypeOptionHideChildren | eTypeOptionHideValue, true); } static void RegisterStdStringSummaryProvider( @@ -1515,6 +1531,23 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { lldb_private::formatters::ContainerSizeSummaryProvider, "libstdc++ std::span summary provider", "^std::span<.+>$", stl_summary_flags, true); + + AddCXXSummary( + cpp_category_sp, + lldb_private::formatters::LibStdcppPartialOrderingSummaryProvider, + "libstdc++ std::partial_ordering summary provider", + "std::partial_ordering", eTypeOptionHideChildren | eTypeOptionHideValue, + false); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibStdcppWeakOrderingSummaryProvider, + "libstdc++ std::weak_ordering summary provider", + "std::weak_ordering", + eTypeOptionHideChildren | eTypeOptionHideValue, false); + AddCXXSummary( + cpp_category_sp, + lldb_private::formatters::LibStdcppStrongOrderingSummaryProvider, + "libstdc++ std::strong_ordering summary provider", "std::strong_ordering", + eTypeOptionHideChildren | eTypeOptionHideValue, false); } static lldb_private::SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 141c5c9a2caf9..914abd9590c95 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -256,6 +256,92 @@ bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider( return true; } +static std::optional<int64_t> LibcxxExtractOrderingValue(ValueObject &valobj) { + lldb::ValueObjectSP value_sp = valobj.GetChildMemberWithName("__value_"); + if (!value_sp) + return std::nullopt; + bool success; + int64_t value = value_sp->GetValueAsSigned(0, &success); + if (!success) + return std::nullopt; + return value; +} + +bool lldb_private::formatters::LibcxxPartialOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibcxxExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equivalent"; + break; + case 1: + stream << "greater"; + break; + case -127: + stream << "unordered"; + break; + default: + stream << "Invalid partial ordering value"; + break; + } + return true; +} + +bool lldb_private::formatters::LibcxxWeakOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibcxxExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equivalent"; + break; + case 1: + stream << "greater"; + break; + default: + stream << "Invalid weak ordering value"; + break; + } + return true; +} + +bool lldb_private::formatters::LibcxxStrongOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibcxxExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equal"; + break; + case 1: + stream << "greater"; + break; + default: + stream << "Invalid strong ordering value"; + break; + } + return true; +} + /* (lldb) fr var ibeg --raw --ptr-depth 1 -T (std::__1::__wrap_iter<int *>) ibeg = { @@ -495,8 +581,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; @@ -639,23 +725,23 @@ bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( } static std::tuple<bool, ValueObjectSP, size_t> -LibcxxExtractStringViewData(ValueObject& valobj) { +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, {}, {}); + 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, {}, {}); + 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<bool, ValueObjectSP, size_t>(false, {}, {}); - return std::make_tuple(true,dataobj,size); + return std::make_tuple(true, dataobj, size); } template <StringPrinter::StringElementType element_type> diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index 8fd29288da35f..69cca8ee621d9 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -92,6 +92,18 @@ bool LibcxxFunctionSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::function<> +bool LibcxxPartialOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::partial_ordering + +bool LibcxxWeakOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::weak_ordering + +bool LibcxxStrongOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::strong_ordering + SyntheticChildrenFrontEnd * LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 86f0a5ad78a9a..c1e06850be9b3 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -73,7 +73,6 @@ class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override; private: - // The lifetime of a ValueObject and all its derivative ValueObjects // (children, clones, etc.) is managed by a ClusterManager. These // objects are only destroyed when every shared pointer to any of them @@ -410,3 +409,91 @@ bool formatters::LibStdcppVariantSummaryProvider( stream << " Active Type = " << active_type.GetDisplayTypeName() << " "; return true; } + +static std::optional<int64_t> +LibStdcppExtractOrderingValue(ValueObject &valobj) { + lldb::ValueObjectSP value_sp = valobj.GetChildMemberWithName("_M_value"); + if (!value_sp) + return std::nullopt; + bool success; + int64_t value = value_sp->GetValueAsSigned(0, &success); + if (!success) + return std::nullopt; + return value; +} + +bool lldb_private::formatters::LibStdcppPartialOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equivalent"; + break; + case 1: + stream << "greater"; + break; + case -128: + case 2: + stream << "unordered"; + break; + default: + stream << "Invalid partial ordering value"; + break; + } + return true; +} + +bool lldb_private::formatters::LibStdcppWeakOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equivalent"; + break; + case 1: + stream << "greater"; + break; + default: + stream << "Invalid weak ordering value"; + break; + } + return true; +} + +bool lldb_private::formatters::LibStdcppStrongOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj); + if (!value) { + stream << "Summary Unavailable"; + return true; + } + switch (*value) { + case -1: + stream << "less"; + break; + case 0: + stream << "equal"; + break; + case 1: + stream << "greater"; + break; + default: + stream << "Invalid strong ordering value"; + break; + } + return true; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index 8d2c81f2bbcbb..94d4968b45175 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -33,6 +33,18 @@ bool LibStdcppVariantSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libstdc++ std::variant<> +bool LibStdcppPartialOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libstdc++ std::partial_ordering + +bool LibStdcppWeakOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libstdc++ std::weak_ordering + +bool LibStdcppStrongOrderingSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libstdc++ std::strong_ordering + SyntheticChildrenFrontEnd * LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/Makefile new file mode 100644 index 0000000000000..4f79c0a900c3a --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++20 + +include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/TestDataFormatterStdOrdering.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/TestDataFormatterStdOrdering.py new file mode 100644 index 0000000000000..aa0b08249030a --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/TestDataFormatterStdOrdering.py @@ -0,0 +1,42 @@ +""" +Test std::*_ordering summary. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class StdOrderingTestCase(TestBase): + def do_test(self): + lldbutil.run_to_source_breakpoint( + self, "// break here", lldb.SBFileSpec("main.cpp") + ) + + self.expect( + "frame variable", + substrs=[ + "(std::partial_ordering) po_less = less", + "(std::partial_ordering) po_equivalent = equivalent", + "(std::partial_ordering) po_greater = greater", + "(std::partial_ordering) po_unordered = unordered", + "(std::weak_ordering) wo_less = less", + "(std::weak_ordering) wo_equivalent = equivalent", + "(std::weak_ordering) wo_greater = greater", + "(std::strong_ordering) so_less = less", + "(std::strong_ordering) so_equal = equal", + "(std::strong_ordering) so_equivalent = equal", + "(std::strong_ordering) so_greater = greater", + ], + ) + + @add_test_categories(["libc++"]) + def test_libcxx(self): + self.build(dictionary={"USE_LIBCPP": 1}) + self.do_test() + + @add_test_categories(["libstdcxx"]) + def test_libstdcxx(self): + self.build(dictionary={"USE_LIBSTDCPP": 1}) + self.do_test() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/main.cpp new file mode 100644 index 0000000000000..2135d5558c1e7 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/ordering/main.cpp @@ -0,0 +1,16 @@ +#include <compare> + +int main() { + auto po_less = std::partial_ordering::less; + auto po_equivalent = std::partial_ordering::equivalent; + auto po_greater = std::partial_ordering::greater; + auto po_unordered = std::partial_ordering::unordered; + auto wo_less = std::weak_ordering::less; + auto wo_equivalent = std::weak_ordering::equivalent; + auto wo_greater = std::weak_ordering::greater; + auto so_less = std::strong_ordering::less; + auto so_equal = std::strong_ordering::equal; + auto so_equivalent = std::strong_ordering::equivalent; + auto so_greater = std::strong_ordering::greater; + return 0; // break here +} `````````` </details> https://github.com/llvm/llvm-project/pull/174195 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
