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]

PING #2: Re: [PATCH v2] Improve MI -var-info-path-expression for nested struct/union case.


Ping #2.

Thanks,
Andrew

On 05/06/2014 3:11 PM, Andrew Burgess wrote:
> Ping!
> 
> The regression Vladimir pointed out is fixed in V2 with no regressions
> in any of the new tests I've added.
> 
> Tested on x86-64 RHEL5 with no regressions.
> 
> Thanks,
> Andrew
> 
> On 29/05/2014 9:55 AM, Andrew Burgess wrote:
>> Ping!
>>
>> Thanks,
>> Andrew
>>
>> On 19/05/2014 10:33 PM, Andrew Burgess wrote:
>>> Volodya ,
>>>
>>> Thanks for taking the time to look at this patch for me.
>>>
>>> I've extended the test case to cover the extra case that you found.
>>>
>>> In order to get this test passing I took onboard what you noticed, that the
>>> logic for is_path_expr_parent is really language specific, so I've made
>>> is_path_expr_parent a method on varobj_ops.  The current code is only ever
>>> called for C/C++ anyway, all the other languages do their own thing.  This
>>> allows me to move the existing is_path_expr_parent into c-varobj.c, and
>>> gives access to adjust_value_for_child_access, which fixes the issue.
>>>
>>> The remaining additional changes are just fallout from adding the new
>>> varobj_ops method.
>>>
>>> Is this ok to apply?
>>>
>>> Thanks,
>>>
>>> Andrew
>>>
>>> ---
>>> The MI command -var-info-path-expression currently does not handle
>>> non-anonymous structs / unions nested within other structs / unions, it
>>> will skip parts of the expression.
>>>
>>> Add a new method to the varobj_ops structure, is_path_expr_parent, to allow
>>> language specific control over finding the parent varobj, the current logic
>>> becomes the C/C++ version and is extended to handle the nested cases.
>>>
>>> gdb/ChangeLog:
>>>
>>> 	* ada-varobj.c (ada_varobj_ops): Fill in is_path_expr_parent
>>> 	field.
>>> 	* c-varobj.c (c_is_path_expr_parent): New function, moved core
>>> 	from varobj.c, with additional checks.
>>> 	(c_varobj_ops): Fill in is_path_expr_parent field.
>>> 	(cplus_varobj_ops): Fill in is_path_expr_parent field.
>>> 	* jv-varobj.c (java_varobj_ops): Fill in is_path_expr_parent
>>> 	field.
>>> 	* varobj.c (is_path_expr_parent): Call is_path_expr_parent varobj
>>> 	ops method.
>>> 	(varobj_default_is_path_expr_parent): New function.
>>> 	* varobj.h (lang_varobj_ops): Add is_path_expr_parent field.
>>> 	(varobj_default_is_path_expr_parent): Declare new function.
>>>
>>> gdb/testsuite/ChangeLog:
>>>
>>> 	* gdb.mi/var-cmd.c (do_nested_struct_union_tests): New function
>>> 	setting up test structures.
>>> 	(main): Call new test function.
>>> 	* gdb.mi/mi2-var-child.exp: Create additional breakpoint in new
>>> 	test function, continue into test function and walk test
>>> 	structures.
>>> ---
>>>  gdb/ada-varobj.c                       |  3 +-
>>>  gdb/c-varobj.c                         | 56 ++++++++++++++++++++++++-
>>>  gdb/jv-varobj.c                        |  3 +-
>>>  gdb/testsuite/gdb.mi/mi2-var-child.exp | 76 ++++++++++++++++++++++++++++++++++
>>>  gdb/testsuite/gdb.mi/var-cmd.c         | 68 ++++++++++++++++++++++++++++++
>>>  gdb/varobj.c                           | 20 ++++-----
>>>  gdb/varobj.h                           |  9 ++++
>>>  7 files changed, 221 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/gdb/ada-varobj.c b/gdb/ada-varobj.c
>>> index b9f83be..3d56526 100644
>>> --- a/gdb/ada-varobj.c
>>> +++ b/gdb/ada-varobj.c
>>> @@ -1026,5 +1026,6 @@ const struct lang_varobj_ops ada_varobj_ops =
>>>    ada_type_of_child,
>>>    ada_value_of_variable,
>>>    ada_value_is_changeable_p,
>>> -  ada_value_has_mutated
>>> +  ada_value_has_mutated,
>>> +  varobj_default_is_path_expr_parent
>>>  };
>>> diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
>>> index 9c2860d..f7bc52b 100644
>>> --- a/gdb/c-varobj.c
>>> +++ b/gdb/c-varobj.c
>>> @@ -126,6 +126,56 @@ adjust_value_for_child_access (struct value **value,
>>>      }
>>>  }
>>>  
>>> +/* Is VAR a path expression parent, i.e., can it be used to construct
>>> +   a valid path expression?  */
>>> +
>>> +static int
>>> +c_is_path_expr_parent (struct varobj *var)
>>> +{
>>> +  struct type *type;
>>> +
>>> +  /* "Fake" children are not path_expr parents.  */
>>> +  if (CPLUS_FAKE_CHILD (var))
>>> +    return 0;
>>> +
>>> +  type = varobj_get_gdb_type (var);
>>> +
>>> +  /* Anonymous unions and structs are also not path_expr parents.  */
>>> +  if ((TYPE_CODE (type) == TYPE_CODE_STRUCT
>>> +       || TYPE_CODE (type) == TYPE_CODE_UNION)
>>> +      && TYPE_NAME (type) == NULL
>>> +      && TYPE_TAG_NAME (type) == NULL)
>>> +    {
>>> +      struct varobj *parent = var->parent;
>>> +
>>> +      while (parent != NULL && CPLUS_FAKE_CHILD (parent))
>>> +	parent = parent->parent;
>>> +
>>> +      if (parent != NULL)
>>> +	{
>>> +	  struct type *parent_type;
>>> +	  int was_ptr;
>>> +
>>> +	  parent_type = varobj_get_value_type (parent);
>>> +	  adjust_value_for_child_access (NULL, &parent_type, &was_ptr, 0);
>>> +
>>> +	  if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
>>> +	      || TYPE_CODE (parent_type) == TYPE_CODE_UNION)
>>> +	    {
>>> +	      const char *field_name;
>>> +
>>> +	      gdb_assert (var->index < TYPE_NFIELDS (parent_type));
>>> +	      field_name = TYPE_FIELD_NAME (parent_type, var->index);
>>> +	      return !(field_name == NULL || *field_name == '\0');
>>> +	    }
>>> +	}
>>> +
>>> +      return 0;
>>> +    }
>>> +
>>> +  return 1;
>>> +}
>>> +
>>>  /* C */
>>>  
>>>  static int
>>> @@ -493,7 +543,8 @@ const struct lang_varobj_ops c_varobj_ops =
>>>     c_type_of_child,
>>>     c_value_of_variable,
>>>     varobj_default_value_is_changeable_p,
>>> -   NULL /* value_has_mutated */
>>> +   NULL, /* value_has_mutated */
>>> +   c_is_path_expr_parent  /* is_path_expr_parent */
>>>  };
>>>  
>>>  /* A little convenience enum for dealing with C++/Java.  */
>>> @@ -904,7 +955,8 @@ const struct lang_varobj_ops cplus_varobj_ops =
>>>     cplus_type_of_child,
>>>     cplus_value_of_variable,
>>>     varobj_default_value_is_changeable_p,
>>> -   NULL /* value_has_mutated */
>>> +   NULL, /* value_has_mutated */
>>> +   c_is_path_expr_parent  /* is_path_expr_parent */
>>>  };
>>>  
>>>  
>>> diff --git a/gdb/jv-varobj.c b/gdb/jv-varobj.c
>>> index 0bb8e64..fb4d417 100644
>>> --- a/gdb/jv-varobj.c
>>> +++ b/gdb/jv-varobj.c
>>> @@ -101,5 +101,6 @@ const struct lang_varobj_ops java_varobj_ops =
>>>     java_type_of_child,
>>>     java_value_of_variable,
>>>     varobj_default_value_is_changeable_p,
>>> -   NULL /* value_has_mutated */
>>> +   NULL, /* value_has_mutated */
>>> +   varobj_default_is_path_expr_parent
>>>  };
>>> diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp
>>> index f992a63..fc02066 100644
>>> --- a/gdb/testsuite/gdb.mi/mi2-var-child.exp
>>> +++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp
>>> @@ -1163,6 +1163,13 @@ mi_create_breakpoint \
>>>      "$srcfile:$lineno" "break in do_anonymous_type_tests" \
>>>      -disp keep -func do_anonymous_type_tests \
>>>      -file ".*var-cmd.c" -line $lineno
>>> +
>>> +set lineno [gdb_get_line_number "nested struct union tests breakpoint"]
>>> +mi_create_breakpoint \
>>> +    "$srcfile:$lineno" "break in do_nested_struct_union_tests" \
>>> +    -disp keep -func do_nested_struct_union_tests \
>>> +    -file ".*var-cmd.c" -line $lineno
>>> +
>>>  mi_execute_to "exec-continue" "breakpoint-hit" "do_anonymous_type_tests" ""\
>>>      ".*" ".*" {"" "disp=\"keep\""} \
>>>      "continue to do_anonymous_type_tests breakpoint"
>>> @@ -1236,5 +1243,74 @@ set tree {
>>>  
>>>  mi_walk_varobj_tree c $tree verify_everything
>>>  
>>> +mi_send_resuming_command "exec-continue" \
>>> +    "continuing execution to enter do_nested_struct_union_tests"
>>> +mi_expect_stop "breakpoint-hit" "do_nested_struct_union_tests" ".*" ".*" ".*" \
>>> +    {.* disp="keep"} "Run till MI stops in do_nested_struct_union_tests"
>>> +
>>> +set struct_ss_tree {
>>> +    {struct s_a} a1 {
>>> +      int a {}
>>> +    }
>>> +    {struct s_b} b1 {
>>> +      int b {}
>>> +    }
>>> +    {union u_ab} u1 {
>>> +      {struct s_a} a {
>>> +        int a {}
>>> +      }
>>> +      {struct s_b} b {
>>> +        int b {}
>>> +      }
>>> +    }
>>> +    anonymous union {
>>> +      {struct s_a} a2 {
>>> +        int a {}
>>> +      }
>>> +      {struct s_b} b2 {
>>> +        int b {}
>>> +      }
>>> +    }
>>> +    {union {...}} u2 {
>>> +      {struct s_a} a3 {
>>> +        int a {}
>>> +      }
>>> +      {struct s_b} b3 {
>>> +        int b {}
>>> +      }
>>> +    }
>>> +  }
>>> +
>>> +set tree "
>>> +  {struct ss} var {
>>> +    $struct_ss_tree
>>> +  }
>>> +"
>>> +
>>> +mi_walk_varobj_tree c $tree verify_everything
>>> +
>>> +set tree {
>>> +  {struct {...}} var2 {
>>> +    {td_u_ab} ab {
>>> +      {td_s_a} a {
>>> +	int a {}
>>> +      }
>>> +      {td_s_b} b {
>>> +	int b {}
>>> +      }
>>> +    }
>>> +  }
>>> +}
>>> +
>>> +mi_walk_varobj_tree c $tree verify_everything
>>> +
>>> +set tree "
>>> +  {struct ss *} ss_ptr {
>>> +    $struct_ss_tree
>>> +  }
>>> +"
>>> +
>>> +mi_walk_varobj_tree c $tree verify_everything
>>> +
>>>  mi_gdb_exit
>>>  return 0
>>> diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c
>>> index 698b294..4bb2746 100644
>>> --- a/gdb/testsuite/gdb.mi/var-cmd.c
>>> +++ b/gdb/testsuite/gdb.mi/var-cmd.c
>>> @@ -552,6 +552,73 @@ do_anonymous_type_tests (void)
>>>    return; /* anonymous type tests breakpoint */
>>>  }
>>>  
>>> +void
>>> +do_nested_struct_union_tests (void)
>>> +{
>>> +  struct s_a
>>> +  {
>>> +    int a;
>>> +  };
>>> +  struct s_b
>>> +  {
>>> +    int b;
>>> +  };
>>> +  union u_ab
>>> +  {
>>> +    struct s_a a;
>>> +    struct s_b b;
>>> +  };
>>> +  struct ss
>>> +  {
>>> +    struct s_a a1;
>>> +    struct s_b b1;
>>> +    union u_ab u1;
>>> +
>>> +    /* Anonymous union.  */
>>> +    union
>>> +    {
>>> +      struct s_a a2;
>>> +      struct s_b b2;
>>> +    };
>>> +
>>> +    union
>>> +    {
>>> +      struct s_a a3;
>>> +      struct s_b b3;
>>> +    } u2;
>>> +  };
>>> +
>>> +  typedef struct
>>> +  {
>>> +    int a;
>>> +  } td_s_a;
>>> +
>>> +  typedef struct
>>> +  {
>>> +    int b;
>>> +  } td_s_b;
>>> +
>>> +  typedef union
>>> +  {
>>> +    td_s_a a;
>>> +    td_s_b b;
>>> +  } td_u_ab;
>>> +
>>> +  struct ss var;
>>> +  struct
>>> +  {
>>> +    td_u_ab ab;
>>> +  } var2;
>>> +
>>> +  struct ss *ss_ptr;
>>> +
>>> +  memset (&var, 0, sizeof (var));
>>> +  memset (&var2, 0, sizeof (var2));
>>> +  ss_ptr = &var;
>>> +
>>> +  return; /* nested struct union tests breakpoint */
>>> +}
>>> +
>>>  int
>>>  main (int argc, char *argv [])
>>>  {
>>> @@ -563,6 +630,7 @@ main (int argc, char *argv [])
>>>    do_at_tests ();
>>>    do_bitfield_tests ();
>>>    do_anonymous_type_tests ();
>>> +  do_nested_struct_union_tests ();
>>>    exit (0);
>>>  }
>>>  
>>> diff --git a/gdb/varobj.c b/gdb/varobj.c
>>> index 8016368..7fa98f2 100644
>>> --- a/gdb/varobj.c
>>> +++ b/gdb/varobj.c
>>> @@ -1069,18 +1069,18 @@ varobj_get_gdb_type (struct varobj *var)
>>>  static int
>>>  is_path_expr_parent (struct varobj *var)
>>>  {
>>> -  struct type *type;
>>> -
>>> -  /* "Fake" children are not path_expr parents.  */
>>> -  if (CPLUS_FAKE_CHILD (var))
>>> -    return 0;
>>> +  gdb_assert (var->root->lang_ops->is_path_expr_parent != NULL);
>>> +  return var->root->lang_ops->is_path_expr_parent (var);
>>> +}
>>>  
>>> -  type = varobj_get_value_type (var);
>>> +/* Is VAR a path expression parent, i.e., can it be used to construct
>>> +   a valid path expression?  By default we assume any VAR can be a path
>>> +   parent.  */
>>>  
>>> -  /* Anonymous unions and structs are also not path_expr parents.  */
>>> -  return !((TYPE_CODE (type) == TYPE_CODE_STRUCT
>>> -	    || TYPE_CODE (type) == TYPE_CODE_UNION)
>>> -	   && TYPE_NAME (type) == NULL);
>>> +int
>>> +varobj_default_is_path_expr_parent (struct varobj *var)
>>> +{
>>> +  return 1;
>>>  }
>>>  
>>>  /* Return the path expression parent for VAR.  */
>>> diff --git a/gdb/varobj.h b/gdb/varobj.h
>>> index 1199e0b..12a842b 100644
>>> --- a/gdb/varobj.h
>>> +++ b/gdb/varobj.h
>>> @@ -213,6 +213,12 @@ struct lang_varobj_ops
>>>       Languages where types do not mutate can set this to NULL.  */
>>>    int (*value_has_mutated) (struct varobj *var, struct value *new_value,
>>>  			    struct type *new_type);
>>> +
>>> +  /* Return nonzero if VAR is a suitable path expression parent.
>>> +
>>> +     For C like languages with anonymous structures and unions an anonymous
>>> +     structure or union is not a suitable parent.  */
>>> +  int (*is_path_expr_parent) (struct varobj *var);
>>>  };
>>>  
>>>  extern const struct lang_varobj_ops c_varobj_ops;
>>> @@ -326,4 +332,7 @@ extern void varobj_formatted_print_options (struct value_print_options *opts,
>>>  
>>>  extern void varobj_restrict_range (VEC (varobj_p) *children, int *from,
>>>  				   int *to);
>>> +
>>> +extern int varobj_default_is_path_expr_parent (struct varobj *var);
>>> +
>>>  #endif /* VAROBJ_H */
>>>
>>
>>
>>
> 
> 
> 


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