Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* -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
* -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
* -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

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-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
  -- strict thread matches above, loose matches on Subject: below --
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
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