[Lldb-commits] [lldb] [lldb] optionally match the `__debug` namespace for libstdc++ containers. (PR #140727)
via lldb-commits
lldb-commits at lists.llvm.org
Tue May 20 06:12:06 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Ebuka Ezike (da-viper)
<details>
<summary>Changes</summary>
Fixes #<!-- -->60841
---
Patch is 59.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140727.diff
14 Files Affected:
- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+71-65)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py (+3-1)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/DataFormatterStdMap.py (+300)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile (+8)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py (+7-286)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMapWithDebug.py (+14)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/DataFormatterStdVBool.py (+79)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile (+9-1)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py (+7-69)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBoolWithDebug.py (+14)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/DataFormatterStdVector.py (+219)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile (+8)
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py (+7-202)
- (added) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVectorDebug.py (+16)
``````````diff
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);
}
});
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
)
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]"...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/140727
More information about the lldb-commits
mailing list