Skip to content

Commit 56d45b0

Browse files
mordanteMichael137
andauthored
[lldb][libc++] Adds slice_array data formatters. (#85544)
Co-authored-by: Michael Buch <[email protected]>
1 parent 62361fe commit 56d45b0

File tree

6 files changed

+219
-0
lines changed

6 files changed

+219
-0
lines changed

lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
1313
LibCxxMap.cpp
1414
LibCxxQueue.cpp
1515
LibCxxRangesRefView.cpp
16+
LibCxxSliceArray.cpp
1617
LibCxxSpan.cpp
1718
LibCxxTuple.cpp
1819
LibCxxUnorderedMap.cpp

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
755755
lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator,
756756
"libc++ std::valarray synthetic children",
757757
"^std::__[[:alnum:]]+::valarray<.+>$", stl_deref_flags, true);
758+
AddCXXSynthetic(
759+
cpp_category_sp,
760+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator,
761+
"libc++ std::slice_array synthetic children",
762+
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);
758763
AddCXXSynthetic(
759764
cpp_category_sp,
760765
lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
@@ -880,6 +885,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
880885
lldb_private::formatters::LibcxxContainerSummaryProvider,
881886
"libc++ std::valarray summary provider",
882887
"^std::__[[:alnum:]]+::valarray<.+>$", stl_summary_flags, true);
888+
AddCXXSummary(cpp_category_sp,
889+
lldb_private::formatters::LibcxxStdSliceArraySummaryProvider,
890+
"libc++ std::slice_array summary provider",
891+
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,
892+
true);
883893
AddCXXSummary(
884894
cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
885895
"libc++ std::list summary provider",

lldb/source/Plugins/Language/CPlusPlus/LibCxx.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ bool LibcxxWStringViewSummaryProvider(
5959
ValueObject &valobj, Stream &stream,
6060
const TypeSummaryOptions &options); // libc++ std::wstring_view
6161

62+
bool LibcxxStdSliceArraySummaryProvider(
63+
ValueObject &valobj, Stream &stream,
64+
const TypeSummaryOptions &options); // libc++ std::slice_array
65+
6266
bool LibcxxSmartPointerSummaryProvider(
6367
ValueObject &valobj, Stream &stream,
6468
const TypeSummaryOptions
@@ -223,6 +227,10 @@ SyntheticChildrenFrontEnd *
223227
LibcxxStdValarraySyntheticFrontEndCreator(CXXSyntheticChildren *,
224228
lldb::ValueObjectSP);
225229

230+
SyntheticChildrenFrontEnd *
231+
LibcxxStdSliceArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
232+
lldb::ValueObjectSP);
233+
226234
SyntheticChildrenFrontEnd *
227235
LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
228236
lldb::ValueObjectSP);
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
//===-- LibCxxSliceArray.cpp-----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "LibCxx.h"
10+
11+
#include "lldb/Core/ValueObject.h"
12+
#include "lldb/DataFormatters/FormattersHelpers.h"
13+
#include <optional>
14+
15+
using namespace lldb;
16+
using namespace lldb_private;
17+
using namespace lldb_private::formatters;
18+
19+
namespace lldb_private {
20+
namespace formatters {
21+
22+
bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream,
23+
const TypeSummaryOptions &options) {
24+
ValueObjectSP obj = valobj.GetNonSyntheticValue();
25+
if (!obj)
26+
return false;
27+
28+
ValueObjectSP ptr_sp = obj->GetChildMemberWithName("__size_");
29+
if (!ptr_sp)
30+
return false;
31+
const size_t size = ptr_sp->GetValueAsUnsigned(0);
32+
33+
ptr_sp = obj->GetChildMemberWithName("__stride_");
34+
if (!ptr_sp)
35+
return false;
36+
const size_t stride = ptr_sp->GetValueAsUnsigned(0);
37+
38+
stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size);
39+
40+
return true;
41+
}
42+
43+
/// Data formatter for libc++'s std::slice_array.
44+
///
45+
/// A slice_array is created by using:
46+
/// operator[](std::slice slicearr);
47+
/// and std::slice is created by:
48+
/// slice(std::size_t start, std::size_t size, std::size_t stride);
49+
/// The std::slice_array has the following members:
50+
/// - __vp_ points to std::valarray::__begin_ + @a start
51+
/// - __size_ is @a size
52+
/// - __stride_is @a stride
53+
class LibcxxStdSliceArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
54+
public:
55+
LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
56+
57+
~LibcxxStdSliceArraySyntheticFrontEnd() override;
58+
59+
llvm::Expected<uint32_t> CalculateNumChildren() override;
60+
61+
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
62+
63+
lldb::ChildCacheState Update() override;
64+
65+
bool MightHaveChildren() override;
66+
67+
size_t GetIndexOfChildWithName(ConstString name) override;
68+
69+
private:
70+
/// A non-owning pointer to slice_array.__vp_.
71+
ValueObject *m_start = nullptr;
72+
/// slice_array.__size_.
73+
size_t m_size = 0;
74+
/// slice_array.__stride_.
75+
size_t m_stride = 0;
76+
/// The type of slize_array's template argument T.
77+
CompilerType m_element_type;
78+
/// The sizeof slize_array's template argument T.
79+
uint32_t m_element_size = 0;
80+
};
81+
82+
} // namespace formatters
83+
} // namespace lldb_private
84+
85+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
86+
LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
87+
: SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
88+
if (valobj_sp)
89+
Update();
90+
}
91+
92+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
93+
~LibcxxStdSliceArraySyntheticFrontEnd() {
94+
// these need to stay around because they are child objects who will follow
95+
// their parent's life cycle
96+
// delete m_start;
97+
}
98+
99+
llvm::Expected<uint32_t> lldb_private::formatters::
100+
LibcxxStdSliceArraySyntheticFrontEnd::CalculateNumChildren() {
101+
return m_size;
102+
}
103+
104+
lldb::ValueObjectSP
105+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::GetChildAtIndex(
106+
uint32_t idx) {
107+
if (!m_start)
108+
return lldb::ValueObjectSP();
109+
110+
uint64_t offset = idx * m_stride * m_element_size;
111+
offset = offset + m_start->GetValueAsUnsigned(0);
112+
StreamString name;
113+
name.Printf("[%" PRIu64 "]", (uint64_t)idx);
114+
return CreateValueObjectFromAddress(name.GetString(), offset,
115+
m_backend.GetExecutionContextRef(),
116+
m_element_type);
117+
}
118+
119+
lldb::ChildCacheState
120+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::Update() {
121+
m_start = nullptr;
122+
123+
CompilerType type = m_backend.GetCompilerType();
124+
if (type.GetNumTemplateArguments() == 0)
125+
return ChildCacheState::eRefetch;
126+
127+
m_element_type = type.GetTypeTemplateArgument(0);
128+
if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))
129+
m_element_size = *size;
130+
131+
if (m_element_size == 0)
132+
return ChildCacheState::eRefetch;
133+
134+
ValueObjectSP start = m_backend.GetChildMemberWithName("__vp_");
135+
ValueObjectSP size = m_backend.GetChildMemberWithName("__size_");
136+
ValueObjectSP stride = m_backend.GetChildMemberWithName("__stride_");
137+
138+
if (!start || !size || !stride)
139+
return ChildCacheState::eRefetch;
140+
141+
m_start = start.get();
142+
m_size = size->GetValueAsUnsigned(0);
143+
m_stride = stride->GetValueAsUnsigned(0);
144+
145+
return ChildCacheState::eRefetch;
146+
}
147+
148+
bool lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
149+
MightHaveChildren() {
150+
return true;
151+
}
152+
153+
size_t lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
154+
GetIndexOfChildWithName(ConstString name) {
155+
if (!m_start)
156+
return std::numeric_limits<size_t>::max();
157+
return ExtractIndexFromString(name.GetCString());
158+
}
159+
160+
lldb_private::SyntheticChildrenFrontEnd *
161+
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(
162+
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
163+
if (!valobj_sp)
164+
return nullptr;
165+
return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);
166+
}

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ def test_with_run_command(self):
1818
self, "break here", lldb.SBFileSpec("main.cpp", False)
1919
)
2020

21+
#
22+
# std::valarray
23+
#
24+
2125
self.expect(
2226
"frame variable va_int",
2327
substrs=[
@@ -76,3 +80,30 @@ def test_with_run_command(self):
7680
error=True,
7781
substrs=['array index 4 is not valid for "(valarray<double>) va_double"'],
7882
)
83+
84+
#
85+
# std::slice_array
86+
#
87+
88+
self.expect(
89+
"frame variable sa",
90+
substrs=[
91+
"sa = stride=2 size=4",
92+
"[0] = 1",
93+
"[1] = 3",
94+
"[2] = 5",
95+
"[3] = 7",
96+
"}",
97+
],
98+
)
99+
100+
# check access-by-index
101+
self.expect("frame variable sa[0]", substrs=["1"])
102+
self.expect("frame variable sa[1]", substrs=["3"])
103+
self.expect("frame variable sa[2]", substrs=["5"])
104+
self.expect("frame variable sa[3]", substrs=["7"])
105+
self.expect(
106+
"frame variable sa[4]",
107+
error=True,
108+
substrs=['array index 4 is not valid for "(slice_array<int>) sa"'],
109+
)

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ int main() {
1313

1414
std::valarray<double> va_double({1.0, 0.5, 0.25, 0.125});
1515

16+
std::valarray<int> va({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
17+
std::slice_array<int> sa = va[std::slice(1, 4, 2)];
18+
1619
std::cout << "break here\n";
1720
}

0 commit comments

Comments
 (0)