shafik created this revision.
shafik added reviewers: vsk, jingham.
This adds a formatter for libc++ `std::unique_ptr`. We currently already have
formatters for `std::shared_ptr` and `std::weak_ptr`.
I also refactored `GetValueOfCompressedPair(...)` out of `LibCxxList.cpp` since
I need the same functionality and it made sense to share it.
https://reviews.llvm.org/D76476
Files:
lldb/include/lldb/DataFormatters/FormattersHelpers.h
lldb/source/DataFormatters/FormattersHelpers.cpp
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/Makefile
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
@@ -0,0 +1,12 @@
+#include <cstdio>
+#include <string>
+#include <memory>
+
+int main()
+{
+ std::unique_ptr<int> up_empty;
+ std::unique_ptr<int> up_int = std::make_unique<int>(10);
+ std::unique_ptr<std::string> up_str = std::make_unique<std::string>("hello");
+
+ return 0; // break here
+}
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
@@ -0,0 +1,37 @@
+"""
+Test lldb data formatter for libc++ std::unique_ptr.
+"""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class LibcxUniquePtrDataFormatterTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(["libc++"])
+ def test_with_run_command(self):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+
+ (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
+ lldb.SBFileSpec("main.cpp", False))
+
+ self.expect("frame variable up_empty",
+ substrs=['(std::unique_ptr<int, std::default_delete<int> >) up_empty = nullptr {',
+ '__value_ = ',
+ '}'])
+
+ self.expect("frame variable up_int",
+ substrs=['(std::unique_ptr<int, std::default_delete<int> >) up_int = 10 {',
+ '__value_ = ',
+ '}'])
+
+ self.expect("frame variable up_str",
+ substrs=['up_str = "hello" {',
+ '__value_ = ',
+ '}'])
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/Makefile
@@ -0,0 +1,6 @@
+CXX_SOURCES := main.cpp
+
+USE_LIBCPP := 1
+
+CXXFLAGS_EXTRAS := -std=c++14
+include Makefile.rules
Index: lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -290,15 +290,6 @@
m_element_type);
}
-static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) {
- ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true);
- if (! value) {
- // pre-r300140 member name
- value = pair.GetChildMemberWithName(ConstString("__first_"), true);
- }
- return value;
-}
-
bool ForwardListFrontEnd::Update() {
AbstractListFrontEnd::Update();
Index: lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -43,6 +43,10 @@
const TypeSummaryOptions
&options); // libc++ std::shared_ptr<> and std::weak_ptr<>
+// libc++ std::unique_ptr<>
+bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
bool LibcxxFunctionSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::function<>
@@ -107,6 +111,26 @@
lldb::ByteOrder m_byte_order;
};
+class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+ ~LibcxxUniquePtrSyntheticFrontEnd() override;
+
+private:
+ lldb::ValueObjectSP m_compressed_pair_sp;
+};
+
SyntheticChildrenFrontEnd *
LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -115,6 +139,10 @@
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
SyntheticChildrenFrontEnd *
LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
Index: lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -144,6 +144,43 @@
return true;
}
+bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
+ if (!ptr_sp)
+ return false;
+
+ ptr_sp = GetValueOfCompressedPair(*ptr_sp);
+ if (!ptr_sp)
+ return false;
+
+ if (ptr_sp->GetValueAsUnsigned(0) == 0) {
+ stream.Printf("nullptr");
+ return true;
+ } else {
+ bool print_pointee = false;
+ Status error;
+ ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
+ if (pointee_sp && error.Success()) {
+ if (pointee_sp->DumpPrintableRepresentation(
+ stream, ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::PrintableRepresentationSpecialCases::eDisable,
+ false))
+ print_pointee = true;
+ }
+ if (!print_pointee)
+ stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ }
+
+ return true;
+}
+
/*
(lldb) fr var ibeg --raw --ptr-depth 1
(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
@@ -449,6 +486,67 @@
: nullptr);
}
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+ if (valobj_sp)
+ Update();
+}
+
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ ~LibcxxUniquePtrSyntheticFrontEnd() = default;
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp)
+ : nullptr);
+}
+
+size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return (m_compressed_pair_sp ? 1 : 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (!m_compressed_pair_sp)
+ return lldb::ValueObjectSP();
+
+ if (idx != 0)
+ return lldb::ValueObjectSP();
+
+ return m_compressed_pair_sp;
+}
+
+bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
+ if (!ptr_sp)
+ return false;
+
+ m_compressed_pair_sp = GetValueOfCompressedPair(*ptr_sp);
+
+ return false;
+}
+
+bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
+}
+
+size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ if (name == "__value_")
+ return 0;
+ return UINT32_MAX;
+}
+
bool lldb_private::formatters::LibcxxContainerSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
if (valobj.IsPointerType()) {
Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -611,6 +611,13 @@
"shared_ptr synthetic children",
ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
+ "unique_ptr synthetic children",
+ ConstString("^(std::__[[:alnum:]]+::)unique_ptr<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
@@ -715,6 +722,11 @@
"libc++ std::weak_ptr summary provider",
ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
+ "libc++ std::unique_ptr summary provider",
+ ConstString("^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"),
+ stl_summary_flags, true);
AddCXXSynthetic(
cpp_category_sp,
Index: lldb/source/DataFormatters/FormattersHelpers.cpp
===================================================================
--- lldb/source/DataFormatters/FormattersHelpers.cpp
+++ lldb/source/DataFormatters/FormattersHelpers.cpp
@@ -142,3 +142,14 @@
return data_addr;
}
+
+lldb::ValueObjectSP
+lldb_private::formatters::GetValueOfCompressedPair(ValueObject &pair) {
+ ValueObjectSP value =
+ pair.GetChildMemberWithName(ConstString("__value_"), true);
+ if (!value) {
+ // pre-r300140 member name
+ value = pair.GetChildMemberWithName(ConstString("__first_"), true);
+ }
+ return value;
+}
Index: lldb/include/lldb/DataFormatters/FormattersHelpers.h
===================================================================
--- lldb/include/lldb/DataFormatters/FormattersHelpers.h
+++ lldb/include/lldb/DataFormatters/FormattersHelpers.h
@@ -56,6 +56,8 @@
lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj);
+lldb::ValueObjectSP GetValueOfCompressedPair(ValueObject &pair);
+
time_t GetOSXEpoch();
struct InferiorSizedWord {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits