This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Add real-type to MI output
- From: Simon Marchi <simon dot marchi at ericsson dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: <marc-andre dot laperle at ericsson dot com>, Simon Marchi <simon dot marchi at ericsson dot com>
- Date: Mon, 16 Feb 2015 19:22:25 -0500
- Subject: [PATCH] Add real-type to MI output
- Authentication-results: sourceware.org; auth=none
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
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?
I will add the doc bits, news and a test when the code part is OK.
gdb/ChangeLog:
* mi/mi-cmd-var.c (print_varobj): Add real type field.
(varobj_update_one): Same.
* varobj.c (varobj_get_real_type): New function.
* varobj.c (varobj_get_real_type): Same.
---
gdb/mi/mi-cmd-var.c | 13 +++++++++++++
gdb/varobj.c | 14 ++++++++++++++
gdb/varobj.h | 2 ++
3 files changed, 29 insertions(+)
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index d9b37f8..730b92a 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -75,6 +75,15 @@ print_varobj (struct varobj *var, enum print_values print_values,
if (type != NULL)
{
ui_out_field_string (uiout, "type", type);
+
+ xfree (type);
+ }
+
+ type = varobj_get_real_type (var);
+ if (type != NULL)
+ {
+ ui_out_field_string (uiout, "real-type", type);
+
xfree (type);
}
@@ -780,9 +789,13 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
if (r->type_changed)
{
char *type_name = varobj_get_type (r->varobj);
+ char *real_type_name = varobj_get_real_type (r->varobj);
ui_out_field_string (uiout, "new_type", type_name);
+ ui_out_field_string (uiout, "new_real_type", real_type_name);
+
xfree (type_name);
+ xfree (real_type_name);
}
if (r->type_changed || r->children_changed)
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 43ea96f..bc4e1c2 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -989,6 +989,20 @@ varobj_get_type (struct varobj *var)
return type_to_string (var->type);
}
+/* Same as varobj_get_type, but with typedefs resolved. */
+
+char *
+varobj_get_real_type (struct varobj *var)
+{
+ /* For the "fake" variables, do not return a type. (Its type is
+ NULL, too.)
+ Do not return a type for invalid variables as well. */
+ if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
+ return NULL;
+
+ return type_to_string (check_typedef (var->type));
+}
+
/* Obtain the type of an object variable. */
struct type *
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 6fe7009..9210661 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -285,6 +285,8 @@ extern char *varobj_get_type (struct varobj *var);
extern struct type *varobj_get_gdb_type (const struct varobj *var);
+extern char *varobj_get_real_type (struct varobj *var);
+
extern char *varobj_get_path_expr (const struct varobj *var);
extern const struct language_defn *
--
2.1.4