tberghammer created this revision.
tberghammer added reviewers: labath, granata.enrico.
tberghammer added a subscriber: lldb-commits.

Improve the libstdc++ smart pointer formatters

      

- Display the strong/weak count in the summary
- Display the pointed object as a synthetic member
- Create synthetic children for weak/strong count


https://reviews.llvm.org/D25726

Files:
  
packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py
  source/Plugins/Language/CPlusPlus/LibStdcpp.cpp

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<DataBufferHeap>(&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);
 }
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,19 +31,35 @@
                     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")
 
         self.expect("frame variable nsp", substrs=['nsp = nullptr'])
         self.expect("frame variable isp", substrs=['isp = nullptr'])
         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'])
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to