Index: packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py +++ packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py @@ -31,12 +31,24 @@ substrs=['stopped', 'stop reason = breakpoint']) self.expect("frame variable nsp", substrs=['nsp = nullptr']) - self.expect("frame variable isp", substrs=['isp = 123']) - self.expect("frame variable ssp", substrs=['ssp = "foobar"']) + self.expect("frame variable isp", substrs=['isp = 123', 'strong=1', 'weak=1']) + self.expect("frame variable isp.object", substrs=['object = 123']) + self.expect("frame variable isp.count", substrs=['count = 1']) + self.expect("frame variable isp.weak_count", substrs=['weak_count = 1']) + self.expect("frame variable ssp", substrs=['ssp = "foobar"', 'strong=1', 'weak=1']) + self.expect("frame variable ssp.object", substrs=['object = "foobar"']) + self.expect("frame variable ssp.count", substrs=['count = 1']) + self.expect("frame variable ssp.weak_count", substrs=['weak_count = 1']) self.expect("frame variable nwp", substrs=['nwp = nullptr']) - self.expect("frame variable iwp", substrs=['iwp = 123']) - self.expect("frame variable swp", substrs=['swp = "foobar"']) + self.expect("frame variable iwp", substrs=['iwp = 123', 'strong=1', 'weak=1']) + self.expect("frame variable iwp.object", substrs=['object = 123']) + self.expect("frame variable iwp.count", substrs=['count = 1']) + self.expect("frame variable iwp.weak_count", substrs=['weak_count = 1']) + self.expect("frame variable swp", substrs=['swp = "foobar"', 'strong=1', 'weak=1']) + self.expect("frame variable swp.object", substrs=['object = "foobar"']) + self.expect("frame variable swp.count", substrs=['count = 1']) + self.expect("frame variable swp.weak_count", substrs=['weak_count = 1']) self.runCmd("continue") @@ -45,5 +57,9 @@ self.expect("frame variable ssp", substrs=['ssp = nullptr']) self.expect("frame variable nwp", substrs=['nwp = nullptr']) - self.expect("frame variable iwp", substrs=['iwp = nullptr']) - self.expect("frame variable swp", substrs=['swp = nullptr']) + self.expect("frame variable iwp", substrs=['iwp = nullptr', 'strong=0', 'weak=1']) + self.expect("frame variable iwp.count", substrs=['count = 0']) + self.expect("frame variable iwp.weak_count", substrs=['weak_count = 1']) + self.expect("frame variable swp", substrs=['swp = nullptr', 'strong=0', 'weak=1']) + self.expect("frame variable swp.count", substrs=['count = 0']) + self.expect("frame variable swp.weak_count", substrs=['weak_count = 1']) Index: source/Plugins/Language/CPlusPlus/LibStdcpp.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -76,6 +76,20 @@ bool MightHaveChildren() override; size_t GetIndexOfChildWithName(const ConstString &name) override; + + bool GetSummary(Stream &stream, const TypeSummaryOptions &options); + + private: + ValueObjectSP m_ptr_obj; + ValueObjectSP m_obj_obj; + ValueObjectSP m_use_obj; + ValueObjectSP m_weak_obj; + + uint8_t m_ptr_size = 0; + lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; + + bool IsEmpty(); + bool IsValid(); }; } // end of anonymous namespace @@ -355,35 +369,126 @@ LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd( lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp) { - if (valobj_sp) - Update(); + Update(); } -size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; } +bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { + ValueObjectSP valobj_backend_sp = m_backend.GetSP(); + if (!valobj_backend_sp) return false; -lldb::ValueObjectSP -LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { - ValueObjectSP valobj_sp = m_backend.GetSP(); - if (!valobj_sp) - return lldb::ValueObjectSP(); + ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue(); + if (!valobj_sp) return false; - if (idx == 0) - return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); - else - return lldb::ValueObjectSP(); -} + TargetSP target_sp(valobj_sp->GetTargetSP()); + if (!target_sp) return false; -bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; } + m_byte_order = target_sp->GetArchitecture().GetByteOrder(); + m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); + + m_ptr_obj = valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); + + m_use_obj = valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), + ConstString("_M_pi"), + ConstString("_M_use_count")}); + + m_weak_obj = valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), + ConstString("_M_pi"), + ConstString("_M_weak_count")}); + + if (m_use_obj && m_weak_obj && m_use_obj->GetValueAsUnsigned(0) > 0) { + bool success = false; + uint64_t count = m_weak_obj->GetValueAsUnsigned(0, &success) - 1; + if (success) { + auto data = std::make_shared(&count, sizeof(count)); + m_weak_obj = CreateValueObjectFromData( + "weak_count", DataExtractor(data, m_byte_order, m_ptr_size), + m_weak_obj->GetExecutionContextRef(), m_weak_obj->GetCompilerType()); + } + } + + if (m_ptr_obj && !IsEmpty()) { + Error error; + m_obj_obj = m_ptr_obj->Dereference(error); + if (error.Success()) { + m_obj_obj->SetName(ConstString("object")); + } + } + + return false; +} bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; } +lldb::ValueObjectSP LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + if (idx == 0) return m_obj_obj; + if (idx == 1) return m_ptr_obj; + if (idx == 2) return m_use_obj; + if (idx == 3) return m_weak_obj; + return lldb::ValueObjectSP(); +} + +size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { + if (IsEmpty()) return 0; + return 1; +} + size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName( const ConstString &name) { - if (name == ConstString("_M_ptr")) - return 0; + if (name == ConstString("obj") || name == ConstString("object")) return 0; + if (name == ConstString("ptr") || name == ConstString("pointer") || + name == ConstString("_M_ptr")) + return 1; + if (name == ConstString("cnt") || name == ConstString("count") || + name == ConstString("use_count") || name == ConstString("strong") || + name == ConstString("_M_use_count")) + return 2; + if (name == ConstString("weak") || name == ConstString("weak_count") || + name == ConstString("_M_weak_count")) + return 3; return UINT32_MAX; } +bool LibStdcppSharedPtrSyntheticFrontEnd::GetSummary( + Stream &stream, const TypeSummaryOptions &options) { + if (!IsValid()) return false; + + if (IsEmpty()) { + stream.Printf("nullptr"); + } else { + Error error; + bool print_pointee = false; + if (m_obj_obj) { + if (m_obj_obj->DumpPrintableRepresentation( + stream, ValueObject::eValueObjectRepresentationStyleSummary, + lldb::eFormatInvalid, + ValueObject::ePrintableRepresentationSpecialCasesDisable, + false)) { + print_pointee = true; + } + } + if (!print_pointee) + stream.Printf("ptr = 0x%" PRIx64, m_ptr_obj->GetValueAsUnsigned(0)); + } + + if (m_use_obj && m_use_obj->GetError().Success()) + stream.Printf(" strong=%" PRIu64, m_use_obj->GetValueAsUnsigned(0)); + + if (m_weak_obj && m_weak_obj->GetError().Success()) + stream.Printf(" weak=%" PRIu64, m_weak_obj->GetValueAsUnsigned(0)); + + return true; +} + +bool LibStdcppSharedPtrSyntheticFrontEnd::IsValid() { + return m_ptr_obj != nullptr; +} + +bool LibStdcppSharedPtrSyntheticFrontEnd::IsEmpty() { + return !IsValid() || m_ptr_obj->GetValueAsUnsigned(0) == 0 || + (m_use_obj && m_use_obj->GetValueAsUnsigned(0) == 0); +} + SyntheticChildrenFrontEnd * lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { @@ -393,38 +498,6 @@ bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); - if (!valobj_sp) - return false; - - ValueObjectSP ptr_sp( - valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true)); - if (!ptr_sp) - return false; - - ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath( - {ConstString("_M_refcount"), ConstString("_M_pi"), - ConstString("_M_use_count")})); - if (!usecount_sp) - return false; - - if (ptr_sp->GetValueAsUnsigned(0) == 0 || - usecount_sp->GetValueAsUnsigned(0) == 0) { - stream.Printf("nullptr"); - return true; - } - - Error error; - ValueObjectSP pointee_sp = ptr_sp->Dereference(error); - if (pointee_sp && error.Success()) { - if (pointee_sp->DumpPrintableRepresentation( - stream, ValueObject::eValueObjectRepresentationStyleSummary, - lldb::eFormatInvalid, - ValueObject::ePrintableRepresentationSpecialCasesDisable, false)) { - return true; - } - } - - stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); - return true; + LibStdcppSharedPtrSyntheticFrontEnd formatter(valobj.GetSP()); + return formatter.GetSummary(stream, options); }