[lldb] [llvm] [lldb] Add MSVC STL/libstdc++ formatters for queue, stack, and priority_queue (PR #217241)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 03:41:03 PDT 2026


https://github.com/Daedie-git updated https://github.com/llvm/llvm-project/pull/217241

>From 8ccd14da97acec8e51f7014aac1dc18c56a6fef8 Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <bjorn.schobben at aimsport.com>
Date: Wed, 19 Aug 2026 10:52:59 +0200
Subject: [PATCH 1/4] [lldb] Add MSVC STL/libstdc++ formatters for queue,
 stack, and priority_queue

These adaptors store the container in a member named `c` in both MSVC
STL and libstdc++. Reuse the existing adaptor frontend and register it
for the un-inlined std:: names. libc++ continues to use the inline
namespace regex.

Part of #24834
---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 21 ++++++++
 .../queue/TestDataFormatterStdQueue.py        | 54 ++++++++++++++-----
 .../data-formatter-stl/generic/queue/main.cpp | 10 +++-
 3 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 8225c2141a84a..c28e75745dfca 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1947,6 +1947,27 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 "MSVC STL/libstdc++ std::strong_ordering summary provider",
                 "std::strong_ordering",
                 eTypeOptionHideChildren | eTypeOptionHideValue, false);
+
+  // Container adaptors store the underlying container in a member named `c`
+  // in both MSVC STL and libstdc++.
+  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+                  "std::queue synthetic children", "^std::queue<.+>(( )?&)?$",
+                  stl_synth_flags, true);
+  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+                  "std::stack synthetic children", "^std::stack<.+>(( )?&)?$",
+                  stl_synth_flags, true);
+  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+                  "std::priority_queue synthetic children",
+                  "^std::priority_queue<.+>(( )?&)?$", stl_synth_flags, true);
+  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
+                "std::queue summary provider", "^std::queue<.+>(( )?&)?$",
+                stl_summary_flags, true);
+  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
+                "std::stack summary provider", "^std::stack<.+>(( )?&)?$",
+                stl_summary_flags, true);
+  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
+                "std::priority_queue summary provider",
+                "^std::priority_queue<.+>(( )?&)?$", stl_summary_flags, true);
 }
 
 static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/TestDataFormatterStdQueue.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/TestDataFormatterStdQueue.py
index d5ae06bd057c4..166ed83220d2b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/TestDataFormatterStdQueue.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/TestDataFormatterStdQueue.py
@@ -15,28 +15,54 @@ def setUp(self):
         TestBase.setUp(self)
         self.namespace = "std"
 
-    def check_variable(self, name):
+    def check_sequence(self, name, type_name):
         var = self.frame().FindVariable(name)
-        self.assertTrue(var.IsValid())
-
-        queue = self.namespace + "::queue"
-        self.assertIn(queue, var.GetDisplayTypeName())
-        self.assertEqual(var.GetNumChildren(), 5)
+        self.assertTrue(var.IsValid(), name)
+        self.assertIn(self.namespace + "::" + type_name, var.GetDisplayTypeName())
+        self.assertEqual(var.GetNumChildren(), 5, name)
         for i in range(5):
             ch = var.GetChildAtIndex(i)
-            self.assertTrue(ch.IsValid())
-            self.assertEqual(ch.GetValueAsSigned(), i + 1)
+            self.assertTrue(ch.IsValid(), f"{name}[{i}]")
+            self.assertEqual(ch.GetValueAsSigned(), i + 1, f"{name}[{i}]")
+
+    def check_priority_queue(self, name):
+        var = self.frame().FindVariable(name)
+        self.assertTrue(var.IsValid(), name)
+        self.assertIn(self.namespace + "::priority_queue", var.GetDisplayTypeName())
+        self.assertEqual(var.GetNumChildren(), 5, name)
+        values = sorted(var.GetChildAtIndex(i).GetValueAsSigned() for i in range(5))
+        self.assertEqual(values, [1, 2, 3, 4, 5])
+
+    def do_test_queues(self):
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp", False)
+        )
+        self.check_sequence("q1", "queue")
+        self.check_sequence("q2", "queue")
+
+    def do_test_adaptors(self):
+        self.do_test_queues()
+        self.check_sequence("s1", "stack")
+        self.check_sequence("s2", "stack")
+        self.check_priority_queue("pq")
+
+    @expectedFailureAll(
+        bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
+    )
+    @add_test_categories(["libstdcxx"])
+    def test_libstdcxx(self):
+        self.build(dictionary={"USE_LIBSTDCPP": 1})
+        self.do_test_adaptors()
 
     @expectedFailureAll(
         bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android"
     )
     @add_test_categories(["libc++"])
     def test_libcxx(self):
-        """Test that std::queue is displayed correctly"""
         self.build(dictionary={"USE_LIBCPP": 1})
-        lldbutil.run_to_source_breakpoint(
-            self, "// break here", lldb.SBFileSpec("main.cpp", False)
-        )
+        self.do_test_queues()
 
-        self.check_variable("q1")
-        self.check_variable("q2")
+    @add_test_categories(["msvcstl"])
+    def test_msvcstl(self):
+        self.build()
+        self.do_test_adaptors()
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/main.cpp
index 406b437914932..a85c5f8ce39d2 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/queue/main.cpp
@@ -1,9 +1,15 @@
 #include <queue>
+#include <stack>
 #include <vector>
 
 int main() {
   std::queue<int> q1{{1, 2, 3, 4, 5}};
   std::queue<int, std::vector<int>> q2{{1, 2, 3, 4, 5}};
-  int ret = q1.size() + q2.size(); // break here
-  return ret;
+  std::stack<int> s1{{1, 2, 3, 4, 5}};
+  std::stack<int, std::vector<int>> s2{{1, 2, 3, 4, 5}};
+  std::priority_queue<int> pq;
+  for (int v : {1, 2, 3, 4, 5})
+    pq.push(v);
+  int ret = q1.size() + q2.size() + s1.size() + s2.size() + pq.size();
+  return ret; // break here
 }

>From 255b09e5785d95790d2da6d21a33a906f884ce5a Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <bjorn.schobben at aimsport.com>
Date: Wed, 19 Aug 2026 13:29:36 +0200
Subject: [PATCH 2/4] [lldb] Rename queue frontend to
 GenericContainerAdaptorFrontEndCreator

The protected member `c` is required by the standard, so the same
frontend covers libc++, libstdc++, and MSVC STL.

Part of #24834
---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 12 ++++++------
 .../Plugins/Language/CPlusPlus/LibCxx.h       |  7 +++++--
 .../Language/CPlusPlus/LibCxxQueue.cpp        | 19 +++++++++----------
 3 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index c28e75745dfca..b1fc657069de9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -908,7 +908,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
       "libc++ std::unordered containers synthetic children",
       "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",
       stl_synth_flags, true);
-  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                   "libc++ std::queue synthetic children",
                   "^std::__[[:alnum:]]+::queue<.+>$", stl_synth_flags, true);
   AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
@@ -1948,15 +1948,15 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 "std::strong_ordering",
                 eTypeOptionHideChildren | eTypeOptionHideValue, false);
 
-  // Container adaptors store the underlying container in a member named `c`
-  // in both MSVC STL and libstdc++.
-  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+  // Container adaptors expose the underlying container as the standard
+  // protected member `c` ([queue.defn], [stack.defn], [priqueue.overview]).
+  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                   "std::queue synthetic children", "^std::queue<.+>(( )?&)?$",
                   stl_synth_flags, true);
-  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                   "std::stack synthetic children", "^std::stack<.+>(( )?&)?$",
                   stl_synth_flags, true);
-  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                   "std::priority_queue synthetic children",
                   "^std::priority_queue<.+>(( )?&)?$", stl_synth_flags, true);
   AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index b2cbff8890861..c593428cb081f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -209,8 +209,11 @@ SyntheticChildrenFrontEnd *
 LibCxxUnorderedMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                                    lldb::ValueObjectSP);
 
-SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
-                                                      lldb::ValueObjectSP);
+// std::queue / std::stack / std::priority_queue. The underlying container
+// is the standard protected member `c`.
+SyntheticChildrenFrontEnd *
+GenericContainerAdaptorFrontEndCreator(CXXSyntheticChildren *,
+                                       lldb::ValueObjectSP);
 
 SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
                                                       lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
index 9d9ae354f3c09..7e0abce5ece40 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -15,9 +15,10 @@ using namespace lldb_private;
 
 namespace {
 
-class QueueFrontEnd : public SyntheticChildrenFrontEnd {
+class ContainerAdaptorFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-  QueueFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
+  ContainerAdaptorFrontEnd(ValueObject &valobj)
+      : SyntheticChildrenFrontEnd(valobj) {
     Update();
   }
 
@@ -34,8 +35,7 @@ class QueueFrontEnd : public SyntheticChildrenFrontEnd {
   }
 
   ValueObjectSP GetChildAtIndex(uint32_t idx) override {
-    return m_container_sp ? m_container_sp->GetChildAtIndex(idx)
-                          : nullptr;
+    return m_container_sp ? m_container_sp->GetChildAtIndex(idx) : nullptr;
   }
 
 private:
@@ -44,11 +44,11 @@ class QueueFrontEnd : public SyntheticChildrenFrontEnd {
   // objects are only destroyed when every shared pointer to any of them
   // is destroyed, so we must not store a shared pointer to any ValueObject
   // derived from our backend ValueObject (since we're in the same cluster).
-  ValueObject* m_container_sp = nullptr;
+  ValueObject *m_container_sp = nullptr;
 };
 } // namespace
 
-lldb::ChildCacheState QueueFrontEnd::Update() {
+lldb::ChildCacheState ContainerAdaptorFrontEnd::Update() {
   m_container_sp = nullptr;
   ValueObjectSP c_sp = m_backend.GetChildMemberWithName("c");
   if (!c_sp)
@@ -57,10 +57,9 @@ lldb::ChildCacheState QueueFrontEnd::Update() {
   return lldb::ChildCacheState::eRefetch;
 }
 
-SyntheticChildrenFrontEnd *
-formatters::LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
-                                       lldb::ValueObjectSP valobj_sp) {
+SyntheticChildrenFrontEnd *formatters::GenericContainerAdaptorFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
   if (valobj_sp)
-    return new QueueFrontEnd(*valobj_sp);
+    return new ContainerAdaptorFrontEnd(*valobj_sp);
   return nullptr;
 }

>From 9df48c1863693d73fecd17e35b50f2bd83770070 Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <bjorn.schobben at aimsport.com>
Date: Wed, 19 Aug 2026 18:11:31 +0200
Subject: [PATCH 3/4] [lldb] Move container adaptor frontend to
 GenericQueue.cpp

The frontend is shared by libc++, libstdc++, and MSVC STL. Put the
declaration in Generic.h and drop the LibCxxQueue.cpp name.
---
 lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt       | 2 +-
 lldb/source/Plugins/Language/CPlusPlus/Generic.h            | 6 ++++++
 .../CPlusPlus/{LibCxxQueue.cpp => GenericQueue.cpp}         | 5 +++--
 lldb/source/Plugins/Language/CPlusPlus/LibCxx.h             | 6 ------
 .../lldb/source/Plugins/Language/CPlusPlus/BUILD.gn         | 2 +-
 5 files changed, 11 insertions(+), 10 deletions(-)
 rename lldb/source/Plugins/Language/CPlusPlus/{LibCxxQueue.cpp => GenericQueue.cpp} (94%)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 68093f3c96017..b0f5b38d642c1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -21,10 +21,10 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
   GenericInitializerList.cpp
   GenericList.cpp
   GenericOptional.cpp
+  GenericQueue.cpp
   LibCxx.cpp
   LibCxxAtomic.cpp
   LibCxxMap.cpp
-  LibCxxQueue.cpp
   LibCxxRangesRefView.cpp
   LibCxxSliceArray.cpp
   LibCxxProxyArray.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
index 539eddd3d3e78..1f86b95c521f3 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Generic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -27,6 +27,12 @@ lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr,
 SyntheticChildrenFrontEnd *
 GenericInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                                lldb::ValueObjectSP valobj_sp);
+
+// std::queue / std::stack / std::priority_queue. The underlying container
+// is the standard protected member `c`.
+SyntheticChildrenFrontEnd *
+GenericContainerAdaptorFrontEndCreator(CXXSyntheticChildren *,
+                                       lldb::ValueObjectSP valobj_sp);
 } // namespace formatters
 } // namespace lldb_private
 
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
similarity index 94%
rename from lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
rename to lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
index 7e0abce5ece40..4939ec6d7a3b9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxQueue.cpp ---------------------------------------------------===//
+//===-- GenericQueue.cpp --------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "LibCxx.h"
+#include "Generic.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
 #include "llvm/Support/ErrorExtras.h"
 
 using namespace lldb;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index c593428cb081f..b2057c2f30b63 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -209,12 +209,6 @@ SyntheticChildrenFrontEnd *
 LibCxxUnorderedMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                                    lldb::ValueObjectSP);
 
-// std::queue / std::stack / std::priority_queue. The underlying container
-// is the standard protected member `c`.
-SyntheticChildrenFrontEnd *
-GenericContainerAdaptorFrontEndCreator(CXXSyntheticChildren *,
-                                       lldb::ValueObjectSP);
-
 SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
                                                       lldb::ValueObjectSP);
 
diff --git a/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn
index d7732a059ef29..dda2d6985fe50 100644
--- a/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn
@@ -43,11 +43,11 @@ static_library("CPlusPlus") {
     "GenericInitializerList.cpp",
     "GenericList.cpp",
     "GenericOptional.cpp",
+    "GenericQueue.cpp",
     "LibCxx.cpp",
     "LibCxxAtomic.cpp",
     "LibCxxMap.cpp",
     "LibCxxProxyArray.cpp",
-    "LibCxxQueue.cpp",
     "LibCxxRangesRefView.cpp",
     "LibCxxSliceArray.cpp",
     "LibCxxSpan.cpp",

>From 3cce01c3876fe622a2b99e6d548e2cad867b54a4 Mon Sep 17 00:00:00 2001
From: Daedie-git <HC_Daedalus at hotmail.com>
Date: Thu, 20 Aug 2026 12:40:53 +0200
Subject: [PATCH 4/4] Update
 lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp

Co-authored-by: Nerixyz <nero.9 at hotmail.de>
---
 lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
index 4939ec6d7a3b9..3c20c1afe2e9c 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericQueue.cpp
@@ -1,4 +1,4 @@
-//===-- GenericQueue.cpp --------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.



More information about the llvm-commits mailing list