This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improved pretty printing for smart pointers


Hello *,

I found the pretty printers for std::shared_ptr, std::weak_ptr and std::unique_ptr (as provided by svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python) not sufficient for daily use as they only generate a description (including the address of the pointee) but do not pretty print the pointee itself. This behaviour implies that one has to copy the address of the pointee, cast it to the pointee's type, and dereference the result. To improve on the current state of affairs, I improved the pretty printers to generate children. For std::shared_ptr and std::weak_ptr, three children are generated, namely "Use count", "Weak count", and "Managed value". For std::unique_ptr, one child is generated, namely "Managed value". Using this solution with an IDE like kdevelop or Eclipse CTD, it only needs two clicks to see the value managed by a smart pointer.

I attached my patch in the hope that you will find it interesting and that it will be integrated into your suite of GCC STL pretty printers.

Best regards,
Michael Marte




Index: libstdcxx/v6/printers.py
===================================================================
--- libstdcxx/v6/printers.py	(revision 197410)
+++ libstdcxx/v6/printers.py	(working copy)
@@ -57,10 +57,35 @@
 class SharedPointerPrinter:
     "Print a shared_ptr or weak_ptr"
 
+    class _iterator:
+        def __init__(self, sharedPointer):
+            self.sharedPointer = sharedPointer
+            self.managedValue = sharedPointer.val['_M_ptr']
+            self.count = 0
+
+        def __iter__(self):
+            return self
+
+        def next(self):
+            if self.managedValue == 0:
+                raise StopIteration
+            self.count = self.count + 1
+            if (self.count == 1):
+                return ('Use count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_use_count'])
+            elif (self.count == 2):
+                return ('Weak count', self.sharedPointer.val['_M_refcount']['_M_pi']['_M_weak_count'] - 1)
+            elif (self.count == 3):
+                return ('Managed value', self.managedValue)
+            else:
+                raise StopIteration
+
     def __init__ (self, typename, val):
         self.typename = typename
         self.val = val
 
+    def children (self):
+        return self._iterator(self)
+
     def to_string (self):
         state = 'empty'
         refcounts = self.val['_M_refcount']['_M_pi']
@@ -68,17 +93,35 @@
             usecount = refcounts['_M_use_count']
             weakcount = refcounts['_M_weak_count']
             if usecount == 0:
-                state = 'expired, weak %d' % weakcount
+                state = 'expired, weakcount %d' % weakcount
             else:
-                state = 'count %d, weak %d' % (usecount, weakcount - 1)
-        return '%s (%s) %s' % (self.typename, state, self.val['_M_ptr'])
+                state = 'usecount %d, weakcount %d' % (usecount, weakcount - 1)
+        return '%s (%s) to %s' % (self.typename, state, self.val['_M_ptr'])
 
 class UniquePointerPrinter:
     "Print a unique_ptr"
 
+    class _iterator:
+        def __init__(self, uniquePointer):
+            self.uniquePointer = uniquePointer
+            self.managedValue = uniquePointer.val['_M_t']['_M_head_impl']
+            self.count = 0
+
+        def __iter__(self):
+            return self
+
+        def next(self):
+            if self.managedValue == 0 or self.count == 1:
+                raise StopIteration
+            self.count = self.count + 1
+            return ('Managed value', self.managedValue)
+
     def __init__ (self, typename, val):
         self.val = val
 
+    def children (self):
+        return self._iterator(self)
+
     def to_string (self):
         v = self.val['_M_t']['_M_head_impl']
         return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]