[Lldb-commits] [lldb] [lldb] Add MSVC STL/libstdc++ formatters for error_code and error_condition (PR #217245)

via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 20 05:08:12 PDT 2026


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

>From 5deb7d631ef7421509305e28dbf3fa0e7370101a Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <bjorn.schobben at aimsport.com>
Date: Wed, 19 Aug 2026 11:05:25 +0200
Subject: [PATCH 1/2] [lldb] Add MSVC STL/libstdc++ formatters for error_code
 and error_condition

Print the stored integer as value=N. Both STLs share the std:: names;
read _Myval on MSVC and _M_value on libstdc++. Leave children visible
so the category pointer stays inspectable.

Part of #24834
---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 17 ++++++++
 .../Plugins/Language/CPlusPlus/MsvcStl.cpp    | 23 +++++++++++
 .../Plugins/Language/CPlusPlus/MsvcStl.h      |  5 +++
 .../generic/error_code/Makefile               |  2 +
 .../TestDataFormatterStdErrorCode.py          | 39 +++++++++++++++++++
 .../generic/error_code/main.cpp               |  9 +++++
 .../msvc-simulators/error_code/Makefile       |  2 +
 ...tDataFormatterMsvcStlErrorCodeSimulator.py | 25 ++++++++++++
 .../msvc-simulators/error_code/main.cpp       | 19 +++++++++
 9 files changed, 141 insertions(+)
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/Makefile
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
 create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 8225c2141a84a..2d47f6793712f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1947,6 +1947,23 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 "MSVC STL/libstdc++ std::strong_ordering summary provider",
                 "std::strong_ordering",
                 eTypeOptionHideChildren | eTypeOptionHideValue, false);
+
+  // Keep children visible: the summary only prints the integer value, so
+  // the category pointer (_Mycat / _M_cat) must still be inspectable.
+  TypeSummaryImpl::Flags error_code_flags;
+  error_code_flags.SetCascades(true)
+      .SetSkipPointers(false)
+      .SetSkipReferences(false)
+      .SetDontShowChildren(false)
+      .SetDontShowValue(false)
+      .SetShowMembersOneLiner(false)
+      .SetHideItemNames(false);
+  AddCXXSummary(cpp_category_sp, MsvcStlErrorCodeSummaryProvider,
+                "MSVC STL/libstdc++ std::error_code summary provider",
+                "std::error_code", error_code_flags);
+  AddCXXSummary(cpp_category_sp, MsvcStlErrorCodeSummaryProvider,
+                "MSVC STL/libstdc++ std::error_condition summary provider",
+                "std::error_condition", error_code_flags);
 }
 
 static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
index 93a01acdc0f0a..2f69312f19ab9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
@@ -305,3 +305,26 @@ bool lldb_private::formatters::MsvcStlStrongOrderingSummaryProvider(
   }
   return true;
 }
+
+bool lldb_private::formatters::IsMsvcStlErrorCode(ValueObject &valobj) {
+  if (auto valobj_sp = valobj.GetNonSyntheticValue())
+    return valobj_sp->GetChildMemberWithName("_Myval") != nullptr &&
+           valobj_sp->GetChildMemberWithName("_Mycat") != nullptr;
+  return false;
+}
+
+bool lldb_private::formatters::MsvcStlErrorCodeSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+  ValueObjectSP value_sp = valobj.GetChildMemberWithName("_Myval");
+  if (!value_sp)
+    value_sp = valobj.GetChildMemberWithName("_M_value");
+  if (!value_sp)
+    return false;
+
+  const char *value = value_sp->GetValueAsCString();
+  if (!value)
+    return false;
+
+  stream.Printf("value=%s", value);
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index 0bdd548dd99e3..8f00abc2ed625 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -142,6 +142,11 @@ SyntheticChildrenFrontEnd *
 MsvcStlSpanSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                     lldb::ValueObjectSP valobj_sp);
 
+// MSVC STL std::error_code / std::error_condition
+bool IsMsvcStlErrorCode(ValueObject &valobj);
+bool MsvcStlErrorCodeSummaryProvider(ValueObject &valobj, Stream &stream,
+                                     const TypeSummaryOptions &options);
+
 } // namespace formatters
 } // namespace lldb_private
 
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/Makefile
new file mode 100644
index 0000000000000..3d0b98f13f3d7
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/Makefile
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
new file mode 100644
index 0000000000000..1d847ee56b31d
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
@@ -0,0 +1,39 @@
+"""Test std::error_code / std::error_condition summaries."""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class StdErrorCodeTestCase(TestBase):
+    SHARED_BUILD_TESTCASE = False
+    TEST_WITH_PDB_DEBUG_INFO = True
+
+    def do_test(self):
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        ec = self.frame().FindVariable("ec")
+        self.assertTrue(ec.GetError().Success())
+        self.assertRegex(ec.summary, r"value=\d+")
+        self.assertGreaterEqual(ec.GetNumChildren(), 1)
+
+        econd = self.frame().FindVariable("econd")
+        self.assertTrue(econd.GetError().Success())
+        self.assertRegex(econd.summary, r"value=\d+")
+
+        default_ec = self.frame().FindVariable("default_ec")
+        self.assertTrue(default_ec.GetError().Success())
+        self.assertEqual(default_ec.summary, "value=0")
+
+    @add_test_categories(["libstdcxx"])
+    def test_libstdcxx(self):
+        self.build(dictionary={"USE_LIBSTDCPP": 1})
+        self.do_test()
+
+    @add_test_categories(["msvcstl"])
+    def test_msvcstl(self):
+        self.build()
+        self.do_test()
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
new file mode 100644
index 0000000000000..d6dca8b6290ca
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
@@ -0,0 +1,9 @@
+#include <system_error>
+
+int main() {
+  std::error_code ec =
+      std::make_error_code(std::errc::no_such_file_or_directory);
+  std::error_condition econd = std::errc::no_such_file_or_directory;
+  std::error_code default_ec;
+  return 0; // break here
+}
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
new file mode 100644
index 0000000000000..3d0b98f13f3d7
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
new file mode 100644
index 0000000000000..d7915e60574b9
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
@@ -0,0 +1,25 @@
+"""Simulate MSVC STL std::error_code and check the formatter."""
+
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class MsvcStlErrorCodeSimulatorTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec("main.cpp")
+        )
+
+        ec = self.frame().FindVariable("ec")
+        self.assertTrue(ec.IsValid())
+        self.assertGreaterEqual(ec.GetNumChildren(), 1)
+        self.assertIsNotNone(ec.GetChildMemberWithName("_Mycat"))
+        self.expect("frame variable ec", substrs=["value=2"])
+
+        econd = self.frame().FindVariable("econd")
+        self.assertTrue(econd.IsValid())
+        self.assertGreaterEqual(econd.GetNumChildren(), 1)
+        self.expect("frame variable econd", substrs=["value=7"])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp
new file mode 100644
index 0000000000000..b72103175ba7f
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp
@@ -0,0 +1,19 @@
+// Layout approximation of MSVC STL std::error_code / error_condition.
+
+namespace std {
+struct error_code {
+  int _Myval;
+  const void *_Mycat;
+};
+
+struct error_condition {
+  int _Myval;
+  const void *_Mycat;
+};
+} // namespace std
+
+int main() {
+  std::error_code ec{2, nullptr};
+  std::error_condition econd{7, nullptr};
+  return 0; // break here
+}

>From 9fdb72d67edf23d779b218e9b114cc926498a003 Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <bjorn.schobben at aimsport.com>
Date: Thu, 20 Aug 2026 14:05:30 +0200
Subject: [PATCH 2/2] [lldb] Expose error categories as synthetic children

---
 .../Plugins/Language/CPlusPlus/CMakeLists.txt |  1 +
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 11 ++-
 .../Plugins/Language/CPlusPlus/Generic.h      |  6 ++
 .../Language/CPlusPlus/GenericErrorCode.cpp   | 93 +++++++++++++++++++
 .../Plugins/Language/CPlusPlus/MsvcStl.cpp    | 23 -----
 .../Plugins/Language/CPlusPlus/MsvcStl.h      |  5 -
 .../TestDataFormatterStdErrorCode.py          | 26 +++---
 .../generic/error_code/main.cpp               |  6 +-
 .../msvc-simulators/error_code/Makefile       |  2 -
 ...tDataFormatterMsvcStlErrorCodeSimulator.py | 25 -----
 .../msvc-simulators/error_code/main.cpp       | 19 ----
 11 files changed, 124 insertions(+), 93 deletions(-)
 create mode 100644 lldb/source/Plugins/Language/CPlusPlus/GenericErrorCode.cpp
 delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
 delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
 delete mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 68093f3c96017..d2ecafb92f33e 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -18,6 +18,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
   CxxStringTypes.cpp
   Generic.cpp
   GenericBitset.cpp
+  GenericErrorCode.cpp
   GenericInitializerList.cpp
   GenericList.cpp
   GenericOptional.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 2d47f6793712f..fd84c937e4bb6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1948,8 +1948,7 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
                 "std::strong_ordering",
                 eTypeOptionHideChildren | eTypeOptionHideValue, false);
 
-  // Keep children visible: the summary only prints the integer value, so
-  // the category pointer (_Mycat / _M_cat) must still be inspectable.
+  // Keep the synthetic Category child visible alongside the integer summary.
   TypeSummaryImpl::Flags error_code_flags;
   error_code_flags.SetCascades(true)
       .SetSkipPointers(false)
@@ -1958,12 +1957,16 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
       .SetDontShowValue(false)
       .SetShowMembersOneLiner(false)
       .SetHideItemNames(false);
-  AddCXXSummary(cpp_category_sp, MsvcStlErrorCodeSummaryProvider,
+  AddCXXSummary(cpp_category_sp, GenericErrorCodeSummaryProvider,
                 "MSVC STL/libstdc++ std::error_code summary provider",
                 "std::error_code", error_code_flags);
-  AddCXXSummary(cpp_category_sp, MsvcStlErrorCodeSummaryProvider,
+  AddCXXSummary(cpp_category_sp, GenericErrorCodeSummaryProvider,
                 "MSVC STL/libstdc++ std::error_condition summary provider",
                 "std::error_condition", error_code_flags);
+  AddCXXSynthetic(cpp_category_sp, GenericErrorCodeSyntheticFrontEndCreator,
+                  "MSVC STL/libstdc++ std::error_code/error_condition "
+                  "synthetic children",
+                  "^std::error_(code|condition)$", stl_synth_flags, true);
 }
 
 static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
index 539eddd3d3e78..917402dd2caea 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Generic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -19,6 +19,12 @@ namespace formatters {
 bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
                                     const TypeSummaryOptions &options);
 
+bool GenericErrorCodeSummaryProvider(ValueObject &valobj, Stream &stream,
+                                     const TypeSummaryOptions &options);
+SyntheticChildrenFrontEnd *
+GenericErrorCodeSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                         lldb::ValueObjectSP valobj_sp);
+
 /// Return the ValueObjectSP of the underlying pointer member whose type
 /// is a desugared 'std::shared_ptr::element_type *'.
 lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericErrorCode.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericErrorCode.cpp
new file mode 100644
index 0000000000000..a0da3dbb2b5db
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericErrorCode.cpp
@@ -0,0 +1,93 @@
+//===-- GenericErrorCode.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Generic.h"
+
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "llvm/Support/ErrorExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+ValueObjectSP GetValue(ValueObject &valobj) {
+  ValueObjectSP value_sp = valobj.GetChildMemberWithName("_Myval");
+  if (!value_sp)
+    value_sp = valobj.GetChildMemberWithName("_M_value");
+  return value_sp;
+}
+
+ValueObjectSP GetCategory(ValueObject &valobj) {
+  ValueObjectSP category_sp = valobj.GetChildMemberWithName("_Mycat");
+  if (!category_sp)
+    category_sp = valobj.GetChildMemberWithName("_M_cat");
+  return category_sp;
+}
+
+class GenericErrorCodeFrontend : public SyntheticChildrenFrontEnd {
+public:
+  explicit GenericErrorCodeFrontend(ValueObject &valobj)
+      : SyntheticChildrenFrontEnd(valobj) {
+    Update();
+  }
+
+  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
+    if (name == "Category" && m_category)
+      return 0;
+    return llvm::createStringErrorV("type has no child named '{0}'", name);
+  }
+
+  llvm::Expected<uint32_t> CalculateNumChildren() override {
+    return m_category ? 1U : 0U;
+  }
+
+  ValueObjectSP GetChildAtIndex(uint32_t idx) override {
+    if (idx != 0 || !m_category)
+      return {};
+    return m_category->Clone(ConstString("Category"));
+  }
+
+  lldb::ChildCacheState Update() override {
+    m_category = GetCategory(m_backend).get();
+    return lldb::ChildCacheState::eRefetch;
+  }
+
+private:
+  // Children derived from the backend share its ClusterManager. Keeping a
+  // shared pointer here would create an ownership cycle.
+  ValueObject *m_category = nullptr;
+};
+
+} // namespace
+
+bool lldb_private::formatters::GenericErrorCodeSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+  ValueObjectSP valobj_sp = valobj.GetNonSyntheticValue();
+  if (!valobj_sp)
+    return false;
+
+  ValueObjectSP value_sp = GetValue(*valobj_sp);
+  if (!value_sp)
+    return false;
+
+  const char *value = value_sp->GetValueAsCString();
+  if (!value)
+    return false;
+
+  stream.Printf("value=%s", value);
+  return true;
+}
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::GenericErrorCodeSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  if (!valobj_sp)
+    return nullptr;
+  return new GenericErrorCodeFrontend(*valobj_sp);
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
index 2f69312f19ab9..93a01acdc0f0a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
@@ -305,26 +305,3 @@ bool lldb_private::formatters::MsvcStlStrongOrderingSummaryProvider(
   }
   return true;
 }
-
-bool lldb_private::formatters::IsMsvcStlErrorCode(ValueObject &valobj) {
-  if (auto valobj_sp = valobj.GetNonSyntheticValue())
-    return valobj_sp->GetChildMemberWithName("_Myval") != nullptr &&
-           valobj_sp->GetChildMemberWithName("_Mycat") != nullptr;
-  return false;
-}
-
-bool lldb_private::formatters::MsvcStlErrorCodeSummaryProvider(
-    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
-  ValueObjectSP value_sp = valobj.GetChildMemberWithName("_Myval");
-  if (!value_sp)
-    value_sp = valobj.GetChildMemberWithName("_M_value");
-  if (!value_sp)
-    return false;
-
-  const char *value = value_sp->GetValueAsCString();
-  if (!value)
-    return false;
-
-  stream.Printf("value=%s", value);
-  return true;
-}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index 8f00abc2ed625..0bdd548dd99e3 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -142,11 +142,6 @@ SyntheticChildrenFrontEnd *
 MsvcStlSpanSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                     lldb::ValueObjectSP valobj_sp);
 
-// MSVC STL std::error_code / std::error_condition
-bool IsMsvcStlErrorCode(ValueObject &valobj);
-bool MsvcStlErrorCodeSummaryProvider(ValueObject &valobj, Stream &stream,
-                                     const TypeSummaryOptions &options);
-
 } // namespace formatters
 } // namespace lldb_private
 
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
index 1d847ee56b31d..bb428d0436976 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/TestDataFormatterStdErrorCode.py
@@ -10,23 +10,25 @@ class StdErrorCodeTestCase(TestBase):
     SHARED_BUILD_TESTCASE = False
     TEST_WITH_PDB_DEBUG_INFO = True
 
+    def check_value(self, name, summary):
+        value = self.frame().FindVariable(name)
+        self.assertSuccess(value.GetError())
+        self.assertEqual(value.summary, summary)
+        self.assertEqual(value.GetNumChildren(), 1)
+
+        category = value.GetChildMemberWithName("Category")
+        self.assertTrue(category.IsValid())
+        self.assertNotEqual(category.GetValueAsUnsigned(), 0)
+
     def do_test(self):
         lldbutil.run_to_source_breakpoint(
             self, "// break here", lldb.SBFileSpec("main.cpp")
         )
 
-        ec = self.frame().FindVariable("ec")
-        self.assertTrue(ec.GetError().Success())
-        self.assertRegex(ec.summary, r"value=\d+")
-        self.assertGreaterEqual(ec.GetNumChildren(), 1)
-
-        econd = self.frame().FindVariable("econd")
-        self.assertTrue(econd.GetError().Success())
-        self.assertRegex(econd.summary, r"value=\d+")
-
-        default_ec = self.frame().FindVariable("default_ec")
-        self.assertTrue(default_ec.GetError().Success())
-        self.assertEqual(default_ec.summary, "value=0")
+        self.check_value("ec", "value=2")
+        self.check_value("econd", "value=7")
+        self.check_value("negative", "value=-1")
+        self.check_value("default_ec", "value=0")
 
     @add_test_categories(["libstdcxx"])
     def test_libstdcxx(self):
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
index d6dca8b6290ca..a15a9cb473a3d 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/error_code/main.cpp
@@ -1,9 +1,9 @@
 #include <system_error>
 
 int main() {
-  std::error_code ec =
-      std::make_error_code(std::errc::no_such_file_or_directory);
-  std::error_condition econd = std::errc::no_such_file_or_directory;
+  std::error_code ec(2, std::generic_category());
+  std::error_condition econd(7, std::generic_category());
+  std::error_code negative(-1, std::generic_category());
   std::error_code default_ec;
   return 0; // break here
 }
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
deleted file mode 100644
index 3d0b98f13f3d7..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-CXX_SOURCES := main.cpp
-include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
deleted file mode 100644
index d7915e60574b9..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/TestDataFormatterMsvcStlErrorCodeSimulator.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""Simulate MSVC STL std::error_code and check the formatter."""
-
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class MsvcStlErrorCodeSimulatorTestCase(TestBase):
-    NO_DEBUG_INFO_TESTCASE = True
-
-    def test(self):
-        self.build()
-        lldbutil.run_to_source_breakpoint(
-            self, "break here", lldb.SBFileSpec("main.cpp")
-        )
-
-        ec = self.frame().FindVariable("ec")
-        self.assertTrue(ec.IsValid())
-        self.assertGreaterEqual(ec.GetNumChildren(), 1)
-        self.assertIsNotNone(ec.GetChildMemberWithName("_Mycat"))
-        self.expect("frame variable ec", substrs=["value=2"])
-
-        econd = self.frame().FindVariable("econd")
-        self.assertTrue(econd.IsValid())
-        self.assertGreaterEqual(econd.GetNumChildren(), 1)
-        self.expect("frame variable econd", substrs=["value=7"])
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp
deleted file mode 100644
index b72103175ba7f..0000000000000
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/msvc-simulators/error_code/main.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Layout approximation of MSVC STL std::error_code / error_condition.
-
-namespace std {
-struct error_code {
-  int _Myval;
-  const void *_Mycat;
-};
-
-struct error_condition {
-  int _Myval;
-  const void *_Mycat;
-};
-} // namespace std
-
-int main() {
-  std::error_code ec{2, nullptr};
-  std::error_condition econd{7, nullptr};
-  return 0; // break here
-}



More information about the lldb-commits mailing list