From: Doug Evans Date: Tue, 29 Jun 2010 16:53:10 +0000 (+0000) Subject: PR c++/11702 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=254e6b9ed4abf109cb8399aa3f8f387f7eb2465c;p=binutils-gdb.git PR c++/11702 * NEWS: Add entry. * dwarf2read.c (dwarf2_add_field): If DW_AT_const_value is present, create a symbol for the field and record the value. (new_symbol): Handle DW_TAG_member. * gdbtypes.c (field_is_static): Remove FIXME. * symtab.c (search_symbols): When searching for VARIABLES_DOMAIN, only ignore LOC_CONST symbols that are enums. testsuite/ Test PR c++/11702. * gdb.cp/m-static.exp: Add testcase. * gdb.cp/m-static.h (gnu_obj_4): Add initialized static const member. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index df91ef95ae6..07f2bf4db8e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2010-06-29 Doug Evans + PR gdb/11702 + * NEWS: Add entry. + * dwarf2read.c (dwarf2_add_field): If DW_AT_const_value is present, + create a symbol for the field and record the value. + (new_symbol): Handle DW_TAG_member. + * gdbtypes.c (field_is_static): Remove FIXME. + * symtab.c (search_symbols): When searching for VARIABLES_DOMAIN, + only ignore LOC_CONST symbols that are enums. + * dwarf2read.c: Remove trailing whitespace. Delete FIELD_LOC_KIND_DWARF_BLOCK, unused. diff --git a/gdb/NEWS b/gdb/NEWS index 73ff05fd37b..4764c01d147 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -32,6 +32,11 @@ GDB now also supports proper overload resolution for all the previously mentioned flavors of operators. + ** static const class members + + Printing of static const class members that are initialized in the + class definition has been fixed. + * Windows Thread Information Block access. On Windows targets, GDB now supports displaying the Windows Thread diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index c1727525c9e..127d10fc741 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4528,6 +4528,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, fp = &new_field->field; + /* NOTE: According to the dwarf standard, static data members are + indicated by having DW_AT_external. + The check here for ! die_is_declaration is historical. + This test is replicated in new_symbol. */ + if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu)) { /* Data member other than a C++ static data member. */ @@ -4643,6 +4648,14 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, if (fieldname == NULL) return; + attr = dwarf2_attr (die, DW_AT_const_value, cu); + if (attr) + { + /* A static const member, not much different than an enum as far as + we're concerned, except that we can support more types. */ + new_symbol (die, NULL, cu); + } + /* Get physical name. */ physname = (char *) dwarf2_physname (fieldname, die, cu); @@ -8824,6 +8837,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) BLOCK_FUNCTION from the blockvector. */ break; case DW_TAG_variable: + case DW_TAG_member: /* Compilation with minimal debug info may result in variables with missing type entries. Change the misleading `void' type to something sensible. */ @@ -8832,6 +8846,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) = objfile_type (objfile)->nodebug_data_symbol; attr = dwarf2_attr (die, DW_AT_const_value, cu); + /* In the case of DW_TAG_member, we should only be called for + static const members. */ + if (die->tag == DW_TAG_member) + { + /* NOTE: This test seems wrong according to the dwarf standard. + static data members are represented by DW_AT_external. + However, dwarf2_add_field is currently calling + die_is_declaration to check, so we do the same. */ + gdb_assert (die_is_declaration (die, cu)); + gdb_assert (attr); + } if (attr) { dwarf2_const_value (attr, sym, cu); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5d1d4203e79..ba8c7e41243 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2512,9 +2512,7 @@ field_is_static (struct field *f) to the address of the enclosing struct. It would be nice to have a dedicated flag that would be set for static fields when the type is being created. But in practice, checking the field - loc_kind should give us an accurate answer (at least as long as - we assume that DWARF block locations are not going to be used - for static fields). FIXME? */ + loc_kind should give us an accurate answer. */ return (FIELD_LOC_KIND (*f) == FIELD_LOC_KIND_PHYSNAME || FIELD_LOC_KIND (*f) == FIELD_LOC_KIND_PHYSADDR); } diff --git a/gdb/symtab.c b/gdb/symtab.c index feb986f17c8..9472c24e4b7 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -3057,10 +3057,15 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], if (file_matches (real_symtab->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) - && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF + && ((kind == VARIABLES_DOMAIN + && SYMBOL_CLASS (sym) != LOC_TYPEDEF && SYMBOL_CLASS (sym) != LOC_UNRESOLVED && SYMBOL_CLASS (sym) != LOC_BLOCK - && SYMBOL_CLASS (sym) != LOC_CONST) + /* LOC_CONST can be used for more than just enums, + e.g., c++ static const members. + We only want to skip enums here. */ + && !(SYMBOL_CLASS (sym) == LOC_CONST + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM)) || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK) || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF)))) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 21a1be11eb3..65f0db3618a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-06-29 Doug Evans + + Test PR c++/11702. + * gdb.cp/m-static.exp: Add testcase. + * gdb.cp/m-static.h (gnu_obj_4): Add initialized static const member. + 2010-06-28 Phil Muldoon Tom Tromey Thiago Jung Bauermann diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp index dda8d844e9b..6b457d295d0 100644 --- a/gdb/testsuite/gdb.cp/m-static.exp +++ b/gdb/testsuite/gdb.cp/m-static.exp @@ -56,12 +56,14 @@ gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} - if ![runto_main] then { perror "couldn't run to breakpoint" continue } +get_debug_format +set non_dwarf [expr ! [test_debug_format "DWARF 2"]] + # First, run to after we've constructed all the objects: gdb_breakpoint [gdb_get_line_number "constructs-done"] @@ -125,6 +127,16 @@ gdb_test "print test4.elsewhere" "\\$\[0-9\].* = 221" "static const int initiali # static const int that nobody initializes. From PR gdb/635. gdb_test "print test4.nowhere" "field nowhere is nonexistent or has been optimized out" "static const int initialized nowhere" +# static const initialized in the class definition, PR gdb/11702. +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "print test4.everywhere" "\\$\[0-9\].* = 317" "static const int initialized in class definition" +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "print test4.somewhere" "\\$\[0-9\].* = 3.14\[0-9\]*" "static const float initialized in class definition" + +# Also make sure static const members can be found via "info var". +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "info variable everywhere" "File .*/m-static\[.\]h.*const int gnu_obj_4::everywhere;" "info variable everywhere" + # Perhaps at some point test4 should also include a test for a static # const int that was initialized in the header file. But I'm not sure # that GDB's current behavior in such situations is either consistent diff --git a/gdb/testsuite/gdb.cp/m-static.h b/gdb/testsuite/gdb.cp/m-static.h index 012cd770e47..bcedfff4eea 100644 --- a/gdb/testsuite/gdb.cp/m-static.h +++ b/gdb/testsuite/gdb.cp/m-static.h @@ -5,8 +5,8 @@ class gnu_obj_4 public: static const int elsewhere; static const int nowhere; - // At some point, perhaps: - // static const int everywhere = 317; + static const int everywhere = 317; + static const float somewhere = 3.14159; // try to ensure test4 is actually allocated int dummy;