This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[python][patch] Attempt to use Python pretty-printers on base classesof a derived class (where no Python pretty-printer exists for that derivedclass).
- From: Phil Muldoon <pmuldoon at redhat dot com>
- To: Project Archer <archer at sourceware dot org>
- Date: Thu, 02 Apr 2009 13:35:54 +0100
- Subject: [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