mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 15:36:07 +00:00
[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
This commit is contained in:
parent
1b9cd51d55
commit
a567d6809e
@ -56,6 +56,8 @@ size_t ExtractIndexFromString(const char *item_name);
|
|||||||
|
|
||||||
lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj);
|
lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj);
|
||||||
|
|
||||||
|
lldb::ValueObjectSP GetValueOfLibCXXCompressedPair(ValueObject &pair);
|
||||||
|
|
||||||
time_t GetOSXEpoch();
|
time_t GetOSXEpoch();
|
||||||
|
|
||||||
struct InferiorSizedWord {
|
struct InferiorSizedWord {
|
||||||
|
@ -142,3 +142,14 @@ lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) {
|
|||||||
|
|
||||||
return data_addr;
|
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;
|
||||||
|
}
|
||||||
|
@ -611,6 +611,15 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
|
|||||||
"shared_ptr synthetic children",
|
"shared_ptr synthetic children",
|
||||||
ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
|
ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
|
||||||
stl_synth_flags, true);
|
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(
|
AddCXXSynthetic(
|
||||||
cpp_category_sp,
|
cpp_category_sp,
|
||||||
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
|
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
|
||||||
@ -715,6 +724,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
|
|||||||
"libc++ std::weak_ptr summary provider",
|
"libc++ std::weak_ptr summary provider",
|
||||||
ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
|
ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
|
||||||
stl_summary_flags, true);
|
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(
|
AddCXXSynthetic(
|
||||||
cpp_category_sp,
|
cpp_category_sp,
|
||||||
|
@ -144,6 +144,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
|
|||||||
return true;
|
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
|
(lldb) fr var ibeg --raw --ptr-depth 1
|
||||||
(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
|
(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
|
||||||
@ -449,6 +486,67 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
|
|||||||
: nullptr);
|
: 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(
|
bool lldb_private::formatters::LibcxxContainerSummaryProvider(
|
||||||
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
|
||||||
if (valobj.IsPointerType()) {
|
if (valobj.IsPointerType()) {
|
||||||
|
@ -43,6 +43,10 @@ bool LibcxxSmartPointerSummaryProvider(
|
|||||||
const TypeSummaryOptions
|
const TypeSummaryOptions
|
||||||
&options); // libc++ std::shared_ptr<> and std::weak_ptr<>
|
&options); // libc++ std::shared_ptr<> and std::weak_ptr<>
|
||||||
|
|
||||||
|
// libc++ std::unique_ptr<>
|
||||||
|
bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream,
|
||||||
|
const TypeSummaryOptions &options);
|
||||||
|
|
||||||
bool LibcxxFunctionSummaryProvider(
|
bool LibcxxFunctionSummaryProvider(
|
||||||
ValueObject &valobj, Stream &stream,
|
ValueObject &valobj, Stream &stream,
|
||||||
const TypeSummaryOptions &options); // libc++ std::function<>
|
const TypeSummaryOptions &options); // libc++ std::function<>
|
||||||
@ -107,6 +111,26 @@ private:
|
|||||||
lldb::ByteOrder m_byte_order;
|
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 *
|
SyntheticChildrenFrontEnd *
|
||||||
LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
||||||
lldb::ValueObjectSP);
|
lldb::ValueObjectSP);
|
||||||
@ -115,6 +139,10 @@ SyntheticChildrenFrontEnd *
|
|||||||
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
||||||
lldb::ValueObjectSP);
|
lldb::ValueObjectSP);
|
||||||
|
|
||||||
|
SyntheticChildrenFrontEnd *
|
||||||
|
LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
||||||
|
lldb::ValueObjectSP);
|
||||||
|
|
||||||
SyntheticChildrenFrontEnd *
|
SyntheticChildrenFrontEnd *
|
||||||
LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
|
||||||
lldb::ValueObjectSP);
|
lldb::ValueObjectSP);
|
||||||
|
@ -290,15 +290,6 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) {
|
|||||||
m_element_type);
|
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() {
|
bool ForwardListFrontEnd::Update() {
|
||||||
AbstractListFrontEnd::Update();
|
AbstractListFrontEnd::Update();
|
||||||
|
|
||||||
@ -311,7 +302,7 @@ bool ForwardListFrontEnd::Update() {
|
|||||||
m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
|
m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
|
||||||
if (!impl_sp)
|
if (!impl_sp)
|
||||||
return false;
|
return false;
|
||||||
impl_sp = GetValueOfCompressedPair(*impl_sp);
|
impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp);
|
||||||
if (!impl_sp)
|
if (!impl_sp)
|
||||||
return false;
|
return false;
|
||||||
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
|
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
|
||||||
@ -332,7 +323,7 @@ size_t ListFrontEnd::CalculateNumChildren() {
|
|||||||
ValueObjectSP size_alloc(
|
ValueObjectSP size_alloc(
|
||||||
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
|
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
|
||||||
if (size_alloc) {
|
if (size_alloc) {
|
||||||
ValueObjectSP value = GetValueOfCompressedPair(*size_alloc);
|
ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc);
|
||||||
if (value) {
|
if (value) {
|
||||||
m_count = value->GetValueAsUnsigned(UINT32_MAX);
|
m_count = value->GetValueAsUnsigned(UINT32_MAX);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
CXX_SOURCES := main.cpp
|
||||||
|
|
||||||
|
USE_LIBCPP := 1
|
||||||
|
|
||||||
|
CXXFLAGS_EXTRAS := -std=c++14
|
||||||
|
include Makefile.rules
|
@ -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_ = ',
|
||||||
|
'}'])
|
@ -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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user