This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfcd288b52aa7: [formatters] Add a libstdcpp formatter for
for unordered_map, unordered_set… (authored by danilashtefan, committed by
Walter Erquinigo <[email protected]>).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D113760/new/
https://reviews.llvm.org/D113760
Files:
lldb/examples/synthetic/gnu_libstdcpp.py
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/Makefile
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-
-using std::string;
-
-#define intstr_map std::unordered_map<int, string>
-#define intstr_mmap std::unordered_multimap<int, string>
-
-#define int_set std::unordered_set<int>
-#define str_set std::unordered_set<string>
-#define int_mset std::unordered_multiset<int>
-#define str_mset std::unordered_multiset<string>
-
-int g_the_foo = 0;
-
-int thefoo_rw(int arg = 1)
-{
- if (arg < 0)
- arg = 0;
- if (!arg)
- arg = 1;
- g_the_foo += arg;
- return g_the_foo;
-}
-
-int main()
-{
- intstr_map map;
- map.emplace(1,"hello");
- map.emplace(2,"world");
- map.emplace(3,"this");
- map.emplace(4,"is");
- map.emplace(5,"me");
- thefoo_rw(); // Set break point at this line.
-
- intstr_mmap mmap;
- mmap.emplace(1,"hello");
- mmap.emplace(2,"hello");
- mmap.emplace(2,"world");
- mmap.emplace(3,"this");
- mmap.emplace(3,"this");
- mmap.emplace(3,"this");
- thefoo_rw(); // Set break point at this line.
-
- int_set iset;
- iset.emplace(1);
- iset.emplace(2);
- iset.emplace(3);
- iset.emplace(4);
- iset.emplace(5);
- thefoo_rw(); // Set break point at this line.
-
- str_set sset;
- sset.emplace("hello");
- sset.emplace("world");
- sset.emplace("this");
- sset.emplace("is");
- sset.emplace("me");
- thefoo_rw(); // Set break point at this line.
-
- int_mset imset;
- imset.emplace(1);
- imset.emplace(2);
- imset.emplace(2);
- imset.emplace(3);
- imset.emplace(3);
- imset.emplace(3);
- thefoo_rw(); // Set break point at this line.
-
- str_mset smset;
- smset.emplace("hello");
- smset.emplace("world");
- smset.emplace("world");
- smset.emplace("is");
- smset.emplace("is");
- thefoo_rw(); // Set break point at this line.
-
- return 0;
-}
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-CXX_SOURCES := main.cpp
-
-# Work around "exception specification in declaration does not match previous
-# declaration" errors present in older libc++ releases. This error was fixed in
-# the 3.8 release.
-CFLAGS_EXTRAS := -fno-exceptions
-
-USE_LIBCPP := 1
-include Makefile.rules
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
@@ -0,0 +1,68 @@
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1) {
+ if (arg < 0)
+ arg = 0;
+ if (!arg)
+ arg = 1;
+ g_the_foo += arg;
+ return g_the_foo;
+}
+
+int main() {
+ std::unordered_map<int, std::string> map;
+ map.emplace(1, "hello");
+ map.emplace(2, "world");
+ map.emplace(3, "this");
+ map.emplace(4, "is");
+ map.emplace(5, "me");
+ thefoo_rw(); // Set break point at this line.
+
+ std::unordered_multimap<int, std::string> mmap;
+ mmap.emplace(1, "hello");
+ mmap.emplace(2, "hello");
+ mmap.emplace(2, "world");
+ mmap.emplace(3, "this");
+ mmap.emplace(3, "this");
+ mmap.emplace(3, "this");
+ thefoo_rw(); // Set break point at this line.
+
+ std::unordered_set<int> iset;
+ iset.emplace(1);
+ iset.emplace(2);
+ iset.emplace(3);
+ iset.emplace(4);
+ iset.emplace(5);
+ thefoo_rw(); // Set break point at this line.
+
+ std::unordered_set<std::string> sset;
+ sset.emplace("hello");
+ sset.emplace("world");
+ sset.emplace("this");
+ sset.emplace("is");
+ sset.emplace("me");
+ thefoo_rw(); // Set break point at this line.
+
+ std::unordered_multiset<int> imset;
+ imset.emplace(1);
+ imset.emplace(2);
+ imset.emplace(2);
+ imset.emplace(3);
+ imset.emplace(3);
+ imset.emplace(3);
+ thefoo_rw(); // Set break point at this line.
+
+ std::unordered_multiset<std::string> smset;
+ smset.emplace("hello");
+ smset.emplace("world");
+ smset.emplace("world");
+ smset.emplace("is");
+ smset.emplace("is");
+ thefoo_rw(); // Set break point at this line.
+
+ return 0;
+}
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
@@ -9,18 +9,19 @@
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+USE_LIBSTDCPP = "USE_LIBSTDCPP"
+USE_LIBCPP = "USE_LIBCPP"
-class LibcxxUnorderedDataFormatterTestCase(TestBase):
-
+class GenericUnorderedDataFormatterTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
TestBase.setUp(self)
self.namespace = 'std'
- @add_test_categories(["libc++"])
- def test_with_run_command(self):
- self.build()
+
+ def do_test_with_run_command(self, stdlib_type):
+ self.build(dictionary={stdlib_type: "1"})
self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
lldbutil.run_break_set_by_source_regexp(
@@ -76,3 +77,11 @@
self.expect(("frame variable %s" % var_name), patterns=patterns)
self.expect(("frame variable %s" % var_name), patterns=patterns)
self.runCmd("continue")
+
+ @add_test_categories(["libstdcxx"])
+ def test_with_run_command_libstdcpp(self):
+ self.do_test_with_run_command(USE_LIBSTDCPP)
+
+ @add_test_categories(["libc++"])
+ def test_with_run_command_libcpp(self):
+ self.do_test_with_run_command(USE_LIBCPP)
\ No newline at end of file
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -918,6 +918,11 @@
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_deref_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
@@ -954,6 +959,10 @@
RegularExpression("^std::multiset<.+> >(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
TypeSummaryImplSP(
Index: lldb/examples/synthetic/gnu_libstdcpp.py
===================================================================
--- lldb/examples/synthetic/gnu_libstdcpp.py
+++ lldb/examples/synthetic/gnu_libstdcpp.py
@@ -9,6 +9,86 @@
# before relying on these formatters to do the right thing for your setup
+"""
+ This formatter can be applied to all
+ unordered map-like structures (unordered_map, unordered_multimap, unordered_set, unordered_multiset)
+"""
+class StdUnorderedMapSynthProvider:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.count = None
+ self.kind = self.get_object_kind(valobj)
+
+ def get_object_kind(self, valobj):
+ type_name = valobj.GetTypeName()
+ return "set" if "set" in type_name else "map"
+
+ def extract_type(self):
+ type = self.valobj.GetType()
+ # type of std::pair<key, value> is the first template
+ # argument type of the 4th template argument to std::map and
+ # 3rd template argument for std::set. That's why
+ # we need to know kind of the object
+ template_arg_num = 4 if self.kind == "map" else 3
+ allocator_type = type.GetTemplateArgumentType(template_arg_num)
+ data_type = allocator_type.GetTemplateArgumentType(0)
+ return data_type
+
+ def update(self):
+ # preemptively setting this to None - we might end up changing our mind
+ # later
+ self.count = None
+ try:
+ self.head = self.valobj.GetChildMemberWithName('_M_h')
+ self.before_begin = self.head.GetChildMemberWithName('_M_before_begin')
+ self.next = self.before_begin.GetChildMemberWithName('_M_nxt')
+ self.data_type = self.extract_type()
+ self.skip_size = self.next.GetType().GetByteSize()
+ self.data_size = self.data_type.GetByteSize()
+ except:
+ pass
+ return False
+
+ def get_child_index(self, name):
+ try:
+ return int(name.lstrip('[').rstrip(']'))
+ except:
+ return -1
+
+ def get_child_at_index(self, index):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "Being asked to fetch child[" + str(index) + "]"
+ if index < 0:
+ return None
+ if index >= self.num_children():
+ return None
+ try:
+ offset = index
+ current = self.next
+ while offset > 0:
+ current = current.GetChildMemberWithName('_M_nxt')
+ offset = offset - 1
+ return current.CreateChildAtOffset( '[' + str(index) + ']', self.skip_size, self.data_type)
+
+ except:
+ logger >> "Cannot get child"
+ return None
+
+ def num_children(self):
+ if self.count is None:
+ self.count = self.num_children_impl()
+ return self.count
+
+ def num_children_impl(self):
+ logger = lldb.formatters.Logger.Logger()
+ try:
+ count = self.head.GetChildMemberWithName('_M_element_count').GetValueAsUnsigned(0)
+ return count
+ except:
+ logger >> "Could not determine the size"
+ return 0
+
+
class AbstractListSynthProvider:
def __init__(self, valobj, dict, has_prev):
'''
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits