[Lldb-commits] [lldb] [lldb] optionally match the `__debug` namespace for libstdc++ containers. (PR #140727)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Tue May 20 14:57:33 PDT 2025
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/140727
>From f7d90b3e3ec052adc10ca79459249409a5ed69c2 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Sun, 18 May 2025 09:55:25 +0100
Subject: [PATCH 01/10] [lldb] optionally match the `__debug` namespace for
libstdc++ containers.
If libstdc++ is compiled with `_GLIBCXX_DEBUG` flag it puts the containers in the namespace `std::__debug`. this causes the summary and synthetic formatters not to match the types. The formatters is updated to optionally match the `__debug::`.
The formatters now clashed with the libc++ containers namespace regex which uses `std::__1` namespace
The libc++ formatter is loaded first, then the libstdc++ since the priority of the formatters in lldb is the last one added.
Fixes #60841
---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 136 +++++++++---------
1 file changed, 71 insertions(+), 65 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 542f13bef23e7..f6fc7e7114953 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1449,104 +1449,110 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags.SetFrontEndWantsDereference();
cpp_category_sp->AddTypeSynthetic(
- "^std::vector<.+>(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?vector<.+>(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::map<.+> >(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?map<.+> >(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::deque<.+>(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug)?deque<.+>(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::set<.+> >(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?set<.+> >(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::unordered_(multi)?(map|set)<.+> >$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::(__debug::)?unordered_(multi)?(map|set)<.+> >$",
+ eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::(__cxx11::)?list<.+>(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::((__debug::)?|(__cxx11::)?)list<.+>(( )?&)?$",
+ eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
- "^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ "^std::((__debug::)?|(__cxx11::)?)forward_list<.+>(( )?&)?$",
+ eFormatterMatchRegex,
+ std::make_shared<ScriptedSyntheticChildren>(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider"));
cpp_category_sp->AddTypeSynthetic(
"^std::variant<.+>$", eFormatterMatchRegex,
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ std::make_shared<ScriptedSyntheticChildren>(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider"));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
- cpp_category_sp->AddTypeSummary("^std::bitset<.+>(( )?&)?$",
- eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::vector<.+>(( )?&)?$",
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?bitset<.+>(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::map<.+> >(( )?&)?$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?vector<.+>(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::set<.+> >(( )?&)?$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?map<.+> >(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::deque<.+>(( )?&)?$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?set<.+> >(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::multimap<.+> >(( )?&)?$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?deque<.+>(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::multiset<.+> >(( )?&)?$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?multimap<.+> >(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::unordered_(multi)?(map|set)<.+> >$",
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary("^std::(__debug::)?multiset<.+> >(( )?&)?$",
eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
- cpp_category_sp->AddTypeSummary("^std::(__cxx11::)?list<.+>(( )?&)?$",
- eFormatterMatchRegex,
- TypeSummaryImplSP(new StringSummaryFormat(
- stl_summary_flags, "size=${svar%#}")));
+ std::make_shared<StringSummaryFormat>(
+ stl_summary_flags, "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary(
+ "^std::(__debug::)?unordered_(multi)?(map|set)<.+> >$",
+ eFormatterMatchRegex,
+ std::make_shared<StringSummaryFormat>(stl_summary_flags,
+ "size=${svar%#}"));
cpp_category_sp->AddTypeSummary(
- "^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
- TypeSummaryImplSP(new ScriptSummaryFormat(
+ "^std::((__debug::)?|(__cxx11::)?)list<.+>(( )?&)?$",
+ eFormatterMatchRegex,
+ std::make_shared<StringSummaryFormat>(stl_summary_flags,
+ "size=${svar%#}"));
+ cpp_category_sp->AddTypeSummary(
+ "^std::((__debug::)?|(__cxx11::)?)forward_list<.+>(( )?&)?$",
+ eFormatterMatchRegex,
+ std::make_shared<ScriptSummaryFormat>(
stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider"));
cpp_category_sp->AddTypeSummary(
"^std::variant<.+>$", eFormatterMatchRegex,
- TypeSummaryImplSP(new ScriptSummaryFormat(
+ std::make_shared<ScriptSummaryFormat>(
stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider")));
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider"));
AddCXXSynthetic(
cpp_category_sp,
@@ -1592,7 +1598,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
- "std::bitset synthetic child", "^std::bitset<.+>(( )?&)?$",
+ "std::bitset synthetic child", "^std::(__debug::)?bitset<.+>(( )?&)?$",
stl_deref_flags, true);
AddCXXSynthetic(
@@ -1731,8 +1737,8 @@ lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
g_category);
if (g_category) {
- LoadLibStdcppFormatters(g_category);
LoadLibCxxFormatters(g_category);
+ LoadLibStdcppFormatters(g_category);
LoadSystemFormatters(g_category);
}
});
>From b18de60fe04e65afd30429dc6b23aba5924b2a73 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Sun, 18 May 2025 10:05:53 +0100
Subject: [PATCH 02/10] [lldb] Update test crashes because it depended on the
order of the strings.
---
.../data-formatter-categories/TestDataFormatterCategories.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py b/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
index f602d017f28b7..344fbb8994ba5 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
@@ -335,5 +335,7 @@ def cleanup():
# and also validate that one can print formatters for a language
self.expect(
- "type summary list -l c++", substrs=["vector", "map", "list", "string"]
+ "type summary list -l c++",
+ substrs=["vector", "map", "list", "string"],
+ ordered=False
)
>From 975b2dd78becb988375d20deae80a311eb0b21d4 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Sun, 18 May 2025 10:22:37 +0100
Subject: [PATCH 03/10] [lldb] Update std::vector test
---
.../vector/DataFormatterStdVector.py | 219 ++++++++++++++++++
.../libstdcpp/vector/Makefile | 8 +
.../vector/TestDataFormatterStdVector.py | 209 +----------------
.../vector/TestDataFormatterStdVectorDebug.py | 16 ++
4 files changed, 250 insertions(+), 202 deletions(-)
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
new file mode 100644
index 0000000000000..07fb2a222f321
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
@@ -0,0 +1,219 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from abc import abstractmethod
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
+from lldbsuite.test import lldbutil
+
+
+class StdVectorDataFormatterBase(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.")
+
+ @abstractmethod
+ def test_with_run_command(self):
+ pass
+
+ def with_run_command(self, artifact_name: str):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), 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)
+
+ # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
+ self.expect("frame variable numbers", substrs=["numbers = size=0"])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect(
+ "frame variable numbers", substrs=["numbers = size=1", "[0] = 1", "}"]
+ )
+
+ # add some more data
+ self.runCmd("c")
+
+ self.expect(
+ "frame variable numbers",
+ substrs=[
+ "numbers = size=4",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "}",
+ ],
+ )
+
+ self.expect(
+ "expression numbers",
+ substrs=[
+ "$",
+ "size=4",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "}",
+ ],
+ )
+
+ # check access to synthetic children
+ self.runCmd(
+ 'type summary add --summary-string "item 0 is ${var[0]}" std::int_vect int_vect'
+ )
+ self.expect("frame variable numbers", substrs=["item 0 is 1"])
+
+ self.runCmd(
+ 'type summary add --summary-string "item 0 is ${svar[0]}" std::int_vect int_vect'
+ )
+ # import time
+ # time.sleep(19)
+ self.expect("frame variable numbers", substrs=["item 0 is 1"])
+ # move on with synths
+ self.runCmd("type summary delete std::int_vect")
+ self.runCmd("type summary delete int_vect")
+
+ # add some more data
+ self.runCmd("c")
+
+ self.expect(
+ "frame variable numbers",
+ substrs=[
+ "numbers = size=7",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "[4] = 12345",
+ "[5] = 123456",
+ "[6] = 1234567",
+ "}",
+ ],
+ )
+
+ self.expect(
+ "expression numbers",
+ substrs=[
+ "$",
+ "size=7",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "[4] = 12345",
+ "[5] = 123456",
+ "[6] = 1234567",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable numbers[0]", substrs=["1"])
+ self.expect("frame variable numbers[1]", substrs=["12"])
+ self.expect("frame variable numbers[2]", substrs=["123"])
+ self.expect("frame variable numbers[3]", substrs=["1234"])
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect(
+ "expression numbers[6]", matching=False, error=True, substrs=["1234567"]
+ )
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(
+ self.frame().FindVariable("numbers").MightHaveChildren(),
+ "numbers.MightHaveChildren() says False for non empty!",
+ )
+
+ # clear out the vector and see that we do the right thing once again
+ self.runCmd("c")
+
+ self.expect("frame variable numbers", substrs=["numbers = size=0"])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect(
+ "frame variable numbers", substrs=["numbers = size=1", "[0] = 7", "}"]
+ )
+
+ # check if we can display strings
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["goofy", "is", "smart"])
+
+ self.expect("expression strings", substrs=["goofy", "is", "smart"])
+
+ # test summaries based on synthetic children
+ self.runCmd(
+ 'type summary add std::string_vect string_vect --summary-string "vector has ${svar%#} items" -e'
+ )
+ self.expect(
+ "frame variable strings",
+ substrs=["vector has 3 items", "goofy", "is", "smart"],
+ )
+
+ self.expect(
+ "expression strings", substrs=["vector has 3 items", "goofy", "is", "smart"]
+ )
+
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["vector has 4 items"])
+
+ # check access-by-index
+ self.expect("frame variable strings[0]", substrs=["goofy"])
+ self.expect("frame variable strings[1]", substrs=["is"])
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect(
+ "expression strings[0]", matching=False, error=True, substrs=["goofy"]
+ )
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(
+ self.frame().FindVariable("strings").MightHaveChildren(),
+ "strings.MightHaveChildren() says False for non empty!",
+ )
+
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["vector has 0 items"])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
index 654e4b15bd568..6bb9503378934 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
@@ -3,4 +3,12 @@ CXX_SOURCES := main.cpp
CXXFLAGS := -O0
USE_LIBSTDCPP := 1
+all: debug_a.out
+
include Makefile.rules
+
+debug_main.o: main.cpp
+ $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
+
+debug_a.out: debug_main.o
+ $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
index e7d3ab3916927..b824a5024197a 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -1,211 +1,16 @@
"""
-Test lldb data formatter subsystem.
+Test lldb data formatter subsystem for std::vector.
"""
+from typing import override
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+from DataFormatterStdVector import StdVectorDataFormatterBase
-class StdVectorDataFormatterTestCase(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.")
-
+class NoDebugTestCase(StdVectorDataFormatterBase):
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ @override
def test_with_run_command(self):
- """Test that that file and class static variables display correctly."""
- self.build()
- 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)
- self.runCmd("settings set target.max-children-count 256", check=False)
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
-
- # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
- self.expect("frame variable numbers", substrs=["numbers = size=0"])
-
- self.runCmd("c")
-
- # first value added
- self.expect(
- "frame variable numbers", substrs=["numbers = size=1", "[0] = 1", "}"]
- )
-
- # add some more data
- self.runCmd("c")
-
- self.expect(
- "frame variable numbers",
- substrs=[
- "numbers = size=4",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "}",
- ],
- )
-
- self.expect(
- "expression numbers",
- substrs=[
- "$",
- "size=4",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "}",
- ],
- )
-
- # check access to synthetic children
- self.runCmd(
- 'type summary add --summary-string "item 0 is ${var[0]}" std::int_vect int_vect'
- )
- self.expect("frame variable numbers", substrs=["item 0 is 1"])
-
- self.runCmd(
- 'type summary add --summary-string "item 0 is ${svar[0]}" std::int_vect int_vect'
- )
- # import time
- # time.sleep(19)
- self.expect("frame variable numbers", substrs=["item 0 is 1"])
- # move on with synths
- self.runCmd("type summary delete std::int_vect")
- self.runCmd("type summary delete int_vect")
-
- # add some more data
- self.runCmd("c")
-
- self.expect(
- "frame variable numbers",
- substrs=[
- "numbers = size=7",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "[4] = 12345",
- "[5] = 123456",
- "[6] = 1234567",
- "}",
- ],
- )
-
- self.expect(
- "expression numbers",
- substrs=[
- "$",
- "size=7",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "[4] = 12345",
- "[5] = 123456",
- "[6] = 1234567",
- "}",
- ],
- )
-
- # check access-by-index
- self.expect("frame variable numbers[0]", substrs=["1"])
- self.expect("frame variable numbers[1]", substrs=["12"])
- self.expect("frame variable numbers[2]", substrs=["123"])
- self.expect("frame variable numbers[3]", substrs=["1234"])
-
- # but check that expression does not rely on us
- # (when expression gets to call into STL code correctly, we will have to find
- # another way to check this)
- self.expect(
- "expression numbers[6]", matching=False, error=True, substrs=["1234567"]
- )
-
- # check that MightHaveChildren() gets it right
- self.assertTrue(
- self.frame().FindVariable("numbers").MightHaveChildren(),
- "numbers.MightHaveChildren() says False for non empty!",
- )
-
- # clear out the vector and see that we do the right thing once again
- self.runCmd("c")
-
- self.expect("frame variable numbers", substrs=["numbers = size=0"])
-
- self.runCmd("c")
-
- # first value added
- self.expect(
- "frame variable numbers", substrs=["numbers = size=1", "[0] = 7", "}"]
- )
-
- # check if we can display strings
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["goofy", "is", "smart"])
-
- self.expect("expression strings", substrs=["goofy", "is", "smart"])
-
- # test summaries based on synthetic children
- self.runCmd(
- 'type summary add std::string_vect string_vect --summary-string "vector has ${svar%#} items" -e'
- )
- self.expect(
- "frame variable strings",
- substrs=["vector has 3 items", "goofy", "is", "smart"],
- )
-
- self.expect(
- "expression strings", substrs=["vector has 3 items", "goofy", "is", "smart"]
- )
-
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["vector has 4 items"])
-
- # check access-by-index
- self.expect("frame variable strings[0]", substrs=["goofy"])
- self.expect("frame variable strings[1]", substrs=["is"])
-
- # but check that expression does not rely on us
- # (when expression gets to call into STL code correctly, we will have to find
- # another way to check this)
- self.expect(
- "expression strings[0]", matching=False, error=True, substrs=["goofy"]
- )
-
- # check that MightHaveChildren() gets it right
- self.assertTrue(
- self.frame().FindVariable("strings").MightHaveChildren(),
- "strings.MightHaveChildren() says False for non empty!",
- )
-
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["vector has 0 items"])
+ self.with_run_command("a.out")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
new file mode 100644
index 0000000000000..0007d4bff42cc
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
@@ -0,0 +1,16 @@
+"""
+Test lldb data formatter subsystem for std::vector with -D_GLIBCXX_DEBUG flag
+"""
+
+from typing import override
+
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+from DataFormatterStdVector import StdVectorDataFormatterBase
+
+
+class WithDebugTestCase(StdVectorDataFormatterBase):
+ @add_test_categories(["libstdcxx"])
+ @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ @override
+ def test_with_run_command(self):
+ self.with_run_command("debug_a.out")
>From 52954c6d50a607a4504644a5ef2dfab5c1402f63 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Sun, 18 May 2025 10:39:26 +0100
Subject: [PATCH 04/10] [lldb] Update std::vector<bool> test
---
.../libstdcpp/vbool/DataFormatterStdVBool.py | 79 +++++++++++++++++++
.../libstdcpp/vbool/Makefile | 10 ++-
.../vbool/TestDataFormatterStdVBool.py | 76 ++----------------
.../TestDataFormatterStdVBoolWithDebug.py | 14 ++++
4 files changed, 109 insertions(+), 70 deletions(-)
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
new file mode 100644
index 0000000000000..2f26659223130
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
@@ -0,0 +1,79 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from abc import abstractmethod
+from lldbsuite.test.decorators import add_test_categories
+from lldbsuite.test.lldbtest import CURRENT_EXECUTABLE_SET, RUN_SUCCEEDED, STOPPED_DUE_TO_BREAKPOINT, TestBase, \
+ line_number
+from lldbsuite.test import lldbutil
+
+
+class StdVBoolDataFormatterBase(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.")
+
+ @abstractmethod
+ def test_with_run_command(self):
+ pass
+
+ def with_run_command(self, artifact_name: str):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ self.runCmd("file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line(
+ self, "main.cpp", self.line, num_expected_locations=-1
+ )
+
+ 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(
+ "frame variable vBool",
+ substrs=[
+ "size=49",
+ "[0] = false",
+ "[1] = true",
+ "[18] = false",
+ "[27] = true",
+ "[36] = false",
+ "[47] = true",
+ "[48] = true",
+ ],
+ )
+
+ self.expect(
+ "expr vBool",
+ substrs=[
+ "size=49",
+ "[0] = false",
+ "[1] = true",
+ "[18] = false",
+ "[27] = true",
+ "[36] = false",
+ "[47] = true",
+ "[48] = true",
+ ],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
index c825977b1a5dc..6bb9503378934 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
@@ -1,6 +1,14 @@
CXX_SOURCES := main.cpp
-CFLAGS_EXTRAS := -O0
+CXXFLAGS := -O0
USE_LIBSTDCPP := 1
+all: debug_a.out
+
include Makefile.rules
+
+debug_main.o: main.cpp
+ $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
+
+debug_a.out: debug_main.o
+ $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
index 696d1c672192d..44bed4b8b15ab 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -1,76 +1,14 @@
"""
-Test lldb data formatter subsystem.
+Test lldb data formatter subsystem for std::vector<bool>
"""
+from typing import override
+from lldbsuite.test.decorators import add_test_categories
+from DataFormatterStdVBool import StdVBoolDataFormatterBase
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class StdVBoolDataFormatterTestCase(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.")
+class StdVBoolDataFormatter(StdVBoolDataFormatterBase):
@add_test_categories(["libstdcxx"])
+ @override
def test_with_run_command(self):
- """Test that that file and class static variables display correctly."""
- self.build()
- self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
-
- lldbutil.run_break_set_by_file_and_line(
- self, "main.cpp", self.line, num_expected_locations=-1
- )
-
- 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(
- "frame variable vBool",
- substrs=[
- "size=49",
- "[0] = false",
- "[1] = true",
- "[18] = false",
- "[27] = true",
- "[36] = false",
- "[47] = true",
- "[48] = true",
- ],
- )
-
- self.expect(
- "expr vBool",
- substrs=[
- "size=49",
- "[0] = false",
- "[1] = true",
- "[18] = false",
- "[27] = true",
- "[36] = false",
- "[47] = true",
- "[48] = true",
- ],
- )
+ self.with_run_command("a.out")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
new file mode 100644
index 0000000000000..0210d9cf75c7e
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
@@ -0,0 +1,14 @@
+"""
+Test lldb data formatter subsystem for std::vector<bool> with flag "_GLIBCXX_DEBUG"
+"""
+
+from typing import override
+from lldbsuite.test.decorators import add_test_categories
+from DataFormatterStdVBool import StdVBoolDataFormatterBase
+
+
+class StdVBoolDataFormatterWithDebug(StdVBoolDataFormatterBase):
+ @add_test_categories(["libstdcxx"])
+ @override
+ def test_with_run_command(self):
+ self.with_run_command("debug_a.out")
>From a9e861455b43992d0afae68b600e662932d2a219 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Sun, 18 May 2025 12:38:58 +0100
Subject: [PATCH 05/10] [lldb] Update std::map test
---
.../libstdcpp/map/DataFormatterStdMap.py | 300 ++++++++++++++++++
.../data-formatter-stl/libstdcpp/map/Makefile | 8 +
.../libstdcpp/map/TestDataFormatterStdMap.py | 293 +----------------
.../map/TestDataFormatterStdMapWithDebug.py | 14 +
4 files changed, 329 insertions(+), 286 deletions(-)
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
new file mode 100644
index 0000000000000..f6dac643b95a0
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
@@ -0,0 +1,300 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from abc import abstractmethod
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
+from lldbsuite.test import lldbutil
+
+
+class StdMapDataFormatterBase(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.")
+
+ @abstractmethod
+ def test_with_run_command(self):
+ pass
+
+ def with_run_command(self, artifact_name: str, namespace: str = ""):
+ """Test that that file and class static variables display correctly."""
+ self.build()
+ self.runCmd("file " + self.getBuildArtifact(artifact_name), 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.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/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
index bf8e6b8703f36..a54f061fdf541 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
@@ -2,4 +2,12 @@ CXX_SOURCES := main.cpp
USE_LIBSTDCPP := 1
+all: debug_a.out
+
include Makefile.rules
+
+debug_main.o: main.cpp
+ $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
+
+debug_a.out: debug_main.o
+ $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
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
index 0cdc213841be6..9b8a9fa9e3054 100644
--- 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
@@ -1,293 +1,14 @@
"""
-Test lldb data formatter subsystem.
+Test lldb data formatter subsystem for std::map
"""
+from typing import override
+from DataFormatterStdMap import StdMapDataFormatterBase
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
-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.")
-
+class StdMapDataFormatter(StdMapDataFormatterBase):
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ @override
def test_with_run_command(self):
- """Test that that file and class static variables display correctly."""
- self.build()
- 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)
- self.runCmd("settings set target.max-children-count 256", check=False)
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
-
- self.runCmd("frame variable ii --show-types")
-
- self.runCmd(
- 'type summary add -x "std::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", "{}"])
+ self.with_run_command("a.out")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
new file mode 100644
index 0000000000000..1567e1e995b1f
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
@@ -0,0 +1,14 @@
+"""
+Test lldb data formatter subsystem for std::map with '_GLIBCXX_DEBUG' flag
+"""
+from typing import override
+from DataFormatterStdMap import StdMapDataFormatterBase
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+
+
+class StdMapDataFormatterWithDebug(StdMapDataFormatterBase):
+ @add_test_categories(["libstdcxx"])
+ @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ @override
+ def test_with_run_command(self):
+ self.with_run_command("debug_a.out", "__debug::")
>From ce0695a52d87c4bf145921a6dc09c2bd4a613a9d Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 20 May 2025 14:23:50 +0100
Subject: [PATCH 06/10] [lldb] format test.
---
.../data-formatter-categories/TestDataFormatterCategories.py | 2 +-
.../data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py | 4 +++-
.../libstdcpp/map/TestDataFormatterStdMap.py | 1 +
.../libstdcpp/map/TestDataFormatterStdMapWithDebug.py | 1 +
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py b/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
index 344fbb8994ba5..f659f1edd1fc9 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
@@ -337,5 +337,5 @@ def cleanup():
self.expect(
"type summary list -l c++",
substrs=["vector", "map", "list", "string"],
- ordered=False
+ ordered=False,
)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
index f6dac643b95a0..59eb23f64668e 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
@@ -28,7 +28,9 @@ def test_with_run_command(self):
def with_run_command(self, artifact_name: str, namespace: str = ""):
"""Test that that file and class static variables display correctly."""
self.build()
- self.runCmd("file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET)
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
+ )
lldbutil.run_break_set_by_source_regexp(self, "Set break point at this line.")
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
index 9b8a9fa9e3054..0e600b6c98c14 100644
--- 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
@@ -1,6 +1,7 @@
"""
Test lldb data formatter subsystem for std::map
"""
+
from typing import override
from DataFormatterStdMap import StdMapDataFormatterBase
from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
index 1567e1e995b1f..c5f12a10642db 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
@@ -1,6 +1,7 @@
"""
Test lldb data formatter subsystem for std::map with '_GLIBCXX_DEBUG' flag
"""
+
from typing import override
from DataFormatterStdMap import StdMapDataFormatterBase
from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
>From 59f9cef584f776330bf327ffbd0d827d0f3b38d6 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 20 May 2025 17:06:23 +0100
Subject: [PATCH 07/10] [lldb] review changes.
---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 91 ++++++++++---------
.../libstdcpp/map/DataFormatterStdMap.py | 6 +-
.../libstdcpp/map/TestDataFormatterStdMap.py | 3 +-
.../map/TestDataFormatterStdMapWithDebug.py | 3 +-
.../libstdcpp/vbool/DataFormatterStdVBool.py | 19 ++--
.../libstdcpp/vbool/Makefile | 10 +-
.../vbool/TestDataFormatterStdVBool.py | 3 +-
.../TestDataFormatterStdVBoolWithDebug.py | 3 +-
.../vector/DataFormatterStdVector.py | 5 +-
.../libstdcpp/vector/Makefile | 8 --
.../vector/TestDataFormatterStdVector.py | 3 +-
.../vector/TestDataFormatterStdVectorDebug.py | 5 +-
12 files changed, 80 insertions(+), 79 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index f6fc7e7114953..e98eef49f501a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -592,7 +592,7 @@ class NodeAllocator {
public:
void reset() { Alloc.Reset(); }
- template <typename T, typename... Args> T *makeNode(Args &&... args) {
+ template <typename T, typename... Args> T *makeNode(Args &&...args) {
return new (Alloc.Allocate(sizeof(T), alignof(T)))
T(std::forward<Args>(args)...);
}
@@ -614,7 +614,7 @@ class ManglingSubstitutor
ManglingSubstitutor() : Base(nullptr, nullptr) {}
template <typename... Ts>
- ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
+ ConstString substitute(llvm::StringRef Mangled, Ts &&...Vals) {
this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
return substituteImpl(Mangled);
}
@@ -1450,109 +1450,109 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?vector<.+>(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?map<.+> >(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug)?deque<.+>(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?set<.+> >(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::(__debug::)?unordered_(multi)?(map|set)<.+> >$",
eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::((__debug::)?|(__cxx11::)?)list<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::((__debug::)?|(__cxx11::)?)forward_list<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
cpp_category_sp->AddTypeSynthetic(
"^std::variant<.+>$", eFormatterMatchRegex,
- std::make_shared<ScriptedSyntheticChildren>(
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
cpp_category_sp->AddTypeSummary("^std::(__debug::)?bitset<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?vector<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?map<.+> >(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?set<.+> >(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?deque<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?multimap<.+> >(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary("^std::(__debug::)?multiset<.+> >(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(
- stl_summary_flags, "size=${svar%#}"));
+ TypeSummaryImplSP(new StringSummaryFormat(
+ stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary(
"^std::(__debug::)?unordered_(multi)?(map|set)<.+> >$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(stl_summary_flags,
- "size=${svar%#}"));
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary(
"^std::((__debug::)?|(__cxx11::)?)list<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<StringSummaryFormat>(stl_summary_flags,
- "size=${svar%#}"));
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->AddTypeSummary(
"^std::((__debug::)?|(__cxx11::)?)forward_list<.+>(( )?&)?$",
eFormatterMatchRegex,
- std::make_shared<ScriptSummaryFormat>(
+ TypeSummaryImplSP(new ScriptSummaryFormat(
stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
cpp_category_sp->AddTypeSummary(
"^std::variant<.+>$", eFormatterMatchRegex,
- std::make_shared<ScriptSummaryFormat>(
+ TypeSummaryImplSP(new ScriptSummaryFormat(
stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider"));
+ "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider")));
AddCXXSynthetic(
cpp_category_sp,
@@ -1737,6 +1737,9 @@ lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
g_category);
if (g_category) {
+ // NOTE: the libstdcpp formatters are loaded after libcxx formatters
+ // because of a conflict matching the `__debug`namespace in libstdcpp.
+ // since lldb priorities the last loaded matching formatter.
LoadLibCxxFormatters(g_category);
LoadLibStdcppFormatters(g_category);
LoadSystemFormatters(g_category);
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
index 59eb23f64668e..81ecb36f0bf81 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
@@ -3,7 +3,6 @@
"""
from abc import abstractmethod
-from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
from lldbsuite.test.lldbtest import (
CURRENT_EXECUTABLE_SET,
RUN_SUCCEEDED,
@@ -25,9 +24,10 @@ def setUp(self):
def test_with_run_command(self):
pass
- def with_run_command(self, artifact_name: str, namespace: str = ""):
+ def with_run_command(self, namespace: str, dictionary: dict):
"""Test that that file and class static variables display correctly."""
- self.build()
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
self.runCmd(
"file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
)
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
index 0e600b6c98c14..f6fe435b53482 100644
--- 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
@@ -12,4 +12,5 @@ class StdMapDataFormatter(StdMapDataFormatterBase):
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
@override
def test_with_run_command(self):
- self.with_run_command("a.out")
+ build_args = {"EXE": "a.out"}
+ self.with_run_command("", build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
index c5f12a10642db..9b9b740a64dc2 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
@@ -12,4 +12,5 @@ class StdMapDataFormatterWithDebug(StdMapDataFormatterBase):
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
@override
def test_with_run_command(self):
- self.with_run_command("debug_a.out", "__debug::")
+ build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ self.with_run_command("__debug::", build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
index 2f26659223130..4ad469cd2a391 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
@@ -3,9 +3,13 @@
"""
from abc import abstractmethod
-from lldbsuite.test.decorators import add_test_categories
-from lldbsuite.test.lldbtest import CURRENT_EXECUTABLE_SET, RUN_SUCCEEDED, STOPPED_DUE_TO_BREAKPOINT, TestBase, \
- line_number
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
from lldbsuite.test import lldbutil
@@ -20,10 +24,13 @@ def setUp(self):
def test_with_run_command(self):
pass
- def with_run_command(self, artifact_name: str):
+ def with_run_command(self, dictionary: dict):
"""Test that that file and class static variables display correctly."""
- self.build()
- self.runCmd("file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET)
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
+ )
lldbutil.run_break_set_by_file_and_line(
self, "main.cpp", self.line, num_expected_locations=-1
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
index 6bb9503378934..c825977b1a5dc 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
@@ -1,14 +1,6 @@
CXX_SOURCES := main.cpp
-CXXFLAGS := -O0
+CFLAGS_EXTRAS := -O0
USE_LIBSTDCPP := 1
-all: debug_a.out
-
include Makefile.rules
-
-debug_main.o: main.cpp
- $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
-
-debug_a.out: debug_main.o
- $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
index 44bed4b8b15ab..a2483a444bedb 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -11,4 +11,5 @@ class StdVBoolDataFormatter(StdVBoolDataFormatterBase):
@add_test_categories(["libstdcxx"])
@override
def test_with_run_command(self):
- self.with_run_command("a.out")
+ build_args = {"EXE": "a.out"}
+ self.with_run_command(build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
index 0210d9cf75c7e..3977b68b304c1 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
@@ -11,4 +11,5 @@ class StdVBoolDataFormatterWithDebug(StdVBoolDataFormatterBase):
@add_test_categories(["libstdcxx"])
@override
def test_with_run_command(self):
- self.with_run_command("debug_a.out")
+ build_args = {"EXE": "debug_a.out", "_GLIBCXX_DEBUG": 1}
+ self.with_run_command(build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
index 07fb2a222f321..e236ed01e408c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
@@ -24,9 +24,10 @@ def setUp(self):
def test_with_run_command(self):
pass
- def with_run_command(self, artifact_name: str):
+ def with_run_command(self, dictionary: dict):
"""Test that that file and class static variables display correctly."""
- self.build()
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
self.runCmd(
"file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
index 6bb9503378934..654e4b15bd568 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
@@ -3,12 +3,4 @@ CXX_SOURCES := main.cpp
CXXFLAGS := -O0
USE_LIBSTDCPP := 1
-all: debug_a.out
-
include Makefile.rules
-
-debug_main.o: main.cpp
- $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
-
-debug_a.out: debug_main.o
- $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
index b824a5024197a..62d0cbc72d224 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -13,4 +13,5 @@ class NoDebugTestCase(StdVectorDataFormatterBase):
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
@override
def test_with_run_command(self):
- self.with_run_command("a.out")
+ build_args = {"EXE": "a.out"}
+ self.with_run_command(build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
index 0007d4bff42cc..373ea7ef83dcc 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
@@ -1,5 +1,5 @@
"""
-Test lldb data formatter subsystem for std::vector with -D_GLIBCXX_DEBUG flag
+Test lldb data formatter subsystem for std::vector with `_GLIBCXX_DEBUG` flag
"""
from typing import override
@@ -13,4 +13,5 @@ class WithDebugTestCase(StdVectorDataFormatterBase):
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
@override
def test_with_run_command(self):
- self.with_run_command("debug_a.out")
+ build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ self.with_run_command(build_args)
>From ff2eb0288a8ba24d920d8129ef237c72a99ee9a8 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 20 May 2025 17:37:31 +0100
Subject: [PATCH 08/10] [lldb] Move tests to one file.
---
.../libstdcpp/map/DataFormatterStdMap.py | 302 -----------------
.../libstdcpp/map/TestDataFormatterStdMap.py | 303 +++++++++++++++++-
.../map/TestDataFormatterStdMapWithDebug.py | 16 -
.../libstdcpp/vbool/DataFormatterStdVBool.py | 86 -----
.../vbool/TestDataFormatterStdVBool.py | 87 ++++-
.../TestDataFormatterStdVBoolWithDebug.py | 15 -
.../vector/DataFormatterStdVector.py | 220 -------------
.../vector/TestDataFormatterStdVector.py | 223 ++++++++++++-
.../vector/TestDataFormatterStdVectorDebug.py | 17 -
9 files changed, 599 insertions(+), 670 deletions(-)
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
deleted file mode 100644
index 81ecb36f0bf81..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py
+++ /dev/null
@@ -1,302 +0,0 @@
-"""
-Test lldb data formatter subsystem.
-"""
-
-from abc import abstractmethod
-from lldbsuite.test.lldbtest import (
- CURRENT_EXECUTABLE_SET,
- RUN_SUCCEEDED,
- STOPPED_DUE_TO_BREAKPOINT,
- TestBase,
- line_number,
-)
-from lldbsuite.test import lldbutil
-
-
-class StdMapDataFormatterBase(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.")
-
- @abstractmethod
- def test_with_run_command(self):
- pass
-
- def with_run_command(self, namespace: str, dictionary: dict):
- """Test that that file and class static variables display correctly."""
- self.build(dictionary=dictionary)
- artifact_name = dictionary.get("EXE", "a.out")
- self.runCmd(
- "file " + self.getBuildArtifact(artifact_name), 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.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/TestDataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
index f6fe435b53482..72463b38c7995 100644
--- 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
@@ -1,16 +1,313 @@
"""
-Test lldb data formatter subsystem for std::map
+Test lldb data formatter subsystem.
"""
from typing import override
-from DataFormatterStdMap import StdMapDataFormatterBase
from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
+from lldbsuite.test import lldbutil
-class StdMapDataFormatter(StdMapDataFormatterBase):
+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")
@override
def test_with_run_command(self):
build_args = {"EXE": "a.out"}
self.with_run_command("", build_args)
+
+ @add_test_categories(["libstdcxx"])
+ @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ @override
+ def test_with_run_command_debug(self):
+ build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ self.with_run_command("__debug::", build_args)
+
+ def with_run_command(self, namespace: str, dictionary: dict):
+ """Test that that file and class static variables display correctly."""
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), 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.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/TestDataFormatterStdMapWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
deleted file mode 100644
index 9b9b740a64dc2..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Test lldb data formatter subsystem for std::map with '_GLIBCXX_DEBUG' flag
-"""
-
-from typing import override
-from DataFormatterStdMap import StdMapDataFormatterBase
-from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
-
-
-class StdMapDataFormatterWithDebug(StdMapDataFormatterBase):
- @add_test_categories(["libstdcxx"])
- @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
- @override
- def test_with_run_command(self):
- build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
- self.with_run_command("__debug::", build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
deleted file mode 100644
index 4ad469cd2a391..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-Test lldb data formatter subsystem.
-"""
-
-from abc import abstractmethod
-from lldbsuite.test.lldbtest import (
- CURRENT_EXECUTABLE_SET,
- RUN_SUCCEEDED,
- STOPPED_DUE_TO_BREAKPOINT,
- TestBase,
- line_number,
-)
-from lldbsuite.test import lldbutil
-
-
-class StdVBoolDataFormatterBase(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.")
-
- @abstractmethod
- def test_with_run_command(self):
- pass
-
- def with_run_command(self, dictionary: dict):
- """Test that that file and class static variables display correctly."""
- self.build(dictionary=dictionary)
- artifact_name = dictionary.get("EXE", "a.out")
- self.runCmd(
- "file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
- )
-
- lldbutil.run_break_set_by_file_and_line(
- self, "main.cpp", self.line, num_expected_locations=-1
- )
-
- 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(
- "frame variable vBool",
- substrs=[
- "size=49",
- "[0] = false",
- "[1] = true",
- "[18] = false",
- "[27] = true",
- "[36] = false",
- "[47] = true",
- "[48] = true",
- ],
- )
-
- self.expect(
- "expr vBool",
- substrs=[
- "size=49",
- "[0] = false",
- "[1] = true",
- "[18] = false",
- "[27] = true",
- "[36] = false",
- "[47] = true",
- "[48] = true",
- ],
- )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
index a2483a444bedb..2716440822f64 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -1,15 +1,92 @@
"""
-Test lldb data formatter subsystem for std::vector<bool>
+Test lldb data formatter subsystem.
"""
-from typing import override
from lldbsuite.test.decorators import add_test_categories
-from DataFormatterStdVBool import StdVBoolDataFormatterBase
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
+from lldbsuite.test import lldbutil
-class StdVBoolDataFormatter(StdVBoolDataFormatterBase):
+class StdVBoolDataFormatterTestCase(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"])
- @override
def test_with_run_command(self):
build_args = {"EXE": "a.out"}
self.with_run_command(build_args)
+
+ @add_test_categories(["libstdcxx"])
+ def test_with_run_command_debug(self):
+ build_args = {"EXE": "debug_a.out", "_GLIBCXX_DEBUG": 1}
+ self.with_run_command(build_args)
+
+ def with_run_command(self, dictionary: dict):
+ """Test that that file and class static variables display correctly."""
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), CURRENT_EXECUTABLE_SET
+ )
+
+ lldbutil.run_break_set_by_file_and_line(
+ self, "main.cpp", self.line, num_expected_locations=-1
+ )
+
+ 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(
+ "frame variable vBool",
+ substrs=[
+ "size=49",
+ "[0] = false",
+ "[1] = true",
+ "[18] = false",
+ "[27] = true",
+ "[36] = false",
+ "[47] = true",
+ "[48] = true",
+ ],
+ )
+
+ self.expect(
+ "expr vBool",
+ substrs=[
+ "size=49",
+ "[0] = false",
+ "[1] = true",
+ "[18] = false",
+ "[27] = true",
+ "[36] = false",
+ "[47] = true",
+ "[48] = true",
+ ],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
deleted file mode 100644
index 3977b68b304c1..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
-Test lldb data formatter subsystem for std::vector<bool> with flag "_GLIBCXX_DEBUG"
-"""
-
-from typing import override
-from lldbsuite.test.decorators import add_test_categories
-from DataFormatterStdVBool import StdVBoolDataFormatterBase
-
-
-class StdVBoolDataFormatterWithDebug(StdVBoolDataFormatterBase):
- @add_test_categories(["libstdcxx"])
- @override
- def test_with_run_command(self):
- build_args = {"EXE": "debug_a.out", "_GLIBCXX_DEBUG": 1}
- self.with_run_command(build_args)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
deleted file mode 100644
index e236ed01e408c..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
-Test lldb data formatter subsystem.
-"""
-
-from abc import abstractmethod
-from lldbsuite.test.lldbtest import (
- CURRENT_EXECUTABLE_SET,
- RUN_SUCCEEDED,
- STOPPED_DUE_TO_BREAKPOINT,
- TestBase,
- line_number,
-)
-from lldbsuite.test import lldbutil
-
-
-class StdVectorDataFormatterBase(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.")
-
- @abstractmethod
- def test_with_run_command(self):
- pass
-
- def with_run_command(self, dictionary: dict):
- """Test that that file and class static variables display correctly."""
- self.build(dictionary=dictionary)
- artifact_name = dictionary.get("EXE", "a.out")
- self.runCmd(
- "file " + self.getBuildArtifact(artifact_name), 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)
-
- # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
- self.expect("frame variable numbers", substrs=["numbers = size=0"])
-
- self.runCmd("c")
-
- # first value added
- self.expect(
- "frame variable numbers", substrs=["numbers = size=1", "[0] = 1", "}"]
- )
-
- # add some more data
- self.runCmd("c")
-
- self.expect(
- "frame variable numbers",
- substrs=[
- "numbers = size=4",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "}",
- ],
- )
-
- self.expect(
- "expression numbers",
- substrs=[
- "$",
- "size=4",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "}",
- ],
- )
-
- # check access to synthetic children
- self.runCmd(
- 'type summary add --summary-string "item 0 is ${var[0]}" std::int_vect int_vect'
- )
- self.expect("frame variable numbers", substrs=["item 0 is 1"])
-
- self.runCmd(
- 'type summary add --summary-string "item 0 is ${svar[0]}" std::int_vect int_vect'
- )
- # import time
- # time.sleep(19)
- self.expect("frame variable numbers", substrs=["item 0 is 1"])
- # move on with synths
- self.runCmd("type summary delete std::int_vect")
- self.runCmd("type summary delete int_vect")
-
- # add some more data
- self.runCmd("c")
-
- self.expect(
- "frame variable numbers",
- substrs=[
- "numbers = size=7",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "[4] = 12345",
- "[5] = 123456",
- "[6] = 1234567",
- "}",
- ],
- )
-
- self.expect(
- "expression numbers",
- substrs=[
- "$",
- "size=7",
- "[0] = 1",
- "[1] = 12",
- "[2] = 123",
- "[3] = 1234",
- "[4] = 12345",
- "[5] = 123456",
- "[6] = 1234567",
- "}",
- ],
- )
-
- # check access-by-index
- self.expect("frame variable numbers[0]", substrs=["1"])
- self.expect("frame variable numbers[1]", substrs=["12"])
- self.expect("frame variable numbers[2]", substrs=["123"])
- self.expect("frame variable numbers[3]", substrs=["1234"])
-
- # but check that expression does not rely on us
- # (when expression gets to call into STL code correctly, we will have to find
- # another way to check this)
- self.expect(
- "expression numbers[6]", matching=False, error=True, substrs=["1234567"]
- )
-
- # check that MightHaveChildren() gets it right
- self.assertTrue(
- self.frame().FindVariable("numbers").MightHaveChildren(),
- "numbers.MightHaveChildren() says False for non empty!",
- )
-
- # clear out the vector and see that we do the right thing once again
- self.runCmd("c")
-
- self.expect("frame variable numbers", substrs=["numbers = size=0"])
-
- self.runCmd("c")
-
- # first value added
- self.expect(
- "frame variable numbers", substrs=["numbers = size=1", "[0] = 7", "}"]
- )
-
- # check if we can display strings
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["goofy", "is", "smart"])
-
- self.expect("expression strings", substrs=["goofy", "is", "smart"])
-
- # test summaries based on synthetic children
- self.runCmd(
- 'type summary add std::string_vect string_vect --summary-string "vector has ${svar%#} items" -e'
- )
- self.expect(
- "frame variable strings",
- substrs=["vector has 3 items", "goofy", "is", "smart"],
- )
-
- self.expect(
- "expression strings", substrs=["vector has 3 items", "goofy", "is", "smart"]
- )
-
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["vector has 4 items"])
-
- # check access-by-index
- self.expect("frame variable strings[0]", substrs=["goofy"])
- self.expect("frame variable strings[1]", substrs=["is"])
-
- # but check that expression does not rely on us
- # (when expression gets to call into STL code correctly, we will have to find
- # another way to check this)
- self.expect(
- "expression strings[0]", matching=False, error=True, substrs=["goofy"]
- )
-
- # check that MightHaveChildren() gets it right
- self.assertTrue(
- self.frame().FindVariable("strings").MightHaveChildren(),
- "strings.MightHaveChildren() says False for non empty!",
- )
-
- self.runCmd("c")
-
- self.expect("frame variable strings", substrs=["vector has 0 items"])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
index 62d0cbc72d224..014be9467dd9c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -1,17 +1,228 @@
"""
-Test lldb data formatter subsystem for std::vector.
+Test lldb data formatter subsystem.
"""
-from typing import override
-
from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
-from DataFormatterStdVector import StdVectorDataFormatterBase
+from lldbsuite.test.lldbtest import (
+ CURRENT_EXECUTABLE_SET,
+ RUN_SUCCEEDED,
+ STOPPED_DUE_TO_BREAKPOINT,
+ TestBase,
+ line_number,
+)
+from lldbsuite.test import lldbutil
+
+class StdVectorDataFormatterTestCase(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.")
-class NoDebugTestCase(StdVectorDataFormatterBase):
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
- @override
def test_with_run_command(self):
build_args = {"EXE": "a.out"}
self.with_run_command(build_args)
+
+ @add_test_categories(["libstdcxx"])
+ @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
+ def test_with_run_command_debug(self):
+ build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ self.with_run_command(build_args)
+
+ def with_run_command(self, dictionary: dict):
+ """Test that that file and class static variables display correctly."""
+ self.build(dictionary=dictionary)
+ artifact_name = dictionary.get("EXE", "a.out")
+ self.runCmd(
+ "file " + self.getBuildArtifact(artifact_name), 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)
+
+ # empty vectors (and storage pointers SHOULD BOTH BE NULL..)
+ self.expect("frame variable numbers", substrs=["numbers = size=0"])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect(
+ "frame variable numbers", substrs=["numbers = size=1", "[0] = 1", "}"]
+ )
+
+ # add some more data
+ self.runCmd("c")
+
+ self.expect(
+ "frame variable numbers",
+ substrs=[
+ "numbers = size=4",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "}",
+ ],
+ )
+
+ self.expect(
+ "expression numbers",
+ substrs=[
+ "$",
+ "size=4",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "}",
+ ],
+ )
+
+ # check access to synthetic children
+ self.runCmd(
+ 'type summary add --summary-string "item 0 is ${var[0]}" std::int_vect int_vect'
+ )
+ self.expect("frame variable numbers", substrs=["item 0 is 1"])
+
+ self.runCmd(
+ 'type summary add --summary-string "item 0 is ${svar[0]}" std::int_vect int_vect'
+ )
+ # import time
+ # time.sleep(19)
+ self.expect("frame variable numbers", substrs=["item 0 is 1"])
+ # move on with synths
+ self.runCmd("type summary delete std::int_vect")
+ self.runCmd("type summary delete int_vect")
+
+ # add some more data
+ self.runCmd("c")
+
+ self.expect(
+ "frame variable numbers",
+ substrs=[
+ "numbers = size=7",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "[4] = 12345",
+ "[5] = 123456",
+ "[6] = 1234567",
+ "}",
+ ],
+ )
+
+ self.expect(
+ "expression numbers",
+ substrs=[
+ "$",
+ "size=7",
+ "[0] = 1",
+ "[1] = 12",
+ "[2] = 123",
+ "[3] = 1234",
+ "[4] = 12345",
+ "[5] = 123456",
+ "[6] = 1234567",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable numbers[0]", substrs=["1"])
+ self.expect("frame variable numbers[1]", substrs=["12"])
+ self.expect("frame variable numbers[2]", substrs=["123"])
+ self.expect("frame variable numbers[3]", substrs=["1234"])
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect(
+ "expression numbers[6]", matching=False, error=True, substrs=["1234567"]
+ )
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(
+ self.frame().FindVariable("numbers").MightHaveChildren(),
+ "numbers.MightHaveChildren() says False for non empty!",
+ )
+
+ # clear out the vector and see that we do the right thing once again
+ self.runCmd("c")
+
+ self.expect("frame variable numbers", substrs=["numbers = size=0"])
+
+ self.runCmd("c")
+
+ # first value added
+ self.expect(
+ "frame variable numbers", substrs=["numbers = size=1", "[0] = 7", "}"]
+ )
+
+ # check if we can display strings
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["goofy", "is", "smart"])
+
+ self.expect("expression strings", substrs=["goofy", "is", "smart"])
+
+ # test summaries based on synthetic children
+ self.runCmd(
+ 'type summary add std::string_vect string_vect --summary-string "vector has ${svar%#} items" -e'
+ )
+ self.expect(
+ "frame variable strings",
+ substrs=["vector has 3 items", "goofy", "is", "smart"],
+ )
+
+ self.expect(
+ "expression strings", substrs=["vector has 3 items", "goofy", "is", "smart"]
+ )
+
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["vector has 4 items"])
+
+ # check access-by-index
+ self.expect("frame variable strings[0]", substrs=["goofy"])
+ self.expect("frame variable strings[1]", substrs=["is"])
+
+ # but check that expression does not rely on us
+ # (when expression gets to call into STL code correctly, we will have to find
+ # another way to check this)
+ self.expect(
+ "expression strings[0]", matching=False, error=True, substrs=["goofy"]
+ )
+
+ # check that MightHaveChildren() gets it right
+ self.assertTrue(
+ self.frame().FindVariable("strings").MightHaveChildren(),
+ "strings.MightHaveChildren() says False for non empty!",
+ )
+
+ self.runCmd("c")
+
+ self.expect("frame variable strings", substrs=["vector has 0 items"])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
deleted file mode 100644
index 373ea7ef83dcc..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
-Test lldb data formatter subsystem for std::vector with `_GLIBCXX_DEBUG` flag
-"""
-
-from typing import override
-
-from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
-from DataFormatterStdVector import StdVectorDataFormatterBase
-
-
-class WithDebugTestCase(StdVectorDataFormatterBase):
- @add_test_categories(["libstdcxx"])
- @expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
- @override
- def test_with_run_command(self):
- build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
- self.with_run_command(build_args)
>From 9b4400fcff0852319ebecb7586d587e6a1108446 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 20 May 2025 17:41:13 +0100
Subject: [PATCH 09/10] [lldb] Update makefile
---
.../data-formatter-stl/libstdcpp/map/Makefile | 8 --------
1 file changed, 8 deletions(-)
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/libstdcpp/map/Makefile
index a54f061fdf541..bf8e6b8703f36 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
@@ -2,12 +2,4 @@ CXX_SOURCES := main.cpp
USE_LIBSTDCPP := 1
-all: debug_a.out
-
include Makefile.rules
-
-debug_main.o: main.cpp
- $(CXX) $(PCHFLAGS) $(CXXFLAGS) -D_GLIBCXX_DEBUG -MT $@ -MD -MP -MF $*.d -c -o $@ $<
-
-debug_a.out: debug_main.o
- $(LD) debug_main.o $(LDFLAGS) -o debug_a.out
\ No newline at end of file
>From 3fdd8e3e3638d5b895a772aa4a2f7defee872dab Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 20 May 2025 22:57:15 +0100
Subject: [PATCH 10/10] [lldb] review changes.
---
.../libstdcpp/map/TestDataFormatterStdMap.py | 12 ++++++------
.../libstdcpp/vbool/TestDataFormatterStdVBool.py | 2 +-
.../libstdcpp/vector/TestDataFormatterStdVector.py | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
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
index 72463b38c7995..2edb6a1e2540f 100644
--- 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
@@ -2,8 +2,7 @@
Test lldb data formatter subsystem.
"""
-from typing import override
-from lldbsuite.test.decorators import add_test_categories, expectedFailureAll
+from lldbsuite.test.decorators import add_test_categories, expectedFailureAll, skip
from lldbsuite.test.lldbtest import (
CURRENT_EXECUTABLE_SET,
RUN_SUCCEEDED,
@@ -23,16 +22,14 @@ def setUp(self):
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
- @override
def test_with_run_command(self):
build_args = {"EXE": "a.out"}
self.with_run_command("", build_args)
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
- @override
def test_with_run_command_debug(self):
- build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ build_args = {"CXXFLAGS": "-D_GLIBCXX_DEBUG", "EXE": "debug_a.out"}
self.with_run_command("__debug::", build_args)
def with_run_command(self, namespace: str, dictionary: dict):
@@ -68,10 +65,13 @@ def cleanup():
self.runCmd("frame variable ii --show-types")
+ match = f"std::{namespace}map<"
self.runCmd(
- f'type summary add -x "std::{namespace}map<" --summary-string "map has ${{svar%#}} items" -e'
+ f'type summary add -x "{match}" --summary-string "map has ${{svar%#}} items" -e'
)
+ # self.assertFalse(True, match)
+ # self.expect("frame variable -D 0 --raw ii", substrs=["boom"])
self.expect("frame variable ii", substrs=["map has 0 items", "{}"])
self.runCmd("c")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
index 2716440822f64..55c1d8e0589ef 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
@@ -27,7 +27,7 @@ def test_with_run_command(self):
@add_test_categories(["libstdcxx"])
def test_with_run_command_debug(self):
- build_args = {"EXE": "debug_a.out", "_GLIBCXX_DEBUG": 1}
+ build_args = {"CXXFLAGS": "-D_GLIBCXX_DEBUG", "EXE": "debug_a.out"}
self.with_run_command(build_args)
def with_run_command(self, dictionary: dict):
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
index 014be9467dd9c..8f3cb6a065ae4 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
@@ -29,7 +29,7 @@ def test_with_run_command(self):
@add_test_categories(["libstdcxx"])
@expectedFailureAll(bugnumber="llvm.org/pr50861", compiler="gcc")
def test_with_run_command_debug(self):
- build_args = {"_GLIBCXX_DEBUG": 1, "EXE": "debug_a.out"}
+ build_args = {"CXXFLAGS": "-D_GLIBCXX_DEBUG", "EXE": "debug_a.out"}
self.with_run_command(build_args)
def with_run_command(self, dictionary: dict):
More information about the lldb-commits
mailing list