Author: nerix Date: 2025-11-07T14:16:44+01:00 New Revision: 311d115ed809724855f821616ed7aabab32896d4
URL: https://github.com/llvm/llvm-project/commit/311d115ed809724855f821616ed7aabab32896d4 DIFF: https://github.com/llvm/llvm-project/commit/311d115ed809724855f821616ed7aabab32896d4.diff LOG: [LLDB] Run MSVC STL string(-view) tests with PDB (#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. Added: Modified: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string/TestDataFormatterStdU8String.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py Removed: ################################################################################ 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..5c915b6d9f588 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,47 @@ 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( - "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"' - ) - self.expect_var_path("u32_empty", type="std::u32string_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=u32string_view_name, 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 +124,35 @@ 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( - "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"' - ) - self.expect_var_path("u32_empty", type="std::u32string_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=u32string_view_name, 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
