From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 791 invoked by alias); 25 Dec 2006 09:02:43 -0000 Received: (qmail 781 invoked by uid 22791); 25 Dec 2006 09:02:41 -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; Mon, 25 Dec 2006 09:02:34 +0000 Received: from Debian-exim by zigzag.lvk.cs.msu.su with spam-scanned (Exim 4.50) id 1Gylj1-0007fQ-JT for gdb-patches@sources.redhat.com; Mon, 25 Dec 2006 12:02:30 +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 1Gylj0-0007fN-Ik for gdb-patches@sources.redhat.com; Mon, 25 Dec 2006 12:02:27 +0300 From: Vladimir Prus To: gdb-patches@sources.redhat.com Subject: -var-info-path-expression Date: Mon, 25 Dec 2006 09:02:00 -0000 User-Agent: KMail/1.9.1 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_6M5jFASlp2QQn4c" Message-Id: <200612251200.42622.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: 2006-12/txt/msg00315.txt.bz2 --Boundary-00=_6M5jFASlp2QQn4c Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 2228 This patch implements new MI command, -var-info-path-expression, that, given a variable object, returns full expression that corresponds to it. Both KDevelop and Eclipse have now code that guesses such full expression, and that code is rather hacky, and not exactly correct. Moreover, as soon as MI is taught to get the true type polymorphic C++ objects and display fields of the real type, such full expression cannot be computed in frontend at all. The essence of this patch -- which expressions are returned in which cases -- are ported without change from the Apple branch. The code structure is much different though -- this patch capitalizes on MI refactoring patches I've posted recently. 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. - 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. Comments are appreciated. - 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=_6M5jFASlp2QQn4c Content-Type: text/x-diff; charset="us-ascii"; 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=_6M5jFASlp2QQn4c--