[Lldb-commits] [lldb] r300047 - Fix libc++ vector<bool> data formatter (bug #32553)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 12 03:59:25 PDT 2017


Author: labath
Date: Wed Apr 12 05:59:24 2017
New Revision: 300047

URL: http://llvm.org/viewvc/llvm-project?rev=300047&view=rev
Log:
Fix libc++ vector<bool> data formatter (bug #32553)

Summary:
The iteration list through the available data formatters was undefined,
which meant that the vector<bool> formatter kicked in only in cases
where it happened to be queried before the general vector formatter. To
fix this, I merge the two data formatter entries into one, and select
which implementation to use in the factory function.

Reviewers: jasonmolenda, tberghammer, EricWF

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D31880

Modified:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
    lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py?rev=300047&r1=300046&r2=300047&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py Wed Apr 12 05:59:24 2017
@@ -24,7 +24,6 @@ class LibcxxVBoolDataFormatterTestCase(T
         self.line = line_number('main.cpp', '// Set break point at this line.')
 
     @add_test_categories(["libc++"])
-    @expectedFailureAll(bugnumber="llvm.org/pr32553")
     def test_with_run_command(self):
         """Test that that file and class static variables display correctly."""
         self.build()

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=300047&r1=300046&r2=300047&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Wed Apr 12 05:59:24 2017
@@ -560,13 +560,6 @@ static void LoadLibCxxFormatters(lldb::T
 
   AddCXXSynthetic(
       cpp_category_sp,
-      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
-      "libc++ std::vector<bool> synthetic children",
-      ConstString(
-          "^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"),
-      stl_synth_flags, true);
-  AddCXXSynthetic(
-      cpp_category_sp,
       lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
       "libc++ std::vector synthetic children",
       ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
@@ -584,19 +577,6 @@ static void LoadLibCxxFormatters(lldb::T
       true);
   AddCXXSynthetic(
       cpp_category_sp,
-      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
-      "libc++ std::vector<bool> synthetic children",
-      ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"),
-      stl_synth_flags, true);
-  AddCXXSynthetic(
-      cpp_category_sp,
-      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator,
-      "libc++ std::vector<bool> synthetic children",
-      ConstString(
-          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
-      stl_synth_flags, true);
-  AddCXXSynthetic(
-      cpp_category_sp,
       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
       "libc++ std::set synthetic children",
       ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags,
@@ -653,12 +633,6 @@ static void LoadLibCxxFormatters(lldb::T
 
   stl_summary_flags.SetDontShowChildren(false);
   stl_summary_flags.SetSkipPointers(false);
-  AddCXXSummary(
-      cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
-      "libc++ std::vector<bool> summary provider",
-      ConstString(
-          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
-      stl_summary_flags, true);
   AddCXXSummary(cpp_category_sp,
                 lldb_private::formatters::LibcxxContainerSummaryProvider,
                 "libc++ std::vector summary provider",
@@ -723,12 +697,6 @@ static void LoadLibCxxFormatters(lldb::T
       "std::vector iterator synthetic children",
       ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
 
-  AddCXXSummary(
-      cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
-      "libc++ std::vector<bool> summary provider",
-      ConstString(
-          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"),
-      stl_summary_flags, true);
   AddCXXSynthetic(
       cpp_category_sp,
       lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp?rev=300047&r1=300046&r2=300047&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp Wed Apr 12 05:59:24 2017
@@ -76,155 +76,6 @@ bool lldb_private::formatters::LibcxxSma
   return true;
 }
 
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
-    LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-    : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(),
-      m_count(0), m_base_data_address(0), m_children() {
-  if (valobj_sp) {
-    Update();
-    m_bool_type =
-        valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
-  }
-}
-
-size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
-    CalculateNumChildren() {
-  return m_count;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex(
-    size_t idx) {
-  auto iter = m_children.find(idx), end = m_children.end();
-  if (iter != end)
-    return iter->second;
-  if (idx >= m_count)
-    return ValueObjectSP();
-  if (m_base_data_address == 0 || m_count == 0)
-    return ValueObjectSP();
-  if (!m_bool_type)
-    return ValueObjectSP();
-  size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
-  size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
-  lldb::addr_t byte_location = m_base_data_address + byte_idx;
-  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
-  if (!process_sp)
-    return ValueObjectSP();
-  uint8_t byte = 0;
-  uint8_t mask = 0;
-  Error err;
-  size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
-  if (err.Fail() || bytes_read == 0)
-    return ValueObjectSP();
-  switch (bit_index) {
-  case 0:
-    mask = 1;
-    break;
-  case 1:
-    mask = 2;
-    break;
-  case 2:
-    mask = 4;
-    break;
-  case 3:
-    mask = 8;
-    break;
-  case 4:
-    mask = 16;
-    break;
-  case 5:
-    mask = 32;
-    break;
-  case 6:
-    mask = 64;
-    break;
-  case 7:
-    mask = 128;
-    break;
-  default:
-    return ValueObjectSP();
-  }
-  bool bit_set = ((byte & mask) != 0);
-  DataBufferSP buffer_sp(
-      new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
-  if (bit_set && buffer_sp && buffer_sp->GetBytes())
-    *(buffer_sp->GetBytes()) =
-        1; // regardless of endianness, anything non-zero is true
-  StreamString name;
-  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-  ValueObjectSP retval_sp(CreateValueObjectFromData(
-      name.GetString(), DataExtractor(buffer_sp, process_sp->GetByteOrder(),
-                                      process_sp->GetAddressByteSize()),
-      m_exe_ctx_ref, m_bool_type));
-  if (retval_sp)
-    m_children[idx] = retval_sp;
-  return retval_sp;
-}
-
-/*(std::__1::vector<std::__1::allocator<bool> >) vBool = {
- __begin_ = 0x00000001001000e0
- __size_ = 56
- __cap_alloc_ = {
- std::__1::__libcpp_compressed_pair_imp<unsigned long,
- std::__1::allocator<unsigned long> > = {
- __first_ = 1
- }
- }
- }*/
-
-bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() {
-  m_children.clear();
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-    return false;
-  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  ValueObjectSP size_sp(
-      valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
-  if (!size_sp)
-    return false;
-  m_count = size_sp->GetValueAsUnsigned(0);
-  if (!m_count)
-    return true;
-  ValueObjectSP begin_sp(
-      valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
-  if (!begin_sp) {
-    m_count = 0;
-    return false;
-  }
-  m_base_data_address = begin_sp->GetValueAsUnsigned(0);
-  if (!m_base_data_address) {
-    m_count = 0;
-    return false;
-  }
-  return false;
-}
-
-bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
-    MightHaveChildren() {
-  return true;
-}
-
-size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
-    GetIndexOfChildWithName(const ConstString &name) {
-  if (!m_count || !m_base_data_address)
-    return UINT32_MAX;
-  const char *item_name = name.GetCString();
-  uint32_t idx = ExtractIndexFromString(item_name);
-  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
-    return UINT32_MAX;
-  return idx;
-}
-
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
-    ~LibcxxVectorBoolSyntheticFrontEnd() = default;
-
-SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator(
-    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
-  return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp)
-                    : nullptr);
-}
-
 /*
  (lldb) fr var ibeg --raw --ptr-depth 1
  (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h?rev=300047&r1=300046&r2=300047&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.h Wed Apr 12 05:59:24 2017
@@ -32,30 +32,6 @@ bool LibcxxSmartPointerSummaryProvider(
     const TypeSummaryOptions
         &options); // libc++ std::shared_ptr<> and std::weak_ptr<>
 
-class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
-  LibcxxVectorBoolSyntheticFrontEnd(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;
-
-  ~LibcxxVectorBoolSyntheticFrontEnd() override;
-
-private:
-  CompilerType m_bool_type;
-  ExecutionContextRef m_exe_ctx_ref;
-  uint64_t m_count;
-  lldb::addr_t m_base_data_address;
-  std::map<size_t, lldb::ValueObjectSP> m_children;
-};
-
 SyntheticChildrenFrontEnd *
 LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                          lldb::ValueObjectSP);

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp?rev=300047&r1=300046&r2=300047&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp Wed Apr 12 05:59:24 2017
@@ -45,6 +45,29 @@ private:
   CompilerType m_element_type;
   uint32_t m_element_size;
 };
+
+class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override { return true; }
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+  CompilerType m_bool_type;
+  ExecutionContextRef m_exe_ctx_ref;
+  uint64_t m_count;
+  lldb::addr_t m_base_data_address;
+  std::map<size_t, lldb::ValueObjectSP> m_children;
+};
+
 } // namespace formatters
 } // namespace lldb_private
 
@@ -133,9 +156,126 @@ size_t lldb_private::formatters::LibcxxS
   return ExtractIndexFromString(name.GetCString());
 }
 
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+    LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(),
+      m_count(0), m_base_data_address(0), m_children() {
+  if (valobj_sp) {
+    Update();
+    m_bool_type =
+        valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
+  }
+}
+
+size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+    CalculateNumChildren() {
+  return m_count;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  auto iter = m_children.find(idx), end = m_children.end();
+  if (iter != end)
+    return iter->second;
+  if (idx >= m_count)
+    return ValueObjectSP();
+  if (m_base_data_address == 0 || m_count == 0)
+    return ValueObjectSP();
+  if (!m_bool_type)
+    return ValueObjectSP();
+  size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
+  size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
+  lldb::addr_t byte_location = m_base_data_address + byte_idx;
+  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
+  if (!process_sp)
+    return ValueObjectSP();
+  uint8_t byte = 0;
+  uint8_t mask = 0;
+  Error err;
+  size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
+  if (err.Fail() || bytes_read == 0)
+    return ValueObjectSP();
+  mask = 1 << bit_index;
+  bool bit_set = ((byte & mask) != 0);
+  DataBufferSP buffer_sp(
+      new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
+  if (bit_set && buffer_sp && buffer_sp->GetBytes()) {
+    // regardless of endianness, anything non-zero is true
+    *(buffer_sp->GetBytes()) = 1;
+  }
+  StreamString name;
+  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+  ValueObjectSP retval_sp(CreateValueObjectFromData(
+      name.GetString(),
+      DataExtractor(buffer_sp, process_sp->GetByteOrder(),
+                    process_sp->GetAddressByteSize()),
+      m_exe_ctx_ref, m_bool_type));
+  if (retval_sp)
+    m_children[idx] = retval_sp;
+  return retval_sp;
+}
+
+/*(std::__1::vector<std::__1::allocator<bool> >) vBool = {
+ __begin_ = 0x00000001001000e0
+ __size_ = 56
+ __cap_alloc_ = {
+ std::__1::__libcpp_compressed_pair_imp<unsigned long,
+ std::__1::allocator<unsigned long> > = {
+ __first_ = 1
+ }
+ }
+ }*/
+
+bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() {
+  m_children.clear();
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  ValueObjectSP size_sp(
+      valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
+  if (!size_sp)
+    return false;
+  m_count = size_sp->GetValueAsUnsigned(0);
+  if (!m_count)
+    return true;
+  ValueObjectSP begin_sp(
+      valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
+  if (!begin_sp) {
+    m_count = 0;
+    return false;
+  }
+  m_base_data_address = begin_sp->GetValueAsUnsigned(0);
+  if (!m_base_data_address) {
+    m_count = 0;
+    return false;
+  }
+  return false;
+}
+
+size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
+    GetIndexOfChildWithName(const ConstString &name) {
+  if (!m_count || !m_base_data_address)
+    return UINT32_MAX;
+  const char *item_name = name.GetCString();
+  uint32_t idx = ExtractIndexFromString(item_name);
+  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+    return UINT32_MAX;
+  return idx;
+}
+
 lldb_private::SyntheticChildrenFrontEnd *
 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
-  return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp)
-                    : nullptr);
+  if (!valobj_sp)
+    return nullptr;
+  CompilerType type = valobj_sp->GetCompilerType();
+  if (!type.IsValid() || type.GetNumTemplateArguments() == 0)
+    return nullptr;
+  TemplateArgumentKind kind;
+  CompilerType arg_type = type.GetTemplateArgument(0, kind);
+  if (arg_type.GetTypeName() == ConstString("bool"))
+    return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp);
+  return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp);
 }




More information about the lldb-commits mailing list