diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 77047c077c678..eb46913be98b2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1515,8 +1515,8 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, - "std::map iterator synthetic children", "^std::_Rb_tree_iterator<.+>$", - stl_synth_flags, true); + "std::map iterator synthetic children", + "^std::_Rb_tree_(const_)?iterator<.+>$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/Makefile similarity index 70% rename from lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile rename to lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/Makefile index bf8e6b8703f36..99998b20bcb05 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/Makefile @@ -1,5 +1,3 @@ CXX_SOURCES := main.cpp -USE_LIBSTDCPP := 1 - include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/TestDataFormatterStdMap.py similarity index 94% rename from lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py rename to lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/TestDataFormatterStdMap.py index b2b83a3b46114..5851588b59b5f 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/TestDataFormatterStdMap.py @@ -2,14 +2,13 @@ Test lldb data formatter subsystem. """ - import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil -class LibcxxMapDataFormatterTestCase(TestBase): +class StdMapDataFormatterTestCase(TestBase): def setUp(self): TestBase.setUp(self) ns = "ndk" if lldbplatformutil.target_is_android() else "" @@ -22,10 +21,8 @@ def check_pair(self, first_value, second_value): ] return ValueCheck(children=pair_children) - @add_test_categories(["libc++"]) - def test_with_run_command(self): + def do_test(self): """Test that that file and class static variables display correctly.""" - self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( @@ -326,3 +323,23 @@ def cleanup(): lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs=["%s::map" % ns, "size=0", "{}"]) + + @add_test_categories(["libc++"]) + def test_libcxx(self): + self.build(dictionary={"USE_LIBCPP": 1}) + self.do_test() + + @add_test_categories(["libstdcxx"]) + def test_libstdcxx(self): + self.build(dictionary={"USE_LIBSTDCPP": 1}) + self.do_test() + + @expectedFailureAll( + bugnumber="Don't support formatting __gnu_debug::_Safe_iterator yet" + ) + @add_test_categories(["libstdcxx"]) + def test_libstdcxx_debug(self): + self.build( + dictionary={"USE_LIBSTDCPP": 1, "CXXFLAGS_EXTRAS": "-D_GLIBCXX_DEBUG"} + ) + self.do_test() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/main.cpp new file mode 100644 index 0000000000000..91bdf0b58d9e4 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/map/main.cpp @@ -0,0 +1,80 @@ +#include +#include + +#define intint_map std::map +#define strint_map std::map +#define intstr_map std::map +#define strstr_map std::map + +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[0] = 0; // Set break point at this line. + ii[1] = 1; + + intint_map::iterator it = ii.begin(); + intint_map::const_iterator const_it = ii.cbegin(); + std::printf("%d %d\n", it->second, const_it->second); + + thefoo_rw(1); // Set break point at this line. + ii[2] = 0; + ii[3] = 1; + thefoo_rw(1); // Set break point at this line. + ii[4] = 0; + ii[5] = 1; + ii[6] = 0; + ii[7] = 1; + thefoo_rw(1); // Set break point at this line. + ii[85] = 1234567; + + ii.clear(); + + strint_map si; + thefoo_rw(1); // Set break point at this line. + + si["zero"] = 0; + thefoo_rw(1); // Set break point at this line. + si["one"] = 1; + si["two"] = 2; + si["three"] = 3; + thefoo_rw(1); // Set break point at this line. + si["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[85] = "goofy"; + is[1] = "is"; + is[2] = "smart"; + is[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["ciao"] = "hello"; + ss["casa"] = "house"; + ss["gatto"] = "cat"; + thefoo_rw(1); // Set break point at this line. + ss["a Mac.."] = "..is always a Mac!"; + + ss.clear(); + thefoo_rw(1); // Set break point at this line. + return 0; +} diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile deleted file mode 100644 index 564cbada74e08..0000000000000 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -CXX_SOURCES := main.cpp - -USE_LIBCPP := 1 - -CXXFLAGS_EXTRAS := -O0 -include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp deleted file mode 100644 index 43ce6aeefd2a2..0000000000000 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -#define intint_map std::map -#define strint_map std::map -#define intstr_map std::map -#define strstr_map std::map - -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[0] = 0; // Set break point at this line. - ii[1] = 1; - - intint_map::iterator it = ii.begin(); - intint_map::const_iterator const_it = ii.cbegin(); - std::printf("%d %d\n", it->second, const_it->second); - - thefoo_rw(1); // Set break point at this line. - ii[2] = 0; - ii[3] = 1; - thefoo_rw(1); // Set break point at this line. - ii[4] = 0; - ii[5] = 1; - ii[6] = 0; - ii[7] = 1; - thefoo_rw(1); // Set break point at this line. - ii[85] = 1234567; - - ii.clear(); - - strint_map si; - thefoo_rw(1); // Set break point at this line. - - si["zero"] = 0; - thefoo_rw(1); // Set break point at this line. - si["one"] = 1; - si["two"] = 2; - si["three"] = 3; - thefoo_rw(1); // Set break point at this line. - si["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[85] = "goofy"; - is[1] = "is"; - is[2] = "smart"; - is[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["ciao"] = "hello"; - ss["casa"] = "house"; - ss["gatto"] = "cat"; - thefoo_rw(1); // Set break point at this line. - ss["a Mac.."] = "..is always a Mac!"; - - ss.clear(); - thefoo_rw(1); // Set break point at this line. - return 0; -} diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py deleted file mode 100644 index 2d76c02657a7d..0000000000000 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py +++ /dev/null @@ -1,301 +0,0 @@ -""" -Test lldb data formatter subsystem. -""" - -from typing import Optional -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class StdMapDataFormatterTestCase(TestBase): - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break at. - self.line = line_number("main.cpp", "// Set break point at this line.") - - @add_test_categories(["libstdcxx"]) - @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc") - def test_with_run_command(self): - self.with_run_command() - - @add_test_categories(["libstdcxx"]) - @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc") - def test_with_run_command_debug(self): - build_args = {"CXXFLAGS_EXTRAS": "-D_GLIBCXX_DEBUG"} - self.with_run_command("__debug::", build_args) - - def with_run_command(self, namespace: str = "", dictionary: Optional[dict] = None): - """Test that that file and class static variables display correctly.""" - self.build(dictionary=dictionary) - self.runCmd("file " + self.getBuildArtifact("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) - - # Execute the cleanup function during test case tear down. - self.addTearDownHook(cleanup) - - self.runCmd("frame variable ii --show-types") - - self.runCmd( - f'type summary add -x "std::{namespace}map<" --summary-string "map has ${{svar%#}} items" -e' - ) - - self.expect("frame variable ii", substrs=["map has 0 items", "{}"]) - - self.runCmd("c") - - self.expect( - "frame variable ii", - substrs=[ - "map has 2 items", - "[0] = ", - "first = 0", - "second = 0", - "[1] = ", - "first = 1", - "second = 1", - ], - ) - - self.runCmd("c") - - self.expect( - "frame variable ii", - substrs=[ - "map has 4 items", - "[2] = ", - "first = 2", - "second = 0", - "[3] = ", - "first = 3", - "second = 1", - ], - ) - - self.runCmd("c") - - self.expect( - "frame variable ii", - substrs=[ - "map has 9 items", - "[5] = ", - "first = 5", - "second = 0", - "[7] = ", - "first = 7", - "second = 1", - ], - ) - - self.expect( - "expression ii", - substrs=[ - "map has 9 items", - "[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 ="]) - - self.expect("frame variable ii[8]", matching=True, substrs=["1234567"]) - - # 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("c") - - self.expect("frame variable ii", substrs=["map has 0 items", "{}"]) - - self.runCmd("frame variable si --show-types") - - self.expect("frame variable si", substrs=["map has 0 items", "{}"]) - - self.runCmd("c") - - self.expect( - "frame variable si", - substrs=["map has 1 items", "[0] = ", 'first = "zero"', "second = 0"], - ) - - self.runCmd("c") - - self.expect( - "frame variable si", - substrs=[ - "map has 5 items", - '[0] = (first = "four", second = 4)', - '[1] = (first = "one", second = 1)', - '[2] = (first = "three", second = 3)', - '[3] = (first = "two", second = 2)', - '[4] = (first = "zero", second = 0)', - ], - ) - - self.expect( - "expression si", - substrs=[ - "map has 5 items", - '[0] = (first = "four", second = 4)', - '[1] = (first = "one", second = 1)', - '[2] = (first = "three", second = 3)', - '[3] = (first = "two", second = 2)', - '[4] = (first = "zero", second = 0)', - ], - ) - - # check access-by-index - self.expect("frame variable si[0]", substrs=["first = ", "four", "second = 4"]) - - # check that MightHaveChildren() gets it right - self.assertTrue( - self.frame().FindVariable("si").MightHaveChildren(), - "si.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 si[0]", matching=False, error=True, - # substrs = ['first = ', 'zero']) - - self.runCmd("c") - - self.expect("frame variable si", substrs=["map has 0 items", "{}"]) - - self.runCmd("frame variable is --show-types") - - self.expect("frame variable is", substrs=["map has 0 items", "{}"]) - - self.runCmd("c") - - self.expect( - "frame variable is", - substrs=[ - "map has 4 items", - '[0] = (first = 1, second = "is")', - '[1] = (first = 2, second = "smart")', - '[2] = (first = 3, second = "!!!")', - '[3] = (first = 85, second = "goofy")', - ], - ) - - self.expect( - "expression is", - substrs=[ - "map has 4 items", - '[0] = (first = 1, second = "is")', - '[1] = (first = 2, second = "smart")', - '[2] = (first = 3, second = "!!!")', - '[3] = (first = 85, second = "goofy")', - ], - ) - - # check access-by-index - self.expect("frame variable is[0]", substrs=["first = ", "second ="]) - - # check that MightHaveChildren() gets it right - self.assertTrue( - self.frame().FindVariable("is").MightHaveChildren(), - "is.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 is[0]", matching=False, error=True, - # substrs = ['first = ', 'goofy']) - - self.runCmd("c") - - self.expect("frame variable is", substrs=["map has 0 items", "{}"]) - - self.runCmd("frame variable ss --show-types") - - self.expect("frame variable ss", substrs=["map has 0 items", "{}"]) - - self.runCmd("c") - - self.expect( - "frame variable ss", - substrs=[ - "map has 4 items", - '[0] = (first = "a Mac..", second = "..is always a Mac!")', - '[1] = (first = "casa", second = "house")', - '[2] = (first = "ciao", second = "hello")', - '[3] = (first = "gatto", second = "cat")', - ], - ) - - self.expect( - "expression ss", - substrs=[ - "map has 4 items", - '[0] = (first = "a Mac..", second = "..is always a Mac!")', - '[1] = (first = "casa", second = "house")', - '[2] = (first = "ciao", second = "hello")', - '[3] = (first = "gatto", second = "cat")', - ], - ) - - # check access-by-index - self.expect("frame variable ss[3]", substrs=["gatto", "cat"]) - - # check that MightHaveChildren() gets it right - self.assertTrue( - self.frame().FindVariable("ss").MightHaveChildren(), - "ss.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 ss[3]", matching=False, error=True, - # substrs = ['gatto']) - - self.runCmd("c") - - self.expect("frame variable ss", substrs=["map has 0 items", "{}"]) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp deleted file mode 100644 index d5e5b212782d8..0000000000000 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include - -#define intint_map std::map -#define strint_map std::map -#define intstr_map std::map -#define strstr_map std::map - - -int main() -{ - intint_map ii; - - ii[0] = 0; // Set break point at this line. - ii[1] = 1; - ii[2] = 0;// Set break point at this line. - ii[3] = 1; - ii[4] = 0;// Set break point at this line. - ii[5] = 1; - ii[6] = 0; - ii[7] = 1; - ii[85] = 1234567; - - ii.clear();// Set break point at this line. - - strint_map si; - - si["zero"] = 0;// Set break point at this line. - si["one"] = 1;// Set break point at this line. - si["two"] = 2; - si["three"] = 3; - si["four"] = 4; - - si.clear();// Set break point at this line. - - intstr_map is; - - is[85] = "goofy";// Set break point at this line. - is[1] = "is"; - is[2] = "smart"; - is[3] = "!!!"; - - is.clear();// Set break point at this line. - - strstr_map ss; - - ss["ciao"] = "hello";// Set break point at this line. - ss["casa"] = "house"; - ss["gatto"] = "cat"; - ss["a Mac.."] = "..is always a Mac!"; - - ss.clear();// Set break point at this line. - - return 0;// Set break point at this line. -}