This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Add real-type to MI output
- From: Vladimir Prus <vladimir at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 17 Feb 2015 09:26:35 +0300
- Subject: Re: [PATCH] Add real-type to MI output
- Authentication-results: sourceware.org; auth=none
- References: <1424132545-26322-1-git-send-email-simon dot marchi at ericsson dot com>
Hi Simon,
On 02/17/2015 03:22 AM, Simon Marchi wrote:
This patch adds a new "real-type" field to MI output, so that whenever
we give the type of a variable, we also give its real type. By real
type, I mean the type after resolving all layers of typedefs (i.e. what
check_typedef does).
[more about the name choice lower]
We are trying to solve a minor annoyance in Eclipse CDT. When a pointer
is declared using a typedef in a structure, such as:
typedef int* IntPointer;
struct ExampleStruct {
IntPointer member;
};
struct ExampleStruct e;
the response from gdb when listing the children of "e" looks like:
^done,numchild="1",children=[child={name="var3.member",exp="member",numchild="1",type="IntPointer",thread-id="1"}],has_more="0"
CDT has no easy way of knowing that type "IntPointer" is a pointer, and
that it should ask gdb for the value of "member" and display it.
Instead, it assumes that it's a structure and displays "{...}" as the
value. By adding the real-type information:
...,type="IntPointer",real-type="int *",...
CDT is able to determine that "member" has a value of its own and
display it. By teaching CDT about that new field, we get the right
result:
http://i.imgur.com/Sx5ZPfO.png
I don't think it's the best way to accomplish the desired effect. Instead, you can invoke -var-list-children with the
--simple-values option. Then, you'd have either "{...}" as value or the pointer value reported directly by GDB. You'd
also potentially save a roundtrip to get the value.
Actually, just did something similar internally - it was a bit tricky to get that in Eclipse DSF, and I had a special
case, but still seems better than expanding the interface with GDB?
Another case, what do you do with std::shared_ptr<Foo> or boost::shared_ptr<Foo>? Both would be naturally shown
similarly to Foo* - where you see the value immediately and can expand the object - and GDB would be able to do
so with a suitable pretty-printer, but if a frontend is supposed to parse types, that won't work.
About the naming:
Right now, the term "real type" means the run-time type, in the sense of
looking at an object through a pointer to a virtual class. However, it's
not part of any API or significant user interface (only one I found is
in the output of "whatis"), so it's not set in stone. If I could
choose, I would give "real type" the meaning of the current patch, and
call the other one the "runtime type". Or is there already a term for it?
What do you think?
Other ideas that went through my mind, if "real type" is not an option:
* canonical-type
* resolved-type
* underlying-type
Another issue. It doesn't affect us, but I wasn't sure about this case:
struct blah {
...
};
typedef struct blah blah_t;
blah_t *b;
What should real-type return for b? Right now it returns "blah_t *", but
should it return "struct blah *" instead?
If if were to return 'struct blah *', what would frontend do? Try to parse the type?
Trying to parse 'int *' is already a tad risky - i.e. do you handle all possible syntax,
like:
std::vector<My::Namespace::C> *
Quite some time ago we discussed the idea of exposing GDB type system to a frontend:
https://www.sourceware.org/ml/gdb/2006-04/msg00016.html
However, that will not be easy, and so far, frontends did not need entire type.
--
Vladimir Prus
CodeSourcery / Mentor Embedded
http://vladimirprus.com