From patchwork Tue Feb 17 00:22:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 5098 Received: (qmail 30899 invoked by alias); 17 Feb 2015 00:22:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 30880 invoked by uid 89); 17 Feb 2015 00:22:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: usevmg21.ericsson.net Received: from usevmg21.ericsson.net (HELO usevmg21.ericsson.net) (198.24.6.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 17 Feb 2015 00:22:38 +0000 Received: from EUSAAHC003.ericsson.se (Unknown_Domain [147.117.188.81]) by usevmg21.ericsson.net (Symantec Mail Security) with SMTP id 59.EA.25146.AB922E45; Mon, 16 Feb 2015 18:32:42 +0100 (CET) Received: from elxcz23q12-y4.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.81) with Microsoft SMTP Server (TLS) id 14.3.210.2; Mon, 16 Feb 2015 19:22:34 -0500 From: Simon Marchi To: CC: , Simon Marchi Subject: [PATCH] Add real-type to MI output Date: Mon, 16 Feb 2015 19:22:25 -0500 Message-ID: <1424132545-26322-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 X-IsSubscribed: yes 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 *