This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] mi/10586
- From: Keith Seitz <keiths at redhat dot com>
- To: "gdb-patches at sourceware dot org ml" <gdb-patches at sourceware dot org>
- Date: Fri, 11 Nov 2011 13:30:01 -0800
- Subject: [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