[Lldb-commits] [lldb] [lldb][libc++] Adds slice_array data formatters. (PR #85544)

via lldb-commits lldb-commits at lists.llvm.org
Sat Mar 16 10:15:25 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Mark de Wever (mordante)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/85544.diff


6 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt (+1) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+10) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+8) 
- (added) lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp (+166) 
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py (+31) 
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp (+3) 


``````````diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 97fa894ea73761..0c6fdb2b957315 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -13,6 +13,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
   LibCxxMap.cpp
   LibCxxQueue.cpp
   LibCxxRangesRefView.cpp
+  LibCxxSliceArray.cpp
   LibCxxSpan.cpp
   LibCxxTuple.cpp
   LibCxxUnorderedMap.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 675ca385186102..4a536096a066ff 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -755,6 +755,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
       lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator,
       "libc++ std::valarray synthetic children",
       "^std::__[[:alnum:]]+::valarray<.+>$", stl_deref_flags, true);
+  AddCXXSynthetic(
+      cpp_category_sp,
+      lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator,
+      "libc++ std::slice_array synthetic children",
+      "^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);
   AddCXXSynthetic(
       cpp_category_sp,
       lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
@@ -880,6 +885,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 lldb_private::formatters::LibcxxContainerSummaryProvider,
                 "libc++ std::valarray summary provider",
                 "^std::__[[:alnum:]]+::valarray<.+>$", stl_summary_flags, true);
+  AddCXXSummary(cpp_category_sp,
+                lldb_private::formatters::LibcxxStdSliceArraySummaryProvider,
+                "libc++ std::slice_array summary provider",
+                "^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,
+                true);
   AddCXXSummary(
       cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
       "libc++ std::list summary provider",
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index a59f21841ec890..d8b807d180e068 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -59,6 +59,10 @@ bool LibcxxWStringViewSummaryProvider(
     ValueObject &valobj, Stream &stream,
     const TypeSummaryOptions &options); // libc++ std::wstring_view
 
+bool LibcxxStdSliceArraySummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libc++ std::slice_array
+
 bool LibcxxSmartPointerSummaryProvider(
     ValueObject &valobj, Stream &stream,
     const TypeSummaryOptions
@@ -223,6 +227,10 @@ SyntheticChildrenFrontEnd *
 LibcxxStdValarraySyntheticFrontEndCreator(CXXSyntheticChildren *,
                                           lldb::ValueObjectSP);
 
+SyntheticChildrenFrontEnd *
+LibcxxStdSliceArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                            lldb::ValueObjectSP);
+
 SyntheticChildrenFrontEnd *
 LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                       lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp
new file mode 100644
index 00000000000000..724514dd0697b9
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp
@@ -0,0 +1,166 @@
+//===-- LibCxxSliceArray.cpp-----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include <optional>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace lldb_private {
+namespace formatters {
+
+bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream,
+                                        const TypeSummaryOptions &options) {
+  ValueObjectSP obj = valobj.GetNonSyntheticValue();
+  if (!obj)
+    return false;
+
+  ValueObjectSP ptr_sp = obj->GetChildMemberWithName("__size_");
+  if (!ptr_sp)
+    return false;
+  const size_t size = ptr_sp->GetValueAsUnsigned(0);
+
+  ptr_sp = obj->GetChildMemberWithName("__stride_");
+  if (!ptr_sp)
+    return false;
+  const size_t stride = ptr_sp->GetValueAsUnsigned(0);
+
+  stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size);
+
+  return true;
+}
+
+/// Data formatter for libc++'s std::slice_array.
+///
+/// A slice_array is created by using:
+///   operator[](std::slice slicearr);
+/// and std::slice is created by:
+///   slice(std::size_t start, std::size_t size, std::size_t stride);
+/// The std::slice_array has the following members:
+/// - __vp_ pointes to std::valarray::__begin_ + @a start
+/// - __size_ is @a size
+/// - __stride_is @a stride
+class LibcxxStdSliceArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~LibcxxStdSliceArraySyntheticFrontEnd() override;
+
+  llvm::Expected<uint32_t> CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
+
+  lldb::ChildCacheState Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(ConstString name) override;
+
+private:
+  /// A non-owning pointer to slice_array.__vp_.
+  ValueObject *m_start = nullptr;
+  /// slice_array.__size_.
+  size_t m_size = 0;
+  /// slice_array.__stride_.
+  size_t m_stride = 0;
+  /// The type of slize_array's template argument T.
+  CompilerType m_element_type;
+  /// The sizeof slize_array's template argument T.
+  uint32_t m_element_size = 0;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
+    LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
+  if (valobj_sp)
+    Update();
+}
+
+lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
+    ~LibcxxStdSliceArraySyntheticFrontEnd() {
+  // these need to stay around because they are child objects who will follow
+  // their parent's life cycle
+  // delete m_start;
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+    LibcxxStdSliceArraySyntheticFrontEnd::CalculateNumChildren() {
+  return m_size;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::GetChildAtIndex(
+    uint32_t idx) {
+  if (!m_start)
+    return lldb::ValueObjectSP();
+
+  uint64_t offset = idx * m_stride * m_element_size;
+  offset = offset + m_start->GetValueAsUnsigned(0);
+  StreamString name;
+  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+  return CreateValueObjectFromAddress(name.GetString(), offset,
+                                      m_backend.GetExecutionContextRef(),
+                                      m_element_type);
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::Update() {
+  m_start = nullptr;
+
+  CompilerType type = m_backend.GetCompilerType();
+  if (type.GetNumTemplateArguments() == 0)
+    return ChildCacheState::eRefetch;
+
+  m_element_type = type.GetTypeTemplateArgument(0);
+  if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))
+    m_element_size = *size;
+
+  if (m_element_size == 0)
+    return ChildCacheState::eRefetch;
+
+  ValueObjectSP start = m_backend.GetChildMemberWithName("__vp_");
+  ValueObjectSP size = m_backend.GetChildMemberWithName("__size_");
+  ValueObjectSP stride = m_backend.GetChildMemberWithName("__stride_");
+
+  if (!start || !size || !stride)
+    return ChildCacheState::eRefetch;
+
+  m_start = start.get();
+  m_size = size->GetValueAsUnsigned(0);
+  m_stride = stride->GetValueAsUnsigned(0);
+
+  return ChildCacheState::eRefetch;
+}
+
+bool lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
+}
+
+size_t lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
+    GetIndexOfChildWithName(ConstString name) {
+  if (!m_start)
+    return std::numeric_limits<size_t>::max();
+  return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  if (!valobj_sp)
+    return nullptr;
+  return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
index 7b54b3485d04d4..b59b770ed6790d 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
@@ -18,6 +18,10 @@ def test_with_run_command(self):
             self, "break here", lldb.SBFileSpec("main.cpp", False)
         )
 
+        #
+        # std::valarray
+        #
+
         self.expect(
             "frame variable va_int",
             substrs=[
@@ -76,3 +80,30 @@ def test_with_run_command(self):
             error=True,
             substrs=['array index 4 is not valid for "(valarray<double>) va_double"'],
         )
+
+        #
+        # std::slice_array
+        #
+
+        self.expect(
+            "frame variable sa",
+            substrs=[
+                "sa = stride=2 size=4",
+                "[0] = 1",
+                "[1] = 3",
+                "[2] = 5",
+                "[3] = 7",
+                "}",
+            ],
+        )
+
+        # check access-by-index
+        self.expect("frame variable sa[0]", substrs=["1"])
+        self.expect("frame variable sa[1]", substrs=["3"])
+        self.expect("frame variable sa[2]", substrs=["5"])
+        self.expect("frame variable sa[3]", substrs=["7"])
+        self.expect(
+            "frame variable sa[4]",
+            error=True,
+            substrs=['array index 4 is not valid for "(slice_array<int>) sa"'],
+        )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
index f32921e16fa10e..1481d8b4032927 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
@@ -13,5 +13,8 @@ int main() {
 
   std::valarray<double> va_double({1.0, 0.5, 0.25, 0.125});
 
+  std::valarray<int> va({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+  std::slice_array<int> sa = va[std::slice(1, 4, 2)];
+
   std::cout << "break here\n";
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/85544


More information about the lldb-commits mailing list