Reland [LLDB] Fix MS STL variant with non-trivial types and PDB (#176189)
Relands #171489 which was reverted due to a test failure on GreenDragon.
As suggested in
https://github.com/llvm/llvm-project/pull/171489#issuecomment-3754098800,
I'm checking for `std::string` on Darwin and `std::basic_string<char>`
otherwise, however I can't test that locally.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
index 3e7647b..55e9642 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
@@ -67,12 +67,18 @@
ValueObjectSP GetNthStorage(ValueObject &outer, int64_t index) {
// We need to find the std::_Variant_storage base class.
- // -> std::_SMF_control (typedef to std::_Variant_base)
- ValueObjectSP container_sp = outer.GetSP()->GetChildAtIndex(0);
- if (!container_sp)
+ // Navigate "down" to std::_Variant_base by finding the holder of "_Which".
+ // This might be down a few levels if a variant member isn't trivially
+ // destructible/copyable/etc.
+ ValueObjectSP which_sp = outer.GetChildMemberWithName("_Which");
+ if (!which_sp)
return nullptr;
- // -> std::_Variant_storage
- container_sp = container_sp->GetChildAtIndex(0);
+ ValueObject *parent = which_sp->GetParent();
+ if (!parent)
+ return nullptr;
+
+ // Now go to std::_Variant_storage.
+ ValueObjectSP container_sp = parent->GetChildAtIndex(0);
if (!container_sp)
return nullptr;
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/TestDataFormatterStdVariant.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/TestDataFormatterStdVariant.py
index 1ae07a9..cd03c12 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/TestDataFormatterStdVariant.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/TestDataFormatterStdVariant.py
@@ -50,6 +50,14 @@
],
)
+ self.expect_expr(
+ "v4",
+ result_summary=" Active Type = int ",
+ result_children=[
+ ValueCheck(name="Value", value="4"),
+ ],
+ )
+
lldbutil.continue_to_breakpoint(self.process, bkpt)
self.expect(
@@ -69,6 +77,23 @@
substrs=["v3 = Active Type = char {", "Value = 'A'", "}"],
)
+ if self.getDebugInfo() == "pdb":
+ string_name = (
+ "std::basic_string<char, std::char_traits<char>, std::allocator<char>>"
+ )
+ elif self.platformIsDarwin():
+ string_name = "std::string"
+ else:
+ string_name = "std::basic_string<char>"
+
+ self.expect_expr(
+ "v4",
+ result_summary=f" Active Type = {string_name} ",
+ result_children=[
+ ValueCheck(name="Value", summary='"a string"'),
+ ],
+ )
+
self.expect("frame variable v_valueless", substrs=["v_valueless = No Value"])
self.expect(
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/main.cpp
index 620b97b..9983104 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/main.cpp
@@ -49,6 +49,8 @@
S>
v_300_types_valueless;
+ std::variant<int, bool, std::string> v4 = 4;
+
v_valueless = 5;
v_300_types_valueless.emplace<0>(10);
@@ -70,6 +72,9 @@
// state when we change its value.
v1 = 2.0;
d = std::get<double>(v1);
+
+ v4 = "a string";
+
printf("%f\n", d); // break here
try {