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