This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: -var-info-path-expression


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





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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]