Skip to content

Commit 3eb9e65

Browse files
danilashtefanWalter Erquinigo
authored andcommitted
[formatters] Add a libstdcpp formatter for set and unify tests across stdlibs
This diff adds a data formatter for libstdcpp's set. Besides, it unifies the tests for set for libcxx and libstdcpp for maintainability. Reviewed By: wallace Differential Revision: https://reviews.llvm.org/D112537
1 parent 288f1f8 commit 3eb9e65

File tree

6 files changed

+114
-93
lines changed

6 files changed

+114
-93
lines changed

lldb/examples/synthetic/gnu_libstdcpp.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,19 +314,23 @@ def update(self):
314314
def has_children(self):
315315
return True
316316

317-
318-
class StdMapSynthProvider:
317+
"""
318+
Set and Map have the same underlying data structure,
319+
therefore we can use exactly the same implementation for the formatter.
320+
"""
321+
class StdSetOrMapSynthProvider:
319322

320323
def __init__(self, valobj, dict):
321324
logger = lldb.formatters.Logger.Logger()
322325
self.valobj = valobj
323326
self.count = None
324-
logger >> "Providing synthetic children for a map named " + \
327+
self.kind = "set" if "set" in valobj.GetTypeName() else "map"
328+
logger >> "Providing synthetic children for a " + self.kind + " named " + \
325329
str(valobj.GetName())
326330

327331
# we need this function as a temporary workaround for rdar://problem/10801549
328332
# which prevents us from extracting the std::pair<K,V> SBType out of the template
329-
# arguments for _Rep_Type _M_t in the map itself - because we have to make up the
333+
# arguments for _Rep_Type _M_t in the object itself - because we have to make up the
330334
# typename and then find it, we may hit the situation were std::string has multiple
331335
# names but only one is actually referenced in the debug information. hence, we need
332336
# to replace the longer versions of std::string with the shorter one in order to be able
@@ -349,7 +353,7 @@ def update(self):
349353
# later
350354
self.count = None
351355
try:
352-
# we will set this to True if we find out that discovering a node in the map takes more steps than the overall size of the RB tree
356+
# we will set this to True if we find out that discovering a node in the object takes more steps than the overall size of the RB tree
353357
# if this gets set to True, then we will merrily return None for
354358
# any child from that moment on
355359
self.garbage = False

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,14 +902,19 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
902902
RegularExpression("^std::map<.+> >(( )?&)?$"),
903903
SyntheticChildrenSP(new ScriptedSyntheticChildren(
904904
stl_synth_flags,
905-
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
905+
"lldb.formatters.cpp.gnu_libstdcpp.StdSetOrMapSynthProvider")));
906+
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
907+
RegularExpression("^std::set<.+> >(( )?&)?$"),
908+
SyntheticChildrenSP(new ScriptedSyntheticChildren(
909+
stl_deref_flags,
910+
"lldb.formatters.cpp.gnu_libstdcpp.StdSetOrMapSynthProvider")));
906911
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
907912
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
908913
SyntheticChildrenSP(new ScriptedSyntheticChildren(
909914
stl_synth_flags,
910915
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
911916
stl_summary_flags.SetDontShowChildren(false);
912-
stl_summary_flags.SetSkipPointers(true);
917+
stl_summary_flags.SetSkipPointers(false);
913918
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
914919
RegularExpression("^std::bitset<.+>(( )?&)?$"),
915920
TypeSummaryImplSP(
@@ -922,6 +927,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
922927
RegularExpression("^std::map<.+> >(( )?&)?$"),
923928
TypeSummaryImplSP(
924929
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
930+
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
931+
RegularExpression("^std::set<.+> >(( )?&)?$"),
932+
TypeSummaryImplSP(
933+
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
925934
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
926935
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
927936
TypeSummaryImplSP(
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
CXX_SOURCES := main.cpp
22

3-
USE_LIBCPP := 1
4-
5-
CXXFLAGS_EXTRAS := -O0
63
include Makefile.rules
Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from lldbsuite.test.lldbtest import *
1010
from lldbsuite.test import lldbutil
1111

12+
USE_LIBSTDCPP = "USE_LIBSTDCPP"
13+
USE_LIBCPP = "USE_LIBCPP"
1214

1315
class LibcxxSetDataFormatterTestCase(TestBase):
1416

@@ -18,34 +20,29 @@ def setUp(self):
1820
TestBase.setUp(self)
1921
self.namespace = 'std'
2022

21-
def getVariableType(self, name):
23+
def findVariable(self, name):
2224
var = self.frame().FindVariable(name)
2325
self.assertTrue(var.IsValid())
26+
return var
27+
28+
def getVariableType(self, name):
29+
var = self.findVariable(name)
2430
return var.GetType().GetDisplayTypeName()
2531

26-
def check_ii(self, var_name):
27-
""" This checks the value of the bitset stored in ii at the call to by_ref_and_ptr.
28-
We use this to make sure we get the same values for ii when we look at the object
29-
directly, and when we look at a reference to the object. """
30-
self.expect(
31-
"frame variable " + var_name,
32-
substrs=["size=7",
33-
"[2] = 2",
34-
"[3] = 3",
35-
"[6] = 6"])
36-
self.expect("frame variable " + var_name + "[2]", substrs=[" = 2"])
37-
self.expect(
38-
"p " + var_name,
39-
substrs=[
40-
"size=7",
41-
"[2] = 2",
42-
"[3] = 3",
43-
"[6] = 6"])
32+
def check(self, var_name, size):
33+
var = self.findVariable(var_name)
34+
self.assertEqual(var.GetNumChildren(), size)
35+
children = []
36+
for i in range(size):
37+
child = var.GetChildAtIndex(i)
38+
children.append(ValueCheck(value=child.GetValue()))
39+
self.expect_var_path(var_name, type=self.getVariableType(var_name), children=children)
4440

45-
@add_test_categories(["libc++"])
46-
def test_with_run_command(self):
41+
42+
43+
def do_test_with_run_command(self,stdlib_type):
4744
"""Test that that file and class static variables display correctly."""
48-
self.build()
45+
self.build(dictionary={stdlib_type: "1"})
4946
(self.target, process, _, bkpt) = lldbutil.run_to_source_breakpoint(
5047
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp", False))
5148

@@ -79,7 +76,7 @@ def cleanup():
7976
"[4] = 4",
8077
"[5] = 5"])
8178
lldbutil.continue_to_breakpoint(process, bkpt)
82-
self.check_ii("ii")
79+
self.check("ii",7)
8380

8481
lldbutil.continue_to_breakpoint(process, bkpt)
8582
self.expect("frame variable ii", substrs=["size=0", "{}"])
@@ -120,19 +117,36 @@ def cleanup():
120117
'[0] = "a"',
121118
'[1] = "a very long string is right here"',
122119
'[2] = "c"'])
120+
self.check("ss",3)
121+
122+
@add_test_categories(["libstdcxx"])
123+
def test_with_run_command_libstdcpp(self):
124+
self.do_test_with_run_command(USE_LIBSTDCPP)
123125

124126
@add_test_categories(["libc++"])
125-
def test_ref_and_ptr(self):
127+
def test_with_run_command_libcpp(self):
128+
self.do_test_with_run_command(USE_LIBCPP)
129+
130+
131+
def do_test_ref_and_ptr(self,stdlib_type):
126132
"""Test that the data formatters work on ref and ptr."""
127133
self.build()
128134
(self.target, process, _, bkpt) = lldbutil.run_to_source_breakpoint(
129135
self, "Stop here to check by ref and ptr.",
130136
lldb.SBFileSpec("main.cpp", False))
131137
# The reference should print just like the value:
132-
self.check_ii("ref")
138+
self.check("ref", 7)
139+
self.check("ptr", 7)
133140

134141
self.expect("frame variable ptr",
135142
substrs=["ptr =", "size=7"])
136143
self.expect("expr ptr",
137144
substrs=["size=7"])
138145

146+
@add_test_categories(["libstdcxx"])
147+
def test_ref_and_ptr_libstdcpp(self):
148+
self.do_test_ref_and_ptr(USE_LIBSTDCPP)
149+
150+
@add_test_categories(["libc++"])
151+
def test_ref_and_ptr_libcpp(self):
152+
self.do_test_ref_and_ptr(USE_LIBCPP)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <set>
2+
#include <string>
3+
4+
int g_the_foo = 0;
5+
6+
int thefoo_rw(int arg = 1) {
7+
if (arg < 0)
8+
arg = 0;
9+
if (!arg)
10+
arg = 1;
11+
g_the_foo += arg;
12+
return g_the_foo;
13+
}
14+
15+
void by_ref_and_ptr(std::set<int> &ref, std::set<int> *ptr) {
16+
// Stop here to check by ref and ptr
17+
return;
18+
}
19+
20+
int main() {
21+
std::set<int> ii;
22+
thefoo_rw(1); // Set break point at this line.
23+
24+
ii.insert(0);
25+
ii.insert(1);
26+
ii.insert(2);
27+
ii.insert(3);
28+
ii.insert(4);
29+
ii.insert(5);
30+
thefoo_rw(1); // Set break point at this line.
31+
32+
ii.insert(6);
33+
thefoo_rw(1); // Set break point at this line.
34+
35+
by_ref_and_ptr(ii, &ii);
36+
37+
ii.clear();
38+
thefoo_rw(1); // Set break point at this line.
39+
40+
std::set<std::string> ss;
41+
thefoo_rw(1); // Set break point at this line.
42+
43+
ss.insert("a");
44+
ss.insert("a very long string is right here");
45+
thefoo_rw(1); // Set break point at this line.
46+
47+
ss.insert("b");
48+
ss.insert("c");
49+
thefoo_rw(1); // Set break point at this line.
50+
51+
ss.erase("b");
52+
thefoo_rw(1); // Set break point at this line.
53+
54+
return 0;
55+
}

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

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)