-
Notifications
You must be signed in to change notification settings - Fork 15.7k
[lldb] Add std::*_ordering summary providers #174195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-lldb Author: Sergei Druzhkov (DrSergei) ChangesI want to propose adding summary providers for Full diff: https://github.com/llvm/llvm-project/pull/174195.diff 8 Files Affected:
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
+}
|
Nerixyz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The values from the MSVC STL are similar (https://github.com/microsoft/STL/blob/cbe2ee99caf122555a305d18f69e57c75b3fe5ec/stl/debugger/STL.natvis#L2012-L2032).
If you want to add them here, I can run the test for you before a merge, since we don't have a Windows premerge CI.
| bool short_mode = false; // this means the string is in short-mode and the | ||
| // data is stored inline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the changes below are unrelated (probably from format-on-save?).
...onalities/data-formatter/data-formatter-stl/generic/ordering/TestDataFormatterStdOrdering.py
Show resolved
Hide resolved
| "(std::strong_ordering) so_equal = equal", | ||
| "(std::strong_ordering) so_equivalent = equal", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we distinguish strong_ordering::equal from strong_ordering::equivalent even though they are semantically the same ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They have the same value representation (0). Both of GDB pretty-printers and MSVC Natvis use equal in this case, so I prefer to keep existing behavior.
Michael137
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be great if you could split this into separate PRs per STL. Otherwise LGTM (modulo the existing comments)
Thanks, I will add implementation for MSVC stl and libc++ in separate PRs |
I want to propose adding summary providers for
std::*_orderingtypes introduced inC++20. GDB already has pretty-printers for them, so I think it will be useful.