diff options
11 files changed, 735 insertions, 22 deletions
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index ff4e966fc27..28c3f82e2df 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -627,6 +627,9 @@ FormatManager::LoadLibcxxFormatters() AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__1::list<.+>(( )?&)?$"), stl_synth_flags, true); AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__1::map<.+> >(( )?&)?$"), stl_synth_flags, true); AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__1::vector<std::__1::allocator<bool> >"), stl_synth_flags); + AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__1::set<.+> >(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true); libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, @@ -642,6 +645,9 @@ FormatManager::LoadLibcxxFormatters() AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__1::map<.+>(( )?&)?$"), stl_summary_flags, true); AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__1::deque<.+>(( )?&)?$"), stl_summary_flags, true); AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__1::vector<std::__1::allocator<bool> >"), stl_summary_flags); + AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__1::set<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__1::multiset<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__1::multimap<.+>(( )?&)?$"), stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); AddStringSummary(libcxx_category_sp, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})}", ConstString("^std::__1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true); diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py index ff5a0266cc2..05a96e33418 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py @@ -58,17 +58,15 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib']) self.runCmd("frame variable ii --show-types") - - self.runCmd("type summary add -x \"std::__1::map<\" --summary-string \"map has ${svar%#} items\" -e") - + self.expect('frame variable ii', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.expect('frame variable ii', - substrs = ['map has 2 items', + substrs = ['size=2', '[0] = {', 'first = 0', 'second = 0', @@ -79,7 +77,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect('frame variable ii', - substrs = ['map has 4 items', + substrs = ['size=4', '[2] = {', 'first = 2', 'second = 0', @@ -90,7 +88,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect("frame variable ii", - substrs = ['map has 8 items', + substrs = ['size=8', '[5] = {', 'first = 5', 'second = 0', @@ -99,7 +97,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): 'second = 1']) self.expect("p ii", - substrs = ['map has 8 items', + substrs = ['size=8', '[5] = {', 'first = 5', 'second = 0', @@ -129,19 +127,19 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect('frame variable ii', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("frame variable si --show-types") self.expect('frame variable si', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.expect('frame variable si', - substrs = ['map has 1 items', + substrs = ['size=1', '[0] = ', 'first = \"zero\"', 'second = 0']) @@ -149,7 +147,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect("frame variable si", - substrs = ['map has 4 items', + substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', @@ -164,7 +162,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): 'second = 3']) self.expect("p si", - substrs = ['map has 4 items', + substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', @@ -197,20 +195,20 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect('frame variable si', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.runCmd("frame variable is --show-types") self.expect('frame variable is', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.expect("frame variable is", - substrs = ['map has 4 items', + substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', @@ -225,7 +223,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): 'first = 3']) self.expect("p is", - substrs = ['map has 4 items', + substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', @@ -258,20 +256,20 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect('frame variable is', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.runCmd("frame variable ss --show-types") self.expect('frame variable ss', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) self.runCmd("continue"); self.expect("frame variable ss", - substrs = ['map has 3 items', + substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', @@ -283,7 +281,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): 'first = \"gatto\"']) self.expect("p ss", - substrs = ['map has 3 items', + substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', @@ -312,7 +310,7 @@ class LibcxxMapDataFormatterTestCase(TestBase): self.runCmd("continue"); self.expect('frame variable ss', - substrs = ['map has 0 items', + substrs = ['size=0', '{}']) if __name__ == '__main__': diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile new file mode 100644 index 00000000000..e681e094da4 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules + +CXXFLAGS += -stdlib=libc++ -O0 -std=c++11 +LDFLAGS += -stdlib=libc++
\ No newline at end of file diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py new file mode 100644 index 00000000000..bb2bec12ef6 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/TestDataFormatterLibccMultiMap.py @@ -0,0 +1,320 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * +import lldbutil + +class LibcxxMultiMapDataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "multimap") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + @skipIfLinux # No standard locations for libc++ on Linux, so skip for now + @dwarf_test + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.") + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + self.runCmd('type filter clear', check=False) + self.runCmd('type synth clear', check=False) + self.runCmd("settings set target.max-children-count 256", check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib']) + + self.runCmd("frame variable ii --show-types") + + self.expect('frame variable ii', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + + self.expect('frame variable ii', + substrs = ['size=2', + '[0] = {', + 'first = 0', + 'second = 0', + '[1] = {', + 'first = 1', + 'second = 1']) + + self.runCmd("continue"); + + self.expect('frame variable ii', + substrs = ['size=4', + '[2] = {', + 'first = 2', + 'second = 0', + '[3] = {', + 'first = 3', + 'second = 1']) + + self.runCmd("continue"); + + self.expect("frame variable ii", + substrs = ['size=8', + '[5] = {', + 'first = 5', + 'second = 0', + '[7] = {', + 'first = 7', + 'second = 1']) + + self.expect("p ii", + substrs = ['size=8', + '[5] = {', + 'first = 5', + 'second = 0', + '[7] = {', + 'first = 7', + 'second = 1']) + + # check access-by-index + self.expect("frame variable ii[0]", + substrs = ['first = 0', + 'second = 0']); + self.expect("frame variable ii[3]", + substrs = ['first =', + 'second =']); + + # check that MightHaveChildren() gets it right + self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!") + + # check that the expression parser does not make use of + # synthetic children instead of running code + # TOT clang has a fix for this, which makes the expression command here succeed + # since this would make the test fail or succeed depending on clang version in use + # this is safer commented for the time being + #self.expect("expression ii[8]", matching=False, error=True, + # substrs = ['1234567']) + + self.runCmd("continue"); + + self.expect('frame variable ii', + substrs = ['size=0', + '{}']) + + self.runCmd("frame variable si --show-types") + + self.expect('frame variable si', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + + self.expect('frame variable si', + substrs = ['size=1', + '[0] = ', + 'first = \"zero\"', + 'second = 0']) + + self.runCmd("continue"); + + self.expect("frame variable si", + substrs = ['size=4', + '[0] = ', + 'first = \"zero\"', + 'second = 0', + '[1] = ', + 'first = \"one\"', + 'second = 1', + '[2] = ', + 'first = \"two\"', + 'second = 2', + '[3] = ', + 'first = \"three\"', + 'second = 3']) + + self.expect("p si", + substrs = ['size=4', + '[0] = ', + 'first = \"zero\"', + 'second = 0', + '[1] = ', + 'first = \"one\"', + 'second = 1', + '[2] = ', + 'first = \"two\"', + 'second = 2', + '[3] = ', + 'first = \"three\"', + 'second = 3']) + + # check that MightHaveChildren() gets it right + self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!") + + # check access-by-index + self.expect("frame variable si[0]", + substrs = ['first = ', 'one', + 'second = 1']); + + # check that the expression parser does not make use of + # synthetic children instead of running code + # TOT clang has a fix for this, which makes the expression command here succeed + # since this would make the test fail or succeed depending on clang version in use + # this is safer commented for the time being + #self.expect("expression si[0]", matching=False, error=True, + # substrs = ['first = ', 'zero']) + + self.runCmd("continue"); + + self.expect('frame variable si', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + self.runCmd("frame variable is --show-types") + + self.expect('frame variable is', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + + self.expect("frame variable is", + substrs = ['size=4', + '[0] = ', + 'second = \"goofy\"', + 'first = 85', + '[1] = ', + 'second = \"is\"', + 'first = 1', + '[2] = ', + 'second = \"smart\"', + 'first = 2', + '[3] = ', + 'second = \"!!!\"', + 'first = 3']) + + self.expect("p is", + substrs = ['size=4', + '[0] = ', + 'second = \"goofy\"', + 'first = 85', + '[1] = ', + 'second = \"is\"', + 'first = 1', + '[2] = ', + 'second = \"smart\"', + 'first = 2', + '[3] = ', + 'second = \"!!!\"', + 'first = 3']) + + # check that MightHaveChildren() gets it right + self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!") + + # check access-by-index + self.expect("frame variable is[0]", + substrs = ['first = ', + 'second =']); + + # check that the expression parser does not make use of + # synthetic children instead of running code + # TOT clang has a fix for this, which makes the expression command here succeed + # since this would make the test fail or succeed depending on clang version in use + # this is safer commented for the time being + #self.expect("expression is[0]", matching=False, error=True, + # substrs = ['first = ', 'goofy']) + + self.runCmd("continue"); + + self.expect('frame variable is', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + self.runCmd("frame variable ss --show-types") + + self.expect('frame variable ss', + substrs = ['size=0', + '{}']) + + self.runCmd("continue"); + + self.expect("frame variable ss", + substrs = ['size=3', + '[0] = ', + 'second = \"hello\"', + 'first = \"ciao\"', + '[1] = ', + 'second = \"house\"', + 'first = \"casa\"', + '[2] = ', + 'second = \"cat\"', + 'first = \"gatto\"']) + + self.expect("p ss", + substrs = ['size=3', + '[0] = ', + 'second = \"hello\"', + 'first = \"ciao\"', + '[1] = ', + 'second = \"house\"', + 'first = \"casa\"', + '[2] = ', + 'second = \"cat\"', + 'first = \"gatto\"']) + + # check that MightHaveChildren() gets it right + self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!") + + # check access-by-index + self.expect("frame variable ss[2]", + substrs = ['gatto', 'cat']); + + # check that the expression parser does not make use of + # synthetic children instead of running code + # TOT clang has a fix for this, which makes the expression command here succeed + # since this would make the test fail or succeed depending on clang version in use + # this is safer commented for the time being + #self.expect("expression ss[3]", matching=False, error=True, + # substrs = ['gatto']) + + self.runCmd("continue"); + + self.expect('frame variable ss', + substrs = ['size=0', + '{}']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp new file mode 100644 index 00000000000..f1a6e2ab4a7 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp @@ -0,0 +1,81 @@ +#include <string> +#ifdef _LIBCPP_INLINE_VISIBILITY +#undef _LIBCPP_INLINE_VISIBILITY +#endif +#define _LIBCPP_INLINE_VISIBILITY +#include <map> + +#define intint_map std::multimap<int, int> +#define strint_map std::multimap<std::string, int> +#define intstr_map std::multimap<int, std::string> +#define strstr_map std::multimap<std::string, std::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() +{ + intint_map ii; + + ii.emplace(0,0); // Set break point at this line. + ii.emplace(1,1); + thefoo_rw(1); // Set break point at this line. + ii.emplace(2,0); + ii.emplace(3,1); + thefoo_rw(1); // Set break point at this line. + ii.emplace(4,0); + ii.emplace(5,1); + ii.emplace(6,0); + ii.emplace(7,1); + thefoo_rw(1); // Set break point at this line. + ii.emplace(85,1234567); + + ii.clear(); + + strint_map si; + thefoo_rw(1); // Set break point at this line. + + si.emplace("zero",0); + thefoo_rw(1); // Set break point at this line. + si.emplace("one",1); + si.emplace("two",2); + si.emplace("three",3); + thefoo_rw(1); // Set break point at this line. + si.emplace("four",4); + + si.clear(); + thefoo_rw(1); // Set break point at this line. + + intstr_map is; + thefoo_rw(1); // Set break point at this line. + is.emplace(85,"goofy"); + is.emplace(1,"is"); + is.emplace(2,"smart"); + is.emplace(3,"!!!"); + thefoo_rw(1); // Set break point at this line. + + is.clear(); + thefoo_rw(1); // Set break point at this line. + + strstr_map ss; + thefoo_rw(1); // Set break point at this line. + + ss.emplace("ciao","hello"); + ss.emplace("casa","house"); + ss.emplace("gatto","cat"); + thefoo_rw(1); // Set break point at this line. + ss.emplace("a Mac..","..is always a Mac!"); + + ss.clear(); + thefoo_rw(1); // Set break point at this line. + return 0; +}
\ No newline at end of file diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile new file mode 100644 index 00000000000..f2f2b3f2fb8 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules + +CXXFLAGS += -stdlib=libc++ -O0 +LDFLAGS += -stdlib=libc++
\ No newline at end of file diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py new file mode 100644 index 00000000000..7ee0a147549 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py @@ -0,0 +1,85 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * +import lldbutil + +class LibcxxMultiSetDataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "multiset") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + @skipIfLinux # No standard locations for libc++ on Linux, so skip for now + @dwarf_test + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.") + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + self.runCmd('type filter clear', check=False) + self.runCmd('type synth clear', check=False) + self.runCmd("settings set target.max-children-count 256", check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib']) + + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) + self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) + self.expect("frame variable ii[2]",substrs = [" = 2"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.expect("frame variable ss",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"']) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) + self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) + self.expect("frame variable ss[2]",substrs = [' = "b"']) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp new file mode 100644 index 00000000000..1e1dd3b1603 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/main.cpp @@ -0,0 +1,57 @@ +#include <string> +#ifdef _LIBCPP_INLINE_VISIBILITY +#undef _LIBCPP_INLINE_VISIBILITY +#endif +#define _LIBCPP_INLINE_VISIBILITY +#include <set> + +typedef std::multiset<int> intset; +typedef std::multiset<std::string> stringset; + +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() +{ + intset ii; + thefoo_rw(1); // Set break point at this line. + + ii.insert(0); + ii.insert(1); + ii.insert(2); + ii.insert(3); + ii.insert(4); + ii.insert(5); + thefoo_rw(1); // Set break point at this line. + + ii.insert(6); + thefoo_rw(1); // Set break point at this line. + + ii.clear(); + thefoo_rw(1); // Set break point at this line. + + stringset ss; + thefoo_rw(1); // Set break point at this line. + + ss.insert("a"); + ss.insert("a very long string is right here"); + thefoo_rw(1); // Set break point at this line. + + ss.insert("b"); + ss.insert("c"); + thefoo_rw(1); // Set break point at this line. + + ss.erase("b"); + thefoo_rw(1); // Set break point at this line. + + return 0; +} diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile new file mode 100644 index 00000000000..f2f2b3f2fb8 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules + +CXXFLAGS += -stdlib=libc++ -O0 +LDFLAGS += -stdlib=libc++
\ No newline at end of file diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py new file mode 100644 index 00000000000..e1d9171acee --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py @@ -0,0 +1,85 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * +import lldbutil + +class LibcxxSetDataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "set") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + @skipIfLinux # No standard locations for libc++ on Linux, so skip for now + @dwarf_test + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.") + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + self.runCmd('type filter clear', check=False) + self.runCmd('type synth clear', check=False) + self.runCmd("settings set target.max-children-count 256", check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib']) + + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) + self.expect("frame variable ii[2]",substrs = [" = 2"]) + self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ii",substrs = ["size=0","{}"]) + self.expect("frame variable ss",substrs = ["size=0","{}"]) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"']) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) + self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) + self.expect("frame variable ss[2]",substrs = [' = "b"']) + self.runCmd("continue") + self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp new file mode 100644 index 00000000000..cc3033ef26e --- /dev/null +++ b/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/main.cpp @@ -0,0 +1,57 @@ +#include <string> +#ifdef _LIBCPP_INLINE_VISIBILITY +#undef _LIBCPP_INLINE_VISIBILITY +#endif +#define _LIBCPP_INLINE_VISIBILITY +#include <set> + +typedef std::set<int> intset; +typedef std::set<std::string> stringset; + +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() +{ + intset ii; + thefoo_rw(1); // Set break point at this line. + + ii.insert(0); + ii.insert(1); + ii.insert(2); + ii.insert(3); + ii.insert(4); + ii.insert(5); + thefoo_rw(1); // Set break point at this line. + + ii.insert(6); + thefoo_rw(1); // Set break point at this line. + + ii.clear(); + thefoo_rw(1); // Set break point at this line. + + stringset ss; + thefoo_rw(1); // Set break point at this line. + + ss.insert("a"); + ss.insert("a very long string is right here"); + thefoo_rw(1); // Set break point at this line. + + ss.insert("b"); + ss.insert("c"); + thefoo_rw(1); // Set break point at this line. + + ss.erase("b"); + thefoo_rw(1); // Set break point at this line. + + return 0; +} |