https://github.com/Nerixyz updated 
https://github.com/llvm/llvm-project/pull/175570

>From 9b5f77b5b05e1c57cc279e1704a131392a9f855d Mon Sep 17 00:00:00 2001
From: Nerixyz <[email protected]>
Date: Mon, 12 Jan 2026 16:36:21 +0100
Subject: [PATCH 1/2] [LLDB] Add MSVC STL bitset formatter

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 27 +++++++++++---
 .../Language/CPlusPlus/GenericBitset.cpp      | 30 ++++++++++++++++
 .../Plugins/Language/CPlusPlus/MsvcStl.h      |  6 ++++
 .../bitset/TestDataFormatterGenericBitset.py  | 36 ++++++++++++-------
 4 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index bdc67a004b06c..09c5e578b2150 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1419,10 +1419,10 @@ static void 
LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
   stl_summary_flags.SetDontShowChildren(false);
   stl_summary_flags.SetSkipPointers(false);
 
-  AddCXXSummary(
-      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
-      "libstdc++ std::bitset summary provider",
-      "^std::(__debug::)?bitset<.+>(( )?&)?$", stl_summary_flags, true);
+  AddCXXSummary(cpp_category_sp,
+                lldb_private::formatters::ContainerSizeSummaryProvider,
+                "libstdc++ std::bitset summary provider",
+                "^std::__debug::bitset<.+>(( )?&)?$", stl_summary_flags, true);
 
   AddCXXSummary(cpp_category_sp,
                 lldb_private::formatters::ContainerSizeSummaryProvider,
@@ -1499,7 +1499,7 @@ static void 
LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
   AddCXXSynthetic(
       cpp_category_sp,
       lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
-      "std::bitset synthetic child", "^std::(__debug::)?bitset<.+>(( )?&)?$",
+      "std::bitset synthetic child", "^std::__debug::bitset<.+>(( )?&)?$",
       stl_deref_flags, true);
 
   AddCXXSummary(cpp_category_sp,
@@ -1690,6 +1690,17 @@ GenericSpanSyntheticFrontEndCreator(CXXSyntheticChildren 
*children,
   return LibStdcppSpanSyntheticFrontEndCreator(children, valobj_sp);
 }
 
+static SyntheticChildrenFrontEnd *
+GenericBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *children,
+                                      ValueObjectSP valobj_sp) {
+  if (!valobj_sp)
+    return nullptr;
+
+  if (IsMsvcStlBitset(*valobj_sp))
+    return MsvcStlBitsetSyntheticFrontEndCreator(children, valobj_sp);
+  return LibStdcppBitsetSyntheticFrontEndCreator(children, valobj_sp);
+}
+
 /// Load formatters that are formatting types from more than one STL
 static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
   if (!cpp_category_sp)
@@ -1850,6 +1861,9 @@ static void 
LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                   "std::(multi)?map/set synthetic children",
                   "^std::(multi)?(map|set)<.+>(( )?&)?$", stl_synth_flags,
                   true);
+  AddCXXSynthetic(cpp_category_sp, GenericBitsetSyntheticFrontEndCreator,
+                  "std::bitset synthetic children", "^std::bitset<.+>(( 
)?&)?$",
+                  stl_deref_flags, true);
 
   AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                 "std::initializer_list summary provider",
@@ -1900,6 +1914,9 @@ static void 
LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
   AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                 "MSVC STL/libstd++ std::span summary provider",
                 "^std::span<.+>$", stl_summary_flags, true);
+  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
+                "MSVC STL/libstdc++ std::bitset summary provider",
+                "^std::bitset<.+>(( )?&)?$", stl_summary_flags, true);
 }
 
 static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index f2521ec750875..5f905006dfbcb 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -8,6 +8,7 @@
 
 #include "LibCxx.h"
 #include "LibStdcpp.h"
+#include "MsvcStl.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
 #include "lldb/Target/Target.h"
@@ -24,6 +25,7 @@ class GenericBitsetFrontEnd : public 
SyntheticChildrenFrontEnd {
   enum class StdLib {
     LibCxx,
     LibStdcpp,
+    MsvcStl,
   };
 
   GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib);
@@ -75,11 +77,14 @@ GenericBitsetFrontEnd::GenericBitsetFrontEnd(ValueObject 
&valobj, StdLib stdlib)
 llvm::StringRef GenericBitsetFrontEnd::GetDataContainerMemberName() {
   static constexpr llvm::StringLiteral s_libcxx_case("__first_");
   static constexpr llvm::StringLiteral s_libstdcpp_case("_M_w");
+  static constexpr llvm::StringLiteral s_msvcstl_case("_Array");
   switch (m_stdlib) {
   case StdLib::LibCxx:
     return s_libcxx_case;
   case StdLib::LibStdcpp:
     return s_libstdcpp_case;
+  case StdLib::MsvcStl:
+    return s_msvcstl_case;
   }
   llvm_unreachable("Unknown StdLib enum");
 }
@@ -96,6 +101,17 @@ lldb::ChildCacheState GenericBitsetFrontEnd::Update() {
 
   if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
     size = arg->value.GetAPSInt().getLimitedValue();
+  else {
+    // PDB doesn't create template types. Instead, the type is a (non-template)
+    // struct with the name "bitset<N>".
+    ConstString type_name =
+        m_backend.GetCompilerType().GetTypeName(/*BaseOnly=*/true);
+    llvm::StringRef size_str = type_name.GetStringRef();
+    size_str.consume_front("bitset<");
+    size_str.consume_back(">");
+    if (size_str.getAsInteger(10, size))
+      return lldb::ChildCacheState::eRefetch;
+  }
 
   m_elements.assign(size, ValueObjectSP());
   m_first =
@@ -156,3 +172,17 @@ SyntheticChildrenFrontEnd 
*formatters::LibcxxBitsetSyntheticFrontEndCreator(
                                      GenericBitsetFrontEnd::StdLib::LibCxx);
   return nullptr;
 }
+
+bool formatters::IsMsvcStlBitset(ValueObject &valobj) {
+  if (ValueObjectSP valobj_sp = valobj.GetNonSyntheticValue())
+    return valobj_sp->GetChildMemberWithName("_Array") != nullptr;
+  return false;
+}
+
+SyntheticChildrenFrontEnd *formatters::MsvcStlBitsetSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  if (valobj_sp)
+    return new GenericBitsetFrontEnd(*valobj_sp,
+                                     GenericBitsetFrontEnd::StdLib::MsvcStl);
+  return nullptr;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h 
b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index b25005914e36e..f6c6a62929165 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -127,6 +127,12 @@ SyntheticChildrenFrontEnd *
 MsvcStlSpanSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                     lldb::ValueObjectSP valobj_sp);
 
+// MSVC STL std::bitset<>
+bool IsMsvcStlBitset(ValueObject &valobj);
+SyntheticChildrenFrontEnd *
+MsvcStlBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                      lldb::ValueObjectSP valobj_sp);
+
 } // namespace formatters
 } // namespace lldb_private
 
diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
index 98000036eebe7..e94024c56eb80 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
@@ -8,14 +8,14 @@
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
-USE_LIBSTDCPP = "USE_LIBSTDCPP"
-USE_LIBCPP = "USE_LIBCPP"
 VALUE = "VALUE"
 REFERENCE = "REFERENCE"
 POINTER = "POINTER"
 
 
 class GenericBitsetDataFormatterTestCase(TestBase):
+    TEST_WITH_PDB_DEBUG_INFO = True
+
     def setUp(self):
         TestBase.setUp(self)
         primes = [1] * 1000
@@ -47,16 +47,14 @@ def check(self, name, size, variant):
             self.assertEqual(
                 child.GetValueAsUnsigned(),
                 self.primes[i],
-                "variable: %s, index: %d" % (name, size),
+                "variable: %s, index: %d" % (name, i),
             )
         self.expect_var_path(
             name, type=self.getBitsetVariant(size, variant), children=children
         )
 
-    def do_test_value(self, stdlib_type):
+    def do_test_value(self):
         """Test that std::bitset is displayed correctly"""
-        self.build(dictionary={stdlib_type: "1"})
-
         lldbutil.run_to_source_breakpoint(
             self, "// break here", lldb.SBFileSpec("main.cpp", False)
         )
@@ -68,16 +66,21 @@ def do_test_value(self, stdlib_type):
 
     @add_test_categories(["libstdcxx"])
     def test_value_libstdcpp(self):
-        self.do_test_value(USE_LIBSTDCPP)
+        self.build(dictionary={'USE_LIBSTDCPP': "1"})
+        self.do_test_value()
 
     @add_test_categories(["libc++"])
     def test_value_libcpp(self):
-        self.do_test_value(USE_LIBCPP)
+        self.build(dictionary={'USE_LIBCPP': "1"})
+        self.do_test_value()
 
-    def do_test_ptr_and_ref(self, stdlib_type):
-        """Test that ref and ptr to std::bitset is displayed correctly"""
-        self.build(dictionary={stdlib_type: "1"})
+    @add_test_categories(["msvcstl"])
+    def test_value_msvcstl(self):
+        self.build()
+        self.do_test_value()
 
+    def do_test_ptr_and_ref(self):
+        """Test that ref and ptr to std::bitset is displayed correctly"""
         (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(
             self, "Check ref and ptr", lldb.SBFileSpec("main.cpp", False)
         )
@@ -97,8 +100,15 @@ def do_test_ptr_and_ref(self, stdlib_type):
 
     @add_test_categories(["libstdcxx"])
     def test_ptr_and_ref_libstdcpp(self):
-        self.do_test_ptr_and_ref(USE_LIBSTDCPP)
+        self.build(dictionary={'USE_LIBSTDCPP': "1"})
+        self.do_test_ptr_and_ref()
 
     @add_test_categories(["libc++"])
     def test_ptr_and_ref_libcpp(self):
-        self.do_test_ptr_and_ref(USE_LIBCPP)
+        self.build(dictionary={'USE_LIBCPP': "1"})
+        self.do_test_ptr_and_ref()
+
+    @add_test_categories(["msvcstl"])
+    def test_ptr_and_ref_msvcstl(self):
+        self.build()
+        self.do_test_ptr_and_ref()

>From fc3e5c9f7493ee13dfe29f595b4e2ff554feaa72 Mon Sep 17 00:00:00 2001
From: Nerixyz <[email protected]>
Date: Mon, 12 Jan 2026 16:55:06 +0100
Subject: [PATCH 2/2] fix: formatting

---
 .../generic/bitset/TestDataFormatterGenericBitset.py      | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
index e94024c56eb80..80431ce958b9d 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py
@@ -66,12 +66,12 @@ def do_test_value(self):
 
     @add_test_categories(["libstdcxx"])
     def test_value_libstdcpp(self):
-        self.build(dictionary={'USE_LIBSTDCPP': "1"})
+        self.build(dictionary={"USE_LIBSTDCPP": "1"})
         self.do_test_value()
 
     @add_test_categories(["libc++"])
     def test_value_libcpp(self):
-        self.build(dictionary={'USE_LIBCPP': "1"})
+        self.build(dictionary={"USE_LIBCPP": "1"})
         self.do_test_value()
 
     @add_test_categories(["msvcstl"])
@@ -100,12 +100,12 @@ def do_test_ptr_and_ref(self):
 
     @add_test_categories(["libstdcxx"])
     def test_ptr_and_ref_libstdcpp(self):
-        self.build(dictionary={'USE_LIBSTDCPP': "1"})
+        self.build(dictionary={"USE_LIBSTDCPP": "1"})
         self.do_test_ptr_and_ref()
 
     @add_test_categories(["libc++"])
     def test_ptr_and_ref_libcpp(self):
-        self.build(dictionary={'USE_LIBCPP': "1"})
+        self.build(dictionary={"USE_LIBCPP": "1"})
         self.do_test_ptr_and_ref()
 
     @add_test_categories(["msvcstl"])

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

Reply via email to