[Lldb-commits] [lldb] [lldb][test] Move std::string_view from libcxx to generic directory (PR #147563)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 9 02:52:42 PDT 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/147563
>From 07ee63fa3f707507d332e52626ac109f2e1829f1 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 8 Jul 2025 18:30:16 +0100
Subject: [PATCH 1/2] [lldb][test] Move std::string_view from libcxx to generic
directory
This just moves the test from `libcxx` to `generic`. There are currently no `std::queue` formatters for libstdc++ so I didn't add a test-case for it.
Split out from https://github.com/llvm/llvm-project/pull/146740
---
.../TestDataFormatterLibcxxStringView.py | 0
.../generic/string_view/Makefile | 4 +
.../TestDataFormatterStdStringView.py | 165 ++++++++++++++++++
.../{libcxx => generic}/string_view/main.cpp | 0
.../libcxx/string_view/Makefile | 6 -
5 files changed, 169 insertions(+), 6 deletions(-)
rename lldb/test/API/functionalities/data-formatter/data-formatter-stl/{libcxx/string_view => generic/string}/TestDataFormatterLibcxxStringView.py (100%)
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/Makefile
create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py
rename lldb/test/API/functionalities/data-formatter/data-formatter-stl/{libcxx => generic}/string_view/main.cpp (100%)
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/Makefile
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py
similarity index 100%
rename from lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py
rename to lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/Makefile
new file mode 100644
index 0000000000000..d5f5fec8441b5
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -std=c++17
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py
new file mode 100644
index 0000000000000..fb934130f663f
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py
@@ -0,0 +1,165 @@
+# coding=utf8
+"""
+Test lldb data formatter subsystem.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class StdStringViewDataFormatterTestCase(TestBase):
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line1 = line_number("main.cpp", "// Set break point at this line.")
+ self.line2 = line_number(
+ "main.cpp", "// Break here to look at bad string view."
+ )
+
+ def do_test(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line(
+ self, "main.cpp", self.line1, num_expected_locations=-1
+ )
+ lldbutil.run_break_set_by_file_and_line(
+ self, "main.cpp", self.line2, 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)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
+ self.expect_var_path(
+ "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
+ )
+ self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
+ self.expect_var_path("empty", type="std::string_view", summary='""')
+ self.expect_var_path("q_source", type="std::string", summary='"hello world"')
+ self.expect_var_path("q", type="std::string_view", summary='"hello world"')
+ self.expect_var_path(
+ "Q",
+ type="std::string_view",
+ summary='"quite a long std::strin with lots of info inside it"',
+ )
+ self.expect_var_path(
+ "IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
+ )
+ self.expect_var_path(
+ "IHaveEmbeddedZerosToo",
+ type="std::wstring_view",
+ summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
+ )
+ self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
+ self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
+ self.expect_var_path(
+ "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
+ )
+ self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
+ self.expect_var_path(
+ "oops", type="std::string_view", summary='"Hellooo World\\n"'
+ )
+
+ # GetSummary returns None so can't be checked by expect_var_path, so we
+ # use the str representation instead
+ null_obj = self.frame().GetValueForVariablePath("null_str")
+ self.assertEqual(null_obj.GetSummary(), "Summary Unavailable")
+ self.assertEqual(str(null_obj), "(std::string_view *) null_str = nullptr")
+
+ self.runCmd("n")
+
+ TheVeryLongOne = self.frame().FindVariable("TheVeryLongOne")
+ summaryOptions = lldb.SBTypeSummaryOptions()
+ summaryOptions.SetCapping(lldb.eTypeSummaryUncapped)
+ uncappedSummaryStream = lldb.SBStream()
+ TheVeryLongOne.GetSummary(uncappedSummaryStream, summaryOptions)
+ uncappedSummary = uncappedSummaryStream.GetData()
+ self.assertGreater(
+ uncappedSummary.find("someText"),
+ 0,
+ "uncappedSummary does not include the full string",
+ )
+ summaryOptions.SetCapping(lldb.eTypeSummaryCapped)
+ cappedSummaryStream = lldb.SBStream()
+ TheVeryLongOne.GetSummary(cappedSummaryStream, summaryOptions)
+ cappedSummary = cappedSummaryStream.GetData()
+ self.assertLessEqual(
+ cappedSummary.find("someText"), 0, "cappedSummary includes the full string"
+ )
+
+ self.expect_expr(
+ "s",
+ result_type="std::wstring_view",
+ result_summary='L"hello world! מזל טוב!"',
+ )
+
+ self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
+ self.expect_var_path(
+ "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
+ )
+ self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
+ self.expect_var_path("empty", type="std::string_view", summary='""')
+ self.expect_var_path("q_source", type="std::string", summary='"Hello world"')
+ self.expect_var_path("q", type="std::string_view", summary='"Hello world"')
+ self.expect_var_path(
+ "Q",
+ type="std::string_view",
+ summary='"quite a long std::strin with lots of info inside it"',
+ )
+ self.expect_var_path(
+ "IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
+ )
+ self.expect_var_path(
+ "IHaveEmbeddedZerosToo",
+ type="std::wstring_view",
+ summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
+ )
+ self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
+ self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
+ self.expect_var_path(
+ "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
+ )
+ self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
+
+ self.runCmd("cont")
+ self.expect(
+ "thread list",
+ STOPPED_DUE_TO_BREAKPOINT,
+ substrs=["stopped", "stop reason = breakpoint"],
+ )
+
+ broken_obj = self.frame().GetValueForVariablePath("in_str_view")
+ self.assertEqual(broken_obj.GetSummary(), "Summary Unavailable")
+
+ @expectedFailureAll(
+ bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
+ )
+ # Inline namespace is randomly ignored as Clang due to broken lookup inside
+ # the std namespace.
+ @expectedFailureAll(debug_info="gmodules")
+ @add_test_categories(["libc++"])
+ def test_libcxx(self):
+ self.build(dictionary={"USE_LIBCPP" : 1})
+ self.do_test()
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp
similarity index 100%
rename from lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/main.cpp
rename to lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/Makefile
deleted file mode 100644
index c7c91da728d1e..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-CXX_SOURCES := main.cpp
-
-USE_LIBCPP := 1
-
-CXXFLAGS_EXTRAS := -std=c++11 -O0
-include Makefile.rules
>From 9d42b2f7128c55afee940458983f502176fb7d39 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 9 Jul 2025 11:43:43 +0100
Subject: [PATCH 2/2] fixup! remove redundant file
---
.../TestDataFormatterLibcxxStringView.py | 162 ------------------
1 file changed, 162 deletions(-)
delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py
deleted file mode 100644
index 3883395f23924..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterLibcxxStringView.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# coding=utf8
-"""
-Test lldb data formatter subsystem.
-"""
-
-
-import lldb
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class LibcxxStringViewDataFormatterTestCase(TestBase):
- def setUp(self):
- # Call super's setUp().
- TestBase.setUp(self)
- # Find the line number to break at.
- self.line1 = line_number("main.cpp", "// Set break point at this line.")
- self.line2 = line_number(
- "main.cpp", "// Break here to look at bad string view."
- )
-
- @add_test_categories(["libc++"])
- @expectedFailureAll(
- bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
- )
- # Inline namespace is randomly ignored as Clang due to broken lookup inside
- # the std namespace.
- @expectedFailureAll(debug_info="gmodules")
- 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.line1, num_expected_locations=-1
- )
- lldbutil.run_break_set_by_file_and_line(
- self, "main.cpp", self.line2, 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)
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
-
- self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
- self.expect_var_path(
- "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
- )
- self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
- self.expect_var_path("empty", type="std::string_view", summary='""')
- self.expect_var_path("q_source", type="std::string", summary='"hello world"')
- self.expect_var_path("q", type="std::string_view", summary='"hello world"')
- self.expect_var_path(
- "Q",
- type="std::string_view",
- summary='"quite a long std::strin with lots of info inside it"',
- )
- self.expect_var_path(
- "IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
- )
- self.expect_var_path(
- "IHaveEmbeddedZerosToo",
- type="std::wstring_view",
- summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
- )
- self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
- self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
- self.expect_var_path(
- "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
- )
- self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
- self.expect_var_path(
- "oops", type="std::string_view", summary='"Hellooo World\\n"'
- )
-
- # GetSummary returns None so can't be checked by expect_var_path, so we
- # use the str representation instead
- null_obj = self.frame().GetValueForVariablePath("null_str")
- self.assertEqual(null_obj.GetSummary(), "Summary Unavailable")
- self.assertEqual(str(null_obj), "(std::string_view *) null_str = nullptr")
-
- self.runCmd("n")
-
- TheVeryLongOne = self.frame().FindVariable("TheVeryLongOne")
- summaryOptions = lldb.SBTypeSummaryOptions()
- summaryOptions.SetCapping(lldb.eTypeSummaryUncapped)
- uncappedSummaryStream = lldb.SBStream()
- TheVeryLongOne.GetSummary(uncappedSummaryStream, summaryOptions)
- uncappedSummary = uncappedSummaryStream.GetData()
- self.assertGreater(
- uncappedSummary.find("someText"),
- 0,
- "uncappedSummary does not include the full string",
- )
- summaryOptions.SetCapping(lldb.eTypeSummaryCapped)
- cappedSummaryStream = lldb.SBStream()
- TheVeryLongOne.GetSummary(cappedSummaryStream, summaryOptions)
- cappedSummary = cappedSummaryStream.GetData()
- self.assertLessEqual(
- cappedSummary.find("someText"), 0, "cappedSummary includes the full string"
- )
-
- self.expect_expr(
- "s",
- result_type="std::wstring_view",
- result_summary='L"hello world! מזל טוב!"',
- )
-
- self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
- self.expect_var_path(
- "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
- )
- self.expect_var_path("S", type="std::wstring_view", summary='L"!!!!"')
- self.expect_var_path("empty", type="std::string_view", summary='""')
- self.expect_var_path("q_source", type="std::string", summary='"Hello world"')
- self.expect_var_path("q", type="std::string_view", summary='"Hello world"')
- self.expect_var_path(
- "Q",
- type="std::string_view",
- summary='"quite a long std::strin with lots of info inside it"',
- )
- self.expect_var_path(
- "IHaveEmbeddedZeros", type="std::string_view", summary='"a\\0b\\0c\\0d"'
- )
- self.expect_var_path(
- "IHaveEmbeddedZerosToo",
- type="std::wstring_view",
- summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
- )
- self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"')
- self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""')
- self.expect_var_path(
- "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
- )
- self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""')
-
- self.runCmd("cont")
- self.expect(
- "thread list",
- STOPPED_DUE_TO_BREAKPOINT,
- substrs=["stopped", "stop reason = breakpoint"],
- )
-
- broken_obj = self.frame().GetValueForVariablePath("in_str_view")
- self.assertEqual(broken_obj.GetSummary(), "Summary Unavailable")
More information about the lldb-commits
mailing list