[libcxx-commits] [libcxx] [libcxx] Make std::pair pretty-printer ABI-independent (PR #201768)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 19 06:57:08 PDT 2026


https://github.com/aokblast updated https://github.com/llvm/llvm-project/pull/201768

>From d0700291f695251a2eb3efd6ca710f1efbb819c5 Mon Sep 17 00:00:00 2001
From: aokblast <aokblast at FreeBSD.org>
Date: Fri, 5 Jun 2026 15:26:41 +0800
Subject: [PATCH 1/4] [lldb] Make std::pair pretty-printer ABI-independent

std::pair is printed explicitly instead of relying on GDB's default
struct formatting to keep output stable across ABI configurations.

With _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR (default on
some platforms, e.g. FreeBSD), std::pair gains an empty
__non_trivially_copyable_base base class. GDB would otherwise render
this as <...__non_trivially_copyable_base<...>> = {<No data fields>},
which makes output ABI-dependent.

Only first and second are meaningful, so print them directly.
---
 libcxx/utils/gdb/libcxx/printers.py | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index ccaa6e9a019e8..c345a076330cf 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -182,6 +182,26 @@ def children(self):
             return iter(())
         return self._Children(self.val)
 
+
+class StdPairPrinter(object):
+    """Print a std::pair.
+
+    Print std::pair explicitly instead of relying on GDB's default struct
+    formatting. Some ABI configurations (e.g.
+    _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR, enabled by default on
+    FreeBSD) add an empty __non_trivially_copyable_base base class to
+    std::pair. GDB renders this implementation detail as
+    '<...__non_trivially_copyable_base<...>> = {<No data fields>}', which makes
+    the output ABI-dependent. Only 'first' and 'second' are meaningful, so
+    print just those members.
+    """
+
+    def __init__(self, val):
+        self.val = val
+
+    def children(self):
+        return iter([("first", self.val["first"]), ("second", self.val["second"])])
+
 class StdStringPrinter(object):
     """Print a std::string."""
 
@@ -901,6 +921,7 @@ def __init__(self, name):
             "basic_string": StdStringPrinter,
             "string": StdStringPrinter,
             "string_view": StdStringViewPrinter,
+            "pair": StdPairPrinter,
             "tuple": StdTuplePrinter,
             "unique_ptr": StdUniquePtrPrinter,
             "shared_ptr": StdSharedPointerPrinter,

>From 1a49fb7e2eed4acc7dc137b069c98d1f70af711b Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 18 Jun 2026 15:28:28 -0400
Subject: [PATCH 2/4] Reword comment

---
 libcxx/utils/gdb/libcxx/printers.py | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py
index c345a076330cf..06867b9015555 100644
--- a/libcxx/utils/gdb/libcxx/printers.py
+++ b/libcxx/utils/gdb/libcxx/printers.py
@@ -186,14 +186,8 @@ def children(self):
 class StdPairPrinter(object):
     """Print a std::pair.
 
-    Print std::pair explicitly instead of relying on GDB's default struct
-    formatting. Some ABI configurations (e.g.
-    _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR, enabled by default on
-    FreeBSD) add an empty __non_trivially_copyable_base base class to
-    std::pair. GDB renders this implementation detail as
-    '<...__non_trivially_copyable_base<...>> = {<No data fields>}', which makes
-    the output ABI-dependent. Only 'first' and 'second' are meaningful, so
-    print just those members.
+    Note that we don't rely on GDB's default struct formatting so that we can
+    provide a stable output for std::pair regardless of libc++'s ABI configuration.
     """
 
     def __init__(self, val):

>From edebb9abe25c47a02d9a9bcc663a20388b65fe8c Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 18 Jun 2026 15:32:12 -0400
Subject: [PATCH 3/4] Add test

---
 .../test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
index 1fa7e5a5ceb7f..21f8ad3237379 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -41,6 +41,7 @@
 #include <tuple>
 #include <unordered_map>
 #include <unordered_set>
+#include <utility>
 
 #include "test_macros.h"
 
@@ -295,6 +296,18 @@ void tuple_test() {
       "empty std::tuple");
 }
 
+void pair_test() {
+  std::pair<int, int> ints(1, 2);
+  ComparePrettyPrintToChars(ints, "{first = 1, second = 2}");
+
+  std::pair<std::string, int> mixed("hello", 42);
+  ComparePrettyPrintToChars(mixed, "{first = \"hello\", second = 42}");
+
+  std::pair<int, std::pair<int, int>> nested(1, {2, 3});
+  ComparePrettyPrintToChars(nested,
+      "{first = 1, second = {first = 2, second = 3}}");
+}
+
 void unique_ptr_test() {
   std::unique_ptr<std::string> matilda(new std::string("Matilda"));
   ComparePrettyPrintToRegex(
@@ -747,6 +760,7 @@ int main(int, char**) {
   //u16string_test();
   u32string_test();
   tuple_test();
+  pair_test();
   unique_ptr_test();
   shared_ptr_test();
   bitset_test();

>From b39391cc239d8ba4b834b4df5e7d4ee3bf75a5b5 Mon Sep 17 00:00:00 2001
From: aokblast <aokblast at FreeBSD.org>
Date: Fri, 19 Jun 2026 09:56:51 -0400
Subject: [PATCH 4/4] fixup! Add test

---
 libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
index 21f8ad3237379..b720ef5218d1a 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -304,8 +304,7 @@ void pair_test() {
   ComparePrettyPrintToChars(mixed, "{first = \"hello\", second = 42}");
 
   std::pair<int, std::pair<int, int>> nested(1, {2, 3});
-  ComparePrettyPrintToChars(nested,
-      "{first = 1, second = {first = 2, second = 3}}");
+  ComparePrettyPrintToChars(nested, "{first = 1, second = {first = 2, second = 3}}");
 }
 
 void unique_ptr_test() {



More information about the libcxx-commits mailing list