* Add -var-info-path-expression command
@ 2006-03-17 18:37 Vladimir Prus
2006-04-04 7:25 ` Vladimir Prus
0 siblings, 1 reply; 6+ messages in thread
From: Vladimir Prus @ 2006-03-17 18:37 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1896 bytes --]
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.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: var_info_path_expression.diff --]
[-- Type: text/x-diff; name="var_info_path_expression.diff", Size: 25900 bytes --]
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)
\f
+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);
+}
\f
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;
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: Add -var-info-path-expression command
2006-03-17 18:37 Add -var-info-path-expression command Vladimir Prus
@ 2006-04-04 7:25 ` Vladimir Prus
2006-04-04 13:26 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Vladimir Prus @ 2006-04-04 7:25 UTC (permalink / raw)
To: gdb-patches
Any comments on this yet? I believe we've discussed the rationale for
-var-info-path-expression command in the main list, and agreed that it's
necessary.
- Volodya
> 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.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Add -var-info-path-expression command
2006-04-04 7:25 ` Vladimir Prus
@ 2006-04-04 13:26 ` Daniel Jacobowitz
2006-04-04 13:45 ` Vladimir Prus
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2006-04-04 13:26 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Tue, Apr 04, 2006 at 11:22:02AM +0400, Vladimir Prus wrote:
>
> Any comments on this yet? I believe we've discussed the rationale for
> -var-info-path-expression command in the main list, and agreed that it's
> necessary.
Yes, I think we've agreed on that.
It would be nice if there were test cases and documentation to go with
this.
I've been putting off looking at this patch, because (A) I had a whole
lot of other patches to review, and (B) it's huge and gnarly. I am not
really sure that Apple took the right approach with C++ classes and
run-time type information. Maybe they did, but it's not at all
obvious.
Sorry. If no one else reviews it, I will come back to it later.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Add -var-info-path-expression command
2006-04-04 13:26 ` Daniel Jacobowitz
@ 2006-04-04 13:45 ` Vladimir Prus
2006-04-04 16:13 ` Daniel Jacobowitz
2006-04-04 18:44 ` Eli Zaretskii
0 siblings, 2 replies; 6+ messages in thread
From: Vladimir Prus @ 2006-04-04 13:45 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Tuesday 04 April 2006 17:26, Daniel Jacobowitz wrote:
> On Tue, Apr 04, 2006 at 11:22:02AM +0400, Vladimir Prus wrote:
> > Any comments on this yet? I believe we've discussed the rationale for
> > -var-info-path-expression command in the main list, and agreed that it's
> > necessary.
>
> Yes, I think we've agreed on that.
>
> It would be nice if there were test cases and documentation to go with
> this.
Is this a hard requirement?
> I've been putting off looking at this patch, because (A) I had a whole
> lot of other patches to review, and (B) it's huge and gnarly. I am not
> really sure that Apple took the right approach with C++ classes and
> run-time type information. Maybe they did, but it's not at all
> obvious.
FWIW, I'm not 100% understand what they did, but this does not matter. My
patch does some surgery to grab only -var-info-path-expression, and no
type/RTTI related changes.
- Volodya
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Add -var-info-path-expression command
2006-04-04 13:45 ` Vladimir Prus
@ 2006-04-04 16:13 ` Daniel Jacobowitz
2006-04-04 18:44 ` Eli Zaretskii
1 sibling, 0 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2006-04-04 16:13 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
On Tue, Apr 04, 2006 at 05:44:36PM +0400, Vladimir Prus wrote:
> On Tuesday 04 April 2006 17:26, Daniel Jacobowitz wrote:
> > On Tue, Apr 04, 2006 at 11:22:02AM +0400, Vladimir Prus wrote:
> > > Any comments on this yet? I believe we've discussed the rationale for
> > > -var-info-path-expression command in the main list, and agreed that it's
> > > necessary.
> >
> > Yes, I think we've agreed on that.
> >
> > It would be nice if there were test cases and documentation to go with
> > this.
>
> Is this a hard requirement?
To merge the patch? Yes, I think so.
It also has a lot of formatting issues, at least one APPLE LOCAL
marker, and bunch of untranslated error messages (which might be
inappropriate uses of error; some of them maybe should be internal
errors instead; I didn't check yet).
> > I've been putting off looking at this patch, because (A) I had a whole
> > lot of other patches to review, and (B) it's huge and gnarly. I am not
> > really sure that Apple took the right approach with C++ classes and
> > run-time type information. Maybe they did, but it's not at all
> > obvious.
>
> FWIW, I'm not 100% understand what they did, but this does not matter. My
> patch does some surgery to grab only -var-info-path-expression, and no
> type/RTTI related changes.
+ /* 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;
+
And the related code below.
I'm not saying it's right or wrong, by the way. I'm saying it's
complicated and I need to spend a while thinking about it.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Add -var-info-path-expression command
2006-04-04 13:45 ` Vladimir Prus
2006-04-04 16:13 ` Daniel Jacobowitz
@ 2006-04-04 18:44 ` Eli Zaretskii
1 sibling, 0 replies; 6+ messages in thread
From: Eli Zaretskii @ 2006-04-04 18:44 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches
> From: Vladimir Prus <ghost@cs.msu.su>
> Date: Tue, 4 Apr 2006 17:44:36 +0400
> Cc: gdb-patches@sources.redhat.com
>
> > It would be nice if there were test cases and documentation to go with
> > this.
>
> Is this a hard requirement?
Daniel usually insists on test cases and I usually insist on
documentation for any user-visible changes.
The reason for those requirements is that if the patch submitter
doesn't do it, someone else, usually Daniel and myself, need to do
that for them. Both of us are busy people, so asking us to cover for
others runs a risk that new features will remain untested and
undocumented.
Here's a real-life example: Last time I checked (a few months ago),
there were dozens of undocumented commands, which forced me to spend
several days documenting them (since I don't use many of them, I
needed to reverse-engineer the code to understand what they do and
when they are useful). After that, I've sworn never again to allow
this to happen.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-04-04 18:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-17 18:37 Add -var-info-path-expression command Vladimir Prus
2006-04-04 7:25 ` Vladimir Prus
2006-04-04 13:26 ` Daniel Jacobowitz
2006-04-04 13:45 ` Vladimir Prus
2006-04-04 16:13 ` Daniel Jacobowitz
2006-04-04 18:44 ` Eli Zaretskii
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox