Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 21:38 Tom Tromey,  wrote:

> Jonathan> I've pushed the changes I wanted to make, so you'll have to
> rebase
> Jonathan> your patches now, sorry.
>
> No problem.  I rebased & re-tested them.
> I can send a v2 if you want to double-check (only this large patch
> required any changes), or just go ahead.  Let me know.
>

Just go ahead, the changes are all straightforward so if the tests still
pass, you can push it.


I may not be able to push until Monday.
>
> Tom
>


Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Tom Tromey
Jonathan> I've pushed the changes I wanted to make, so you'll have to rebase
Jonathan> your patches now, sorry.

No problem.  I rebased & re-tested them.
I can send a v2 if you want to double-check (only this large patch
required any changes), or just go ahead.  Let me know.
I may not be able to push until Monday.

Tom


Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023 at 18:50, Tom Tromey via Libstdc++
 wrote:
>
> GDB 14 will add a new ValuePrinter tag class that will be used to
> signal that pretty-printers will agree to the "extension protocol" --
> essentially that they will follow some simple namespace rules, so that
> GDB can add new methods over time.
>
> A couple new methods have already been added to GDB, to support DAP.
> While I haven't implemented these for any libstdc++ printers yet, this
> patch makes the basic conversion: printers derive from
> gdb.ValuePrinter if it is available, and all "non-standard" (that is,
> not specified by GDB) members of the various value-printing classes
> are renamed to have a leading underscore.

OK, thanks.

I've pushed the changes I wanted to make, so you'll have to rebase
your patches now, sorry.


> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +-
>  1 file changed, 605 insertions(+), 596 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d60c8003a63..bbc4375541f 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -97,6 +97,12 @@ try:
>  except ImportError:
>  pass
>
> +# Use the base class if available.
> +if hasattr(gdb, 'ValuePrinter'):
> +printer_base = gdb.ValuePrinter
> +else:
> +printer_base = object
> +
>  # Starting with the type ORIG, search for the member type NAME.  This
>  # handles searching upward through superclasses.  This is needed to
>  # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
> @@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
>  "An iterator for smart pointer types with a single 'child' value"
>
>  def __init__(self, val):
> -self.val = val
> +self._val = val
>
>  def __iter__(self):
>  return self
>
>  def __next__(self):
> -if self.val is None:
> +if self._val is None:
>  raise StopIteration
> -self.val, val = None, self.val
> +self._val, val = None, self._val
>  return ('get()', val)
>
>
> -class SharedPointerPrinter:
> +class SharedPointerPrinter(printer_base):
>  "Print a shared_ptr, weak_ptr, atomic, or atomic"
>
>  def __init__(self, typename, val):
> -self.typename = strip_versioned_namespace(typename)
> -self.val = val
> -self.pointer = val['_M_ptr']
> +self._typename = strip_versioned_namespace(typename)
> +self._val = val
> +self._pointer = val['_M_ptr']
>
>  def children(self):
> -return SmartPtrIterator(self.pointer)
> +return SmartPtrIterator(self._pointer)
>
>  # Return the _Sp_counted_base<>* that holds the refcounts.
>  def _get_refcounts(self):
> -if self.typename == 'std::atomic':
> +if self._typename == 'std::atomic':
>  # A tagged pointer is stored as uintptr_t.
> -ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
> +ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
>  ptr_val = ptr_val - (ptr_val % 2)  # clear lock bit
> -ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
> +ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
>  return ptr_val.cast(ptr_type)
> -return self.val['_M_refcount']['_M_pi']
> +return self._val['_M_refcount']['_M_pi']
>
>  def to_string(self):
>  state = 'empty'
>  refcounts = self._get_refcounts()
> -targ = self.val.type.template_argument(0)
> +targ = self._val.type.template_argument(0)
>  targ = strip_versioned_namespace(str(targ))
>
>  if refcounts != 0:
> @@ -288,7 +294,7 @@ class SharedPointerPrinter:
>  else:
>  state = 'use count %d, weak count %d' % (
>  usecount, weakcount - 1)
> -return '%s<%s> (%s)' % (self.typename, targ, state)
> +return '%s<%s> (%s)' % (self._typename, targ, state)
>
>
>  def _tuple_impl_get(val):
> @@ -347,17 +353,17 @@ def unique_ptr_get(val):
>  return tuple_get(0, tuple_member)
>
>
> -class UniquePointerPrinter:
> +class UniquePointerPrinter(printer_base):
>  "Print a unique_ptr"
>
>  def __init__(self, typename, val):
> -self.val = val
> +self._val = val
>
>  def children(self):
> -return SmartPtrIterator(unique_ptr_get(self.val))
> +return SmartPtrIterator(unique_ptr_get(self._val))
>
>  def to_string(self):
> -return ('std::unique_ptr<%s>' % 
> (str(self.val.type.template_argument(0
> +return ('std::unique_ptr<%s>' % 
> (str(self._val.type.template_argument(0
>
>
>  def get_value_from_aligned_membuf(buf, valtype):
> @@ -381,55 +387,56 @@ def get_value_from_list_node(node):
>  raise ValueError("Unsupported implementation for %s" % str(node.type))
>
>
> -class StdListPrinter:

[PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Tom Tromey
GDB 14 will add a new ValuePrinter tag class that will be used to
signal that pretty-printers will agree to the "extension protocol" --
essentially that they will follow some simple namespace rules, so that
GDB can add new methods over time.

A couple new methods have already been added to GDB, to support DAP.
While I haven't implemented these for any libstdc++ printers yet, this
patch makes the basic conversion: printers derive from
gdb.ValuePrinter if it is available, and all "non-standard" (that is,
not specified by GDB) members of the various value-printing classes
are renamed to have a leading underscore.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +-
 1 file changed, 605 insertions(+), 596 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d60c8003a63..bbc4375541f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -97,6 +97,12 @@ try:
 except ImportError:
 pass
 
+# Use the base class if available.
+if hasattr(gdb, 'ValuePrinter'):
+printer_base = gdb.ValuePrinter
+else:
+printer_base = object
+
 # Starting with the type ORIG, search for the member type NAME.  This
 # handles searching upward through superclasses.  This is needed to
 # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
@@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
 "An iterator for smart pointer types with a single 'child' value"
 
 def __init__(self, val):
-self.val = val
+self._val = val
 
 def __iter__(self):
 return self
 
 def __next__(self):
-if self.val is None:
+if self._val is None:
 raise StopIteration
-self.val, val = None, self.val
+self._val, val = None, self._val
 return ('get()', val)
 
 
-class SharedPointerPrinter:
+class SharedPointerPrinter(printer_base):
 "Print a shared_ptr, weak_ptr, atomic, or atomic"
 
 def __init__(self, typename, val):
-self.typename = strip_versioned_namespace(typename)
-self.val = val
-self.pointer = val['_M_ptr']
+self._typename = strip_versioned_namespace(typename)
+self._val = val
+self._pointer = val['_M_ptr']
 
 def children(self):
-return SmartPtrIterator(self.pointer)
+return SmartPtrIterator(self._pointer)
 
 # Return the _Sp_counted_base<>* that holds the refcounts.
 def _get_refcounts(self):
-if self.typename == 'std::atomic':
+if self._typename == 'std::atomic':
 # A tagged pointer is stored as uintptr_t.
-ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
+ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
 ptr_val = ptr_val - (ptr_val % 2)  # clear lock bit
-ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
+ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
 return ptr_val.cast(ptr_type)
-return self.val['_M_refcount']['_M_pi']
+return self._val['_M_refcount']['_M_pi']
 
 def to_string(self):
 state = 'empty'
 refcounts = self._get_refcounts()
-targ = self.val.type.template_argument(0)
+targ = self._val.type.template_argument(0)
 targ = strip_versioned_namespace(str(targ))
 
 if refcounts != 0:
@@ -288,7 +294,7 @@ class SharedPointerPrinter:
 else:
 state = 'use count %d, weak count %d' % (
 usecount, weakcount - 1)
-return '%s<%s> (%s)' % (self.typename, targ, state)
+return '%s<%s> (%s)' % (self._typename, targ, state)
 
 
 def _tuple_impl_get(val):
@@ -347,17 +353,17 @@ def unique_ptr_get(val):
 return tuple_get(0, tuple_member)
 
 
-class UniquePointerPrinter:
+class UniquePointerPrinter(printer_base):
 "Print a unique_ptr"
 
 def __init__(self, typename, val):
-self.val = val
+self._val = val
 
 def children(self):
-return SmartPtrIterator(unique_ptr_get(self.val))
+return SmartPtrIterator(unique_ptr_get(self._val))
 
 def to_string(self):
-return ('std::unique_ptr<%s>' % 
(str(self.val.type.template_argument(0
+return ('std::unique_ptr<%s>' % 
(str(self._val.type.template_argument(0
 
 
 def get_value_from_aligned_membuf(buf, valtype):
@@ -381,55 +387,56 @@ def get_value_from_list_node(node):
 raise ValueError("Unsupported implementation for %s" % str(node.type))
 
 
-class StdListPrinter:
+class StdListPrinter(printer_base):
 "Print a std::list"
 
 class _iterator(Iterator):
 def __init__(self, nodetype, head):
-self.nodetype = nodetype
-self.base = head['_M_next']
-self.head = head.address
-self.count = 0
+self._nodetype = nodetype
+self._base = head['_M_next']
+self