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

[PATCH] Add real-type to MI output


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


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