Patchwork [v3] libstdc++/51956 improve pretty printers for shared_ptr and weak_ptr

login
register
mail settings
Submitter Jonathan Wakely
Date Feb. 5, 2012, 7:10 p.m.
Message ID <CAH6eHdRgyniYuaZABC4LyYakLWiD7UnfWtkkqZiWdgkCvQY6=A@mail.gmail.com>
Download mbox | patch
Permalink /patch/139659/
State New
Headers show

Comments

Jonathan Wakely - Feb. 5, 2012, 7:10 p.m.
PR libstdc++/51956
        * python/libstdcxx/v6/printers.py (StdPointerPrinter): Rename to...
        (SharedPointerPrinter): This. Also show weak count.
        * testsuite/libstdc++-prettyprinters/shared_ptr.cc: New.

tested x86_64-linux, committed to trunk.

Patch

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 4f34733..f47da61 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -45,19 +45,24 @@  def find_type(orig, name):
             raise ValueError, "Cannot find type %s::%s" % (str(orig), name)
         typ = field.type
 
-class StdPointerPrinter:
-    "Print a smart pointer of some kind"
+class SharedPointerPrinter:
+    "Print a shared_ptr or weak_ptr"
 
     def __init__ (self, typename, val):
         self.typename = typename
         self.val = val
 
     def to_string (self):
-        if self.val['_M_refcount']['_M_pi'] == 0:
-            return '%s (empty) %s' % (self.typename, self.val['_M_ptr'])
-        return '%s (count %d) %s' % (self.typename,
-                                     self.val['_M_refcount']['_M_pi']['_M_use_count'],
-                                     self.val['_M_ptr'])
+        state = 'empty'
+        refcounts = self.val['_M_refcount']['_M_pi']
+        if refcounts != 0:
+            usecount = refcounts['_M_use_count']
+            weakcount = refcounts['_M_weak_count']
+            if usecount == 0:
+                state = 'expired, weak %d' % weakcount
+            else:
+                state = 'count %d, weak %d' % (usecount, weakcount - 1)
+        return '%s (%s) %s' % (self.typename, state, self.val['_M_ptr'])
 
 class UniquePointerPrinter:
     "Print a unique_ptr"
@@ -862,8 +867,8 @@  def build_libstdcxx_dictionary ():
 
     # These are the TR1 and C++0x printers.
     # For array - the default GDB pretty-printer seems reasonable.
-    libstdcxx_printer.add_version('std::', 'shared_ptr', StdPointerPrinter)
-    libstdcxx_printer.add_version('std::', 'weak_ptr', StdPointerPrinter)
+    libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
+    libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter)
     libstdcxx_printer.add_container('std::', 'unordered_map',
                                     Tr1UnorderedMapPrinter)
     libstdcxx_printer.add_container('std::', 'unordered_set',
@@ -875,8 +880,8 @@  def build_libstdcxx_dictionary ():
     libstdcxx_printer.add_container('std::', 'forward_list',
                                     StdForwardListPrinter)
 
-    libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', StdPointerPrinter)
-    libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', StdPointerPrinter)
+    libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter)
+    libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter)
     libstdcxx_printer.add_version('std::tr1::', 'unordered_map',
                                   Tr1UnorderedMapPrinter)
     libstdcxx_printer.add_version('std::tr1::', 'unordered_set',
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
new file mode 100644
index 0000000..9328c5f9
--- /dev/null
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
@@ -0,0 +1,83 @@ 
+// { dg-do run }
+// { dg-options "-std=gnu++11 -g" }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <memory>
+#include <iostream>
+
+template<class T>
+void
+placeholder(const T &s)
+{
+  std::cout << s;
+}
+
+template<class T>
+void
+use(const T &p)
+{
+  placeholder(&p);
+}
+
+struct deleter { void operator()(int*) {} };
+
+std::shared_ptr<int> make(uintptr_t p)
+{
+  return std::shared_ptr<int>(reinterpret_cast<int*>(p), deleter());
+}
+
+int
+main()
+{
+  typedef std::shared_ptr<int> shared;
+  typedef std::weak_ptr<int> weak;
+
+  shared esp;
+// { dg-final { note-test esp "std::shared_ptr (empty) 0x0" } }
+  weak ewp1;
+// { dg-final { note-test ewp1 "std::weak_ptr (empty) 0x0" } }
+  weak ewp2 = esp;
+// { dg-final { note-test ewp2 "std::weak_ptr (empty) 0x0" } }
+
+  shared sp1 = make(0x12345678);
+  shared sp2 = sp1;
+// { dg-final { note-test sp1 "std::shared_ptr (count 2, weak 0) 0x12345678" } }
+
+  shared sp3 = make(0x12344321);
+  weak sp4 = sp3;
+  weak wp1 = sp3;
+// { dg-final { note-test wp1 "std::weak_ptr (count 1, weak 2) 0x12344321" } }
+
+  shared sp5 = make(0x56788765);
+  weak wp2 = sp5;
+  sp5.reset();
+// { dg-final { note-test wp2 "std::weak_ptr (expired, weak 1) 0x56788765" } }
+
+  placeholder(""); // Mark SPOT
+  use(esp);
+  use(ewp1);
+  use(ewp2);
+  use(sp1);
+  use(wp1);
+  use(wp2);
+
+  return 0;
+}
+
+// { dg-final { gdb-test SPOT } }