This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: -var-info-path-expression
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.
--- 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