From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31393 invoked by alias); 27 Jan 2007 21:49:18 -0000 Received: (qmail 31379 invoked by uid 22791); 27 Jan 2007 21:49:15 -0000 X-Spam-Check-By: sourceware.org Received: from zigzag.lvk.cs.msu.su (HELO zigzag.lvk.cs.msu.su) (158.250.17.23) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 27 Jan 2007 21:49:09 +0000 Received: from Debian-exim by zigzag.lvk.cs.msu.su with spam-scanned (Exim 4.50) id 1HAvPw-0006f4-HP for gdb-patches@sources.redhat.com; Sun, 28 Jan 2007 00:49:06 +0300 Received: from localhost ([127.0.0.1] helo=ip6-localhost) by zigzag.lvk.cs.msu.su with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA:32) (Exim 4.50) id 1HAvPk-0006en-OS; Sun, 28 Jan 2007 00:48:49 +0300 From: Vladimir Prus To: Daniel Jacobowitz Subject: Re: -var-info-path-expression Date: Sat, 27 Jan 2007 21:49:00 -0000 User-Agent: KMail/1.9.1 Cc: gdb-patches@sources.redhat.com References: <200612251200.42622.ghost@cs.msu.su> <20070103223920.GN17935@nevyn.them.org> <200701051214.18645.ghost@cs.msu.su> In-Reply-To: <200701051214.18645.ghost@cs.msu.su> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_1i8uFeDQBSKZAuS" Message-Id: <200701280048.37153.ghost@cs.msu.su> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-01/txt/msg00556.txt.bz2 --Boundary-00=_1i8uFeDQBSKZAuS Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 2354 On Friday 05 January 2007 12:14, Vladimir Prus wrote: > > > This is lightly tested by hand, I'll write automated tests later. There's no docs > > > either -- again, will be written after discussion. > > > > > > There is a couple of issues with this patch: > > > > > > - I don't much like 'var-info-path-expression' name, but > > > naming of MI commands is not very important. > > > > True - I think it's fine. > > > > > - I'm not sure why we can't report full expression in the > > > output of -var-list-children. The code I have does not seem > > > very computationally expensive. > > > > Also true. If this would be more useful, I'd be happy to do it that > > way - would you still need -var-info-path-expression? > > No, I think -var-info-path-expression will not be needed then. Except if we > do it that way, we'll have "all of test are broken because they don't expect > an extra field" situation. Grr. I'm not sure what to do here. I guess I do know -- I don't care about minor interface details. It's more important to have this implemented than solving "attribute vs. command" question the right way, and therefore, using a separate command is fine. Do you want me to add docs/tests or you can review the current version of the patch, reposted here fore convenience? - Volodya Implement -var-info-path-expression. * mi/mi-cmds.h (mi_cmd_var_info_path_expression): Declare. * mi/mi-cmds.c (mi_cmds): Register var-info-path-expression. * mi/mi-cmd-var.c (mi_cmd_var_info_path_expression): New. * varobj.c (struct varobj): New field 'path_expr'. (c_path_expr_of_child, cplus_path_expr_of_child) (java_path_expr_of_child): New. (struct language_specific): New field path_expr_of_child. (varobj_create): Initialize the path_expr field. (varobj_get_path_expr): New. (new_variable): Initialize the path_expr field. (free_variable): Free the path_expr field. (adjust_value_for_children_access): New parameter WAS_TYPE. (c_number_of_children): Adjust. (c_describe_child): New parameter CFULL_EXPRESSION. Compute full expression. (c_value_of_child, c_type_of_child): Adjust. (cplus_number_of_children): Adjust. (cplus_describe_child): New parameter CFULL_EXPRESSION. Compute full expression. (cplus_name_of_child, cplus_value_of_child) (cplus_type_of_child): Adjust. * varobj.h (varobj_get_path_expr): Declare. --Boundary-00=_1i8uFeDQBSKZAuS Content-Type: text/x-diff; charset="iso-8859-1"; name="path_expression__gdb_mainline.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="path_expression__gdb_mainline.diff" Content-length: 16939 --- gdb/mi/mi-cmds.h (/patches/gdb/path_4_unify_cpp/gdb_mainline) (revision 2940) +++ gdb/mi/mi-cmds.h (/patches/gdb/path_expression/gdb_mainline) (revision 2940) @@ -108,6 +108,7 @@ extern mi_cmd_argv_ftype mi_cmd_var_crea extern mi_cmd_argv_ftype mi_cmd_var_delete; extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression; extern mi_cmd_argv_ftype mi_cmd_var_info_expression; +extern mi_cmd_argv_ftype mi_cmd_var_info_path_expression; extern mi_cmd_argv_ftype mi_cmd_var_info_num_children; extern mi_cmd_argv_ftype mi_cmd_var_info_type; extern mi_cmd_argv_ftype mi_cmd_var_list_children; --- gdb/mi/mi-cmds.c (/patches/gdb/path_4_unify_cpp/gdb_mainline) (revision 2940) +++ gdb/mi/mi-cmds.c (/patches/gdb/path_expression/gdb_mainline) (revision 2940) @@ -155,6 +155,8 @@ struct mi_cmd mi_cmds[] = { "var-create", { NULL, 0 }, 0, mi_cmd_var_create}, { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete}, { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression}, + { "var-info-path-expression", { NULL, 0 }, 0, + mi_cmd_var_info_path_expression}, { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression}, { "var-info-num-children", { NULL, 0 }, 0, mi_cmd_var_info_num_children}, { "var-info-type", { NULL, 0 }, 0, mi_cmd_var_info_type}, --- gdb/mi/mi-cmd-var.c (/patches/gdb/path_4_unify_cpp/gdb_mainline) (revision 2940) +++ gdb/mi/mi-cmd-var.c (/patches/gdb/path_expression/gdb_mainline) (revision 2940) @@ -380,6 +380,27 @@ mi_cmd_var_info_type (char *command, cha } enum mi_cmd_result +mi_cmd_var_info_path_expression (char *command, char **argv, int argc) +{ + struct varobj *var; + char *path_expr; + + if (argc != 1) + error ("mi_cmd_var_info_path_expression: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_info_path_expression: Variable object not found"); + + path_expr = varobj_get_path_expr (var); + + ui_out_field_string (uiout, "path_expr", path_expr); + + return MI_CMD_DONE; +} + +enum mi_cmd_result mi_cmd_var_info_expression (char *command, char **argv, int argc) { enum varobj_languages lang; --- gdb/varobj.c (/patches/gdb/path_4_unify_cpp/gdb_mainline) (revision 2940) +++ gdb/varobj.c (/patches/gdb/path_expression/gdb_mainline) (revision 2940) @@ -97,6 +97,10 @@ struct varobj /* NOTE: This is the "expression" */ char *name; + /* Alloc'd expression for this child. Can be used to create a + root variable corresponding to this child. */ + char *path_expr; + /* The alloc'd name for this variable's object. This is here for convenience when constructing this object's children. */ char *obj_name; @@ -216,6 +220,8 @@ static char *c_name_of_variable (struct static char *c_name_of_child (struct varobj *parent, int index); +static char *c_path_expr_of_child (struct varobj *child); + static struct value *c_value_of_root (struct varobj **var_handle); static struct value *c_value_of_child (struct varobj *parent, int index); @@ -236,6 +242,8 @@ static char *cplus_name_of_variable (str static char *cplus_name_of_child (struct varobj *parent, int index); +static char *cplus_path_expr_of_child (struct varobj *child); + static struct value *cplus_value_of_root (struct varobj **var_handle); static struct value *cplus_value_of_child (struct varobj *parent, int index); @@ -254,6 +262,8 @@ static char *java_name_of_variable (stru static char *java_name_of_child (struct varobj *parent, int index); +static char *java_path_expr_of_child (struct varobj *child); + static struct value *java_value_of_root (struct varobj **var_handle); static struct value *java_value_of_child (struct varobj *parent, int index); @@ -281,6 +291,10 @@ struct language_specific /* The name of the INDEX'th child of PARENT. */ char *(*name_of_child) (struct varobj * parent, int index); + /* Returns the rooted expression of CHILD, which is a variable + obtain that has some parent. */ + char *(*path_expr_of_child) (struct varobj * child); + /* The ``struct value *'' of the root variable ROOT. */ struct value *(*value_of_root) (struct varobj ** root_handle); @@ -306,6 +320,7 @@ static struct language_specific c_number_of_children, c_name_of_variable, c_name_of_child, + c_path_expr_of_child, c_value_of_root, c_value_of_child, c_type_of_child, @@ -318,6 +333,7 @@ static struct language_specific c_number_of_children, c_name_of_variable, c_name_of_child, + c_path_expr_of_child, c_value_of_root, c_value_of_child, c_type_of_child, @@ -330,6 +346,7 @@ static struct language_specific cplus_number_of_children, cplus_name_of_variable, cplus_name_of_child, + cplus_path_expr_of_child, cplus_value_of_root, cplus_value_of_child, cplus_type_of_child, @@ -342,6 +359,7 @@ static struct language_specific java_number_of_children, java_name_of_variable, java_name_of_child, + java_path_expr_of_child, java_value_of_root, java_value_of_child, java_type_of_child, @@ -425,6 +443,7 @@ varobj_create (char *objname, char *p; enum varobj_languages lang; struct value *value; + int expr_len; /* Parse and evaluate the expression, filling in as much of the variable's data as possible */ @@ -469,7 +488,10 @@ varobj_create (char *objname, var->format = variable_default_display (var); var->root->valid_block = innermost_block; - var->name = savestring (expression, strlen (expression)); + expr_len = strlen (expression); + var->name = savestring (expression, expr_len); + /* For a root var, the name and the expr are the same. */ + var->path_expr = savestring (expression, expr_len); /* When the frame is different from the current frame, we must select the appropriate frame before parsing @@ -757,6 +779,21 @@ varobj_get_gdb_type (struct varobj *var) return var->type; } +/* Return a pointer to the full rooted expression of varobj VAR. + If it has not been computed yet, compute it */ +char * +varobj_get_path_expr (struct varobj *var) +{ + if (var->path_expr != NULL) + return var->path_expr; + else if (is_root_p (var)) + return var->name; + else + { + return (*var->root->lang->path_expr_of_child) (var); + } +} + enum varobj_languages varobj_get_language (struct varobj *var) { @@ -1357,6 +1394,7 @@ new_variable (void) var = (struct varobj *) xmalloc (sizeof (struct varobj)); var->name = NULL; + var->path_expr = NULL; var->obj_name = NULL; var->index = -1; var->type = NULL; @@ -1401,6 +1439,7 @@ free_variable (struct varobj *var) xfree (var->name); xfree (var->obj_name); + xfree (var->path_expr); xfree (var); } @@ -1683,13 +1722,21 @@ varobj_value_is_changeable_p (struct var Both TYPE and *TYPE should be non-null. VALUE can be null if we want to only translate type. *VALUE can be null as well -- if the parent - value is not known. */ + value is not known. + + If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1 + depending on whether pointer was deferenced + in this function. */ static void adjust_value_for_children_access (struct value **value, - struct type **type) + struct type **type, + int *was_ptr) { gdb_assert (type && *type); + if (was_ptr) + *was_ptr = 0; + *type = check_typedef (*type); /* If the parent is reference, we always strip the @@ -1721,6 +1768,8 @@ adjust_value_for_children_access (struct if (value && *value) gdb_value_ind (*value, value); *type = target_type; + if (was_ptr) + *was_ptr = 1; } } } @@ -1733,7 +1782,7 @@ c_number_of_children (struct varobj *var int children = 0; struct type *target; - adjust_value_for_children_access (NULL, &type); + adjust_value_for_children_access (NULL, &type, NULL); target = get_target_type (type); switch (TYPE_CODE (type)) @@ -1826,10 +1875,13 @@ value_struct_element_index (struct value to NULL. */ static void c_describe_child (struct varobj *parent, int index, - char **cname, struct value **cvalue, struct type **ctype) + char **cname, struct value **cvalue, struct type **ctype, + char **cfull_expression) { struct value *value = parent->value; struct type *type = get_type (parent); + char *parent_expression = NULL; + int was_ptr; if (cname) *cname = NULL; @@ -1837,8 +1889,13 @@ c_describe_child (struct varobj *parent, *cvalue = NULL; if (ctype) *ctype = NULL; + if (cfull_expression) + { + *cfull_expression = NULL; + parent_expression = varobj_get_path_expr (parent); + } - adjust_value_for_children_access (&value, &type); + adjust_value_for_children_access (&value, &type, &was_ptr); switch (TYPE_CODE (type)) { @@ -1858,6 +1915,12 @@ c_describe_child (struct varobj *parent, if (ctype) *ctype = get_target_type (type); + if (cfull_expression) + *cfull_expression = xstrprintf ("(%s)[%d]", parent_expression, + index + + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type))); + + break; case TYPE_CODE_STRUCT: @@ -1877,6 +1940,13 @@ c_describe_child (struct varobj *parent, if (ctype) *ctype = TYPE_FIELD_TYPE (type, index); + if (cfull_expression) + { + char *join = was_ptr ? "->" : "."; + *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join, + TYPE_FIELD_NAME (type, index)); + } + break; case TYPE_CODE_PTR: @@ -1892,6 +1962,9 @@ c_describe_child (struct varobj *parent, right. */ if (ctype) *ctype = get_target_type (type); + + if (cfull_expression) + *cfull_expression = xstrprintf ("*(%s)", parent_expression); break; @@ -1899,6 +1972,8 @@ c_describe_child (struct varobj *parent, /* This should not happen */ if (cname) *cname = xstrdup ("???"); + if (cfull_expression) + *cfull_expression = xstrdup ("???"); /* Don't set value and type, we don't know then. */ } } @@ -1907,10 +1982,18 @@ static char * c_name_of_child (struct varobj *parent, int index) { char *name; - c_describe_child (parent, index, &name, NULL, NULL); + c_describe_child (parent, index, &name, NULL, NULL, NULL); return name; } +static char * +c_path_expr_of_child (struct varobj *child) +{ + c_describe_child (child->parent, child->index, NULL, NULL, NULL, + &child->path_expr); + return child->path_expr; +} + static struct value * c_value_of_root (struct varobj **var_handle) { @@ -1961,7 +2044,7 @@ static struct value * c_value_of_child (struct varobj *parent, int index) { struct value *value = NULL; - c_describe_child (parent, index, NULL, &value, NULL); + c_describe_child (parent, index, NULL, &value, NULL, NULL); if (value != NULL) release_value (value); @@ -1972,7 +2055,7 @@ static struct type * c_type_of_child (struct varobj *parent, int index) { struct type *type = NULL; - c_describe_child (parent, index, NULL, NULL, &type); + c_describe_child (parent, index, NULL, NULL, &type, NULL); return type; } @@ -2066,7 +2149,7 @@ cplus_number_of_children (struct varobj if (!CPLUS_FAKE_CHILD (var)) { type = var->type; - adjust_value_for_children_access (NULL, &type); + adjust_value_for_children_access (NULL, &type, NULL); if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || ((TYPE_CODE (type)) == TYPE_CODE_UNION)) @@ -2093,7 +2176,7 @@ cplus_number_of_children (struct varobj int kids[3]; type = var->parent->type; - adjust_value_for_children_access (NULL, &type); + adjust_value_for_children_access (NULL, &type, NULL); cplus_class_num_children (type, kids); if (strcmp (var->name, "public") == 0) @@ -2164,11 +2247,14 @@ match_accessibility (struct type *type, static void cplus_describe_child (struct varobj *parent, int index, - char **cname, struct value **cvalue, struct type **ctype) + char **cname, struct value **cvalue, struct type **ctype, + char **cfull_expression) { char *name = 0; struct value *value; struct type *type; + int was_ptr; + char *parent_expression = NULL; if (cname) *cname = NULL; @@ -2176,24 +2262,30 @@ cplus_describe_child (struct varobj *par *cvalue = NULL; if (ctype) *ctype = NULL; - + if (cfull_expression) + *cfull_expression = NULL; if (CPLUS_FAKE_CHILD (parent)) { value = parent->parent->value; type = get_type (parent->parent); + if (cfull_expression) + parent_expression = varobj_get_path_expr (parent->parent); } else { value = parent->value; type = get_type (parent); + if (cfull_expression) + parent_expression = varobj_get_path_expr (parent); } - adjust_value_for_children_access (&value, &type); + adjust_value_for_children_access (&value, &type, &was_ptr); if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_STRUCT) { + char *join = was_ptr ? "->" : "."; if (CPLUS_FAKE_CHILD (parent)) { /* The fields of the class type are ordered as they @@ -2228,6 +2320,11 @@ cplus_describe_child (struct varobj *par if (ctype) *ctype = TYPE_FIELD_TYPE (type, type_index); + + if (cfull_expression) + *cfull_expression = xstrprintf ("((%s)%s%s)", parent_expression, + join, + TYPE_FIELD_NAME (type, type_index)); } else if (index < TYPE_N_BASECLASSES (type)) { @@ -2245,6 +2342,15 @@ cplus_describe_child (struct varobj *par { *ctype = TYPE_FIELD_TYPE (type, index); } + + if (cfull_expression) + { + char *ptr = was_ptr ? " *" : ""; + *cfull_expression = xstrprintf ("((%s%s) %s)", + TYPE_FIELD_NAME (type, index), + ptr, + parent_expression); + } } else { @@ -2291,12 +2397,12 @@ cplus_describe_child (struct varobj *par if (cname) *cname = access; - /* Value and type are null here. */ + /* Value and type and full expression are null here. */ } } else { - c_describe_child (parent, index, cname, cvalue, ctype); + c_describe_child (parent, index, cname, cvalue, ctype, cfull_expression); } } @@ -2304,10 +2410,18 @@ static char * cplus_name_of_child (struct varobj *parent, int index) { char *name = NULL; - cplus_describe_child (parent, index, &name, NULL, NULL); + cplus_describe_child (parent, index, &name, NULL, NULL, NULL); return name; } +static char * +cplus_path_expr_of_child (struct varobj *child) +{ + cplus_describe_child (child->parent, child->index, NULL, NULL, NULL, + &child->path_expr); + return child->path_expr; +} + static struct value * cplus_value_of_root (struct varobj **var_handle) { @@ -2318,7 +2432,7 @@ static struct value * cplus_value_of_child (struct varobj *parent, int index) { struct value *value = NULL; - cplus_describe_child (parent, index, NULL, &value, NULL); + cplus_describe_child (parent, index, NULL, &value, NULL, NULL); return value; } @@ -2326,7 +2440,7 @@ static struct type * cplus_type_of_child (struct varobj *parent, int index) { struct type *type = NULL; - cplus_describe_child (parent, index, NULL, NULL, &type); + cplus_describe_child (parent, index, NULL, NULL, &type, NULL); return type; } @@ -2398,6 +2512,12 @@ java_name_of_child (struct varobj *paren return name; } +static char * +java_path_expr_of_child (struct varobj *child) +{ + return NULL; +} + static struct value * java_value_of_root (struct varobj **var_handle) { --- gdb/varobj.h (/patches/gdb/path_4_unify_cpp/gdb_mainline) (revision 2940) +++ gdb/varobj.h (/patches/gdb/path_expression/gdb_mainline) (revision 2940) @@ -87,6 +87,8 @@ extern char *varobj_get_type (struct var extern struct type *varobj_get_gdb_type (struct varobj *var); +extern char *varobj_get_path_expr (struct varobj *var); + extern enum varobj_languages varobj_get_language (struct varobj *var); extern int varobj_get_attributes (struct varobj *var); Property changes on: ___________________________________________________________________ Name: csl:base -/all/patches/gdb/path_3_unify/gdb_mainline +/all/patches/gdb/path_4_unify_cpp/gdb_mainline Name: svk:merge d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_1/gdb_mainline:2869 +d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_2_children/gdb_mainline:2879 d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_unify/gdb_mainline:2930 -d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_expression/gdb_mainline:2562 +d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_4_unify_cpp/gdb_mainline:2937 e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:157978 --Boundary-00=_1i8uFeDQBSKZAuS--