* -var-info-path-expression
@ 2007-06-18 10:43 Vladimir Prus
2007-06-18 19:40 ` -var-info-path-expression Eli Zaretskii
2007-07-03 17:14 ` -var-info-path-expression Daniel Jacobowitz
0 siblings, 2 replies; 24+ messages in thread
From: Vladimir Prus @ 2007-06-18 10:43 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1707 bytes --]
The attached patch is a revised, and updated for mainline,
version of my earlier patch to add -var-info-path-expression.
The review of the previous version is at:
http://article.gmane.org/gmane.comp.gdb.patches/32582
and asks for:
1. _() in some places.
2. Not using of name of gdb function in mi error messages
3. Points that path_expr != NULL implies it's not a root
varobj.
Those changes were made. This version of patch builds,
and all MI tests pass. OK?
- 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.
[-- Attachment #2: path_expression.diff --]
[-- Type: text/x-diff, Size: 16138 bytes --]
--- gdb/mi/mi-cmds.h (/mirrors/gdb_mainline) (revision 4325)
+++ gdb/mi/mi-cmds.h (/patches/gdb/path_expression/gdb_mainline) (revision 4325)
@@ -109,6 +109,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 (/mirrors/gdb_mainline) (revision 4325)
+++ gdb/mi/mi-cmds.c (/patches/gdb/path_expression/gdb_mainline) (revision 4325)
@@ -151,6 +151,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 (/mirrors/gdb_mainline) (revision 4325)
+++ gdb/mi/mi-cmd-var.c (/patches/gdb/path_expression/gdb_mainline) (revision 4325)
@@ -413,6 +413,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 (/mirrors/gdb_mainline) (revision 4325)
+++ gdb/varobj.c (/patches/gdb/path_expression/gdb_mainline) (revision 4325)
@@ -101,6 +101,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;
@@ -236,6 +240,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);
@@ -256,6 +262,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);
@@ -274,6 +282,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);
@@ -301,6 +311,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);
@@ -325,6 +339,7 @@ static struct language_specific language
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,
@@ -337,6 +352,7 @@ static struct language_specific language
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,
@@ -349,6 +365,7 @@ static struct language_specific language
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,
@@ -361,6 +378,7 @@ static struct language_specific language
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,
@@ -444,6 +462,7 @@ varobj_create (char *objname,
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ int expr_len;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
@@ -488,7 +507,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
@@ -806,6 +828,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)
{
@@ -1459,6 +1496,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;
@@ -1507,6 +1545,7 @@ free_variable (struct varobj *var)
xfree (var->name);
xfree (var->obj_name);
xfree (var->print_value);
+ xfree (var->path_expr);
xfree (var);
}
@@ -1887,7 +1926,7 @@ c_number_of_children (struct varobj *var
int children = 0;
struct type *target;
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
target = get_target_type (type);
switch (TYPE_CODE (type))
@@ -1983,10 +2022,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_value_type (parent);
+ char *parent_expression = NULL;
+ int was_ptr;
if (cname)
*cname = NULL;
@@ -1994,8 +2036,12 @@ c_describe_child (struct varobj *parent,
*cvalue = NULL;
if (ctype)
*ctype = NULL;
-
- adjust_value_for_child_access (&value, &type);
+ if (cfull_expression)
+ {
+ *cfull_expression = NULL;
+ parent_expression = varobj_get_path_expr (parent);
+ }
+ adjust_value_for_child_access (&value, &type, &was_ptr);
switch (TYPE_CODE (type))
{
@@ -2015,6 +2061,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:
@@ -2034,6 +2086,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:
@@ -2048,6 +2107,9 @@ c_describe_child (struct varobj *parent,
declared type of the variable. */
if (ctype)
*ctype = TYPE_TARGET_TYPE (type);
+
+ if (cfull_expression)
+ *cfull_expression = xstrprintf ("*(%s)", parent_expression);
break;
@@ -2055,6 +2117,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. */
}
}
@@ -2063,10 +2127,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)
{
@@ -2115,7 +2187,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);
return value;
}
@@ -2124,7 +2196,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;
}
@@ -2214,7 +2286,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
type = get_value_type (var);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2241,7 +2313,7 @@ cplus_number_of_children (struct varobj
int kids[3];
type = get_value_type (var->parent);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2312,11 +2384,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;
@@ -2324,24 +2399,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_value_type (parent->parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent->parent);
}
else
{
value = parent->value;
type = get_value_type (parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent);
}
- adjust_value_for_child_access (&value, &type);
+ adjust_value_for_child_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
@@ -2376,6 +2457,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))
{
@@ -2386,12 +2472,22 @@ cplus_describe_child (struct varobj *par
if (cvalue && value)
{
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+ release_value (*cvalue);
}
if (ctype)
{
*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
{
@@ -2438,12 +2534,12 @@ cplus_describe_child (struct varobj *par
if (cname)
*cname = xstrdup (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);
}
}
@@ -2451,10 +2547,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)
{
@@ -2465,7 +2569,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;
}
@@ -2473,7 +2577,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;
}
@@ -2545,6 +2649,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 (/mirrors/gdb_mainline) (revision 4325)
+++ gdb/varobj.h (/patches/gdb/path_expression/gdb_mainline) (revision 4325)
@@ -99,6 +99,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_4_unify_cpp/gdb_mainline
Name: svk:merge
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_1/gdb_mainline:3166
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_2_children/gdb_mainline:3167
+
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_5_references/gdb_mainline:3213
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_unify/gdb_mainline:3168
+
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_4_unify_cpp/gdb_mainline:3214
+e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:174259
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-06-18 10:43 -var-info-path-expression Vladimir Prus
@ 2007-06-18 19:40 ` Eli Zaretskii
2007-06-21 5:15 ` -var-info-path-expression Vladimir Prus
2007-07-03 17:14 ` -var-info-path-expression Daniel Jacobowitz
1 sibling, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2007-06-18 19:40 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Mon, 18 Jun 2007 14:42:59 +0400
>
> Implement -var-info-path-expression.
Shouldn't this be documented?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-06-18 10:43 -var-info-path-expression Vladimir Prus
2007-06-18 19:40 ` -var-info-path-expression Eli Zaretskii
@ 2007-07-03 17:14 ` Daniel Jacobowitz
2007-07-03 17:51 ` -var-info-path-expression Vladimir Prus
1 sibling, 1 reply; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-07-03 17:14 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Mon, Jun 18, 2007 at 02:42:59PM +0400, Vladimir Prus wrote:
>
> The attached patch is a revised, and updated for mainline,
> version of my earlier patch to add -var-info-path-expression.
> The review of the previous version is at:
>
> http://article.gmane.org/gmane.comp.gdb.patches/32582
>
> and asks for:
>
> 1. _() in some places.
> 2. Not using of name of gdb function in mi error messages
> 3. Points that path_expr != NULL implies it's not a root
> varobj.
>
> Those changes were made.
Is this the right version of the patch? I was going to say it was OK,
with documentation, and a few small changes - but that's the list of
small changes above. For instance:
> + if (argc != 1)
> + error ("mi_cmd_var_info_path_expression: Usage: NAME.");
And these two that disagree:
> - 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);
> + 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);
> + }
Anyway, other than that and some comment formatting, it looks fine to me.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-07-03 17:14 ` -var-info-path-expression Daniel Jacobowitz
@ 2007-07-03 17:51 ` Vladimir Prus
2007-07-03 17:58 ` -var-info-path-expression Daniel Jacobowitz
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2007-07-03 17:51 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1148 bytes --]
On Tuesday 03 July 2007 21:13, Daniel Jacobowitz wrote:
> On Mon, Jun 18, 2007 at 02:42:59PM +0400, Vladimir Prus wrote:
> >
> > The attached patch is a revised, and updated for mainline,
> > version of my earlier patch to add -var-info-path-expression.
> > The review of the previous version is at:
> >
> > http://article.gmane.org/gmane.comp.gdb.patches/32582
> >
> > and asks for:
> >
> > 1. _() in some places.
> > 2. Not using of name of gdb function in mi error messages
> > 3. Points that path_expr != NULL implies it's not a root
> > varobj.
> >
> > Those changes were made.
>
> Is this the right version of the patch? I was going to say it was OK,
> with documentation, and a few small changes - but that's the list of
> small changes above.
Oops. I've forgotten to commit said changes to my local repo, from
where patches are generated. Here's updated patch.
> Anyway, other than that and some comment formatting, it looks fine to me.
What kind of formatting? Do you think you can indicate what to fix so that
I can fix it on my own without you pinpointing every problem. Two spaces again,
or something else?
- Volodya
[-- Attachment #2: path_expression.diff --]
[-- Type: text/x-diff, Size: 17092 bytes --]
--- gdb/mi/mi-cmds.h (/mirrors/gdb_mainline) (revision 4330)
+++ gdb/mi/mi-cmds.h (/patches/gdb/path_expression/gdb_mainline) (revision 4330)
@@ -109,6 +109,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 (/mirrors/gdb_mainline) (revision 4330)
+++ gdb/mi/mi-cmds.c (/patches/gdb/path_expression/gdb_mainline) (revision 4330)
@@ -151,6 +151,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 (/mirrors/gdb_mainline) (revision 4330)
+++ gdb/mi/mi-cmd-var.c (/patches/gdb/path_expression/gdb_mainline) (revision 4330)
@@ -413,6 +413,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 (_("Usage: NAME."));
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error (_("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 (/mirrors/gdb_mainline) (revision 4330)
+++ gdb/varobj.c (/patches/gdb/path_expression/gdb_mainline) (revision 4330)
@@ -101,6 +101,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;
@@ -236,6 +240,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);
@@ -256,6 +262,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);
@@ -274,6 +282,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);
@@ -301,6 +311,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);
@@ -325,6 +339,7 @@ static struct language_specific language
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,
@@ -337,6 +352,7 @@ static struct language_specific language
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,
@@ -349,6 +365,7 @@ static struct language_specific language
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,
@@ -361,6 +378,7 @@ static struct language_specific language
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,
@@ -444,6 +462,7 @@ varobj_create (char *objname,
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ int expr_len;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
@@ -488,7 +507,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
@@ -806,6 +828,23 @@ 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
+ {
+ /* For root varobjs, we initialize path_expr
+ when creating varobj, so here it should be
+ child varobj. */
+ gdb_assert (!is_root_p (var));
+ return (*var->root->lang->path_expr_of_child) (var);
+ }
+}
+
enum varobj_languages
varobj_get_language (struct varobj *var)
{
@@ -1459,6 +1498,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;
@@ -1507,6 +1547,7 @@ free_variable (struct varobj *var)
xfree (var->name);
xfree (var->obj_name);
xfree (var->print_value);
+ xfree (var->path_expr);
xfree (var);
}
@@ -1844,13 +1885,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_child_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);
/* The type of value stored in varobj, that is passed
@@ -1871,6 +1920,8 @@ adjust_value_for_child_access (struct va
if (value && *value)
gdb_value_ind (*value, value);
*type = target_type;
+ if (was_ptr)
+ *was_ptr = 1;
}
}
@@ -1887,7 +1938,7 @@ c_number_of_children (struct varobj *var
int children = 0;
struct type *target;
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
target = get_target_type (type);
switch (TYPE_CODE (type))
@@ -1983,10 +2034,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_value_type (parent);
+ char *parent_expression = NULL;
+ int was_ptr;
if (cname)
*cname = NULL;
@@ -1994,8 +2048,12 @@ c_describe_child (struct varobj *parent,
*cvalue = NULL;
if (ctype)
*ctype = NULL;
-
- adjust_value_for_child_access (&value, &type);
+ if (cfull_expression)
+ {
+ *cfull_expression = NULL;
+ parent_expression = varobj_get_path_expr (parent);
+ }
+ adjust_value_for_child_access (&value, &type, &was_ptr);
switch (TYPE_CODE (type))
{
@@ -2015,6 +2073,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:
@@ -2034,6 +2098,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:
@@ -2048,6 +2119,9 @@ c_describe_child (struct varobj *parent,
declared type of the variable. */
if (ctype)
*ctype = TYPE_TARGET_TYPE (type);
+
+ if (cfull_expression)
+ *cfull_expression = xstrprintf ("*(%s)", parent_expression);
break;
@@ -2055,6 +2129,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. */
}
}
@@ -2063,10 +2139,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)
{
@@ -2115,7 +2199,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);
return value;
}
@@ -2124,7 +2208,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;
}
@@ -2214,7 +2298,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
type = get_value_type (var);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2241,7 +2325,7 @@ cplus_number_of_children (struct varobj
int kids[3];
type = get_value_type (var->parent);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2312,11 +2396,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;
@@ -2324,24 +2411,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_value_type (parent->parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent->parent);
}
else
{
value = parent->value;
type = get_value_type (parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent);
}
- adjust_value_for_child_access (&value, &type);
+ adjust_value_for_child_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
@@ -2376,6 +2469,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))
{
@@ -2386,12 +2484,22 @@ cplus_describe_child (struct varobj *par
if (cvalue && value)
{
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+ release_value (*cvalue);
}
if (ctype)
{
*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
{
@@ -2438,12 +2546,12 @@ cplus_describe_child (struct varobj *par
if (cname)
*cname = xstrdup (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);
}
}
@@ -2451,10 +2559,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)
{
@@ -2465,7 +2581,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;
}
@@ -2473,7 +2589,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;
}
@@ -2545,6 +2661,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 (/mirrors/gdb_mainline) (revision 4330)
+++ gdb/varobj.h (/patches/gdb/path_expression/gdb_mainline) (revision 4330)
@@ -99,6 +99,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_4_unify_cpp/gdb_mainline
Name: svk:merge
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_1/gdb_mainline:3166
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_2_children/gdb_mainline:3167
+
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_5_references/gdb_mainline:3213
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_unify/gdb_mainline:3168
+
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_4_unify_cpp/gdb_mainline:3214
+e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:174259
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-07-03 17:51 ` -var-info-path-expression Vladimir Prus
@ 2007-07-03 17:58 ` Daniel Jacobowitz
0 siblings, 0 replies; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-07-03 17:58 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Tue, Jul 03, 2007 at 09:51:19PM +0400, Vladimir Prus wrote:
> > Anyway, other than that and some comment formatting, it looks fine to me.
>
> What kind of formatting? Do you think you can indicate what to fix so that
> I can fix it on my own without you pinpointing every problem. Two spaces again,
> or something else?
Yeah, that and a final period in the comment above
varobj_get_path_expr. I didn't point out each one, because honestly
I'm trying to be less picky about that sort of thing - it's not as if
the comments weren't clear anyway.
This version is OK to commit, but please wait until you have a doc
patch and maybe a testcase to go with it. Thanks for being patient.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 24+ messages in thread
* -var-info-path-expression
@ 2007-08-22 11:23 Vladimir Prus
2007-08-22 15:28 ` -var-info-path-expression Daniel Jacobowitz
2007-08-28 17:18 ` -var-info-path-expression Vladimir Prus
0 siblings, 2 replies; 24+ messages in thread
From: Vladimir Prus @ 2007-08-22 11:23 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 590 bytes --]
This is the hopefully final revision of the patch
to add the -var-info-path-expression command.
The code part of the patch was already approved in:
http://article.gmane.org/gmane.comp.gdb.patches/34902
This revision has these changes:
1. Documentation for the new command
2. Tests for the new command.
3. A fix for a bug discovered while testing.
4. Some formatting tweaks.
I attach a delta patch with just those changes, for easier
review, as well as complete patch against FSF HEAD.
Eli, do doc changes look fine?
Daniel, is the code patch still OK to commit?
Thanks,
Volodya
[-- Attachment #2: path_expression.ChangeLog --]
[-- Type: text/plain, Size: 1304 bytes --]
Implement -var-info-path-expression.
gdb/
* 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/doc
* gdb.texinfo (Variable Objects): Adjust docs
for -var-info-expression and document
-var-info-path-expression.
gdb/testsuite/
* gdb.mi/mi-var-cp.cc (path_expression): New
function.
* gdb.mi/mi-var-cp.exp: Run path exression tests.
[-- Attachment #3: path_expression.diff --]
[-- Type: text/x-diff, Size: 23211 bytes --]
--- gdb/doc/gdb.texinfo (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/doc/gdb.texinfo (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -19304,7 +19304,9 @@ access this functionality:
@item @code{-var-info-type}
@tab show the type of this variable object
@item @code{-var-info-expression}
-@tab print what this variable object represents
+@tab print parent-relative expression that this variable object represents
+@item @code{-var-info-path-expression}
+@tab print full expression that this variable object represents
@item @code{-var-show-attributes}
@tab is this variable editable? does it exist here?
@item @code{-var-evaluate-expression}
@@ -19505,8 +19507,36 @@ returned as a string in the same format
-var-info-expression @var{name}
@end smallexample
-Returns what is represented by the variable object @var{name}:
+Returns the expression that is represented by the variable object
+@var{name}, that is relative to parent variable object and is
+suitable for presenting this variable object is user interface:
+
+@smallexample
+ lang=@var{lang-spec},exp=@var{expression}
+@end smallexample
+
+@noindent
+where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+
+@subheading The @code{-var-info-path-expression} Command
+@findex -var-info-path-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-path-expression @var{name}
+@end smallexample
+
+Returns a full expression that can be evaluated in the current
+context and corresponds to the variable object. Unlike the
+@code{-var-info-expression} command, the returned expression is not relative
+to parent and can be used to create another variable object that will
+always have the same value as the other variable object. Typical
+use of @code{-var-info-path-expression} is creating a watchpoint from
+a variable object.
+
+Example output:
@smallexample
lang=@var{lang-spec},exp=@var{expression}
@end smallexample
--- gdb/testsuite/gdb.mi/mi-var-cp.exp (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/testsuite/gdb.mi/mi-var-cp.exp (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -45,6 +45,7 @@ mi_run_inline_test reference_update
mi_run_inline_test base_in_reference
mi_run_inline_test reference_to_pointer
mi_run_inline_test reference_to_struct
+mi_run_inline_test path_expression
mi_gdb_exit
return 0
--- gdb/testsuite/gdb.mi/mi-var-cp.cc (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/testsuite/gdb.mi/mi-var-cp.cc (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -121,11 +121,97 @@ int reference_to_struct ()
/*: END: reference_to_struct :*/
}
+struct Base1
+{
+ int i;
+};
+
+struct Base2
+{
+ int i;
+};
+
+struct Derived : public Base1, public Base2
+{
+ int i;
+};
+
+/* Test for the -var-info-path-expression command. Although
+ said command is not specific to C++, it's of more importance
+ to C++ than to C, so we test it in mi-var-cp test. */
+int path_expression ()
+{
+ /*: BEGIN: path_expression :*/
+ int i = 10;
+ int *ip = &i;
+ /*: mi_create_varobj IP ip "create varobj for ip"
+ mi_list_varobj_children IP {{IP.\\*ip \\*ip 0 int}} "list children of IP"
+ mi_gdb_test "-var-info-path-expression IP.*ip" \
+ "\\^done,path_expr=\"\\*\\(ip\\)\"" \
+ "-var-info-path-expression IP.*ip"
+ :*/
+ Derived d;
+ Derived *dp = &d;
+ /*: mi_create_varobj DP dp "create varobj for dp"
+ mi_list_varobj_children DP \
+ {{DP.Base1 Base1 1 Base1} \
+ {DP.Base2 Base2 1 Base2} \
+ {DP.public public 1}} "list children of DP"
+ mi_gdb_test "-var-info-path-expression DP.Base1" \
+ "\\^done,path_expr=\"\\(\\*\\(Base1\\*\\) dp\\)\"" \
+ "-var-info-path-expression DP.Base1"
+ mi_list_varobj_children DP.public { \
+ {DP.public.i i 0 int} \
+ } "list children of DP.public"
+ mi_gdb_test "-var-info-path-expression DP.public.i" \
+ "\\^done,path_expr=\"\\(\\(dp\\)->i\\)\"" \
+ "-var-info-path-expression DP.public.i"
+ mi_list_varobj_children DP.Base1 { \
+ {DP.Base1.public public 1} \
+ } "list children of DP.Base1"
+ mi_list_varobj_children DP.Base1.public { \
+ {DP.Base1.public.i i 0 int} \
+ } "list children of DP.Base1.public"
+ mi_gdb_test "-var-info-path-expression DP.Base1.public.i" \
+ "\\^done,path_expr=\"\\(\\(\\(\\*\\(Base1\\*\\) dp\\)\\).i\\)\"" \
+ "-var-info-path-expression DP.Base1.public.i"
+
+ mi_gdb_test "-var-info-path-expression DP.public" \
+ "\\^done,path_expr=\"\"" \
+ "-var-info-path-expression DP.public"
+
+ mi_create_varobj D d "create varobj for d"
+ mi_list_varobj_children D \
+ {{D.Base1 Base1 1 Base1} \
+ {D.Base2 Base2 1 Base2} \
+ {D.public public 1}} "list children of D"
+ mi_gdb_test "-var-info-path-expression D.Base1" \
+ "\\^done,path_expr=\"\\(\\(Base1\\) d\\)\"" \
+ "-var-info-path-expression D.Base1"
+ :*/
+ int array[4] = {1,2,3};
+ array[3] = 10;
+ /*: mi_create_varobj A array "create varobj for array"
+ mi_list_varobj_children A { \
+ {A.0 0 0 int}
+ {A.1 1 0 int}
+ {A.2 2 0 int}
+ {A.3 3 0 int}} "list children of A"
+ mi_gdb_test "-var-info-path-expression A.2" \
+ "\\^done,path_expr=\"\\(array\\)\\\[2\\\]\"" \
+ "-var-info-path-expression A.2"
+ :*/
+
+ return 99;
+ /*: END: path_expression :*/
+}
+
int main ()
{
reference_update_tests ();
base_in_reference_test_main ();
reference_to_pointer ();
reference_to_struct ();
+ path_expression ();
return 0;
}
--- gdb/mi/mi-cmds.h (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/mi/mi-cmds.h (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -109,6 +109,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 (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/mi/mi-cmds.c (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -151,6 +151,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 (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/mi/mi-cmd-var.c (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -414,6 +414,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 (_("Usage: NAME."));
+
+ /* Get varobj handle, if a valid var obj name was specified. */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error (_("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 (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/varobj.c (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -101,6 +101,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;
@@ -236,6 +240,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);
@@ -256,6 +262,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);
@@ -274,6 +282,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);
@@ -301,6 +311,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);
@@ -325,6 +339,7 @@ static struct language_specific language
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,
@@ -337,6 +352,7 @@ static struct language_specific language
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,
@@ -349,6 +365,7 @@ static struct language_specific language
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,
@@ -361,6 +378,7 @@ static struct language_specific language
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,
@@ -444,6 +462,7 @@ varobj_create (char *objname,
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ int expr_len;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
@@ -488,7 +507,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
@@ -806,6 +828,23 @@ 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
+ {
+ /* For root varobjs, we initialize path_expr
+ when creating varobj, so here it should be
+ child varobj. */
+ gdb_assert (!is_root_p (var));
+ return (*var->root->lang->path_expr_of_child) (var);
+ }
+}
+
enum varobj_languages
varobj_get_language (struct varobj *var)
{
@@ -1459,6 +1498,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;
@@ -1507,6 +1547,7 @@ free_variable (struct varobj *var)
xfree (var->name);
xfree (var->obj_name);
xfree (var->print_value);
+ xfree (var->path_expr);
xfree (var);
}
@@ -1847,13 +1888,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_child_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);
/* The type of value stored in varobj, that is passed
@@ -1874,6 +1923,8 @@ adjust_value_for_child_access (struct va
if (value && *value)
gdb_value_ind (*value, value);
*type = target_type;
+ if (was_ptr)
+ *was_ptr = 1;
}
}
@@ -1890,7 +1941,7 @@ c_number_of_children (struct varobj *var
int children = 0;
struct type *target;
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
target = get_target_type (type);
switch (TYPE_CODE (type))
@@ -1986,10 +2037,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_value_type (parent);
+ char *parent_expression = NULL;
+ int was_ptr;
if (cname)
*cname = NULL;
@@ -1997,8 +2051,12 @@ c_describe_child (struct varobj *parent,
*cvalue = NULL;
if (ctype)
*ctype = NULL;
-
- adjust_value_for_child_access (&value, &type);
+ if (cfull_expression)
+ {
+ *cfull_expression = NULL;
+ parent_expression = varobj_get_path_expr (parent);
+ }
+ adjust_value_for_child_access (&value, &type, &was_ptr);
switch (TYPE_CODE (type))
{
@@ -2018,6 +2076,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:
@@ -2037,6 +2101,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:
@@ -2051,6 +2122,9 @@ c_describe_child (struct varobj *parent,
declared type of the variable. */
if (ctype)
*ctype = TYPE_TARGET_TYPE (type);
+
+ if (cfull_expression)
+ *cfull_expression = xstrprintf ("*(%s)", parent_expression);
break;
@@ -2058,6 +2132,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. */
}
}
@@ -2066,10 +2142,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)
{
@@ -2118,7 +2202,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);
return value;
}
@@ -2127,7 +2211,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;
}
@@ -2217,7 +2301,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
type = get_value_type (var);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2244,7 +2328,7 @@ cplus_number_of_children (struct varobj
int kids[3];
type = get_value_type (var->parent);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2315,11 +2399,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 = NULL;
struct value *value;
struct type *type;
+ int was_ptr;
+ char *parent_expression = NULL;
if (cname)
*cname = NULL;
@@ -2327,24 +2414,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_value_type (parent->parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent->parent);
}
else
{
value = parent->value;
type = get_value_type (parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent);
}
- adjust_value_for_child_access (&value, &type);
+ adjust_value_for_child_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
@@ -2379,6 +2472,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))
{
@@ -2389,12 +2487,30 @@ cplus_describe_child (struct varobj *par
if (cvalue && value)
{
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+ release_value (*cvalue);
}
if (ctype)
{
*ctype = TYPE_FIELD_TYPE (type, index);
}
+
+ if (cfull_expression)
+ {
+ char *ptr = was_ptr ? "*" : "";
+ /* Cast the parent to the base' type. Note that in gdb,
+ expression like
+ (Base1)d
+ will create an lvalue, for all appearences, so we don't
+ need to use more fancy:
+ *(Base1*)(&d)
+ construct. */
+ *cfull_expression = xstrprintf ("(%s(%s%s) %s)",
+ ptr,
+ TYPE_FIELD_NAME (type, index),
+ ptr,
+ parent_expression);
+ }
}
else
{
@@ -2442,12 +2558,12 @@ cplus_describe_child (struct varobj *par
if (cname)
*cname = xstrdup (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);
}
}
@@ -2455,10 +2571,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)
{
@@ -2469,7 +2593,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;
}
@@ -2477,7 +2601,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;
}
@@ -2549,6 +2673,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 (/mirrors/gdb_mainline) (revision 4580)
+++ gdb/varobj.h (/patches/gdb/path_expression/gdb_mainline) (revision 4580)
@@ -99,6 +99,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_4_unify_cpp/gdb_mainline
Name: svk:merge
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_1/gdb_mainline:3166
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_2_children/gdb_mainline:3167
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_5_references/gdb_mainline:3213
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_unify/gdb_mainline:3168
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_4_unify_cpp/gdb_mainline:3214
+e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:179582
[-- Attachment #4: path_expression_delta.diff --]
[-- Type: text/x-diff, Size: 7357 bytes --]
--- gdb/doc/gdb.texinfo (revision 4579)
+++ gdb/doc/gdb.texinfo (local)
@@ -19304,7 +19304,9 @@ access this functionality:
@item @code{-var-info-type}
@tab show the type of this variable object
@item @code{-var-info-expression}
-@tab print what this variable object represents
+@tab print parent-relative expression that this variable object represents
+@item @code{-var-info-path-expression}
+@tab print full expression that this variable object represents
@item @code{-var-show-attributes}
@tab is this variable editable? does it exist here?
@item @code{-var-evaluate-expression}
@@ -19505,8 +19507,36 @@ returned as a string in the same format
-var-info-expression @var{name}
@end smallexample
-Returns what is represented by the variable object @var{name}:
+Returns the expression that is represented by the variable object
+@var{name}, that is relative to parent variable object and is
+suitable for presenting this variable object is user interface:
+
+@smallexample
+ lang=@var{lang-spec},exp=@var{expression}
+@end smallexample
+
+@noindent
+where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+
+@subheading The @code{-var-info-path-expression} Command
+@findex -var-info-path-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-path-expression @var{name}
+@end smallexample
+
+Returns a full expression that can be evaluated in the current
+context and corresponds to the variable object. Unlike the
+@code{-var-info-expression} command, the returned expression is not relative
+to parent and can be used to create another variable object that will
+always have the same value as the other variable object. Typical
+use of @code{-var-info-path-expression} is creating a watchpoint from
+a variable object.
+
+Example output:
@smallexample
lang=@var{lang-spec},exp=@var{expression}
@end smallexample
--- gdb/mi/mi-cmd-var.c (revision 4579)
+++ gdb/mi/mi-cmd-var.c (local)
@@ -422,7 +422,7 @@ mi_cmd_var_info_path_expression (char *c
if (argc != 1)
error (_("Usage: NAME."));
- /* Get varobj handle, if a valid var obj name was specified */
+ /* Get varobj handle, if a valid var obj name was specified. */
var = varobj_get_handle (argv[0]);
if (var == NULL)
error (_("Variable object not found"));
--- gdb/testsuite/gdb.mi/mi-var-cp.cc (revision 4579)
+++ gdb/testsuite/gdb.mi/mi-var-cp.cc (local)
@@ -121,11 +121,97 @@ int reference_to_struct ()
/*: END: reference_to_struct :*/
}
+struct Base1
+{
+ int i;
+};
+
+struct Base2
+{
+ int i;
+};
+
+struct Derived : public Base1, public Base2
+{
+ int i;
+};
+
+/* Test for the -var-info-path-expression command. Although
+ said command is not specific to C++, it's of more importance
+ to C++ than to C, so we test it in mi-var-cp test. */
+int path_expression ()
+{
+ /*: BEGIN: path_expression :*/
+ int i = 10;
+ int *ip = &i;
+ /*: mi_create_varobj IP ip "create varobj for ip"
+ mi_list_varobj_children IP {{IP.\\*ip \\*ip 0 int}} "list children of IP"
+ mi_gdb_test "-var-info-path-expression IP.*ip" \
+ "\\^done,path_expr=\"\\*\\(ip\\)\"" \
+ "-var-info-path-expression IP.*ip"
+ :*/
+ Derived d;
+ Derived *dp = &d;
+ /*: mi_create_varobj DP dp "create varobj for dp"
+ mi_list_varobj_children DP \
+ {{DP.Base1 Base1 1 Base1} \
+ {DP.Base2 Base2 1 Base2} \
+ {DP.public public 1}} "list children of DP"
+ mi_gdb_test "-var-info-path-expression DP.Base1" \
+ "\\^done,path_expr=\"\\(\\*\\(Base1\\*\\) dp\\)\"" \
+ "-var-info-path-expression DP.Base1"
+ mi_list_varobj_children DP.public { \
+ {DP.public.i i 0 int} \
+ } "list children of DP.public"
+ mi_gdb_test "-var-info-path-expression DP.public.i" \
+ "\\^done,path_expr=\"\\(\\(dp\\)->i\\)\"" \
+ "-var-info-path-expression DP.public.i"
+ mi_list_varobj_children DP.Base1 { \
+ {DP.Base1.public public 1} \
+ } "list children of DP.Base1"
+ mi_list_varobj_children DP.Base1.public { \
+ {DP.Base1.public.i i 0 int} \
+ } "list children of DP.Base1.public"
+ mi_gdb_test "-var-info-path-expression DP.Base1.public.i" \
+ "\\^done,path_expr=\"\\(\\(\\(\\*\\(Base1\\*\\) dp\\)\\).i\\)\"" \
+ "-var-info-path-expression DP.Base1.public.i"
+
+ mi_gdb_test "-var-info-path-expression DP.public" \
+ "\\^done,path_expr=\"\"" \
+ "-var-info-path-expression DP.public"
+
+ mi_create_varobj D d "create varobj for d"
+ mi_list_varobj_children D \
+ {{D.Base1 Base1 1 Base1} \
+ {D.Base2 Base2 1 Base2} \
+ {D.public public 1}} "list children of D"
+ mi_gdb_test "-var-info-path-expression D.Base1" \
+ "\\^done,path_expr=\"\\(\\(Base1\\) d\\)\"" \
+ "-var-info-path-expression D.Base1"
+ :*/
+ int array[4] = {1,2,3};
+ array[3] = 10;
+ /*: mi_create_varobj A array "create varobj for array"
+ mi_list_varobj_children A { \
+ {A.0 0 0 int}
+ {A.1 1 0 int}
+ {A.2 2 0 int}
+ {A.3 3 0 int}} "list children of A"
+ mi_gdb_test "-var-info-path-expression A.2" \
+ "\\^done,path_expr=\"\\(array\\)\\\[2\\\]\"" \
+ "-var-info-path-expression A.2"
+ :*/
+
+ return 99;
+ /*: END: path_expression :*/
+}
+
int main ()
{
reference_update_tests ();
base_in_reference_test_main ();
reference_to_pointer ();
reference_to_struct ();
+ path_expression ();
return 0;
}
--- gdb/testsuite/gdb.mi/mi-var-cp.exp (revision 4579)
+++ gdb/testsuite/gdb.mi/mi-var-cp.exp (local)
@@ -45,6 +45,7 @@ mi_run_inline_test reference_update
mi_run_inline_test base_in_reference
mi_run_inline_test reference_to_pointer
mi_run_inline_test reference_to_struct
+mi_run_inline_test path_expression
mi_gdb_exit
return 0
--- gdb/varobj.c (revision 4579)
+++ gdb/varobj.c (local)
@@ -102,7 +102,7 @@ struct varobj
char *name;
/* Alloc'd expression for this child. Can be used to create a
- root variable corresponding to this child. */
+ root variable corresponding to this child. */
char *path_expr;
/* The alloc'd name for this variable's object. This is here for
@@ -829,7 +829,7 @@ varobj_get_gdb_type (struct varobj *var)
}
/* Return a pointer to the full rooted expression of varobj VAR.
- If it has not been computed yet, compute it */
+ If it has not been computed yet, compute it. */
char *
varobj_get_path_expr (struct varobj *var)
{
@@ -2497,8 +2497,16 @@ cplus_describe_child (struct varobj *par
if (cfull_expression)
{
- char *ptr = was_ptr ? " *" : "";
- *cfull_expression = xstrprintf ("((%s%s) %s)",
+ char *ptr = was_ptr ? "*" : "";
+ /* Cast the parent to the base' type. Note that in gdb,
+ expression like
+ (Base1)d
+ will create an lvalue, for all appearences, so we don't
+ need to use more fancy:
+ *(Base1*)(&d)
+ construct. */
+ *cfull_expression = xstrprintf ("(%s(%s%s) %s)",
+ ptr,
TYPE_FIELD_NAME (type, index),
ptr,
parent_expression);
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-08-22 11:23 -var-info-path-expression Vladimir Prus
@ 2007-08-22 15:28 ` Daniel Jacobowitz
2007-08-28 17:18 ` -var-info-path-expression Vladimir Prus
1 sibling, 0 replies; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-08-22 15:28 UTC (permalink / raw)
To: gdb-patches
On Wed, Aug 22, 2007 at 03:23:32PM +0400, Vladimir Prus wrote:
> Daniel, is the code patch still OK to commit?
Yes, it is.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-08-22 11:23 -var-info-path-expression Vladimir Prus
2007-08-22 15:28 ` -var-info-path-expression Daniel Jacobowitz
@ 2007-08-28 17:18 ` Vladimir Prus
2007-08-28 19:55 ` -var-info-path-expression Eli Zaretskii
2007-08-31 9:08 ` -var-info-path-expression Eli Zaretskii
1 sibling, 2 replies; 24+ messages in thread
From: Vladimir Prus @ 2007-08-28 17:18 UTC (permalink / raw)
To: gdb-patches, Eli Zaretskii
Vladimir Prus wrote:
>
> This is the hopefully final revision of the patch
> to add the -var-info-path-expression command.
> The code part of the patch was already approved in:
>
> http://article.gmane.org/gmane.comp.gdb.patches/34902
>
> This revision has these changes:
>
> 1. Documentation for the new command
> 2. Tests for the new command.
> 3. A fix for a bug discovered while testing.
> 4. Some formatting tweaks.
>
> I attach a delta patch with just those changes, for easier
> review, as well as complete patch against FSF HEAD.
>
> Eli, do doc changes look fine?
Eli, did you miss that email, or need more time to look at
the doc patches?
Thanks,
Volodya
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-08-28 17:18 ` -var-info-path-expression Vladimir Prus
@ 2007-08-28 19:55 ` Eli Zaretskii
2007-08-31 9:08 ` -var-info-path-expression Eli Zaretskii
1 sibling, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2007-08-28 19:55 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <ghost@cs.msu.su>
> Date: Tue, 28 Aug 2007 21:16:33 +0400
>
> Eli, did you miss that email, or need more time to look at
> the doc patches?
I didn't see the patch, for some reason I cannot grasp. I will review
it soon, thanks.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-08-28 17:18 ` -var-info-path-expression Vladimir Prus
2007-08-28 19:55 ` -var-info-path-expression Eli Zaretskii
@ 2007-08-31 9:08 ` Eli Zaretskii
2007-08-31 9:57 ` -var-info-path-expression Vladimir Prus
1 sibling, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2007-08-31 9:08 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <ghost@cs.msu.su>
> Date: Tue, 28 Aug 2007 21:16:33 +0400
>
> Vladimir Prus wrote:
>
> >
> > This is the hopefully final revision of the patch
> > to add the -var-info-path-expression command.
> > The code part of the patch was already approved in:
> >
> > http://article.gmane.org/gmane.comp.gdb.patches/34902
> [...]
> > Eli, do doc changes look fine?
Here are my comments:
> +Returns the expression that is represented by the variable object
> +@var{name}, that is relative to parent variable object and is
> +suitable for presenting this variable object is user interface:
^^
That "is" looks like a typo. Did you mean "in", perhaps?
> +@smallexample
> + -var-info-path-expression @var{name}
> +@end smallexample
> +
> +Returns a full expression that can be evaluated in the current
> +context and corresponds to the variable object. Unlike the
> +@code{-var-info-expression} command, the returned expression is not relative
> +to parent and can be used to create another variable object that will
> +always have the same value as the other variable object. Typical
> +use of @code{-var-info-path-expression} is creating a watchpoint from
> +a variable object.
> +
> +Example output:
> @smallexample
> lang=@var{lang-spec},exp=@var{expression}
> @end smallexample
I'd like to improve the documentation of -var-info-path-expression and
-var-info-expression, such that the difference between them is clearly
explained. Right now, having read the documentation of both of them,
I am confused about how they differ. What does it mean, exactly,
"expression represented by the variable object", and what does it mean
"relative to parent variable object"? The examples don't help,
either, because they are identical.
How about if you write a real-life example of the output generated by
both commands (i.e. with real expressions, not @var{something}), and
place both of the examples in each section to show how the two
commands differ? Alternatively, have only one example in each
section, and point to the other, as in "Contrast this with the output
generated by -var-info-path-expression below."
> --- gdb/doc/gdb.texinfo (revision 4579)
> +++ gdb/doc/gdb.texinfo (local)
Why there are two patches for gdb.texinfo?
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-08-31 9:08 ` -var-info-path-expression Eli Zaretskii
@ 2007-08-31 9:57 ` Vladimir Prus
2007-08-31 18:04 ` -var-info-path-expression Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2007-08-31 9:57 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2896 bytes --]
On Friday 31 August 2007 13:08:06 Eli Zaretskii wrote:
> > From: Vladimir Prus <ghost@cs.msu.su>
> > Date: Tue, 28 Aug 2007 21:16:33 +0400
> >
> > Vladimir Prus wrote:
> >
> > >
> > > This is the hopefully final revision of the patch
> > > to add the -var-info-path-expression command.
> > > The code part of the patch was already approved in:
> > >
> > > http://article.gmane.org/gmane.comp.gdb.patches/34902
> > [...]
> > > Eli, do doc changes look fine?
>
> Here are my comments:
>
> > +Returns the expression that is represented by the variable object
> > +@var{name}, that is relative to parent variable object and is
> > +suitable for presenting this variable object is user interface:
> ^^
> That "is" looks like a typo. Did you mean "in", perhaps?
>
> > +@smallexample
> > + -var-info-path-expression @var{name}
> > +@end smallexample
> > +
> > +Returns a full expression that can be evaluated in the current
> > +context and corresponds to the variable object. Unlike the
> > +@code{-var-info-expression} command, the returned expression is not relative
> > +to parent and can be used to create another variable object that will
> > +always have the same value as the other variable object. Typical
> > +use of @code{-var-info-path-expression} is creating a watchpoint from
> > +a variable object.
> > +
> > +Example output:
> > @smallexample
> > lang=@var{lang-spec},exp=@var{expression}
> > @end smallexample
>
> I'd like to improve the documentation of -var-info-path-expression and
> -var-info-expression, such that the difference between them is clearly
> explained. Right now, having read the documentation of both of them,
> I am confused about how they differ. What does it mean, exactly,
> "expression represented by the variable object", and what does it mean
> "relative to parent variable object"? The examples don't help,
> either, because they are identical.
>
> How about if you write a real-life example of the output generated by
> both commands (i.e. with real expressions, not @var{something}), and
> place both of the examples in each section to show how the two
> commands differ? Alternatively, have only one example in each
> section, and point to the other, as in "Contrast this with the output
> generated by -var-info-path-expression below."
How about this patch? If has real examples, and tries to stress the
fact that -var-info-expression is only for UI presentation, while
-var-info-path-expression is for getting an expression you can actually
evaluate.
>
> > --- gdb/doc/gdb.texinfo (revision 4579)
> > +++ gdb/doc/gdb.texinfo (local)
>
> Why there are two patches for gdb.texinfo?
Because as I say, I'm sending both a patch against CVS HEAD,
and a delta patch against previous version. The latter is
mostly to help Dan re-review the patch, you could have
ignored it.
- Volodya
[-- Attachment #2: path_expression.diff --]
[-- Type: text/x-diff, Size: 23939 bytes --]
--- gdb/doc/gdb.texinfo (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/doc/gdb.texinfo (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -19312,7 +19312,9 @@ access this functionality:
@item @code{-var-info-type}
@tab show the type of this variable object
@item @code{-var-info-expression}
-@tab print what this variable object represents
+@tab print parent-relative expression that this variable object represents
+@item @code{-var-info-path-expression}
+@tab print full expression that this variable object represents
@item @code{-var-show-attributes}
@tab is this variable editable? does it exist here?
@item @code{-var-evaluate-expression}
@@ -19513,14 +19515,50 @@ returned as a string in the same format
-var-info-expression @var{name}
@end smallexample
-Returns what is represented by the variable object @var{name}:
+Returns a string that is suitable for presenting this
+variable object in user interface. The string is generally
+not valid expression in the current language, and cannot be evaluated.
+
+For example, if @var{a} is an array, and variable object
+@var{A} was created for @var{a}, then we'll get this output:
@smallexample
- lang=@var{lang-spec},exp=@var{expression}
+(gdb) -var-info-expression A.1
+^done,lang="C",exp="1"
@end smallexample
@noindent
-where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+Here, the values of @var{lang} can be @code{@{"C" | "C++" | "Java"@}}.
+
+Note that the output of the @code{-var-list-children} command also
+includes those expressions, so the @code{-var-info-expression} command
+is of limited use.
+
+@subheading The @code{-var-info-path-expression} Command
+@findex -var-info-path-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-path-expression @var{name}
+@end smallexample
+
+Returns an expression that can be evaluated in the current
+context and will yield the same value that a variable object has.
+Compare this with the @code{-var-info-expression} command, which
+result can be used only for UI presentation. Typical use of
+the @code{-var-info-path-expression} command is creating a
+watchpoint from a variable object.
+
+For example, suppose @var{C} is a C++ class, derived from class
+@var{Base}, and that the @var{Base} class has a member called
+@var{m_size}. Assume a variable @var{c} is has the type of
+@var{C} and a variable object @var{C} was created for variable
+@var{c}. Then, we'll get this output:
+@smallexample
+(gdb) -var-info-path-expression C.Base.public.m_size
+^done,path_expr=((Base)c).m_size)
+@end smallexample
@subheading The @code{-var-show-attributes} Command
@findex -var-show-attributes
--- gdb/testsuite/gdb.mi/mi-var-cp.exp (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/testsuite/gdb.mi/mi-var-cp.exp (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -44,6 +44,7 @@ mi_run_inline_test reference_update
mi_run_inline_test base_in_reference
mi_run_inline_test reference_to_pointer
mi_run_inline_test reference_to_struct
+mi_run_inline_test path_expression
mi_gdb_exit
return 0
--- gdb/testsuite/gdb.mi/mi-var-cp.cc (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/testsuite/gdb.mi/mi-var-cp.cc (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -120,11 +120,97 @@ int reference_to_struct ()
/*: END: reference_to_struct :*/
}
+struct Base1
+{
+ int i;
+};
+
+struct Base2
+{
+ int i;
+};
+
+struct Derived : public Base1, public Base2
+{
+ int i;
+};
+
+/* Test for the -var-info-path-expression command. Although
+ said command is not specific to C++, it's of more importance
+ to C++ than to C, so we test it in mi-var-cp test. */
+int path_expression ()
+{
+ /*: BEGIN: path_expression :*/
+ int i = 10;
+ int *ip = &i;
+ /*: mi_create_varobj IP ip "create varobj for ip"
+ mi_list_varobj_children IP {{IP.\\*ip \\*ip 0 int}} "list children of IP"
+ mi_gdb_test "-var-info-path-expression IP.*ip" \
+ "\\^done,path_expr=\"\\*\\(ip\\)\"" \
+ "-var-info-path-expression IP.*ip"
+ :*/
+ Derived d;
+ Derived *dp = &d;
+ /*: mi_create_varobj DP dp "create varobj for dp"
+ mi_list_varobj_children DP \
+ {{DP.Base1 Base1 1 Base1} \
+ {DP.Base2 Base2 1 Base2} \
+ {DP.public public 1}} "list children of DP"
+ mi_gdb_test "-var-info-path-expression DP.Base1" \
+ "\\^done,path_expr=\"\\(\\*\\(Base1\\*\\) dp\\)\"" \
+ "-var-info-path-expression DP.Base1"
+ mi_list_varobj_children DP.public { \
+ {DP.public.i i 0 int} \
+ } "list children of DP.public"
+ mi_gdb_test "-var-info-path-expression DP.public.i" \
+ "\\^done,path_expr=\"\\(\\(dp\\)->i\\)\"" \
+ "-var-info-path-expression DP.public.i"
+ mi_list_varobj_children DP.Base1 { \
+ {DP.Base1.public public 1} \
+ } "list children of DP.Base1"
+ mi_list_varobj_children DP.Base1.public { \
+ {DP.Base1.public.i i 0 int} \
+ } "list children of DP.Base1.public"
+ mi_gdb_test "-var-info-path-expression DP.Base1.public.i" \
+ "\\^done,path_expr=\"\\(\\(\\(\\*\\(Base1\\*\\) dp\\)\\).i\\)\"" \
+ "-var-info-path-expression DP.Base1.public.i"
+
+ mi_gdb_test "-var-info-path-expression DP.public" \
+ "\\^done,path_expr=\"\"" \
+ "-var-info-path-expression DP.public"
+
+ mi_create_varobj D d "create varobj for d"
+ mi_list_varobj_children D \
+ {{D.Base1 Base1 1 Base1} \
+ {D.Base2 Base2 1 Base2} \
+ {D.public public 1}} "list children of D"
+ mi_gdb_test "-var-info-path-expression D.Base1" \
+ "\\^done,path_expr=\"\\(\\(Base1\\) d\\)\"" \
+ "-var-info-path-expression D.Base1"
+ :*/
+ int array[4] = {1,2,3};
+ array[3] = 10;
+ /*: mi_create_varobj A array "create varobj for array"
+ mi_list_varobj_children A { \
+ {A.0 0 0 int}
+ {A.1 1 0 int}
+ {A.2 2 0 int}
+ {A.3 3 0 int}} "list children of A"
+ mi_gdb_test "-var-info-path-expression A.2" \
+ "\\^done,path_expr=\"\\(array\\)\\\[2\\\]\"" \
+ "-var-info-path-expression A.2"
+ :*/
+
+ return 99;
+ /*: END: path_expression :*/
+}
+
int main ()
{
reference_update_tests ();
base_in_reference_test_main ();
reference_to_pointer ();
reference_to_struct ();
+ path_expression ();
return 0;
}
--- gdb/mi/mi-cmds.h (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/mi/mi-cmds.h (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -107,6 +107,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 (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/mi/mi-cmds.c (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -149,6 +149,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 (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/mi/mi-cmd-var.c (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -412,6 +412,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 (_("Usage: NAME."));
+
+ /* Get varobj handle, if a valid var obj name was specified. */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error (_("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 (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/varobj.c (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -99,6 +99,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;
@@ -234,6 +238,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);
@@ -254,6 +260,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);
@@ -272,6 +280,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);
@@ -299,6 +309,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);
@@ -323,6 +337,7 @@ static struct language_specific language
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,
@@ -335,6 +350,7 @@ static struct language_specific language
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,
@@ -347,6 +363,7 @@ static struct language_specific language
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,
@@ -359,6 +376,7 @@ static struct language_specific language
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,
@@ -442,6 +460,7 @@ varobj_create (char *objname,
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ int expr_len;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
@@ -486,7 +505,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
@@ -804,6 +826,23 @@ 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
+ {
+ /* For root varobjs, we initialize path_expr
+ when creating varobj, so here it should be
+ child varobj. */
+ gdb_assert (!is_root_p (var));
+ return (*var->root->lang->path_expr_of_child) (var);
+ }
+}
+
enum varobj_languages
varobj_get_language (struct varobj *var)
{
@@ -1457,6 +1496,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;
@@ -1505,6 +1545,7 @@ free_variable (struct varobj *var)
xfree (var->name);
xfree (var->obj_name);
xfree (var->print_value);
+ xfree (var->path_expr);
xfree (var);
}
@@ -1845,13 +1886,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_child_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);
/* The type of value stored in varobj, that is passed
@@ -1872,6 +1921,8 @@ adjust_value_for_child_access (struct va
if (value && *value)
gdb_value_ind (*value, value);
*type = target_type;
+ if (was_ptr)
+ *was_ptr = 1;
}
}
@@ -1888,7 +1939,7 @@ c_number_of_children (struct varobj *var
int children = 0;
struct type *target;
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
target = get_target_type (type);
switch (TYPE_CODE (type))
@@ -1984,10 +2035,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_value_type (parent);
+ char *parent_expression = NULL;
+ int was_ptr;
if (cname)
*cname = NULL;
@@ -1995,8 +2049,12 @@ c_describe_child (struct varobj *parent,
*cvalue = NULL;
if (ctype)
*ctype = NULL;
-
- adjust_value_for_child_access (&value, &type);
+ if (cfull_expression)
+ {
+ *cfull_expression = NULL;
+ parent_expression = varobj_get_path_expr (parent);
+ }
+ adjust_value_for_child_access (&value, &type, &was_ptr);
switch (TYPE_CODE (type))
{
@@ -2016,6 +2074,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:
@@ -2035,6 +2099,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:
@@ -2049,6 +2120,9 @@ c_describe_child (struct varobj *parent,
declared type of the variable. */
if (ctype)
*ctype = TYPE_TARGET_TYPE (type);
+
+ if (cfull_expression)
+ *cfull_expression = xstrprintf ("*(%s)", parent_expression);
break;
@@ -2056,6 +2130,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. */
}
}
@@ -2064,10 +2140,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)
{
@@ -2116,7 +2200,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);
return value;
}
@@ -2125,7 +2209,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;
}
@@ -2215,7 +2299,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
type = get_value_type (var);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2242,7 +2326,7 @@ cplus_number_of_children (struct varobj
int kids[3];
type = get_value_type (var->parent);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2313,11 +2397,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 = NULL;
struct value *value;
struct type *type;
+ int was_ptr;
+ char *parent_expression = NULL;
if (cname)
*cname = NULL;
@@ -2325,24 +2412,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_value_type (parent->parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent->parent);
}
else
{
value = parent->value;
type = get_value_type (parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent);
}
- adjust_value_for_child_access (&value, &type);
+ adjust_value_for_child_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
@@ -2377,6 +2470,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))
{
@@ -2387,12 +2485,30 @@ cplus_describe_child (struct varobj *par
if (cvalue && value)
{
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+ release_value (*cvalue);
}
if (ctype)
{
*ctype = TYPE_FIELD_TYPE (type, index);
}
+
+ if (cfull_expression)
+ {
+ char *ptr = was_ptr ? "*" : "";
+ /* Cast the parent to the base' type. Note that in gdb,
+ expression like
+ (Base1)d
+ will create an lvalue, for all appearences, so we don't
+ need to use more fancy:
+ *(Base1*)(&d)
+ construct. */
+ *cfull_expression = xstrprintf ("(%s(%s%s) %s)",
+ ptr,
+ TYPE_FIELD_NAME (type, index),
+ ptr,
+ parent_expression);
+ }
}
else
{
@@ -2440,12 +2556,12 @@ cplus_describe_child (struct varobj *par
if (cname)
*cname = xstrdup (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);
}
}
@@ -2453,10 +2569,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)
{
@@ -2467,7 +2591,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;
}
@@ -2475,7 +2599,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;
}
@@ -2547,6 +2671,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 (/mirrors/gdb_mainline) (revision 4657)
+++ gdb/varobj.h (/patches/gdb/path_expression/gdb_mainline) (revision 4657)
@@ -97,6 +97,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_4_unify_cpp/gdb_mainline
Name: svk:merge
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_1/gdb_mainline:3166
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_2_children/gdb_mainline:3167
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_5_references/gdb_mainline:3213
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_3_unify/gdb_mainline:3168
+d48a11ec-ee1c-0410-b3f5-c20844f99675:/patches/gdb/path_4_unify_cpp/gdb_mainline:3214
+e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:180316
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-08-31 9:57 ` -var-info-path-expression Vladimir Prus
@ 2007-08-31 18:04 ` Eli Zaretskii
2007-08-31 18:53 ` -var-info-path-expression Vladimir Prus
0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2007-08-31 18:04 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <ghost@cs.msu.su>
> Date: Fri, 31 Aug 2007 13:57:04 +0400
> Cc: gdb-patches@sources.redhat.com
>
> > How about if you write a real-life example of the output generated by
> > both commands (i.e. with real expressions, not @var{something}), and
> > place both of the examples in each section to show how the two
> > commands differ? Alternatively, have only one example in each
> > section, and point to the other, as in "Contrast this with the output
> > generated by -var-info-path-expression below."
>
> How about this patch? If has real examples, and tries to stress the
> fact that -var-info-expression is only for UI presentation, while
> -var-info-path-expression is for getting an expression you can actually
> evaluate.
Thanks, this needs only a few minot fixes:
> +For example, if @var{a} is an array, and variable object
> +@var{A} was created for @var{a}, then we'll get this output:
It's wrong to use @var in this context: here, `a' and `A' are literal
symbols, they do not stand for something else. So you should use
@code, not @var.
> +Here, the values of @var{lang} can be @code{@{"C" | "C++" | "Java"@}}.
Again, "lang" is a literal string, so use @code.
> +For example, suppose @var{C} is a C++ class, derived from class
^^^
Please use "C@t{++}", it looks better in print.
> +@var{Base}, and that the @var{Base} class has a member called
> +@var{m_size}. Assume a variable @var{c} is has the type of
> +@var{C} and a variable object @var{C} was created for variable
> +@var{c}. Then, we'll get this output:
> +@smallexample
> +(gdb) -var-info-path-expression C.Base.public.m_size
> +^done,path_expr=((Base)c).m_size)
> +@end smallexample
Here, too, all the symbols should have the @code markup.
Thanks again for working on this.
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-08-31 18:04 ` -var-info-path-expression Eli Zaretskii
@ 2007-08-31 18:53 ` Vladimir Prus
2007-09-01 7:56 ` -var-info-path-expression Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2007-08-31 18:53 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2175 bytes --]
On Friday 31 August 2007 22:04:03 Eli Zaretskii wrote:
> > From: Vladimir Prus <ghost@cs.msu.su>
> > Date: Fri, 31 Aug 2007 13:57:04 +0400
> > Cc: gdb-patches@sources.redhat.com
> >
> > > How about if you write a real-life example of the output generated by
> > > both commands (i.e. with real expressions, not @var{something}), and
> > > place both of the examples in each section to show how the two
> > > commands differ? Alternatively, have only one example in each
> > > section, and point to the other, as in "Contrast this with the output
> > > generated by -var-info-path-expression below."
> >
> > How about this patch? If has real examples, and tries to stress the
> > fact that -var-info-expression is only for UI presentation, while
> > -var-info-path-expression is for getting an expression you can actually
> > evaluate.
>
> Thanks, this needs only a few minot fixes:
>
> > +For example, if @var{a} is an array, and variable object
> > +@var{A} was created for @var{a}, then we'll get this output:
>
> It's wrong to use @var in this context: here, `a' and `A' are literal
> symbols, they do not stand for something else. So you should use
> @code, not @var.
So, @var is not for programming language variables (like docbook's varname),
but rather a placeholder (like docbook's replaceable)?
> > +Here, the values of @var{lang} can be @code{@{"C" | "C++" | "Java"@}}.
>
> Again, "lang" is a literal string, so use @code.
>
> > +For example, suppose @var{C} is a C++ class, derived from class
> ^^^
> Please use "C@t{++}", it looks better in print.
>
> > +@var{Base}, and that the @var{Base} class has a member called
> > +@var{m_size}. Assume a variable @var{c} is has the type of
> > +@var{C} and a variable object @var{C} was created for variable
> > +@var{c}. Then, we'll get this output:
> > +@smallexample
> > +(gdb) -var-info-path-expression C.Base.public.m_size
> > +^done,path_expr=((Base)c).m_size)
> > +@end smallexample
>
> Here, too, all the symbols should have the @code markup.
>
> Thanks again for working on this.
Thanks for review. Here's the version I've checked in to CVS.
- Volodya
[-- Attachment #2: path_expression_as_comitted.diff --]
[-- Type: text/x-diff, Size: 27349 bytes --]
Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.8660
diff -u -p -r1.8660 ChangeLog
--- gdb/ChangeLog 31 Aug 2007 18:41:48 -0000 1.8660
+++ gdb/ChangeLog 31 Aug 2007 18:50:38 -0000
@@ -1,5 +1,34 @@
2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
+ 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.
+
+2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
+
* mi/mi-cmd-var.c (print_varobj): If a varobj
type is NULL, don't try to print it.
Index: gdb/varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.93
diff -u -p -r1.93 varobj.c
--- gdb/varobj.c 23 Aug 2007 18:08:46 -0000 1.93
+++ gdb/varobj.c 31 Aug 2007 18:50:38 -0000
@@ -99,6 +99,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;
@@ -234,6 +238,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);
@@ -254,6 +260,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);
@@ -272,6 +280,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);
@@ -299,6 +309,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);
@@ -323,6 +337,7 @@ static struct language_specific language
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,
@@ -335,6 +350,7 @@ static struct language_specific language
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,
@@ -347,6 +363,7 @@ static struct language_specific language
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,
@@ -359,6 +376,7 @@ static struct language_specific language
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,
@@ -442,6 +460,7 @@ varobj_create (char *objname,
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ int expr_len;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
@@ -486,7 +505,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
@@ -804,6 +826,23 @@ 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
+ {
+ /* For root varobjs, we initialize path_expr
+ when creating varobj, so here it should be
+ child varobj. */
+ gdb_assert (!is_root_p (var));
+ return (*var->root->lang->path_expr_of_child) (var);
+ }
+}
+
enum varobj_languages
varobj_get_language (struct varobj *var)
{
@@ -1457,6 +1496,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;
@@ -1505,6 +1545,7 @@ free_variable (struct varobj *var)
xfree (var->name);
xfree (var->obj_name);
xfree (var->print_value);
+ xfree (var->path_expr);
xfree (var);
}
@@ -1845,13 +1886,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_child_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);
/* The type of value stored in varobj, that is passed
@@ -1872,6 +1921,8 @@ adjust_value_for_child_access (struct va
if (value && *value)
gdb_value_ind (*value, value);
*type = target_type;
+ if (was_ptr)
+ *was_ptr = 1;
}
}
@@ -1888,7 +1939,7 @@ c_number_of_children (struct varobj *var
int children = 0;
struct type *target;
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
target = get_target_type (type);
switch (TYPE_CODE (type))
@@ -1984,10 +2035,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_value_type (parent);
+ char *parent_expression = NULL;
+ int was_ptr;
if (cname)
*cname = NULL;
@@ -1995,8 +2049,12 @@ c_describe_child (struct varobj *parent,
*cvalue = NULL;
if (ctype)
*ctype = NULL;
-
- adjust_value_for_child_access (&value, &type);
+ if (cfull_expression)
+ {
+ *cfull_expression = NULL;
+ parent_expression = varobj_get_path_expr (parent);
+ }
+ adjust_value_for_child_access (&value, &type, &was_ptr);
switch (TYPE_CODE (type))
{
@@ -2016,6 +2074,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:
@@ -2035,6 +2099,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:
@@ -2049,6 +2120,9 @@ c_describe_child (struct varobj *parent,
declared type of the variable. */
if (ctype)
*ctype = TYPE_TARGET_TYPE (type);
+
+ if (cfull_expression)
+ *cfull_expression = xstrprintf ("*(%s)", parent_expression);
break;
@@ -2056,6 +2130,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. */
}
}
@@ -2064,10 +2140,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)
{
@@ -2116,7 +2200,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);
return value;
}
@@ -2125,7 +2209,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;
}
@@ -2215,7 +2299,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
type = get_value_type (var);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2242,7 +2326,7 @@ cplus_number_of_children (struct varobj
int kids[3];
type = get_value_type (var->parent);
- adjust_value_for_child_access (NULL, &type);
+ adjust_value_for_child_access (NULL, &type, NULL);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2313,11 +2397,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 = NULL;
struct value *value;
struct type *type;
+ int was_ptr;
+ char *parent_expression = NULL;
if (cname)
*cname = NULL;
@@ -2325,24 +2412,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_value_type (parent->parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent->parent);
}
else
{
value = parent->value;
type = get_value_type (parent);
+ if (cfull_expression)
+ parent_expression = varobj_get_path_expr (parent);
}
- adjust_value_for_child_access (&value, &type);
+ adjust_value_for_child_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
@@ -2377,6 +2470,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))
{
@@ -2387,12 +2485,30 @@ cplus_describe_child (struct varobj *par
if (cvalue && value)
{
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+ release_value (*cvalue);
}
if (ctype)
{
*ctype = TYPE_FIELD_TYPE (type, index);
}
+
+ if (cfull_expression)
+ {
+ char *ptr = was_ptr ? "*" : "";
+ /* Cast the parent to the base' type. Note that in gdb,
+ expression like
+ (Base1)d
+ will create an lvalue, for all appearences, so we don't
+ need to use more fancy:
+ *(Base1*)(&d)
+ construct. */
+ *cfull_expression = xstrprintf ("(%s(%s%s) %s)",
+ ptr,
+ TYPE_FIELD_NAME (type, index),
+ ptr,
+ parent_expression);
+ }
}
else
{
@@ -2440,12 +2556,12 @@ cplus_describe_child (struct varobj *par
if (cname)
*cname = xstrdup (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);
}
}
@@ -2453,10 +2569,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)
{
@@ -2467,7 +2591,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;
}
@@ -2475,7 +2599,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;
}
@@ -2547,6 +2671,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)
{
Index: gdb/varobj.h
===================================================================
RCS file: /cvs/src/src/gdb/varobj.h,v
retrieving revision 1.11
diff -u -p -r1.11 varobj.h
--- gdb/varobj.h 23 Aug 2007 18:08:47 -0000 1.11
+++ gdb/varobj.h 31 Aug 2007 18:50:38 -0000
@@ -97,6 +97,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);
Index: gdb/doc/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/doc/ChangeLog,v
retrieving revision 1.691
diff -u -p -r1.691 ChangeLog
--- gdb/doc/ChangeLog 21 Aug 2007 15:09:59 -0000 1.691
+++ gdb/doc/ChangeLog 31 Aug 2007 18:50:40 -0000
@@ -1,3 +1,9 @@
+2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
+
+ * gdb.texinfo (Variable Objects): Adjust docs
+ for -var-info-expression and document
+ -var-info-path-expression.
+
2007-08-20 Jim Blandy <jimb@codesourcery.com>
* gdb.texinfo (Top): Dedicate manual to the memory of Fred Fish.
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.423
diff -u -p -r1.423 gdb.texinfo
--- gdb/doc/gdb.texinfo 21 Aug 2007 15:09:59 -0000 1.423
+++ gdb/doc/gdb.texinfo 31 Aug 2007 18:50:52 -0000
@@ -19312,7 +19312,9 @@ access this functionality:
@item @code{-var-info-type}
@tab show the type of this variable object
@item @code{-var-info-expression}
-@tab print what this variable object represents
+@tab print parent-relative expression that this variable object represents
+@item @code{-var-info-path-expression}
+@tab print full expression that this variable object represents
@item @code{-var-show-attributes}
@tab is this variable editable? does it exist here?
@item @code{-var-evaluate-expression}
@@ -19513,14 +19515,50 @@ returned as a string in the same format
-var-info-expression @var{name}
@end smallexample
-Returns what is represented by the variable object @var{name}:
+Returns a string that is suitable for presenting this
+variable object in user interface. The string is generally
+not valid expression in the current language, and cannot be evaluated.
+
+For example, if @code{a} is an array, and variable object
+@code{A} was created for @code{a}, then we'll get this output:
@smallexample
- lang=@var{lang-spec},exp=@var{expression}
+(gdb) -var-info-expression A.1
+^done,lang="C",exp="1"
@end smallexample
@noindent
-where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+Here, the values of @code{lang} can be @code{@{"C" | "C++" | "Java"@}}.
+
+Note that the output of the @code{-var-list-children} command also
+includes those expressions, so the @code{-var-info-expression} command
+is of limited use.
+
+@subheading The @code{-var-info-path-expression} Command
+@findex -var-info-path-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-path-expression @var{name}
+@end smallexample
+
+Returns an expression that can be evaluated in the current
+context and will yield the same value that a variable object has.
+Compare this with the @code{-var-info-expression} command, which
+result can be used only for UI presentation. Typical use of
+the @code{-var-info-path-expression} command is creating a
+watchpoint from a variable object.
+
+For example, suppose @code{C} is a C@t{++} class, derived from class
+@code{Base}, and that the @code{Base} class has a member called
+@code{m_size}. Assume a variable @code{c} is has the type of
+@code{C} and a variable object @code{C} was created for variable
+@code{c}. Then, we'll get this output:
+@smallexample
+(gdb) -var-info-path-expression C.Base.public.m_size
+^done,path_expr=((Base)c).m_size)
+@end smallexample
@subheading The @code{-var-show-attributes} Command
@findex -var-show-attributes
Index: gdb/mi/mi-cmd-var.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v
retrieving revision 1.39
diff -u -p -r1.39 mi-cmd-var.c
--- gdb/mi/mi-cmd-var.c 31 Aug 2007 18:41:50 -0000 1.39
+++ gdb/mi/mi-cmd-var.c 31 Aug 2007 18:50:52 -0000
@@ -413,6 +413,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 (_("Usage: NAME."));
+
+ /* Get varobj handle, if a valid var obj name was specified. */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error (_("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;
Index: gdb/mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.26
diff -u -p -r1.26 mi-cmds.c
--- gdb/mi/mi-cmds.c 23 Aug 2007 18:08:48 -0000 1.26
+++ gdb/mi/mi-cmds.c 31 Aug 2007 18:50:52 -0000
@@ -149,6 +149,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},
Index: gdb/mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.23
diff -u -p -r1.23 mi-cmds.h
--- gdb/mi/mi-cmds.h 23 Aug 2007 18:08:48 -0000 1.23
+++ gdb/mi/mi-cmds.h 31 Aug 2007 18:50:52 -0000
@@ -107,6 +107,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;
Index: gdb/testsuite/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/ChangeLog,v
retrieving revision 1.1435
diff -u -p -r1.1435 ChangeLog
--- gdb/testsuite/ChangeLog 27 Aug 2007 14:31:46 -0000 1.1435
+++ gdb/testsuite/ChangeLog 31 Aug 2007 18:50:54 -0000
@@ -1,3 +1,9 @@
+2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
+
+ * gdb.mi/mi-var-cp.cc (path_expression): New
+ function.
+ * gdb.mi/mi-var-cp.exp: Run path exression tests.
+
2007-08-27 Markus Deuling <deuling@de.ibm.com>
* gdb.cp/cp-relocate.exp (add-symbol-file): Change addresses
Index: gdb/testsuite/gdb.mi/mi-var-cp.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-cp.cc,v
retrieving revision 1.8
diff -u -p -r1.8 mi-var-cp.cc
--- gdb/testsuite/gdb.mi/mi-var-cp.cc 23 Aug 2007 18:08:49 -0000 1.8
+++ gdb/testsuite/gdb.mi/mi-var-cp.cc 31 Aug 2007 18:50:55 -0000
@@ -120,11 +120,97 @@ int reference_to_struct ()
/*: END: reference_to_struct :*/
}
+struct Base1
+{
+ int i;
+};
+
+struct Base2
+{
+ int i;
+};
+
+struct Derived : public Base1, public Base2
+{
+ int i;
+};
+
+/* Test for the -var-info-path-expression command. Although
+ said command is not specific to C++, it's of more importance
+ to C++ than to C, so we test it in mi-var-cp test. */
+int path_expression ()
+{
+ /*: BEGIN: path_expression :*/
+ int i = 10;
+ int *ip = &i;
+ /*: mi_create_varobj IP ip "create varobj for ip"
+ mi_list_varobj_children IP {{IP.\\*ip \\*ip 0 int}} "list children of IP"
+ mi_gdb_test "-var-info-path-expression IP.*ip" \
+ "\\^done,path_expr=\"\\*\\(ip\\)\"" \
+ "-var-info-path-expression IP.*ip"
+ :*/
+ Derived d;
+ Derived *dp = &d;
+ /*: mi_create_varobj DP dp "create varobj for dp"
+ mi_list_varobj_children DP \
+ {{DP.Base1 Base1 1 Base1} \
+ {DP.Base2 Base2 1 Base2} \
+ {DP.public public 1}} "list children of DP"
+ mi_gdb_test "-var-info-path-expression DP.Base1" \
+ "\\^done,path_expr=\"\\(\\*\\(Base1\\*\\) dp\\)\"" \
+ "-var-info-path-expression DP.Base1"
+ mi_list_varobj_children DP.public { \
+ {DP.public.i i 0 int} \
+ } "list children of DP.public"
+ mi_gdb_test "-var-info-path-expression DP.public.i" \
+ "\\^done,path_expr=\"\\(\\(dp\\)->i\\)\"" \
+ "-var-info-path-expression DP.public.i"
+ mi_list_varobj_children DP.Base1 { \
+ {DP.Base1.public public 1} \
+ } "list children of DP.Base1"
+ mi_list_varobj_children DP.Base1.public { \
+ {DP.Base1.public.i i 0 int} \
+ } "list children of DP.Base1.public"
+ mi_gdb_test "-var-info-path-expression DP.Base1.public.i" \
+ "\\^done,path_expr=\"\\(\\(\\(\\*\\(Base1\\*\\) dp\\)\\).i\\)\"" \
+ "-var-info-path-expression DP.Base1.public.i"
+
+ mi_gdb_test "-var-info-path-expression DP.public" \
+ "\\^done,path_expr=\"\"" \
+ "-var-info-path-expression DP.public"
+
+ mi_create_varobj D d "create varobj for d"
+ mi_list_varobj_children D \
+ {{D.Base1 Base1 1 Base1} \
+ {D.Base2 Base2 1 Base2} \
+ {D.public public 1}} "list children of D"
+ mi_gdb_test "-var-info-path-expression D.Base1" \
+ "\\^done,path_expr=\"\\(\\(Base1\\) d\\)\"" \
+ "-var-info-path-expression D.Base1"
+ :*/
+ int array[4] = {1,2,3};
+ array[3] = 10;
+ /*: mi_create_varobj A array "create varobj for array"
+ mi_list_varobj_children A { \
+ {A.0 0 0 int}
+ {A.1 1 0 int}
+ {A.2 2 0 int}
+ {A.3 3 0 int}} "list children of A"
+ mi_gdb_test "-var-info-path-expression A.2" \
+ "\\^done,path_expr=\"\\(array\\)\\\[2\\\]\"" \
+ "-var-info-path-expression A.2"
+ :*/
+
+ return 99;
+ /*: END: path_expression :*/
+}
+
int main ()
{
reference_update_tests ();
base_in_reference_test_main ();
reference_to_pointer ();
reference_to_struct ();
+ path_expression ();
return 0;
}
Index: gdb/testsuite/gdb.mi/mi-var-cp.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-cp.exp,v
retrieving revision 1.7
diff -u -p -r1.7 mi-var-cp.exp
--- gdb/testsuite/gdb.mi/mi-var-cp.exp 23 Aug 2007 18:14:19 -0000 1.7
+++ gdb/testsuite/gdb.mi/mi-var-cp.exp 31 Aug 2007 18:50:55 -0000
@@ -44,6 +44,7 @@ mi_run_inline_test reference_update
mi_run_inline_test base_in_reference
mi_run_inline_test reference_to_pointer
mi_run_inline_test reference_to_struct
+mi_run_inline_test path_expression
mi_gdb_exit
return 0
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-08-31 18:53 ` -var-info-path-expression Vladimir Prus
@ 2007-09-01 7:56 ` Eli Zaretskii
0 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2007-09-01 7:56 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <ghost@cs.msu.su>
> Date: Fri, 31 Aug 2007 22:52:47 +0400
> Cc: gdb-patches@sources.redhat.com
>
> > > +For example, if @var{a} is an array, and variable object
> > > +@var{A} was created for @var{a}, then we'll get this output:
> >
> > It's wrong to use @var in this context: here, `a' and `A' are literal
> > symbols, they do not stand for something else. So you should use
> > @code, not @var.
>
> So, @var is not for programming language variables (like docbook's varname),
> but rather a placeholder (like docbook's replaceable)?
Yes, it's a placeholder. It's for the cases when you want to say
things like
frobnicate FILE
and FILE is to be replaced by an actual filename when this command is
used.
There's one borderline case where @var is used, although you could
have said that its argument is not a placeholder: when you describe a
prototype of a function:
int foo (char *bar, struct something *baz);
(This example is for C/C++, but similar examples exist in other
languages that support functions with arguments.) The Texinfo @def*
constructs render the arguments in the @var typeface, for example. In
these cases, we will give "bar" and "baz" the @var markup, because
they are formal parameters of the function, and will be replaced by
something else when the function is actually called. The tricky
aspect of this is that when you describe the parameters from _outside_
of the function, e.g. tell someone how to call it, you should use
@var, while for the description of the _inside_, like when you tell
how it works and cite certain parts of its code, those same symbols
should be in @code, because inside the function they are literal
symbols.
It is these borderline cases, as well as the name of the markup (which
mentally reminds you of the word "variable"), which cause confusion
about its usage.
^ permalink raw reply [flat|nested] 24+ messages in thread
* -var-info-path-expression
@ 2006-12-25 9:02 Vladimir Prus
2007-01-03 22:39 ` -var-info-path-expression Daniel Jacobowitz
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2006-12-25 9:02 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2228 bytes --]
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.
[-- Attachment #2: path_expression__gdb_mainline.diff --]
[-- Type: text/x-diff, Size: 16939 bytes --]
--- 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
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2006-12-25 9:02 -var-info-path-expression Vladimir Prus
@ 2007-01-03 22:39 ` Daniel Jacobowitz
2007-01-05 9:14 ` -var-info-path-expression Vladimir Prus
0 siblings, 1 reply; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-01-03 22:39 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Mon, Dec 25, 2006 at 12:00:42PM +0300, Vladimir Prus wrote:
>
> 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.
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?
Having digested the patch, it looks generally OK. I didn't really
proofread it; I'll save that until there's some docs and tests, and
the earlier patches are in. Sorry, too much at once for me.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-01-03 22:39 ` -var-info-path-expression Daniel Jacobowitz
@ 2007-01-05 9:14 ` Vladimir Prus
2007-01-27 21:49 ` -var-info-path-expression Vladimir Prus
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2007-01-05 9:14 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Thursday 04 January 2007 01:39, Daniel Jacobowitz wrote:
> On Mon, Dec 25, 2006 at 12:00:42PM +0300, Vladimir Prus wrote:
> >
> > 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.
>
> 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.
- Volodya
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-01-05 9:14 ` -var-info-path-expression Vladimir Prus
@ 2007-01-27 21:49 ` Vladimir Prus
2007-01-28 0:46 ` -var-info-path-expression Nick Roberts
2007-01-29 12:17 ` -var-info-path-expression Daniel Jacobowitz
0 siblings, 2 replies; 24+ messages in thread
From: Vladimir Prus @ 2007-01-27 21:49 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2354 bytes --]
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.
[-- Attachment #2: path_expression__gdb_mainline.diff --]
[-- Type: text/x-diff, Size: 16939 bytes --]
--- 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
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-01-27 21:49 ` -var-info-path-expression Vladimir Prus
@ 2007-01-28 0:46 ` Nick Roberts
2007-01-28 7:57 ` -var-info-path-expression Vladimir Prus
2007-01-29 12:17 ` -var-info-path-expression Daniel Jacobowitz
1 sibling, 1 reply; 24+ messages in thread
From: Nick Roberts @ 2007-01-28 0:46 UTC (permalink / raw)
To: Vladimir Prus; +Cc: Daniel Jacobowitz, gdb-patches
> 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)
This argument list gets longer but, apart from only parent and index, only
one argument is non-null at any one time. Would it be better to have
enum varobj_child_properties
{
CHILD_NAME,
CHILD_VALUE,
CHILD_TYPE,
CHILD_FULL_EXPRESSION
}
static void *
c_describe_child (enum varobj_child_properties property,
struct varobj *parent, int index)
and propagate these changes back to struct language_specific so we have:
static char *
name_of_child (struct varobj *var, int index)
{
return (char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index);
}
etc?
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-01-28 0:46 ` -var-info-path-expression Nick Roberts
@ 2007-01-28 7:57 ` Vladimir Prus
2007-01-28 8:35 ` -var-info-path-expression Nick Roberts
0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Prus @ 2007-01-28 7:57 UTC (permalink / raw)
To: Nick Roberts; +Cc: Daniel Jacobowitz, gdb-patches
On Sunday 28 January 2007 03:46, Nick Roberts wrote:
> > 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)
>
> This argument list gets longer but, apart from only parent and index, only
> one argument is non-null at any one time.
A future patch is very likely to change this. In particular, the 'create_child' function
needs both name of the child and its value. I might kill separate function
pointers in struct language_specific and use just single describe_child and
make create_child pass two non-NULL pointers?
> Would it be better to have
>
> enum varobj_child_properties
> {
> CHILD_NAME,
> CHILD_VALUE,
> CHILD_TYPE,
> CHILD_FULL_EXPRESSION
> }
>
> static void *
> c_describe_child (enum varobj_child_properties property,
> struct varobj *parent, int index)
>
> and propagate these changes back to struct language_specific so we have:
>
> static char *
> name_of_child (struct varobj *var, int index)
> {
> return (char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index);
And have casts from void* to the right type? I'm not sure that's any advantage.
- Volodya
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-01-28 7:57 ` -var-info-path-expression Vladimir Prus
@ 2007-01-28 8:35 ` Nick Roberts
2007-01-29 10:53 ` -var-info-path-expression Vladimir Prus
0 siblings, 1 reply; 24+ messages in thread
From: Nick Roberts @ 2007-01-28 8:35 UTC (permalink / raw)
To: Vladimir Prus; +Cc: Daniel Jacobowitz, gdb-patches
> > and propagate these changes back to struct language_specific so we have:
> >
> > static char *
> > name_of_child (struct varobj *var, int index)
> > {
> > return (char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index);
>
> And have casts from void* to the right type? I'm not sure that's any
> advantage.
Maybe using making a cast is as sinful as using a goto statement, I wouldn't
know, but I would call having four times fewer functions an advantage.
Perhaps it would be better to use a macro e.g
#define name_of_child(var, index) \
(char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index)
--
Nick http://www.inet.net.nz/~nickrob
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: -var-info-path-expression
2007-01-28 8:35 ` -var-info-path-expression Nick Roberts
@ 2007-01-29 10:53 ` Vladimir Prus
0 siblings, 0 replies; 24+ messages in thread
From: Vladimir Prus @ 2007-01-29 10:53 UTC (permalink / raw)
To: Nick Roberts; +Cc: Daniel Jacobowitz, gdb-patches
On Sunday 28 January 2007 11:34, Nick Roberts wrote:
> > > and propagate these changes back to struct language_specific so we have:
> > >
> > > static char *
> > > name_of_child (struct varobj *var, int index)
> > > {
> > > return (char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index);
> >
> > And have casts from void* to the right type? I'm not sure that's any
> > advantage.
>
> Maybe using making a cast is as sinful as using a goto statement, I wouldn't
> know, but I would call having four times fewer functions an advantage.
"functions"? You mean having just one function pointer in language_specific? Yes,
I agree that would be superiour and I plan to make such a change, separately.
> Perhaps it would be better to use a macro e.g
>
> #define name_of_child(var, index) \
> (char *) (*var->root->lang->describe_child) (CHILD_NAME, var, index)
I'm not sure, I don't quite see reason to introduce macros if we can
avoid them.
- Volodya
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: -var-info-path-expression
2007-01-27 21:49 ` -var-info-path-expression Vladimir Prus
2007-01-28 0:46 ` -var-info-path-expression Nick Roberts
@ 2007-01-29 12:17 ` Daniel Jacobowitz
1 sibling, 0 replies; 24+ messages in thread
From: Daniel Jacobowitz @ 2007-01-29 12:17 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Sun, Jan 28, 2007 at 12:48:36AM +0300, Vladimir Prus wrote:
> 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?
I'll just review this copy. I think having it pop out of
-var-list-children automatically would be useful, but the testsuite
updates would be a pain - maybe we should keep that in mind when
we add tests for new MI commands and try to use more functions.
> + 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");
Missing _(). Also, we didn't update existing commands, but I think we
decided the "function:" prefixes weren't helpful.
> @@ -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);
> + }
> +}
Since you initialize path_expr at the same time as name, will is_root_p
ever trigger here?
> @@ -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)
Nick's got a point about the growing number of arguments. Would
converting them to a struct simplify it?
struct varobj_child_desc
{
char *name;
struct value *value;
struct type *type;
char *full_expression;
};
Hey... those fields all live in struct varobj... I wonder if this code
ought to be rearranged so that this initializes the child's struct
varobj. But anyway let's not do that right now. The new argument is
fine, I was just thinking out loud.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2007-09-01 7:56 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-18 10:43 -var-info-path-expression Vladimir Prus
2007-06-18 19:40 ` -var-info-path-expression Eli Zaretskii
2007-06-21 5:15 ` -var-info-path-expression Vladimir Prus
2007-07-03 17:14 ` -var-info-path-expression Daniel Jacobowitz
2007-07-03 17:51 ` -var-info-path-expression Vladimir Prus
2007-07-03 17:58 ` -var-info-path-expression Daniel Jacobowitz
-- strict thread matches above, loose matches on Subject: below --
2007-08-22 11:23 -var-info-path-expression Vladimir Prus
2007-08-22 15:28 ` -var-info-path-expression Daniel Jacobowitz
2007-08-28 17:18 ` -var-info-path-expression Vladimir Prus
2007-08-28 19:55 ` -var-info-path-expression Eli Zaretskii
2007-08-31 9:08 ` -var-info-path-expression Eli Zaretskii
2007-08-31 9:57 ` -var-info-path-expression Vladimir Prus
2007-08-31 18:04 ` -var-info-path-expression Eli Zaretskii
2007-08-31 18:53 ` -var-info-path-expression Vladimir Prus
2007-09-01 7:56 ` -var-info-path-expression Eli Zaretskii
2006-12-25 9:02 -var-info-path-expression Vladimir Prus
2007-01-03 22:39 ` -var-info-path-expression Daniel Jacobowitz
2007-01-05 9:14 ` -var-info-path-expression Vladimir Prus
2007-01-27 21:49 ` -var-info-path-expression Vladimir Prus
2007-01-28 0:46 ` -var-info-path-expression Nick Roberts
2007-01-28 7:57 ` -var-info-path-expression Vladimir Prus
2007-01-28 8:35 ` -var-info-path-expression Nick Roberts
2007-01-29 10:53 ` -var-info-path-expression Vladimir Prus
2007-01-29 12:17 ` -var-info-path-expression Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox