PR c++/11702
authorDoug Evans <dje@google.com>
Tue, 29 Jun 2010 16:53:10 +0000 (16:53 +0000)
committerDoug Evans <dje@google.com>
Tue, 29 Jun 2010 16:53:10 +0000 (16:53 +0000)
* 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.

gdb/ChangeLog
gdb/NEWS
gdb/dwarf2read.c
gdb/gdbtypes.c
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/m-static.exp
gdb/testsuite/gdb.cp/m-static.h

index df91ef9..07f2bf4 100644 (file)
@@ -1,5 +1,14 @@
 2010-06-29  Doug Evans  <dje@google.com>
 
+       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.
index 73ff05f..4764c01 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
   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
index c172752..127d10f 100644 (file)
@@ -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);
index 5d1d420..ba8c7e4 100644 (file)
@@ -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);
 }
index feb986f..9472c24 100644 (file)
@@ -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))))
                {
index 21a1be1..65f0db3 100644 (file)
@@ -1,3 +1,9 @@
+2010-06-29  Doug Evans  <dje@google.com>
+
+       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  <pmuldoon@redhat.com>
             Tom Tromey  <tromey@redhat.com>
             Thiago Jung Bauermann  <bauerman@br.ibm.com>
index dda8d84..6b457d2 100644 (file)
@@ -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
index 012cd77..bcedfff 100644 (file)
@@ -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;