https://github.com/Nerixyz created
https://github.com/llvm/llvm-project/pull/166833
PDB doesn't include the typedefs for types, so all types use their full name.
For `std::string` and friends, this means they show up as
`std::basic_string<char, std::char_traits<char>, std::allocator<char>>`.
This PR updates the `std::{,w,u8,u16,u32}string(_view)` tests to account for
this and runs them with PDB.
>From 5abd2412f374a3f67655d9388d95f0e3bb4359b0 Mon Sep 17 00:00:00 2001
From: Nerixyz <[email protected]>
Date: Thu, 6 Nov 2025 20:03:04 +0100
Subject: [PATCH] [LLDB] Run MSVC STL string(-view) tests with PDB
---
.../string/TestDataFormatterStdString.py | 81 ++++++++++++-------
.../TestDataFormatterStdStringView.py | 74 ++++++++++-------
.../u8string/TestDataFormatterStdU8String.py | 16 +++-
.../TestDataFormatterStdU8StringView.py | 16 +++-
4 files changed, 122 insertions(+), 65 deletions(-)
diff --git
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
index 6a27b5d2f0780..00047e419de37 100644
---
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
+++
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
@@ -11,6 +11,8 @@
class StdStringDataFormatterTestCase(TestBase):
+ TEST_WITH_PDB_DEBUG_INFO = True
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -18,6 +20,17 @@ def setUp(self):
self.main_spec = lldb.SBFileSpec("main.cpp")
self.namespace = "std"
+ def _makeStringName(self, typedef: str, char_type: str, allocator=None):
+ if allocator is None:
+ allocator = self.namespace + "::allocator"
+
+ if self.getDebugInfo() == "pdb":
+ return f"{self.namespace}::basic_string<{char_type},
std::char_traits<{char_type}>, {allocator}<{char_type}>>"
+
+ if typedef.startswith("::"):
+ return self.namespace + typedef
+ return typedef
+
def do_test(self):
"""Test that that file and class static variables display correctly."""
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
@@ -36,10 +49,17 @@ def cleanup():
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
- ns = self.namespace
+ string_name = self._makeStringName("::string", "char")
+ wstring_name = self._makeStringName("::wstring", "wchar_t")
+ custom_string_name = self._makeStringName(
+ "CustomString", "char", allocator="CustomAlloc"
+ )
+ custom_wstring_name = self._makeStringName(
+ "CustomWString", "wchar_t", allocator="CustomAlloc"
+ )
# Check 'S' pre-assignment.
- self.expect("frame variable S", substrs=['(%s::wstring) S = L"!!!!"' %
ns])
+ self.expect("frame variable S", substrs=[f'({wstring_name}) S =
L"!!!!"'])
thread.StepOver()
@@ -54,34 +74,31 @@ def cleanup():
)
self.expect_expr(
- "s", result_type=ns + "::wstring", result_summary='L"hello world!
מזל טוב!"'
+ "s", result_type=wstring_name, result_summary='L"hello world! מזל
טוב!"'
)
- self.expect_expr(
- "q", result_type=ns + "::string", result_summary='"hello world"'
- )
+ self.expect_expr("q", result_type=string_name, result_summary='"hello
world"')
self.expect_expr(
"Q",
- result_type=ns + "::string",
+ result_type=string_name,
result_summary='"quite a long std::strin with lots of info inside
it"',
)
self.expect(
"frame variable",
substrs=[
- '(%s::wstring) wempty = L""' % ns,
- '(%s::wstring) s = L"hello world! מזל טוב!"' % ns,
- '(%s::wstring) S = L"!!!!!"' % ns,
+ f'({wstring_name}) wempty = L""',
+ f'({wstring_name}) s = L"hello world! מזל טוב!"',
+ f'({wstring_name}) S = L"!!!!!"',
"(const wchar_t *) mazeltov = 0x",
'L"מזל טוב"',
- '(%s::string) empty = ""' % ns,
- '(%s::string) q = "hello world"' % ns,
- '(%s::string) Q = "quite a long std::strin with lots of info
inside it"'
- % ns,
- "(%s::string *) null_str = nullptr" % ns,
- '(CustomString) custom_str = "hello!"',
- '(CustomWString) custom_wstr = L"hello!"',
+ f'({string_name}) empty = ""',
+ f'({string_name}) q = "hello world"',
+ f'({string_name}) Q = "quite a long std::strin with lots of
info inside it"',
+ f"({string_name} *) null_str = nullptr",
+ f'({custom_string_name}) custom_str = "hello!"',
+ f'({custom_wstring_name}) custom_wstr = L"hello!"',
],
)
@@ -136,19 +153,26 @@ def do_test_multibyte(self):
self, "Set break point at this line.", self.main_spec
)
- ns = self.namespace
+ u16string_name = self._makeStringName("::u16string", "char16_t")
+ u32string_name = self._makeStringName("::u32string", "char32_t")
+ custom_u16string_name = self._makeStringName(
+ "CustomStringU16", "char16_t", allocator="CustomAlloc"
+ )
+ custom_u32string_name = self._makeStringName(
+ "CustomStringU32", "char32_t", allocator="CustomAlloc"
+ )
self.expect(
"frame variable",
substrs=[
- '(%s::u16string) u16_string = u"ß水氶"' % ns,
- '(%s::u16string) u16_empty = u""' % ns,
- '(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
- '(%s::u32string) u32_empty = U""' % ns,
- '(CustomStringU16) custom_u16 = u"ß水氶"',
- '(CustomStringU16) custom_u16_empty = u""',
- '(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
- '(CustomStringU32) custom_u32_empty = U""',
+ f'({u16string_name}) u16_string = u"ß水氶"',
+ f'({u16string_name}) u16_empty = u""',
+ f'({u32string_name}) u32_string = U"🍄🍅🍆🍌"',
+ f'({u32string_name}) u32_empty = U""',
+ f'({custom_u16string_name}) custom_u16 = u"ß水氶"',
+ f'({custom_u16string_name}) custom_u16_empty = u""',
+ f'({custom_u32string_name}) custom_u32 = U"🍄🍅🍆🍌"',
+ f'({custom_u32string_name}) custom_u32_empty = U""',
],
)
@@ -271,9 +295,8 @@ def do_test_embedded_null(self):
self.expect(
"frame variable",
substrs=[
- '(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"' % ns,
- '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ
ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'
- % ns,
+ f'({self._makeStringName("::string", "char")})
IHaveEmbeddedZeros = "a\\0b\\0c\\0d"',
+ f'({self._makeStringName("::wstring", "wchar_t")})
IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"',
],
)
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
index 181141886c5a2..884e689c21655 100644
---
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
@@ -11,6 +11,8 @@
class StdStringViewDataFormatterTestCase(TestBase):
+ TEST_WITH_PDB_DEBUG_INFO = True
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -20,6 +22,12 @@ def setUp(self):
"main.cpp", "// Break here to look at bad string view."
)
+ def _makeStringName(self, typedef: str, char_type: str):
+ if self.getDebugInfo() == "pdb":
+ return f"std::basic_string_view<{char_type},
std::char_traits<{char_type}>>"
+
+ return typedef
+
def do_test(self):
"""Test that that file and class static variables display correctly."""
self.runCmd("file " + self.getBuildArtifact("a.out"),
CURRENT_EXECUTABLE_SET)
@@ -51,39 +59,49 @@ def cleanup():
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
- self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
+ string_view_name = self._makeStringName("std::string_view", "char")
+ wstring_view_name = self._makeStringName("std::wstring_view",
"wchar_t")
+ u16string_view_name = self._makeStringName("std::u16string_view",
"char16_t")
+ u32string_view_name = self._makeStringName("std::u32string_view",
"char32_t")
+ string_name = (
+ "std::basic_string<char, std::char_traits<char>,
std::allocator<char>>"
+ if self.getDebugInfo() == "pdb"
+ else "std::string"
+ )
+
+ self.expect_var_path("wempty", type=wstring_view_name, summary='L""')
self.expect_var_path(
- "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
+ "s", type=wstring_view_name, 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("S", type=wstring_view_name, summary='L"!!!!"')
+ self.expect_var_path("empty", type=string_view_name, summary='""')
+ self.expect_var_path("q_source", type=string_name, summary='"hello
world"')
+ self.expect_var_path("q", type=string_view_name, summary='"hello
world"')
self.expect_var_path(
"Q",
- type="std::string_view",
+ type=string_view_name,
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"'
+ "IHaveEmbeddedZeros", type=string_view_name,
summary='"a\\0b\\0c\\0d"'
)
self.expect_var_path(
"IHaveEmbeddedZerosToo",
- type="std::wstring_view",
+ type=wstring_view_name,
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("u16_string", type=u16string_view_name,
summary='u"ß水氶"')
+ self.expect_var_path("u16_empty", type=u16string_view_name,
summary='u""')
self.expect_var_path(
- "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
+ "u32_string", type=u32string_view_name, summary='U"🍄🍅🍆🍌"'
)
- self.expect_var_path("u32_empty", type="std::u32string_view",
summary='U""')
+ self.expect_var_path("u32_empty", type=u32string_view_name,
summary='U""')
# 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.assertEqual(str(null_obj), f"({string_view_name} *) null_str =
nullptr")
self.runCmd("n")
@@ -108,37 +126,37 @@ def cleanup():
self.expect_expr(
"s",
- result_type="std::wstring_view",
+ result_type=wstring_view_name,
result_summary='L"hello world! מזל טוב!"',
)
- self.expect_var_path("wempty", type="std::wstring_view", summary='L""')
+ self.expect_var_path("wempty", type=wstring_view_name, summary='L""')
self.expect_var_path(
- "s", type="std::wstring_view", summary='L"hello world! מזל טוב!"'
+ "s", type=wstring_view_name, 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("S", type=wstring_view_name, summary='L"!!!!"')
+ self.expect_var_path("empty", type=string_view_name, summary='""')
+ self.expect_var_path("q_source", type=string_name, summary='"Hello
world"')
+ self.expect_var_path("q", type=string_view_name, summary='"Hello
world"')
self.expect_var_path(
"Q",
- type="std::string_view",
+ type=string_view_name,
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"'
+ "IHaveEmbeddedZeros", type=string_view_name,
summary='"a\\0b\\0c\\0d"'
)
self.expect_var_path(
"IHaveEmbeddedZerosToo",
- type="std::wstring_view",
+ type=wstring_view_name,
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("u16_string", type=u16string_view_name,
summary='u"ß水氶"')
+ self.expect_var_path("u16_empty", type=u16string_view_name,
summary='u""')
self.expect_var_path(
- "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"'
+ "u32_string", type=u32string_view_name, summary='U"🍄🍅🍆🍌"'
)
- self.expect_var_path("u32_empty", type="std::u32string_view",
summary='U""')
+ self.expect_var_path("u32_empty", type=u32string_view_name,
summary='U""')
self.runCmd("cont")
self.expect(
diff --git
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py
index b983ee175d389..dda97945f9b23 100644
---
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py
+++
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py
@@ -11,18 +11,26 @@
class StdU8StringDataFormatterTestCase(TestBase):
+ TEST_WITH_PDB_DEBUG_INFO = True
+
def do_test(self):
lldbutil.run_to_source_breakpoint(
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
)
+ string_name = (
+ "std::basic_string<char8_t, std::char_traits<char8_t>,
std::allocator<char8_t>>"
+ if self.getDebugInfo() == "pdb"
+ else "std::u8string"
+ )
+
self.expect(
"frame variable",
substrs=[
- '(std::u8string) u8_string_small = u8"🍄"',
- '(std::u8string) u8_string = u8"❤️👍📄📁😃🧑🌾"',
- '(std::u8string) u8_empty = u8""',
- '(std::u8string) u8_text = u8"ABCd"',
+ f'({string_name}) u8_string_small = u8"🍄"',
+ f'({string_name}) u8_string = u8"❤️👍📄📁😃🧑🌾"',
+ f'({string_name}) u8_empty = u8""',
+ f'({string_name}) u8_text = u8"ABCd"',
],
)
diff --git
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py
index 1e35a0f6bb040..6cf72d18a864f 100644
---
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py
+++
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py
@@ -11,18 +11,26 @@
class StdU8StringViewDataFormatterTestCase(TestBase):
+ TEST_WITH_PDB_DEBUG_INFO = True
+
def do_test(self):
lldbutil.run_to_source_breakpoint(
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
)
+ string_view_name = (
+ "std::basic_string_view<char8_t, std::char_traits<char8_t>>"
+ if self.getDebugInfo() == "pdb"
+ else "std::u8string_view"
+ )
+
self.expect(
"frame variable",
substrs=[
- '(std::u8string_view) u8_string_small = u8"🍄"',
- '(std::u8string_view) u8_string = u8"❤️👍📄📁😃🧑🌾"',
- '(std::u8string_view) u8_empty = u8""',
- '(std::u8string_view) u8_text = u8"ABCd"',
+ f'({string_view_name}) u8_string_small = u8"🍄"',
+ f'({string_view_name}) u8_string = u8"❤️👍📄📁😃🧑🌾"',
+ f'({string_view_name}) u8_empty = u8""',
+ f'({string_view_name}) u8_text = u8"ABCd"',
],
)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits