Author: Nerixyz
Date: 2026-01-12T11:40:12+01:00
New Revision: 9a632fd684e1729b93f9f5272ad6b5798f38ba77

URL: 
https://github.com/llvm/llvm-project/commit/9a632fd684e1729b93f9f5272ad6b5798f38ba77
DIFF: 
https://github.com/llvm/llvm-project/commit/9a632fd684e1729b93f9f5272ad6b5798f38ba77.diff

LOG: [LLDB] Fix MS STL `variant` with non-trivial types (#171489)

When using `std::variant` with non-trivial types, we need to go through
multiple bases to find the `_Which` member. The MSVC STL implements this
in `xsmf_control.h` which conditionally adds/deletes copy/move
constructors/operators.

We now go to `_Variant_base` (the holder of `_Which`). This inherits
from `_Variant_storage`, which is our entry point to finding the n-th
storage (going through `_Tail`).

Added: 
    

Modified: 
    lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
    
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/TestDataFormatterStdVariant.py
    
lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/variant/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
index 3e7647be48bb0..55e964256264f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlVariant.cpp
@@ -67,12 +67,18 @@ std::optional<int64_t> GetIndexValue(ValueObject &valobj) {
 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;
+  ValueObject *parent = which_sp->GetParent();
+  if (!parent)
     return nullptr;
-  // -> std::_Variant_storage
-  container_sp = container_sp->GetChildAtIndex(0);
+
+  // 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 1ae07a91dfe3d..d5c4f5c34cfe0 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 @@ def cleanup():
             ],
         )
 
+        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,19 @@ def cleanup():
             substrs=["v3 =  Active Type = char  {", "Value = 'A'", "}"],
         )
 
+        string_name = (
+            "std::basic_string<char, std::char_traits<char>, 
std::allocator<char>>"
+            if self.getDebugInfo() == "pdb"
+            else "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 620b97b7306f9..9983104ca9628 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 @@ int main() {
       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 @@ int main() {
   // state when we change its value.
   v1 = 2.0;
   d = std::get<double>(v1);
+
+  v4 = "a string";
+
   printf("%f\n", d); // break here
 
   try {


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to