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]

[RFA] mi/10586


Hi,

This bug deals with anonymous structs/unions in varobj. As in: anonymous structs/unions are unaddressable by MI clients.

This bug has been sitting around for quite some time. Vladimir Prus first mentioned this in 2006 (yikes!), and this bug was filed in 2009. At this time, Nick Roberts responded to the bug with a patch that fixed the problem.

I don't know why Nick never submitted the patch here, so I've tweaked his original patch and written some tests for it, and I am now submitting this.

Tested on x86_64-linux.

Keith

ChangeLog
2011-11-11  Keith Seitz  <keiths@redhat.com>

	Based on work by Nick Roberts  <nickrob@snap.net.nz>:
	* varobj.c (c_describe_child): Synthesize a variable name for
	anonymous structs and unions.
	(cplus_describe_child): Likewise.

testsuite/ChangeLog
2011-11-11  Keith Seitz  <keiths@redhat.com>

	* gdb.mi/mi-var-cp.cc (anonymous_structs): New function.
	(class A): New class.
	(class B): New class.
	(main): Call anonymous_structs.
	* gdb.mi/mi-var-cp.exp: Add anonymous struct tests and
	adjust test results.
	* gdb.mi/mi2-var-cp.exp: Likewise.
	* gdb.mi/var-cmd.c (struct _simple_struct): Add two anonymous
	structs.
	* gdb.mi/mi-var-dislay.exp: Add anonymous struct tests and
	adjust test results.
	* gdb.mi/mi2-var-display.exp: Likewise.
 gdb/testsuite/gdb.mi/mi-var-cp.cc        |   42 +++++++++++++++++++
 gdb/testsuite/gdb.mi/mi-var-cp.exp       |   64 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/mi-var-display.exp  |   14 ++++++-
 gdb/testsuite/gdb.mi/mi2-var-display.exp |   14 ++++++-
 gdb/testsuite/gdb.mi/var-cmd.c           |    8 ++++
 gdb/varobj.c                             |   58 ++++++++++++++++++---------
 6 files changed, 179 insertions(+), 21 deletions(-)

diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.cc b/gdb/testsuite/gdb.mi/mi-var-cp.cc
index 54439e6..8cd189f 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cp.cc
+++ b/gdb/testsuite/gdb.mi/mi-var-cp.cc
@@ -205,6 +205,47 @@ int path_expression ()
   /*: END: path_expression :*/
 }
 
+class A
+{
+public:
+  struct {
+    int a;
+    float b;
+  };
+  struct {
+    int c;
+    float d;
+  };
+};
+
+class B : public A
+{
+public:
+  struct {
+    int e;
+    float f;
+  };
+  struct {
+    int g;
+    float h;
+  };
+};
+
+static void
+anonymous_structs (void)
+{
+  B b;
+  b.a = 1;
+  b.b = 2.2;
+  b.c = 3;
+  b.d = 4.4;
+  b.e = 5;
+  b.f = 6.6;
+  b.g = 7;
+  b.h = 8.8;  /* anonymous_structs breakpoint */
+  return;
+}
+
 int main ()
 {
   reference_update_tests ();
@@ -212,5 +253,6 @@ int main ()
   reference_to_pointer ();
   reference_to_struct ();
   path_expression ();
+  anonymous_structs ();
   return 0;
 }
diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.exp b/gdb/testsuite/gdb.mi/mi-var-cp.exp
index 4ca3a68..e905f6b 100644
--- a/gdb/testsuite/gdb.mi/mi-var-cp.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-cp.exp
@@ -46,5 +46,69 @@ mi_run_inline_test reference_to_pointer
 mi_run_inline_test reference_to_struct
 mi_run_inline_test path_expression
 
+# Test anonymous structures
+set lineno [gdb_get_line_number "anonymous_structs breakpoint"]
+mi_create_breakpoint \
+    "$srcfile:$lineno" {[0-9]+} keep {anonymous_structs\(\)} \
+    ".*mi-var-cp.cc" $lineno $hex "break-insert anonymous_structs"
+mi_execute_to "exec-continue" "breakpoint-hit" "anonymous_structs" "" \
+    ".*" ".*" {"" "disp=\"keep\""} "continue to anonymous_structs breakpoint"
+
+mi_create_varobj "b" "b" "create varobj for b"
+mi_list_varobj_children "b" {
+  {b.A A 1 A}
+  {b.public public 2}
+} "list children of b"
+
+mi_list_varobj_children "b.A" {
+  {b.A.public public 2}
+} "list children of b.A"
+
+mi_list_varobj_children "b.A.public" {
+  {b.A.public.anonymous0 anonymous0 1 "struct {...}"}
+  {b.A.public.anonymous1 anonymous1 1 "struct {...}"}
+} "list children of b.A.public"
+
+mi_list_varobj_children "b.A.public.anonymous0" {
+  {b.A.public.anonymous0.public public 2}
+} "list children of b.A.public.anonymous0"
+
+mi_list_varobj_children "b.A.public.anonymous0.public" {
+  {b.A.public.anonymous0.public.a a 0 int}
+  {b.A.public.anonymous0.public.b b 0 float}
+} "list children of b.A.public.anonymous0.public"
+
+mi_list_varobj_children "b.A.public.anonymous1" {
+  {b.A.public.anonymous1.public public 2}
+} "list children of b.A.public.anonymous1"
+
+mi_list_varobj_children "b.A.public.anonymous1.public" {
+  {b.A.public.anonymous1.public.c c 0 int}
+  {b.A.public.anonymous1.public.d d 0 float}
+} "list children of b.A.public.anonymous1.public"
+
+mi_list_varobj_children "b.public" {
+  {b.public.anonymous1 anonymous1 1 "struct {...}"}
+  {b.public.anonymous2 anonymous2 1 "struct {...}"}
+} "list children of b.public"
+
+mi_list_varobj_children "b.public.anonymous1" {
+  {b.public.anonymous1.public public 2}
+} "list children of b.public.anonymous1"
+
+mi_list_varobj_children "b.public.anonymous1.public" {
+  {b.public.anonymous1.public.e e 0 int}
+  {b.public.anonymous1.public.f f 0 float}
+} "list children of b.public.anonymous1.public"
+
+mi_list_varobj_children "b.public.anonymous2" {
+  {b.public.anonymous2.public public 2}
+} "list children of b.public.anonymous2"
+
+mi_list_varobj_children "b.public.anonymous2.public" {
+  {b.public.anonymous2.public.g g 0 int}
+  {b.public.anonymous2.public.h h 0 float}
+} "list children of b.public.anonymous2.public"
+
 mi_gdb_exit
 return 0
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index ff27407..a56b19b 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -474,7 +474,7 @@ mi_gdb_test "-var-show-attributes s" \
 # Test: c_variable-7.34
 # Desc: number of children of s
 mi_gdb_test "-var-info-num-children s" \
-	"\\^done,numchild=\"6\"" \
+	"\\^done,numchild=\"8\"" \
 	"get number of children of s"
 
 # Test: c_variable-7.35
@@ -486,9 +486,21 @@ mi_list_varobj_children s {
         {s.signed_character signed_character 0 "signed char"}
         {s.char_ptr char_ptr 1 {char \*}}
         {s.array_of_10 array_of_10 10 {int \[10\]}}
+        {s.anonymous6 anonymous6 2 "struct {...}"}
+        {s.anonymous7 anonymous7 2 "struct {...}"}
 } "get children of s"
 #} {integer unsigned_integer character signed_character char_ptr array_of_10}
 
+mi_list_varobj_children s.anonymous6 {
+  {s.anonymous6.a a 0 int}
+  {s.anonymous6.b b 0 float}
+} "get childern of s.anonymous6"
+
+mi_list_varobj_children s.anonymous7 {
+  {s.anonymous7.c c 0 int}
+  {s.anonymous7.d d 0 float}
+} "get children of s.anonymous7"
+
 # Test: c_variable-7.40
 # Desc: create anons
 mi_create_varobj anons anons "create local variable anons"
diff --git a/gdb/testsuite/gdb.mi/mi2-var-display.exp b/gdb/testsuite/gdb.mi/mi2-var-display.exp
index 828614b..dde1830 100644
--- a/gdb/testsuite/gdb.mi/mi2-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi2-var-display.exp
@@ -473,7 +473,7 @@ mi_gdb_test "-var-show-attributes s" \
 # Test: c_variable-7.34
 # Desc: number of children of s
 mi_gdb_test "-var-info-num-children s" \
-	"\\^done,numchild=\"6\"" \
+	"\\^done,numchild=\"8\"" \
 	"get number of children of s"
 
 # Test: c_variable-7.35
@@ -485,9 +485,21 @@ mi_list_varobj_children s {
         {s.signed_character signed_character 0 "signed char"}
         {s.char_ptr char_ptr 1 {char \*}}
         {s.array_of_10 array_of_10 10 {int \[10\]}}
+        {s.anonymous6 anonymous6 2 "struct {...}"}
+        {s.anonymous7 anonymous7 2 "struct {...}"}
 } "get children of s"
 #} {integer unsigned_integer character signed_character char_ptr array_of_10}
 
+mi_list_varobj_children s.anonymous6 {
+  {s.anonymous6.a a 0 int}
+  {s.anonymous6.b b 0 float}
+} "get childern of s.anonymous6"
+
+mi_list_varobj_children s.anonymous7 {
+  {s.anonymous7.c c 0 int}
+  {s.anonymous7.d d 0 float}
+} "get children of s.anonymous7"
+
 # Test: c_variable-7.40
 # Desc: create anons
 mi_create_varobj anons anons "create local variable anons"
diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c
index 71c5b9d..5b6af0e 100644
--- a/gdb/testsuite/gdb.mi/var-cmd.c
+++ b/gdb/testsuite/gdb.mi/var-cmd.c
@@ -26,6 +26,14 @@ struct _simple_struct {
   signed char signed_character;
   char *char_ptr;
   int array_of_10[10];
+  struct {
+    int a;
+    float b;
+  };
+  struct {
+    int c;
+    float d;
+  };
 };
 
 typedef struct _simple_struct simpleton;
diff --git a/gdb/varobj.c b/gdb/varobj.c
index f17ff1a..17efd1d 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -3027,26 +3027,38 @@ c_describe_child (struct varobj *parent, int index,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
-      if (cname)
-	*cname = xstrdup (TYPE_FIELD_NAME (type, index));
+      {
+	char *type_name, *name;
 
-      if (cvalue && value)
-	{
-	  /* For C, varobj index is the same as type index.  */
-	  *cvalue = value_struct_element_index (value, index);
-	}
+	type_name = TYPE_FIELD_NAME (type, index);
+	if (*type_name == '\0')
+	  name = xstrprintf ("anonymous%d", index);
+	else
+	  name = type_name;
 
-      if (ctype)
-	*ctype = TYPE_FIELD_TYPE (type, index);
+	if (cname)
+	  *cname = xstrdup (name);
 
-      if (cfull_expression)
-	{
-	  char *join = was_ptr ? "->" : ".";
+	if (cvalue && value)
+	  {
+	    /* For C, varobj index is the same as type index.  */
+	    *cvalue = value_struct_element_index (value, index);
+	  }
 
-	  *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join,
-					  TYPE_FIELD_NAME (type, index));
-	}
+	if (ctype)
+	  *ctype = TYPE_FIELD_TYPE (type, index);
+
+	if (cfull_expression)
+	  {
+	    char *join = was_ptr ? "->" : ".";
+
+	    *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join,
+					    name);
+	  }
 
+	if (*type_name == '\0')
+	  xfree (name);
+      }
       break;
 
     case TYPE_CODE_PTR:
@@ -3432,6 +3444,7 @@ cplus_describe_child (struct varobj *parent, int index,
 	  enum accessibility acc = public_field;
 	  int vptr_fieldno;
 	  struct type *basetype = NULL;
+	  char *name, *type_name;
 
 	  vptr_fieldno = get_vptr_fieldno (type, &basetype);
 	  if (strcmp (parent->name, "private") == 0)
@@ -3450,8 +3463,14 @@ cplus_describe_child (struct varobj *parent, int index,
 	    }
 	  --type_index;
 
+	  type_name = TYPE_FIELD_NAME (type, type_index);
+	  if (*type_name == '\0')
+	    name = xstrprintf ("anonymous%d", type_index);
+	  else
+	    name = type_name;
+
 	  if (cname)
-	    *cname = xstrdup (TYPE_FIELD_NAME (type, type_index));
+	    *cname = xstrdup (name);
 
 	  if (cvalue && value)
 	    *cvalue = value_struct_element_index (value, type_index);
@@ -3461,9 +3480,10 @@ cplus_describe_child (struct varobj *parent, int index,
 
 	  if (cfull_expression)
 	    *cfull_expression
-	      = xstrprintf ("((%s)%s%s)", parent_expression,
-			    join, 
-			    TYPE_FIELD_NAME (type, type_index));
+	      = xstrprintf ("((%s)%s%s)", parent_expression, join, name);
+
+	  if (*type_name == '\0')
+	    xfree (name);
 	}
       else if (index < TYPE_N_BASECLASSES (type))
 	{
-- 
1.7.6.4


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