[Lldb-commits] [lldb] r284830 - Add data formatter for libstdc++ unique_ptr

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 21 08:02:44 PDT 2016


Author: tberghammer
Date: Fri Oct 21 10:02:44 2016
New Revision: 284830

URL: http://llvm.org/viewvc/llvm-project?rev=284830&view=rev
Log:
Add data formatter for libstdc++ unique_ptr

Differential revision: https://reviews.llvm.org/D25734

Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
Modified:
    lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt
    lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/Makefile?rev=284830&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/Makefile Fri Oct 21 10:02:44 2016
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+USE_LIBSTDCPP := 1
+CFLAGS_EXTRAS += $(NO_LIMIT_DEBUG_INFO_FLAGS)
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py?rev=284830&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py Fri Oct 21 10:02:44 2016
@@ -0,0 +1,61 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+import os
+import time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class StdUniquePtrDataFormatterTestCase(TestBase):
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIfFreeBSD
+    @skipIfWindows  # libstdcpp not ported to Windows
+    @skipIfDarwin  # doesn't compile on Darwin
+    def test_with_run_command(self):
+        self.build()
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_source_regexp(
+            self, "Set break point at this line.")
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
+
+        frame = self.frame()
+        self.assertTrue(frame.IsValid())
+
+        self.expect("frame variable nup", substrs=['nup = nullptr'])
+        self.expect("frame variable iup", substrs=['iup = 123', 'object = 123'])
+        self.expect("frame variable sup", substrs=['sup = "foobar"', 'object = "foobar"'])
+
+        self.expect("frame variable ndp", substrs=['ndp = nullptr'])
+        self.expect("frame variable idp", substrs=['idp = 456', 'object = 456', 'deleter = ', 'a = 1', 'b = 2'])
+        self.expect("frame variable sdp", substrs=['sdp = "baz"', 'object = "baz"', 'deleter = ', 'a = 3', 'b = 4'])
+        
+        self.assertEqual(123, frame.GetValueForVariablePath("iup.object").GetValueAsUnsigned())
+        self.assertFalse(frame.GetValueForVariablePath("iup.deleter").IsValid())
+
+        self.assertEqual('"foobar"', frame.GetValueForVariablePath("sup.object").GetSummary())
+        self.assertFalse(frame.GetValueForVariablePath("sup.deleter").IsValid())
+
+        self.assertEqual(456, frame.GetValueForVariablePath("idp.object").GetValueAsUnsigned())
+        self.assertEqual('"baz"', frame.GetValueForVariablePath("sdp.object").GetSummary())
+
+        idp_deleter = frame.GetValueForVariablePath("idp.deleter")
+        self.assertTrue(idp_deleter.IsValid())
+        self.assertEqual(1, idp_deleter.GetChildMemberWithName("a").GetValueAsUnsigned())
+        self.assertEqual(2, idp_deleter.GetChildMemberWithName("b").GetValueAsUnsigned())
+
+        sdp_deleter = frame.GetValueForVariablePath("sdp.deleter")
+        self.assertTrue(sdp_deleter.IsValid())
+        self.assertEqual(3, sdp_deleter.GetChildMemberWithName("a").GetValueAsUnsigned())
+        self.assertEqual(4, sdp_deleter.GetChildMemberWithName("b").GetValueAsUnsigned())

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp?rev=284830&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/main.cpp Fri Oct 21 10:02:44 2016
@@ -0,0 +1,22 @@
+#include <memory>
+#include <string>
+
+struct Deleter {
+  void operator()(void *) {}
+
+  int a;
+  int b;
+};
+
+int main() {
+  std::unique_ptr<char> nup;
+  std::unique_ptr<int> iup(new int{123});
+  std::unique_ptr<std::string> sup(new std::string("foobar"));
+
+  std::unique_ptr<char, Deleter> ndp;
+  std::unique_ptr<int, Deleter> idp(new int{456}, Deleter{1, 2});
+  std::unique_ptr<std::string, Deleter> sdp(new std::string("baz"),
+                                            Deleter{3, 4});
+
+  return 0; // Set break point at this line.
+}

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt?rev=284830&r1=284829&r2=284830&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CMakeLists.txt Fri Oct 21 10:02:44 2016
@@ -12,4 +12,5 @@ add_lldb_library(lldbPluginCPlusPlusLang
   LibStdcpp.cpp
   LibStdcppSmartPointer.cpp
   LibStdcppTuple.cpp
+  LibStdcppUniquePointer.cpp
 )

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp?rev=284830&r1=284829&r2=284830&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Fri Oct 21 10:02:44 2016
@@ -803,6 +803,11 @@ static void LoadLibStdcppFormatters(lldb
 
   AddCXXSynthetic(
       cpp_category_sp,
+      lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
+      "std::unique_ptr synthetic children",
+      ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+  AddCXXSynthetic(
+      cpp_category_sp,
       lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
       "std::shared_ptr synthetic children",
       ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
@@ -818,6 +823,11 @@ static void LoadLibStdcppFormatters(lldb
       stl_synth_flags, true);
 
   AddCXXSummary(cpp_category_sp,
+                lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
+                "libstdc++ std::unique_ptr summary provider",
+                ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
+                true);
+  AddCXXSummary(cpp_category_sp,
                 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
                 "libstdc++ std::shared_ptr summary provider",
                 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h?rev=284830&r1=284829&r2=284830&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h Fri Oct 21 10:02:44 2016
@@ -31,6 +31,10 @@ bool LibStdcppSmartPointerSummaryProvide
     const TypeSummaryOptions
         &options); // libstdc++ std::shared_ptr<> and std::weak_ptr<>
 
+bool LibStdcppUniquePointerSummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<>
+
 SyntheticChildrenFrontEnd *
 LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                              lldb::ValueObjectSP);
@@ -46,6 +50,11 @@ LibStdcppVectorIteratorSyntheticFrontEnd
 SyntheticChildrenFrontEnd *
 LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                            lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                           lldb::ValueObjectSP);
+
 } // namespace formatters
 } // namespace lldb_private
 

Added: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp?rev=284830&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp (added)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp Fri Oct 21 10:02:44 2016
@@ -0,0 +1,160 @@
+//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibStdcpp.h"
+
+#include <memory>
+#include <vector>
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace {
+
+class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  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_del_obj;
+};
+
+} // end of anonymous namespace
+
+LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp) {
+  Update();
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+  ValueObjectSP valobj_backend_sp = m_backend.GetSP();
+  if (!valobj_backend_sp)
+    return false;
+
+  ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
+  if (!valobj_sp)
+    return false;
+
+  ValueObjectSP tuple_sp =
+      valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+  if (!tuple_sp)
+    return false;
+
+  std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend(
+      LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp));
+
+  m_ptr_obj = tuple_frontend->GetChildAtIndex(0);
+  if (m_ptr_obj)
+    m_ptr_obj->SetName(ConstString("pointer"));
+
+  m_del_obj = tuple_frontend->GetChildAtIndex(1);
+  if (m_del_obj)
+    m_del_obj->SetName(ConstString("deleter"));
+
+  if (m_ptr_obj) {
+    Error error;
+    m_obj_obj = m_ptr_obj->Dereference(error);
+    if (error.Success()) {
+      m_obj_obj->SetName(ConstString("object"));
+    }
+  }
+
+  return false;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
+
+lldb::ValueObjectSP
+LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+  if (idx == 0)
+    return m_obj_obj;
+  if (idx == 1)
+    return m_del_obj;
+  if (idx == 2)
+    return m_ptr_obj;
+  return lldb::ValueObjectSP();
+}
+
+size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() {
+  if (m_del_obj)
+    return 2;
+  if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0)
+    return 1;
+  return 0;
+}
+
+size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName(
+    const ConstString &name) {
+  if (name == ConstString("obj") || name == ConstString("object"))
+    return 0;
+  if (name == ConstString("del") || name == ConstString("deleter"))
+    return 1;
+  if (name == ConstString("ptr") || name == ConstString("pointer"))
+    return 2;
+  return UINT32_MAX;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary(
+    Stream &stream, const TypeSummaryOptions &options) {
+  if (!m_ptr_obj)
+    return false;
+
+  if (m_ptr_obj->GetValueAsUnsigned(0) == 0) {
+    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));
+  }
+  return true;
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp)
+                    : nullptr);
+}
+
+bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP());
+  return formatter.GetSummary(stream, options);
+}




More information about the lldb-commits mailing list