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>
 
 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.
        * 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.
 
   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
 * 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;
 
 
   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.  */
   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;
 
       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);
 
       /* 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:
             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.  */
          /* 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);
              = 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);
          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
      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);
 }
   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)
              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_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))))
                {
                          || (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>
 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}
 
 gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 
-
 if ![runto_main] then {
     perror "couldn't run to breakpoint"
     continue
 }
 
 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"]
 # 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 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
 # 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;
  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;
 
   // try to ensure test4 is actually allocated
   int dummy;