This is the mail archive of the archer@sourceware.org mailing list for the Archer 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]

[python][patch] Attempt to use Python pretty-printers on base classesof a derived class (where no Python pretty-printer exists for that derivedclass).


(Sorry for the long subject, but my inner muse has been obliterated by tcl.)

This message is a follow-on from: http://sourceware.org/ml/archer/2009-q1/msg00421.html ([python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class)

This is a new patch, and replaces the previous patch. However the background generated by the thread is relevant.

This patches introduces a small new C++ class "handling" behaviour to the Python pretty-printers. In the existing case, if a search for a Python pretty-printer fails, and there is no printer available for a C++ class, the existing (non-Python) GDB printers then take over. However following on from this case, if that C++ class is a derived class, GDB will print out the base classes as well. In the existing code, there is no window for the Python pretty-printers to be searched and determine if there is a printer for the base classes as GDB parses through them. This patch modifies that behaviour to expose the Python pretty-printers when base class information is parsed.

Here is a an example from the test-case.

Classes:

class VirtualTest { private: int value = 1; };
class Vbase1 : public virtual VirtualTest { };
class Vbase2 : public virtual VirtualTest { };
class Vbase3 : public virtual VirtualTest { };
class Derived : public Vbase1, public Vbase2, public Vbase3 { private: int value = 2; };


In this example, there are Python pretty-printers registered for the base classes: "VirtualTest" and "Vbase1". There is no printer registered for the "Derived" class.

Given the output below, the test is testing:

- That the Python pretty-printers are being searched, and if appropriate, invoked for base class pretty-printing.
- That Base classes (in this case VirtualTest) are only printed once even when printed with a Python pretty-printer.
- That the existence of a pretty-printer for one (but not all) of the virtual base-classes does not confuse the rule about only printing the base class once.


print derived
$11 = {
<Vbase1> = pp class name: Vbase1, <-- Vbase1 pretty-printer.
<Vbase2> = {
<VirtualTest> = pp value variable is: 1, <-- Base class pretty-printer
members of Vbase2:
_vptr.Vbase2 = 0x400b50
},
<Vbase3> = {
members of Vbase3: <-- Did not reprint VirtualTest
_vptr.Vbase3 = 0x400b68
},
members of Derived:
value = 2
}



ChangeLog:


2009-04-02 Phil Muldoon <pmuldoon@redhat.com>

   * cp-valprint.c (cp_print_value): Attempt to execute
   Python pretty-printers on base class elements.

Testsuite ChangeLog:

2009-04-02 Phil Muldoon <pmuldoon@redhat.com>

   * gdb.python/python-prettyprint.exp (run_lang_tests): Add test for
   base class printing in a derived class.
   * gdb.python/python-prettyprint.c (Vbase1, Vbase2, Vbase3)
   (Derived. VirtualTest): New test classes.
   * gdb.python/python-prettyprint.py (pp_multiple_virtual)
   (pp_vbase1): New pretty-printers.
   (register_pretty_printers): Register pp_vbase1, pp_multiple_virtual.

Regards

Phil
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index a96a81a..4ab3596 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -36,6 +36,7 @@
 #include "valprint.h"
 #include "cp-support.h"
 #include "language.h"
+#include "python/python.h"
 
 /* Controls printing of vtbl's */
 static void
@@ -418,12 +419,27 @@ cp_print_value (struct type *type, struct type *real_type,
       if (skip >= 1)
 	fprintf_filtered (stream, "<invalid address>");
       else
-	cp_print_value_fields (baseclass, thistype, base_valaddr,
-			       thisoffset + boffset, address + boffset,
-			       stream, recurse, options,
-			       ((struct type **)
-				obstack_base (&dont_print_vb_obstack)),
-			       0);
+	{
+	  int result = 0;
+
+	  /* Attempt to run the Python pretty-printers on the
+	  baseclass if possible.  */
+	  if (!options->raw)
+	    result = apply_val_pretty_printer (baseclass, base_valaddr,
+					       thisoffset + boffset,
+					       address + boffset,
+					       stream, recurse,
+					       options,
+					       current_language);
+	  	  
+	  if (!result)
+	    cp_print_value_fields (baseclass, thistype, base_valaddr,
+				   thisoffset + boffset, address + boffset,
+				   stream, recurse, options,
+				   ((struct type **)
+				    obstack_base (&dont_print_vb_obstack)),
+				   0);
+	}
       fputs_filtered (", ", stream);
 
     flush_it:
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c
index f8c2435..399be23 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.c
+++ b/gdb/testsuite/gdb.python/python-prettyprint.c
@@ -1,6 +1,6 @@
 /* This testcase is part of GDB, the GNU debugger.
 
-   Copyright 2008 Free Software Foundation, Inc.
+   Copyright 2008, 2009 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -44,6 +44,35 @@ struct SSS
   const S &b;
 };
 SSS::SSS (int x, const S& r) : a(x), b(r) { }
+
+class VirtualTest 
+{ 
+ private: 
+  int value; 
+
+ public: 
+  VirtualTest () 
+    { 
+      value = 1;
+    } 
+};
+
+class Vbase1 : public virtual VirtualTest { };
+class Vbase2 : public virtual VirtualTest { };
+class Vbase3 : public virtual VirtualTest { };
+
+class Derived : public Vbase1, public Vbase2, public Vbase3
+{ 
+ private: 
+  int value; 
+  
+ public:
+  Derived () 
+    { 
+      value = 2; 
+    }
+};
+
 #endif
 
 typedef struct string_repr
@@ -146,6 +175,9 @@ main ()
   SSS sss(15, cps);
 
   SSS& ref (sss);
+
+  Derived derived;
+  
 #endif
 
   add_item (&c, 23);		/* MI breakpoint here */
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.exp b/gdb/testsuite/gdb.python/python-prettyprint.exp
index b2ccb2b..f83b1cd 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/python-prettyprint.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -76,6 +76,8 @@ proc run_lang_tests {lang} {
 	gdb_test "print cpssa" " = {{$nl *zss = 11, *$nl *s =  a=<12> b=<$hex>$nl *}, {$nl *zss = 13, *$nl *s =  a=<14> b=<$hex>$nl *}}"
 	gdb_test "print sss" "= a=<15> b=< a=<8> b=<$hex>>"
 	gdb_test "print ref" "= a=<15> b=< a=<8> b=<$hex>>"
+	gdb_test "print derived" \
+	    " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
     }
 
     gdb_test "print x" " = $hex \"this is x\""
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index e032303..367baa9 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -78,6 +78,20 @@ class pp_sss:
     def to_string(self):
         return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">"
 
+class pp_multiple_virtual:
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "pp value variable is: " + str (self.val['value'])
+
+class pp_vbase1:
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "pp class name: " + self.val.type ().tag ()
+
 def lookup_function (val):
     "Look-up and return a pretty-printer that can print val."
 
@@ -119,6 +133,9 @@ def register_pretty_printers ():
     pretty_printers_dict[re.compile ('^const S &$')]   = pp_s
     pretty_printers_dict[re.compile ('^SSS$')]  = pp_sss
     
+    pretty_printers_dict[re.compile ('^VirtualTest$')] =  pp_multiple_virtual
+    pretty_printers_dict[re.compile ('^Vbase1$')] =  pp_vbase1
+    
     # Note that we purposely omit the typedef names here.
     # Printer lookup is based on canonical name.
     # However, we do need both tagged and untagged variants, to handle

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