This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Add -var-info-path-expression command
- From: Vladimir Prus <ghost at cs dot msu dot su>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 17 Mar 2006 17:32:58 +0300
- Subject: Add -var-info-path-expression command
Hello,
the below patch ports the -var-info-path-expression MI command from Apple
version. It allows on get expression corresponding to any variable object,
in language-specific syntax, which can be used, for example, to set
watchpoint on that expression.
Top-level changelog entry:
2006-03-17 Vladimir Prus <ghost@cs.msu.su>,
port of changes on Apple branch:
2002-03-28 James Ingham <jingham@apple.com>
* varobj.c
(child_exists): Take child index, not child name, for performance.
(get_type_deref): Pass out whether the original was a pointer or
not.
(path_expr_of_variable): New function. This returns the full path
expression to a variable. The intent here is that you could use
this to make a new root varobj corresponding to the child varobj
whose path expression you are getting.
(varobj_get_path_expr): New function. External wrapper for
path_expr_of_variable.
(c_path_expr_of_child, cplus_path_expr_of_child,
java_path_expr_of_child): New functions, return the path expr of a
child in its parent. Also caches the expr for later use.
(is_root_p): New convenience function, returns whether a variable is
a root. Then I changed all the uses of var->name to use
name_of_variable, and the test
for is this a root were changed to use is_root_p.
* varobj.h: (varobj_get_path_expr): New function definition.
MI changelog entry:
2006-03-17 Vladimir Prus <ghost@cs.msu.su>,
port of changes on Apple branch:
2002-03-28 James Ingham <jingham@apple.com>
* mi-cmds.h: Added def'n of mi_cmd_var_info_path_expression.
* mi-cmds.c: Added var-info-path-expression to command list.
* mi-cmd-var.c (mi_cmd_var_info_path_expression) New function,
the MI interface to varobj_get_path_expression.
Index: varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.58
diff -u -p -r1.58 varobj.c
--- varobj.c 14 Feb 2006 19:05:40 -0000 1.58
+++ varobj.c 17 Mar 2006 14:25:08 -0000
@@ -42,6 +42,10 @@ show_varobjdebug (struct ui_file *file,
fprintf_filtered (file, _("Varobj debugging is %s.\n"), value);
}
+/* Non-zero if we use a varobj's full type to construct its children. */
+static int varobj_use_dynamic_type = 1;
+
+
/* String representations of gdb's format codes */
char *varobj_format_string[] =
{ "natural", "binary", "decimal", "hexadecimal", "octal" };
@@ -91,6 +95,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;
@@ -101,6 +109,17 @@ struct varobj
/* The type of this variable. This may NEVER be NULL. */
struct type *type;
+ /* This is the most specific type of a C++ class object - as obtained from
+ value_rtti_type. It will be set in two cases:
+
+ a) If the varobj is a pointer or reference to a C++ object. In this
+ case the dynamic_type will be a pointer or reference to the full
+ class.
+ b) If the varobj is a C++ object. In this case, it will be the type
+ of the full object, and the value field will be adjusted by
+ value_full_object to the full object. */
+ struct type *dynamic_type;
+
/* The value of this expression or subexpression. This may be NULL. */
struct value *value;
@@ -176,7 +195,7 @@ static int install_variable (struct varo
static void uninstall_variable (struct varobj *);
-static struct varobj *child_exists (struct varobj *, char *);
+static struct varobj *child_exists (struct varobj *, int index);
static struct varobj *create_child (struct varobj *, int, char *);
@@ -196,7 +215,7 @@ static struct cleanup *make_cleanup_free
static struct type *get_type (struct varobj *var);
-static struct type *get_type_deref (struct varobj *var);
+static struct type *get_type_deref (struct varobj *var, int *was_ptr);
static struct type *get_target_type (struct type *);
@@ -220,8 +239,12 @@ static int number_of_children (struct va
static char *name_of_variable (struct varobj *);
+static char *path_expr_of_variable (struct varobj *);
+
static char *name_of_child (struct varobj *, int);
+static char *path_expr_of_child (struct varobj *, int);
+
static struct value *value_of_root (struct varobj **var_handle, int *);
static struct value *value_of_child (struct varobj *parent, int index);
@@ -232,6 +255,8 @@ static int variable_editable (struct var
static char *my_value_of_variable (struct varobj *var);
+static int is_root_p (struct varobj *var);
+
static int type_changeable (struct varobj *var);
/* C implementation */
@@ -242,6 +267,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 *parent, int index);
+
static struct value *c_value_of_root (struct varobj **var_handle);
static struct value *c_value_of_child (struct varobj *parent, int index);
@@ -262,6 +289,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 *parent, int index);
+
static struct value *cplus_value_of_root (struct varobj **var_handle);
static struct value *cplus_value_of_child (struct varobj *parent, int index);
@@ -280,6 +309,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 *parent, int index);
+
static struct value *java_value_of_root (struct varobj **var_handle);
static struct value *java_value_of_child (struct varobj *parent, int index);
@@ -307,6 +338,9 @@ 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 the INDEX'th child of PARENT. */
+ char *(*path_expr_of_child) (struct varobj * parent, int index);
+
/* The ``struct value *'' of the root variable ROOT. */
struct value *(*value_of_root) (struct varobj ** root_handle);
@@ -332,6 +366,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,
@@ -344,6 +379,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,
@@ -356,6 +392,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,
@@ -368,6 +405,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,
@@ -380,6 +418,12 @@ enum vsections
{
v_public = 0, v_private, v_protected
};
+static int cplus_real_type_index_for_fake_child_index (
+ struct type *type,
+ enum vsections prot,
+ int num);
+
+
/* Private data */
@@ -402,6 +446,12 @@ static struct vlist **varobj_table;
((x) != NULL && (x)->type == NULL && (x)->value == NULL)
+static int
+is_root_p (struct varobj *var)
+{
+ return (var->root->rootvar == var);
+}
+
/* API Implementation */
/* Creates a varobj (not its children) */
@@ -436,6 +486,7 @@ varobj_create (char *objname,
struct frame_info *old_fi = NULL;
struct block *block;
struct cleanup *old_chain;
+ int expr_len;
/* Fill out a varobj structure for the (root) variable being constructed. */
var = new_root_variable ();
@@ -489,7 +540,12 @@ varobj_create (char *objname,
var->format = variable_default_display (var);
var->root->valid_block = innermost_block;
- var->name = savestring (expression, strlen (expression));
+
+ /* Cache expr_len so we don't compute it twice. */
+ 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
@@ -717,10 +773,12 @@ varobj_list_children (struct varobj *var
*((*childlist) + i) = NULL;
/* check if child exists, if not create */
- name = name_of_child (var, i);
- child = child_exists (var, name);
+ child = child_exists (var, i);
if (child == NULL)
- child = create_child (var, i, name);
+ {
+ name = name_of_child (var, i);
+ child = create_child (var, i, name);
+ }
*((*childlist) + i) = child;
}
@@ -761,6 +819,12 @@ varobj_get_type (struct varobj *var)
return thetype;
}
+char *
+varobj_get_path_expr (struct varobj *var)
+{
+ return path_expr_of_variable(var);
+}
+
/* Obtain the type of an object variable. */
struct type *
@@ -1237,22 +1301,26 @@ uninstall_variable (struct varobj *var)
}
-/* Does a child with the name NAME exist in VAR? If so, return its data.
- If not, return NULL. */
+/* Does a child with the index INDEX exist in VAR? If so, return its data.
+ If not, return NULL. NB. The child must already have been installed
+ in its parent for this call to work. */
static struct varobj *
-child_exists (struct varobj *var, char *name)
+child_exists (struct varobj *var, int index)
{
struct varobj_child *vc;
for (vc = var->children; vc != NULL; vc = vc->next)
{
- if (strcmp (vc->child->name, name) == 0)
+ /* APPLE LOCAL */
+ if (vc->child->index == index)
return vc->child;
}
return NULL;
}
+
+
/* Create and install a child of the parent of the given name */
static struct varobj *
create_child (struct varobj *parent, int index, char *name)
@@ -1336,6 +1404,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;
@@ -1379,6 +1448,7 @@ free_variable (struct varobj *var)
}
xfree (var->name);
+ xfree (var->path_expr);
xfree (var->obj_name);
xfree (var);
}
@@ -1412,9 +1482,12 @@ get_type (struct varobj *var)
return type;
}
-/* This returns the type of the variable, dereferencing pointers, too. */
+/* This returns the type of the variable, dereferencing pointers, too.
+ If was_ptr non-null, this will also return whether the original
+ was a pointer or not. */
+
static struct type *
-get_type_deref (struct varobj *var)
+get_type_deref (struct varobj *var, int *was_ptr)
{
struct type *type;
@@ -1422,7 +1495,13 @@ get_type_deref (struct varobj *var)
if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_PTR
|| TYPE_CODE (type) == TYPE_CODE_REF))
- type = get_target_type (type);
+ {
+ type = get_target_type (type);
+ if (was_ptr != NULL)
+ *was_ptr = 1;
+ }
+ else if (was_ptr != NULL)
+ *was_ptr = 0;
return type;
}
@@ -1596,6 +1675,18 @@ name_of_variable (struct varobj *var)
return (*var->root->lang->name_of_variable) (var);
}
+static char *
+path_expr_of_variable (struct varobj *var)
+{
+ if (var->path_expr != NULL)
+ return var->path_expr;
+ /* APPLE LOCAL is_root_p */
+ else if (is_root_p (var))
+ return var->name;
+ else
+ return path_expr_of_child (var->parent, var->index);
+}
+
/* What is the name of the INDEX'th child of VAR? Returns a malloc'd string. */
static char *
name_of_child (struct varobj *var, int index)
@@ -1603,6 +1694,15 @@ name_of_child (struct varobj *var, int i
return (*var->root->lang->name_of_child) (var, index);
}
+/* What is the rooted expression of the INDEX'th child of VAR? Returns
+ a malloc'd string. */
+static char *
+path_expr_of_child (struct varobj *var, int index)
+{
+ return (*var->root->lang->path_expr_of_child) (var, index);
+}
+
+
/* What is the ``struct value *'' of the root variable VAR?
TYPE_CHANGED controls what to do if the type of a
use_selected_frame = 1 variable changes. On input,
@@ -1814,6 +1914,80 @@ c_number_of_children (struct varobj *var
}
static char *
+c_path_expr_of_child (struct varobj *parent, int index)
+{
+ struct type *type;
+ struct type *target;
+ char *path_expr;
+ struct varobj *child = child_exists (parent, index);
+ char *parent_expr;
+ char *name;
+ int parent_len, child_len, len;
+
+ if (child == NULL)
+ error ("c_path_expr_of_child: "
+ "Tried to get path expression for a null child.");
+
+ parent_expr = path_expr_of_variable (parent);
+ name = name_of_variable (child);
+ parent_len = strlen (parent_expr);
+ child_len = strlen (name);
+ len = parent_len + child_len + 2 + 1; /* 2 for (), and 1 for null */
+
+ type = get_type (parent);
+ target = get_target_type (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ {
+ /* We never get here unless parent->num_children is greater than 0... */
+
+ len += 2;
+ path_expr = (char *) xmalloc (len);
+ sprintf (path_expr, "(%s)[%s]", parent_expr, name);
+ }
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ len += 1;
+ path_expr = (char *) xmalloc (len);
+ sprintf (path_expr, "(%s).%s", parent_expr, name);
+ break;
+
+ case TYPE_CODE_PTR:
+ switch (TYPE_CODE (target))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ len += 2;
+ path_expr = (char *) xmalloc (len);
+ sprintf (path_expr, "(%s)->%s", parent_expr, name);
+ break;
+
+ default:
+ len += parent_len + 2 + 1 + 1;
+ path_expr = (char *) xmalloc (len);
+ sprintf (path_expr, "*(%s)", parent_expr);
+ break;
+ }
+ break;
+
+ default:
+ /* This should not happen */
+ len = 5;
+ path_expr =
+ (char *) xmalloc (len);
+ sprintf (path_expr, "????");
+ }
+
+ child->path_expr = path_expr;
+ return path_expr;
+}
+
+
+static char *
c_name_of_variable (struct varobj *parent)
{
return savestring (parent->name, strlen (parent->name));
@@ -2113,7 +2287,7 @@ cplus_number_of_children (struct varobj
if (!CPLUS_FAKE_CHILD (var))
{
- type = get_type_deref (var);
+ type = get_type_deref (var, 0);
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2139,7 +2313,7 @@ cplus_number_of_children (struct varobj
{
int kids[3];
- type = get_type_deref (var->parent);
+ type = get_type_deref (var->parent, 0);
cplus_class_num_children (type, kids);
if (strcmp (var->name, "public") == 0)
@@ -2185,6 +2359,271 @@ cplus_class_num_children (struct type *t
}
static char *
+cplus_path_expr_of_child (struct varobj *parent, int index)
+{
+ char *path_expr;
+ struct type *type;
+ int children[3];
+ struct varobj *child = child_exists (parent, index);
+ char *parent_expr = path_expr_of_variable (parent);
+ int parent_len = strlen (parent_expr);
+ int child_len;
+ char *child_name;
+ int is_ptr;
+
+ if (child == NULL)
+ error ("cplus_path_expr_of_child: "
+ "Tried to get path expression for a null child.");
+
+ /* The path expression for a fake child is just the parent,
+ that way we can just concatenate the fake child's expr and
+ its real children. */
+
+ if (CPLUS_FAKE_CHILD (child))
+ return parent_expr;
+
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ /* Looking for children of public, private, or protected. */
+ type = get_type_deref (parent->parent, &is_ptr);
+ }
+ else
+ type = get_type_deref (parent, &is_ptr);
+
+ path_expr = NULL;
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ cplus_class_num_children (type, children);
+
+ if (CPLUS_FAKE_CHILD (parent))
+ {
+ int index_in_type;
+ enum vsections prot;
+ char *parent_name = name_of_variable (parent);
+ int child_is_ptr;
+ int dynamic_expr_len, join_expr_len;
+ char *dynamic_expr, *join_expr;
+
+ if (strcmp (parent_name, "private") == 0)
+ prot = v_private;
+ else if (strcmp (parent_name, "protected") == 0)
+ prot = v_protected;
+ else if (strcmp (parent_name, "public") == 0)
+ prot = v_public;
+ else
+ {
+ error ("cplus_make_name_of_child got a parent with invalid "
+ "fake child name: \"%s\".", parent_name);
+ return NULL;
+ }
+
+ index_in_type =
+ cplus_real_type_index_for_fake_child_index (type, prot, index);
+
+ child_name = TYPE_FIELD_NAME (type, index_in_type);
+ child_len = strlen (child_name);
+
+ /* Here's another tricky point. This child varobj might have a
+ dynamic type that's different from it's type, and this could be
+ one of the fields from the dynamic type. If we don't
+ cast it to the dynamic type in this expression, then we won't
+ be able to access those fields. */
+
+ if (varobj_use_dynamic_type != 0
+ && child->dynamic_type != NULL
+ && child->dynamic_type != child->type)
+ {
+ struct type *child_type = NULL;
+ child_type = get_type_deref (child, &child_is_ptr);
+ if (!child_is_ptr)
+ dynamic_expr_len = 0;
+ else
+ {
+ dynamic_expr = TYPE_NAME (child_type);
+ dynamic_expr_len = strlen (dynamic_expr);
+ }
+ }
+ else
+ {
+ dynamic_expr_len = 0;
+ }
+
+ if (is_ptr)
+ {
+ join_expr = "->";
+ join_expr_len = 2;
+ }
+ else
+ {
+ join_expr = ".";
+ join_expr_len = 1;
+ }
+ if (dynamic_expr_len > 0)
+ {
+ /* The literal is duplicated because if we create a temporary
+ variable, gcc warns that it can't check format string,
+ and this breaks compilation if -Werror is given.
+ */
+ path_expr = (char *) xmalloc (dynamic_expr_len + parent_len
+ + join_expr_len + child_len + strlen ("((%s)%s%s)") - 6 + 1);
+ sprintf (path_expr, "((%s *) ((%s)%s%s))", dynamic_expr, parent_expr, join_expr, child_name);
+ }
+ else
+ {
+ path_expr = (char *) xmalloc (parent_len + join_expr_len
+ + child_len + strlen ("((%s)%s%s)") - 4 + 1);
+ sprintf (path_expr, "((%s)%s%s)", parent_expr, join_expr, child_name);
+ }
+ }
+ else if (index < TYPE_N_BASECLASSES (type))
+ {
+ child_name = TYPE_FIELD_NAME (type, index);
+ child_len = strlen (child_name);
+
+ if (is_ptr)
+ {
+ path_expr = (char *) xmalloc (parent_len + child_len + 7 + 1);
+ sprintf (path_expr, "((%s *) %s)", child_name, parent_expr);
+ }
+ else
+ {
+ path_expr = (char *) xmalloc (parent_len + child_len + 5 + 1);
+ sprintf (path_expr, "((%s) %s)", child_name, parent_expr);
+ }
+ }
+ else
+ {
+ /* Everything beyond the baseclasses can
+ only be "public", "private", or "protected" */
+ index -= TYPE_N_BASECLASSES (type);
+ switch (index)
+ {
+ case 0:
+ if (children[v_public] != 0)
+ {
+ path_expr = "public";
+ break;
+ }
+ case 1:
+ if (children[v_private] != 0)
+ {
+ path_expr = "private";
+ break;
+ }
+ case 2:
+ if (children[v_protected] != 0)
+ {
+ path_expr = "protected";
+ break;
+ }
+ default:
+ /* error! */
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (path_expr == NULL)
+ return c_path_expr_of_child (parent, index);
+ else
+ {
+ child->path_expr = path_expr;
+ }
+
+ return path_expr;
+}
+
+/* Compute the index in the type structure TYPE of the NUM'th field
+ of protection level PROT */
+static int
+cplus_real_type_index_for_fake_child_index (struct type *type,
+ enum vsections prot,
+ int num)
+{
+ int num_found = 0;
+ int foundit = 0;
+ int i = 0;
+
+ switch (prot)
+ {
+ case v_public:
+ for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
+ {
+ /* If we have a virtual table pointer, omit it. */
+ if (TYPE_VPTR_BASETYPE (type) == type
+ && TYPE_VPTR_FIELDNO (type) == i)
+ continue;
+
+ if (!TYPE_FIELD_PROTECTED (type, i)
+ && !TYPE_FIELD_PRIVATE (type, i))
+ {
+ if (num_found == num)
+ {
+ foundit = 1;
+ break;
+ }
+ else
+ num_found++;
+ }
+ }
+ break;
+ case v_protected:
+ for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
+ {
+ /* If we have a virtual table pointer, omit it. */
+ if (TYPE_VPTR_BASETYPE (type) == type
+ && TYPE_VPTR_FIELDNO (type) == i)
+ continue;
+
+ if (TYPE_FIELD_PROTECTED (type, i))
+ {
+ if (num_found == num)
+ {
+ foundit = 1;
+ break;
+ }
+ else
+ num_found++;
+ }
+ }
+ break;
+ case v_private:
+ for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
+ {
+ /* If we have a virtual table pointer, omit it. */
+ if (TYPE_VPTR_BASETYPE (type) == type
+ && TYPE_VPTR_FIELDNO (type) == i)
+ continue;
+
+ if (TYPE_FIELD_PRIVATE (type, i))
+ {
+ if (num_found == num)
+ {
+ foundit = 1;
+ break;
+ }
+ else
+ num_found++;
+ }
+ }
+ break;
+ }
+
+ if (!foundit)
+ return -1;
+
+ return i;
+ }
+
+
+
+static char *
cplus_name_of_variable (struct varobj *parent)
{
return c_name_of_variable (parent);
@@ -2199,10 +2638,10 @@ cplus_name_of_child (struct varobj *pare
if (CPLUS_FAKE_CHILD (parent))
{
/* Looking for children of public, private, or protected. */
- type = get_type_deref (parent->parent);
+ type = get_type_deref (parent->parent, 0);
}
else
- type = get_type_deref (parent);
+ type = get_type_deref (parent, 0);
name = NULL;
switch (TYPE_CODE (type))
@@ -2335,9 +2774,9 @@ cplus_value_of_child (struct varobj *par
struct value *value;
if (CPLUS_FAKE_CHILD (parent))
- type = get_type_deref (parent->parent);
+ type = get_type_deref (parent->parent, 0);
else
- type = get_type_deref (parent);
+ type = get_type_deref (parent, 0);
value = NULL;
@@ -2410,10 +2849,10 @@ cplus_type_of_child (struct varobj *pare
if (CPLUS_FAKE_CHILD (parent))
{
/* Looking for the type of a child of public, private, or protected. */
- t = get_type_deref (parent->parent);
+ t = get_type_deref (parent->parent, 0);
}
else
- t = get_type_deref (parent);
+ t = get_type_deref (parent, 0);
type = NULL;
switch (TYPE_CODE (t))
@@ -2542,6 +2981,12 @@ java_value_of_variable (struct varobj *v
{
return cplus_value_of_variable (var);
}
+
+static char *
+java_path_expr_of_child (struct varobj *parent, int index)
+{
+ return cplus_path_expr_of_child (parent, index);
+}
extern void _initialize_varobj (void);
void
@@ -2552,6 +2997,14 @@ _initialize_varobj (void)
varobj_table = xmalloc (sizeof_table);
memset (varobj_table, 0, sizeof_table);
+ add_setshow_boolean_cmd ("varobj-print-object", class_obscure,
+ &varobj_use_dynamic_type, _("\
+Set varobj to construct children using the most specific class type."), _("\
+abc"), NULL,
+ NULL, NULL,
+ &setlist, &showlist);
+
+
add_setshow_zinteger_cmd ("debugvarobj", class_maintenance,
&varobjdebug, _("\
Set varobj debugging."), _("\
Index: varobj.h
===================================================================
RCS file: /cvs/src/src/gdb/varobj.h,v
retrieving revision 1.6
diff -u -p -r1.6 varobj.h
--- varobj.h 17 Dec 2005 22:34:03 -0000 1.6
+++ varobj.h 17 Mar 2006 14:25:08 -0000
@@ -83,6 +83,8 @@ extern int varobj_get_num_children (stru
extern int varobj_list_children (struct varobj *var,
struct varobj ***childlist);
+extern char *varobj_get_path_expr (struct varobj *var);
+
extern char *varobj_get_type (struct varobj *var);
extern struct type *varobj_get_gdb_type (struct varobj *var);
Index: mi/mi-cmd-var.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v
retrieving revision 1.23
diff -u -p -r1.23 mi-cmd-var.c
--- mi/mi-cmd-var.c 23 Dec 2005 18:57:46 -0000 1.23
+++ mi/mi-cmd-var.c 17 Mar 2006 14:25:08 -0000
@@ -371,6 +371,28 @@ 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;
Index: mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.20
diff -u -p -r1.20 mi-cmds.c
--- mi/mi-cmds.c 23 Dec 2005 18:57:46 -0000 1.20
+++ mi/mi-cmds.c 17 Mar 2006 14:25:08 -0000
@@ -162,6 +162,7 @@ struct mi_cmd mi_cmds[] =
{ "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},
+ { "var-info-path-expression", { NULL, 0 }, 0, mi_cmd_var_info_path_expression},
{ "var-list-children", { NULL, 0 }, 0, mi_cmd_var_list_children},
{ "var-set-format", { NULL, 0 }, 0, mi_cmd_var_set_format},
{ "var-show-attributes", { NULL, 0 }, 0, mi_cmd_var_show_attributes},
Index: mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.19
diff -u -p -r1.19 mi-cmds.h
--- mi/mi-cmds.h 23 Dec 2005 18:57:46 -0000 1.19
+++ mi/mi-cmds.h 17 Mar 2006 14:25:08 -0000
@@ -110,6 +110,7 @@ extern mi_cmd_argv_ftype mi_cmd_var_eval
extern mi_cmd_argv_ftype mi_cmd_var_info_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_info_path_expression;
extern mi_cmd_argv_ftype mi_cmd_var_list_children;
extern mi_cmd_argv_ftype mi_cmd_var_set_format;
extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;