-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb][libc++] Adds slice_array data formatters. #85544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mordante
merged 2 commits into
llvm:main
from
mordante:review/data_formatter_slice_array
Mar 17, 2024
Merged
[lldb][libc++] Adds slice_array data formatters. #85544
mordante
merged 2 commits into
llvm:main
from
mordante:review/data_formatter_slice_array
Mar 17, 2024
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-lldb Author: Mark de Wever (mordante) ChangesFull diff: https://github.com/llvm/llvm-project/pull/85544.diff 6 Files Affected:
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";
}
|
Michael137
approved these changes
Mar 17, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks!
Co-authored-by: Michael Buch <[email protected]>
Thanks for the review! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.