From: Keith Seitz <keiths@redhat.com>
To: "gdb-patches@sourceware.org ml" <gdb-patches@sourceware.org>
Subject: [RFA] mi/10586
Date: Fri, 11 Nov 2011 21:30:00 -0000 [thread overview]
Message-ID: <4EBD93D9.2020006@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1295 bytes --]
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.
[-- Attachment #2: 10586.patch --]
[-- Type: text/x-patch, Size: 9703 bytes --]
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
next reply other threads:[~2011-11-11 21:30 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-11 21:30 Keith Seitz [this message]
2011-11-14 15:45 ` Tom Tromey
2011-11-14 18:04 ` Keith Seitz
2011-11-14 18:18 ` Tom Tromey
2011-11-14 19:28 ` Keith Seitz
2011-11-14 20:28 ` Tom Tromey
2011-11-15 17:10 ` Keith Seitz
2011-11-15 17:30 ` Tom Tromey
2011-12-02 22:28 ` Keith Seitz
2011-12-13 1:28 ` Keith Seitz
2011-12-13 19:58 ` Tom Tromey
2011-12-17 1:55 ` Keith Seitz
2011-12-20 16:03 ` Tom Tromey
2012-01-12 23:05 ` Keith Seitz
2011-12-13 20:34 ` Crash regression with Eclipse [Re: [RFA] mi/10586] Jan Kratochvil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EBD93D9.2020006@redhat.com \
--to=keiths@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox