* [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
@ 2009-03-27 17:05 Phil Muldoon
2009-03-27 17:34 ` Tom Tromey
2009-03-27 17:43 ` Pedro Alves
0 siblings, 2 replies; 14+ messages in thread
From: Phil Muldoon @ 2009-03-27 17:05 UTC (permalink / raw)
To: Project Archer
[-- Attachment #1: Type: text/plain, Size: 832 bytes --]
The bug is detailed here:
http://sourceware.org/bugzilla/show_bug.cgi?id=10008
In summary, given this class:
class Y : public std::tr1::unordered_map<int, char *>
{
public:
Y()
{
}
};
Any Python pretty-printers that have been written and registered to
print std::tr1::unordered_map will not work on Y. But there is no
reason, given the lack of a more specialized printer for Y, why the
printer for unordered_map should not print the parts of Y it can
accurately print. This patch attempts to find a base class printer if a
specialized printer does not exist for the class in question.
Built and tested on x8664, with no regressions.
Phil
2009-03-27 Phil Muldoon <pmuldoon@redhat.com>
* cp-valprint.c (cp_print_value_fields): Attempt to run
apply_val_pretty_print on the baseclass of a class.
[-- Attachment #2: derived_class.patch --]
[-- Type: text/x-patch, Size: 1376 bytes --]
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index a96a81a..efc13e5 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
@@ -155,16 +156,33 @@ cp_print_value_fields (struct type *type, struct type *real_type,
int i, len, n_baseclasses;
char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
int fields_seen = 0;
+ int result = 0;
+ struct type *baseclass;
CHECK_TYPEDEF (type);
- fprintf_filtered (stream, "{");
len = TYPE_NFIELDS (type);
n_baseclasses = TYPE_N_BASECLASSES (type);
+ /* Attempt to run the Python pretty-printers on the base class of
+ the derived class. */
+ if (!options->raw)
+ if (n_baseclasses > 0)
+ {
+
+ baseclass = check_typedef (TYPE_BASECLASS (type,0));
+ result = apply_val_pretty_printer (baseclass, valaddr, offset,
+ address, stream, recurse, options,
+ current_language);
+
+ if (result)
+ return;
+ }
+
/* First, print out baseclasses such that we don't print
duplicates of virtual baseclasses. */
+ fprintf_filtered (stream, "{");
if (n_baseclasses > 0)
cp_print_value (type, real_type, valaddr, offset, address, stream,
recurse + 1, options, dont_print_vb);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:05 [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class Phil Muldoon
@ 2009-03-27 17:34 ` Tom Tromey
2009-03-27 17:43 ` Phil Muldoon
2009-03-27 17:46 ` Paul Pluzhnikov
2009-03-27 17:43 ` Pedro Alves
1 sibling, 2 replies; 14+ messages in thread
From: Tom Tromey @ 2009-03-27 17:34 UTC (permalink / raw)
To: Phil Muldoon; +Cc: Project Archer
>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
Looking pretty good :)
Phil> + /* Attempt to run the Python pretty-printers on the base class of
Phil> + the derived class. */
The second line here needs more indentation.
"the" should line up with "Attempt".
Also you need an extra space after the period.
Silly nit-picking... :)
Phil> + if (!options->raw)
Phil> + if (n_baseclasses > 0)
Phil> + {
Phil> +
Declare baseclass and result here, not at the top of the function.
Phil> /* First, print out baseclasses such that we don't print
Phil> duplicates of virtual baseclasses. */
Does this logic continue to work properly if one of the virtual
baseclasses has a pretty-printer?
Please write a couple test cases for this functionality.
thanks,
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:34 ` Tom Tromey
@ 2009-03-27 17:43 ` Phil Muldoon
2009-03-27 17:47 ` Tom Tromey
2009-03-27 17:46 ` Paul Pluzhnikov
1 sibling, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2009-03-27 17:43 UTC (permalink / raw)
To: Tom Tromey; +Cc: Project Archer
Tom Tromey wrote:
> Looking pretty good :)
>
> Phil> + /* Attempt to run the Python pretty-printers on the base class of
> Phil> + the derived class. */
>
> The second line here needs more indentation.
> "the" should line up with "Attempt".
> Also you need an extra space after the period.
>
> Silly nit-picking... :)
>
Thanks.
> Phil> + if (!options->raw)
> Phil> + if (n_baseclasses > 0)
> Phil> + {
> Phil> +
>
> Declare baseclass and result here, not at the top of the function.
>
You know I just moved it from here, I guess I'll move it back ;)
> Phil> /* First, print out baseclasses such that we don't print
> Phil> duplicates of virtual baseclasses. */
>
> Does this logic continue to work properly if one of the virtual
> baseclasses has a pretty-printer?
>
It works in so much as this is a "do or continue with the old logic";
the existing Python pretty-printers would handle these if they were
called, no?
(I might misunderstand your question)
But good point it needs a test ...
> Please write a couple test cases for this functionality.
>
Yeah this is not a full patch (though looking at it, it does look like
one). It's mainly a request for comments and a methodology sanity check
;) I was thinking of a documentation patch in the narrative regarding
printer selection too. But is this just going to be superfluous to the
reader?
Regards
Phil
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:05 [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class Phil Muldoon
2009-03-27 17:34 ` Tom Tromey
@ 2009-03-27 17:43 ` Pedro Alves
2009-03-27 17:50 ` Tom Tromey
1 sibling, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2009-03-27 17:43 UTC (permalink / raw)
To: archer; +Cc: Phil Muldoon
On Friday 27 March 2009 17:04:48, Phil Muldoon wrote:
> The bug is detailed here:
> http://sourceware.org/bugzilla/show_bug.cgi?id=10008
>
> In summary, given this class:
>
> class Y : public std::tr1::unordered_map<int, char *>
> {
> public:
> Y()
> {
> }
> };
>
> Any Python pretty-printers that have been written and registered to
> print std::tr1::unordered_map will not work on Y. But there is no
> reason, given the lack of a more specialized printer for Y, why the
> printer for unordered_map should not print the parts of Y it can
> accurately print. This patch attempts to find a base class printer if a
> specialized printer does not exist for the class in question.
I don't know a thing about python pretty-printing, so excuse any
silly questions, but, anyway...
Does this do sensible things if class Y has some
fields that mask the Base class's ones, when you only have a
pretty printer for Base? Say:
class Base
{
public:
int x;
};
class Y : public Base
{
public:
int x;
};
What about private inheritance, sometimes used as an implementation
detail, but not representing an is-a relationship?
class Y : private Base
{
public:
Y ();
// My API that has nothing to do with Base.
// my own data members
};
--
Pedro Alves
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:34 ` Tom Tromey
2009-03-27 17:43 ` Phil Muldoon
@ 2009-03-27 17:46 ` Paul Pluzhnikov
2009-03-27 18:00 ` Tom Tromey
2009-03-27 18:28 ` Phil Muldoon
1 sibling, 2 replies; 14+ messages in thread
From: Paul Pluzhnikov @ 2009-03-27 17:46 UTC (permalink / raw)
To: Tom Tromey; +Cc: Phil Muldoon, Project Archer
On Fri, Mar 27, 2009 at 10:34 AM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
>
> Looking pretty good :)
>
> Phil> + /* Attempt to run the Python pretty-printers on the base class of
> Phil> + the derived class. */
I can't tell whether the patch would work for 'class X: public Y ...'
Also, here is an earlier thread on the same subject:
http://sourceware.org/ml/archer/2008-q4/msg00503.html
--
Paul Pluzhnikov
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:43 ` Phil Muldoon
@ 2009-03-27 17:47 ` Tom Tromey
0 siblings, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2009-03-27 17:47 UTC (permalink / raw)
To: Phil Muldoon; +Cc: Project Archer
>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
Phil> It works in so much as this is a "do or continue with the old logic";
Phil> the existing Python pretty-printers would handle these if they were
Phil> called, no?
My understanding of the current code is that if you have a repeated
virtual base class, it will only be printed once.
So, the test case here would be to have a pretty-printer for the
virtual base -- then, make sure that it is only invoked a single time.
Phil> I was thinking of a documentation patch in the narrative
Phil> regarding printer selection too. But is this just going to be
Phil> superfluous to the reader?
My first reaction is that we don't need a documentation update for
this. It is just a simple extension of the generic logic to a
different case of printing -- this change is a technical one, related
to the implementation, not really a different use.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:43 ` Pedro Alves
@ 2009-03-27 17:50 ` Tom Tromey
2009-03-27 18:05 ` Phil Muldoon
2009-03-27 18:05 ` Pedro Alves
0 siblings, 2 replies; 14+ messages in thread
From: Tom Tromey @ 2009-03-27 17:50 UTC (permalink / raw)
To: Pedro Alves; +Cc: archer, Phil Muldoon
>>>>> "Pedro" == Pedro Alves <alves.ped@gmail.com> writes:
Pedro> Does this do sensible things if class Y has some
Pedro> fields that mask the Base class's ones, when you only have a
Pedro> pretty printer for Base?
Yeah... it pretty-prints Base, then goes on to print the subclass
fields as usual (perhaps pretty-printing them as well).
Phil, could you post the before- and after- results of your example?
I think that would clear things up.
Pedro> What about private inheritance, sometimes used as an implementation
Pedro> detail, but not representing an is-a relationship?
This will also work; the code doesn't consider access flags.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:46 ` Paul Pluzhnikov
@ 2009-03-27 18:00 ` Tom Tromey
2009-03-27 18:28 ` Phil Muldoon
1 sibling, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2009-03-27 18:00 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: Phil Muldoon, Project Archer
>>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes:
Paul> I can't tell whether the patch would work for 'class X: public Y ...'
It will.
gdb today has some special code for printing C++ classes. This code
first recurses into base classes, then prints the derived class' fields.
What Phil's patch does is hook into this to try to pretty-print a base
class. So, it should apply generally.
Paul> Also, here is an earlier thread on the same subject:
Paul> http://sourceware.org/ml/archer/2008-q4/msg00503.html
Now that pretty-printers are not registered by type, I think the patch
in this thread won't work as-is. A given printer can still be made
completely generic, though, if that is what you want; it just has to
look at the base classes itself.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:50 ` Tom Tromey
@ 2009-03-27 18:05 ` Phil Muldoon
2009-03-27 18:05 ` Pedro Alves
1 sibling, 0 replies; 14+ messages in thread
From: Phil Muldoon @ 2009-03-27 18:05 UTC (permalink / raw)
To: Tom Tromey; +Cc: Pedro Alves, archer, Paul Pluzhnikov
[-- Attachment #1: Type: text/plain, Size: 1396 bytes --]
Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <alves.ped@gmail.com> writes:
>>>>>>
>
> Pedro> Does this do sensible things if class Y has some
> Pedro> fields that mask the Base class's ones, when you only have a
> Pedro> pretty printer for Base?
>
> Yeah... it pretty-prints Base, then goes on to print the subclass
> fields as usual (perhaps pretty-printing them as well).
>
> Phil, could you post the before- and after- results of your example?
> I think that would clear things up.
>
Here (attached) is a file I was using today to test some scenarios. They
do not directly address Pedro's questions (I think your explanation
does). But they do address on of Paul's.
[pmuldoon@localhost gdb]$ ./gdb ~/derived
(pg-gdb) b 45
Reading in symbols for /home/pmuldoon/derived.cpp...
Breakpoint 1 at 0x400b40: file /home/pmuldoon/derived.cpp, line 45.
(pg-gdb) python import gdb.libstdcxx.v6.printers
(pg-gdb) r
Breakpoint 1, main () at /home/pmuldoon/derived.cpp:45
45 return 0;
(pg-gdb) info locals
map = std::map with 1 elements = {
[0x40363d "one"] = 1
}
uomap = std::tr1::unordered_map with 1 elements = {
[21] = 0x403645 "twenty one"
}
nest = {
<Z> = std::map with 1 elements = {
[0x403650 "twenty-two"] = 22
},
members of X:
map = std::tr1::unordered_map with 1 elements = {
[23] = 0x403638 "test"
},
i = 0
}
base = std::map with 1 elements = {
[0x403641 "two"] = 2
}
[-- Attachment #2: derived.cpp --]
[-- Type: text/x-c++src, Size: 489 bytes --]
#include <map>
#include <tr1/unordered_map>
class Y : public std::tr1::unordered_map<int, char *>
{
public:
Y()
{
}
};
class Z : public std::map<const char *, int>
{
public:
Z()
{
}
};
class X : public Z
{
public:
Y map;
int i;
X ()
{
i=0;
map[23] = "test";
}
};
int main()
{
Z map;
Y uomap;
X nest;
std::map<const char *, int> base;
map["one"] = 1;
base["two"] = 2;
uomap[21] = "twenty one";
nest["twenty-two"] = 22;
return 0;
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:50 ` Tom Tromey
2009-03-27 18:05 ` Phil Muldoon
@ 2009-03-27 18:05 ` Pedro Alves
2009-03-27 18:36 ` Tom Tromey
2009-03-27 19:08 ` Phil Muldoon
1 sibling, 2 replies; 14+ messages in thread
From: Pedro Alves @ 2009-03-27 18:05 UTC (permalink / raw)
To: archer, Tom Tromey; +Cc: Phil Muldoon
On Friday 27 March 2009 17:50:39, Tom Tromey wrote:
> Pedro> Does this do sensible things if class Y has some
> Pedro> fields that mask the Base class's ones, when you only have a
> Pedro> pretty printer for Base?
>
> Yeah... it pretty-prints Base, then goes on to print the subclass
> fields as usual (perhaps pretty-printing them as well).
Okay, I was concerned if the pretty printer for Base would
access Y::x instead of Base::x.
--
Pedro Alves
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 17:46 ` Paul Pluzhnikov
2009-03-27 18:00 ` Tom Tromey
@ 2009-03-27 18:28 ` Phil Muldoon
1 sibling, 0 replies; 14+ messages in thread
From: Phil Muldoon @ 2009-03-27 18:28 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: Tom Tromey, Project Archer
Paul Pluzhnikov wrote:
> On Fri, Mar 27, 2009 at 10:34 AM, Tom Tromey <tromey@redhat.com> wrote:
>
>>>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:
>>>>>>>
>> Looking pretty good :)
>>
>> Phil> + /* Attempt to run the Python pretty-printers on the base class of
>> Phil> + the derived class. */
>>
>
> I can't tell whether the patch would work for 'class X: public Y ...'
>
It will. I really should have appended my working examples, but decided
not too. I know better next time ;)
> Also, here is an earlier thread on the same subject:
> http://sourceware.org/ml/archer/2008-q4/msg00503.html
>
>
I've nothing really to add to what Tom already mentioned. But as
printer selection criteria for a value is now pretty much deferred to
the printers themselves, the circumstances discussed in that thread
changed. In this case it was just easier to add a last-chance effort in
the c++ class GDB printer itself. You can always write a base-class
test which is more specialized in the Python printer by mining the
fields for base classes.
Regards
Phil
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 18:05 ` Pedro Alves
@ 2009-03-27 18:36 ` Tom Tromey
2009-03-27 19:08 ` Phil Muldoon
1 sibling, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2009-03-27 18:36 UTC (permalink / raw)
To: Pedro Alves; +Cc: archer, Phil Muldoon
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
Pedro> Okay, I was concerned if the pretty printer for Base would
Pedro> access Y::x instead of Base::x.
Ah, I see. Well, we ought to have a test case to make sure :)
But I think it won't, since the printer will see an object of type
Base.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 18:05 ` Pedro Alves
2009-03-27 18:36 ` Tom Tromey
@ 2009-03-27 19:08 ` Phil Muldoon
2009-03-27 19:25 ` Pedro Alves
1 sibling, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2009-03-27 19:08 UTC (permalink / raw)
To: Pedro Alves; +Cc: archer, Tom Tromey
Pedro Alves wrote:
> On Friday 27 March 2009 17:50:39, Tom Tromey wrote:
>
>> Pedro> Does this do sensible things if class Y has some
>> Pedro> fields that mask the Base class's ones, when you only have a
>> Pedro> pretty printer for Base?
>>
>> Yeah... it pretty-prints Base, then goes on to print the subclass
>> fields as usual (perhaps pretty-printing them as well).
>>
>
> Okay, I was concerned if the pretty printer for Base would
> access Y::x instead of Base::x
It is a printer for Base, but that does not mean it will print out the
Base values. Take this example:
class Base : public std::tr1::unordered_map<int, char *>
{
public:
std::tr1::unordered_map<int, char *> map;
Base ()
{
map[1]="Base";
}
};
class Derived : public Base
{
public:
std::tr1::unordered_map<int, char *> map;
Derived ()
{
map[1]="Derived";
}
};
If you instantiate Derived and print it with the patch, you will get:
(pg-gdb) python import gdb.libstdcxx.v6.printers
(pg-gdb) p derived
$2 = {
<Base> = std::tr1::unordered_map with 0 elements,
members of Derived:
map = std::tr1::unordered_map with 1 elements = {
[1] = 0x403952 "Derived"
}
}
Regards
Phil
Phil
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class.
2009-03-27 19:08 ` Phil Muldoon
@ 2009-03-27 19:25 ` Pedro Alves
0 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2009-03-27 19:25 UTC (permalink / raw)
To: Phil Muldoon; +Cc: archer, Tom Tromey
On Friday 27 March 2009 19:06:45, Phil Muldoon wrote:
> Pedro Alves wrote:
> > On Friday 27 March 2009 17:50:39, Tom Tromey wrote:
> >
> >> Pedro> Does this do sensible things if class Y has some
> >> Pedro> fields that mask the Base class's ones, when you only have a
> >> Pedro> pretty printer for Base?
> >>
> >> Yeah... it pretty-prints Base, then goes on to print the subclass
> >> fields as usual (perhaps pretty-printing them as well).
> >>
> >
> > Okay, I was concerned if the pretty printer for Base would
> > access Y::x instead of Base::x
> It is a printer for Base, but that does not mean it will print out the
> Base values. Take this example:
>
<snip example>
I'm not sure if you're talking about what I'm talking. Here's a
simple example without stl mumbo jumbo, but please don't get caught
up with the actual classes being chosen for the example:
class LibVector
{
private:
char *data;
int len; /* length of data buffer in bytes */
};
class MyApplesVector : public LibVector
{
private:
int len; /* length of each apple in the vector in fruitlenght
units. They all must have the same length. */
}
I was asking if the pretty printer for LibVector, when
applied to MyApplesVector, wouldn't mistake MyApplesVector::len
for LibVector::len, which could cause bad things to happen
when accessing data, or printing the length of the generic
LibVector.
--
Pedro Alves
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-03-27 19:25 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-27 17:05 [python][rfc] Attempt to print the base class if a there is no Python pretty-printer for a derived class Phil Muldoon
2009-03-27 17:34 ` Tom Tromey
2009-03-27 17:43 ` Phil Muldoon
2009-03-27 17:47 ` Tom Tromey
2009-03-27 17:46 ` Paul Pluzhnikov
2009-03-27 18:00 ` Tom Tromey
2009-03-27 18:28 ` Phil Muldoon
2009-03-27 17:43 ` Pedro Alves
2009-03-27 17:50 ` Tom Tromey
2009-03-27 18:05 ` Phil Muldoon
2009-03-27 18:05 ` Pedro Alves
2009-03-27 18:36 ` Tom Tromey
2009-03-27 19:08 ` Phil Muldoon
2009-03-27 19:25 ` Pedro Alves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).