Skip to content

Commit f7ca5a7

Browse files
author
git apple-llvm automerger
committed
Merge commit 'f3e0142cf454' from swift/release/5.9 into stable/20221013
2 parents d8d45aa + f3e0142 commit f7ca5a7

File tree

7 files changed

+197
-0
lines changed

7 files changed

+197
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
1212
LibCxxList.cpp
1313
LibCxxMap.cpp
1414
LibCxxQueue.cpp
15+
LibCxxRangesRefView.cpp
1516
LibCxxSpan.cpp
1617
LibCxxTuple.cpp
1718
LibCxxUnorderedMap.cpp

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,12 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
839839
"libc++ std::span synthetic children",
840840
ConstString("^std::__[[:alnum:]]+::span<.+>(( )?&)?$"), stl_deref_flags,
841841
true);
842+
AddCXXSynthetic(
843+
cpp_category_sp,
844+
lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator,
845+
"libc++ std::ranges::ref_view synthetic children",
846+
ConstString("^std::__[[:alnum:]]+::ranges::ref_view<.+>(( )?&)?$"),
847+
stl_deref_flags, true);
842848

843849
cpp_category_sp->AddTypeSynthetic(
844850
"^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$", eFormatterMatchRegex,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ SyntheticChildrenFrontEnd *
256256
LibcxxStdSpanSyntheticFrontEndCreator(CXXSyntheticChildren *,
257257
lldb::ValueObjectSP);
258258

259+
SyntheticChildrenFrontEnd *
260+
LibcxxStdRangesRefViewSyntheticFrontEndCreator(CXXSyntheticChildren *,
261+
lldb::ValueObjectSP);
262+
259263
} // namespace formatters
260264
} // namespace lldb_private
261265

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===-- LibCxxRangesRefView.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 "lldb/Utility/ConstString.h"
14+
#include "llvm/ADT/APSInt.h"
15+
16+
using namespace lldb;
17+
using namespace lldb_private;
18+
using namespace lldb_private::formatters;
19+
20+
namespace lldb_private {
21+
namespace formatters {
22+
23+
class LibcxxStdRangesRefViewSyntheticFrontEnd
24+
: public SyntheticChildrenFrontEnd {
25+
public:
26+
LibcxxStdRangesRefViewSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
27+
28+
~LibcxxStdRangesRefViewSyntheticFrontEnd() override = default;
29+
30+
size_t CalculateNumChildren() override {
31+
// __range_ will be the sole child of this type
32+
return 1;
33+
}
34+
35+
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
36+
// Since we only have a single child, return it
37+
assert(idx == 0);
38+
return m_range_sp;
39+
}
40+
41+
bool Update() override;
42+
43+
bool MightHaveChildren() override { return true; }
44+
45+
size_t GetIndexOfChildWithName(ConstString name) override {
46+
// We only have a single child
47+
return 0;
48+
}
49+
50+
private:
51+
/// Pointer to the dereferenced __range_ member
52+
lldb::ValueObjectSP m_range_sp = nullptr;
53+
};
54+
55+
lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEnd::
56+
LibcxxStdRangesRefViewSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
57+
: SyntheticChildrenFrontEnd(*valobj_sp) {
58+
if (valobj_sp)
59+
Update();
60+
}
61+
62+
bool lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEnd::
63+
Update() {
64+
ValueObjectSP range_ptr =
65+
GetChildMemberWithName(m_backend, {ConstString("__range_")});
66+
if (!range_ptr)
67+
return false;
68+
69+
lldb_private::Status error;
70+
m_range_sp = range_ptr->Dereference(error);
71+
72+
return error.Success();
73+
}
74+
75+
lldb_private::SyntheticChildrenFrontEnd *
76+
LibcxxStdRangesRefViewSyntheticFrontEndCreator(CXXSyntheticChildren *,
77+
lldb::ValueObjectSP valobj_sp) {
78+
if (!valobj_sp)
79+
return nullptr;
80+
CompilerType type = valobj_sp->GetCompilerType();
81+
if (!type.IsValid())
82+
return nullptr;
83+
return new LibcxxStdRangesRefViewSyntheticFrontEnd(valobj_sp);
84+
}
85+
86+
} // namespace formatters
87+
} // namespace lldb_private
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
USE_LIBCPP := 1
2+
3+
CXX_SOURCES := main.cpp
4+
CXXFLAGS_EXTRAS := -std=c++20
5+
6+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
Test LLDB's std::ranges::ref_view formatter
3+
"""
4+
5+
import lldb
6+
from lldbsuite.test.decorators import *
7+
from lldbsuite.test.lldbtest import *
8+
from lldbsuite.test import lldbutil
9+
10+
11+
class LibcxxRangesRefViewDataFormatterTestCase(TestBase):
12+
13+
def check_string_vec_children(self):
14+
return [ValueCheck(name='[0]', summary='"First"'),
15+
ValueCheck(name='[1]', summary='"Second"'),
16+
ValueCheck(name='[2]', summary='"Third"'),
17+
ValueCheck(name='[3]', summary='"Fourth"')]
18+
19+
def check_string_vec_ref_view(self):
20+
return ValueCheck(
21+
name='*__range_',
22+
summary='size=4',
23+
children=self.check_string_vec_children())
24+
25+
def check_foo(self):
26+
return ValueCheck(
27+
name='vec',
28+
children=self.check_string_vec_children())
29+
30+
@add_test_categories(["libc++"])
31+
@skipIf(bugnumber="rdar://109455906") # The standalone build of LLDB doesn't test against custom libcxx builds
32+
def test_with_run_command(self):
33+
"""Test that std::ranges::ref_view is formatted correctly when printed.
34+
"""
35+
self.build()
36+
(self.target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
37+
self, 'Break here', lldb.SBFileSpec('main.cpp', False))
38+
39+
# Check ref_view over a std::string
40+
self.expect_var_path('single',
41+
children=[ValueCheck(
42+
name='*__range_',
43+
summary='"First"')])
44+
45+
# Check all_view, which is a ref_view in this case
46+
self.expect_var_path('all',
47+
children=[self.check_string_vec_ref_view()])
48+
49+
# Check take_view format. Embeds a ref_view
50+
self.expect_var_path('subset',
51+
children=[
52+
ValueCheck(children=[self.check_string_vec_ref_view()]),
53+
ValueCheck(name='__count_', value='2')
54+
])
55+
56+
lldbutil.continue_to_breakpoint(self.process(), bkpt)
57+
58+
# Check ref_view over custom type 'struct Foo'
59+
self.expect_var_path('view',
60+
children=[ValueCheck(
61+
name='*__range_',
62+
children=[
63+
ValueCheck(name='[0]', type='Foo', children=[self.check_foo()]),
64+
ValueCheck(name='[1]', type='Foo', children=[self.check_foo()])
65+
])
66+
])
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <cstdio>
2+
#include <ranges>
3+
#include <string>
4+
#include <vector>
5+
6+
using string_vec = std::vector<std::string>;
7+
8+
string_vec svec{"First", "Second", "Third", "Fourth"};
9+
10+
struct Foo {
11+
string_vec vec = svec;
12+
};
13+
14+
int main() {
15+
{
16+
auto single = std::ranges::ref_view(svec[0]);
17+
auto all = std::views::all(svec);
18+
auto subset = all | std::views::take(2);
19+
std::puts("Break here");
20+
}
21+
22+
{
23+
Foo f[2];
24+
auto view = std::ranges::ref_view(f);
25+
std::puts("Break here");
26+
}
27+
}

0 commit comments

Comments
 (0)