[Lldb-commits] [lldb] a567d68 - [DataFormatters] Add formatter for libc++ std::unique_ptr
via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 23 11:49:43 PDT 2020
Author: shafik
Date: 2020-03-23T11:48:20-07:00
New Revision: a567d6809e1514f34975d746bb1c93301792a74c
URL: https://github.com/llvm/llvm-project/commit/a567d6809e1514f34975d746bb1c93301792a74c
DIFF: https://github.com/llvm/llvm-project/commit/a567d6809e1514f34975d746bb1c93301792a74c.diff
LOG: [DataFormatters] Add formatter for libc++ std::unique_ptr
This adds a formatter for libc++ std::unique_ptr.
I also refactored GetValueOfCompressedPair(...) out of LibCxxList.cpp since I need the same functionality and it made sense to share it.
Differential Revision: https://reviews.llvm.org/D76476
Added:
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
Modified:
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
Removed:
################################################################################
diff --git a/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/lldb/include/lldb/DataFormatters/FormattersHelpers.h
index 93642e57fde0..a5b0da57e5d8 100644
--- a/lldb/include/lldb/DataFormatters/FormattersHelpers.h
+++ b/lldb/include/lldb/DataFormatters/FormattersHelpers.h
@@ -56,6 +56,8 @@ size_t ExtractIndexFromString(const char *item_name);
lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj);
+lldb::ValueObjectSP GetValueOfLibCXXCompressedPair(ValueObject &pair);
+
time_t GetOSXEpoch();
struct InferiorSizedWord {
diff --git a/lldb/source/DataFormatters/FormattersHelpers.cpp b/lldb/source/DataFormatters/FormattersHelpers.cpp
index 96e93808c18e..7944ff06eee5 100644
--- a/lldb/source/DataFormatters/FormattersHelpers.cpp
+++ b/lldb/source/DataFormatters/FormattersHelpers.cpp
@@ -142,3 +142,14 @@ lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) {
return data_addr;
}
+
+lldb::ValueObjectSP
+lldb_private::formatters::GetValueOfLibCXXCompressedPair(ValueObject &pair) {
+ ValueObjectSP value =
+ pair.GetChildMemberWithName(ConstString("__value_"), true);
+ if (!value) {
+ // pre-r300140 member name
+ value = pair.GetChildMemberWithName(ConstString("__first_"), true);
+ }
+ return value;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 97084da5fffa..ecb577e0c531 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -611,6 +611,15 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"shared_ptr synthetic children",
ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
stl_synth_flags, true);
+
+ ConstString libcxx_std_unique_ptr_regex(
+ "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$");
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
+ "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
+ stl_synth_flags, true);
+
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
@@ -715,6 +724,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"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",
+ libcxx_std_unique_ptr_regex, stl_summary_flags, true);
AddCXXSynthetic(
cpp_category_sp,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 7152ff407f29..84dd09a47d8a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -144,6 +144,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
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 = GetValueOfLibCXXCompressedPair(*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 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
: 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 = GetValueOfLibCXXCompressedPair(*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()) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index a92e8be9abe9..ea5a7c178178 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -43,6 +43,10 @@ bool LibcxxSmartPointerSummaryProvider(
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 @@ class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
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 @@ SyntheticChildrenFrontEnd *
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
SyntheticChildrenFrontEnd *
LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 4c5940a45766..0d5ae16a0b29 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -290,15 +290,6 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) {
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();
@@ -311,7 +302,7 @@ bool ForwardListFrontEnd::Update() {
m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
if (!impl_sp)
return false;
- impl_sp = GetValueOfCompressedPair(*impl_sp);
+ impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp);
if (!impl_sp)
return false;
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
@@ -332,7 +323,7 @@ size_t ListFrontEnd::CalculateNumChildren() {
ValueObjectSP size_alloc(
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
if (size_alloc) {
- ValueObjectSP value = GetValueOfCompressedPair(*size_alloc);
+ ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc);
if (value) {
m_count = value->GetValueAsUnsigned(UINT32_MAX);
}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/Makefile
new file mode 100644
index 000000000000..7e57f13aea55
--- /dev/null
+++ b/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
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
new file mode 100644
index 000000000000..b91e494258bf
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
@@ -0,0 +1,47 @@
+"""
+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_int_ref",
+ substrs=['(std::unique_ptr<int, std::default_delete<int> > &) up_int_ref = 10: {',
+ '__value_ = ',
+ '}'])
+
+ self.expect("frame variable up_int_ref_ref",
+ substrs=['(std::unique_ptr<int, std::default_delete<int> > &&) up_int_ref_ref = 10: {',
+ '__value_ = ',
+ '}'])
+
+ self.expect("frame variable up_str",
+ substrs=['up_str = "hello" {',
+ '__value_ = ',
+ '}'])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
new file mode 100644
index 000000000000..4ccffe2a006d
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/main.cpp
@@ -0,0 +1,13 @@
+#include <cstdio>
+#include <memory>
+#include <string>
+
+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");
+ std::unique_ptr<int> &up_int_ref = up_int;
+ std::unique_ptr<int> &&up_int_ref_ref = std::make_unique<int>(10);
+
+ return 0; // break here
+}
More information about the lldb-commits
mailing list