gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 28 Jun 2010 20:39:30 +0000 (20:39 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 28 Jun 2010 20:39:30 +0000 (20:39 +0000)
* c-typeprint.c (c_type_print_base): For no fields check include also
TYPE_TYPEDEF_FIELD_COUNT.  Print new typedefs section.
* dwarf2read.c (struct typedef_field_list)
(struct field_info) <typedef_field_list, typedef_field_list_count>: New.
(dwarf2_add_typedef): New.
(read_structure_type): Call dwarf2_add_typedef for DW_TAG_typedef.
Copy also FI.TYPEDEF_FIELD_LIST.
* gdbtypes.h (struct typedef_field)
(struct cplus_struct_type) <typedef_field, typedef_field_count>
(TYPE_TYPEDEF_FIELD_ARRAY, TYPE_TYPEDEF_FIELD, TYPE_TYPEDEF_FIELD_NAME)
(TYPE_TYPEDEF_FIELD_TYPE, TYPE_TYPEDEF_FIELD_COUNT): New.

gdb/testsuite/
* gdb.cp/namespace.exp (ptype OtherFileClass typedefs)
(ptype ::C::OtherFileClass typedefs): New.
* gdb.cp/namespace1.cc (C::OtherFileClass::cOtherFileClassType2)
(C::OtherFileClass::cOtherFileClassVar2): New.
(C::OtherFileClass::cOtherFileClassVar_use): Use also
cOtherFileClassVar2.
(C::cOtherFileType2, C::cOtherFileVar2): New.
(C::cOtherFileVar_use): use also cOtherFileVar2.
* gdb.cp/userdef.exp (ptype &*c): Permit arbitrary trailing text.

gdb/ChangeLog
gdb/c-typeprint.c
gdb/dwarf2read.c
gdb/gdbtypes.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/namespace.exp
gdb/testsuite/gdb.cp/namespace1.cc
gdb/testsuite/gdb.cp/userdef.exp

index 39ae349525231976741ede17f8c71d109d8aa0bc..b18b598254eee119dd295c9ffdc4de1d14236e21 100644 (file)
@@ -1,3 +1,17 @@
+2010-06-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * c-typeprint.c (c_type_print_base): For no fields check include also
+       TYPE_TYPEDEF_FIELD_COUNT.  Print new typedefs section.
+       * dwarf2read.c (struct typedef_field_list)
+       (struct field_info) <typedef_field_list, typedef_field_list_count>: New.
+       (dwarf2_add_typedef): New.
+       (read_structure_type): Call dwarf2_add_typedef for DW_TAG_typedef.
+       Copy also FI.TYPEDEF_FIELD_LIST.
+       * gdbtypes.h (struct typedef_field)
+       (struct cplus_struct_type) <typedef_field, typedef_field_count>
+       (TYPE_TYPEDEF_FIELD_ARRAY, TYPE_TYPEDEF_FIELD, TYPE_TYPEDEF_FIELD_NAME)
+       (TYPE_TYPEDEF_FIELD_TYPE, TYPE_TYPEDEF_FIELD_COUNT): New.
+
 2010-06-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * cp-namespace.c (cp_lookup_nested_type): New variable
index f7a305cead02c7074877162ea9445190dd5996e2..926ae2fc5ef329f656d4d4600e1b88a7210b8d34 100644 (file)
@@ -768,7 +768,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
          cp_type_print_derivation_info (stream, type);
 
          fprintf_filtered (stream, "{\n");
-         if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
+         if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0
+             && TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
            {
              if (TYPE_STUB (type))
                fprintfi_filtered (level + 4, stream, _("<incomplete type>\n"));
@@ -1058,6 +1059,29 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
                }
            }
 
+         /* Print typedefs defined in this class.  */
+
+         if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0)
+           {
+             if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0)
+               fprintf_filtered (stream, "\n");
+
+             for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
+               {
+                 struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
+
+                 /* Dereference the typedef declaration itself.  */
+                 gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF);
+                 target = TYPE_TARGET_TYPE (target);
+
+                 print_spaces_filtered (level + 4, stream);
+                 fprintf_filtered (stream, "typedef ");
+                 c_print_type (target, TYPE_TYPEDEF_FIELD_NAME (type, i),
+                               stream, show - 1, level + 4);
+                 fprintf_filtered (stream, ";\n");
+               }
+           }
+
          fprintfi_filtered (level, stream, "}");
 
          if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
index 6893e08ac7c6a2acee086199aa26b88458ddbacd..7febcab6b49525be2f8392b751fcffedae41a111 100644 (file)
@@ -645,6 +645,16 @@ struct field_info
 
     /* Number of entries in the fnfieldlists array.  */
     int nfnfields;
+
+    /* typedefs defined inside this class.  TYPEDEF_FIELD_LIST contains head of
+       a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements.  */
+    struct typedef_field_list
+      {
+       struct typedef_field field;
+       struct typedef_field_list *next;
+      }
+    *typedef_field_list;
+    unsigned typedef_field_list_count;
   };
 
 /* One item on the queue of compilation units to read in full symbols
@@ -4668,6 +4678,39 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
 }
 
+/* Add a typedef defined in the scope of the FIP's class.  */
+
+static void
+dwarf2_add_typedef (struct field_info *fip, struct die_info *die,
+                   struct dwarf2_cu *cu)
+{ 
+  struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct typedef_field_list *new_field;
+  struct attribute *attr;
+  struct typedef_field *fp;
+  char *fieldname = "";
+
+  /* Allocate a new field list entry and link it in.  */
+  new_field = xzalloc (sizeof (*new_field));
+  make_cleanup (xfree, new_field);
+
+  gdb_assert (die->tag == DW_TAG_typedef);
+
+  fp = &new_field->field;
+
+  /* Get name of field.  */
+  fp->name = dwarf2_name (die, cu);
+  if (fp->name == NULL)
+    return;
+
+  fp->type = read_type_die (die, cu);
+
+  new_field->next = fip->typedef_field_list;
+  fip->typedef_field_list = new_field;
+  fip->typedef_field_list_count++;
+}
+
 /* Create the vector of fields, and attach it to the type.  */
 
 static void
@@ -5202,6 +5245,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
              /* C++ base class field.  */
              dwarf2_add_field (&fi, child_die, cu);
            }
+         else if (child_die->tag == DW_TAG_typedef)
+           dwarf2_add_typedef (&fi, child_die, cu);
          child_die = sibling_die (child_die);
        }
 
@@ -5275,6 +5320,28 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                }
            }
        }
+
+      /* Copy fi.typedef_field_list linked list elements content into the
+        allocated array TYPE_TYPEDEF_FIELD_ARRAY (type).  */
+      if (fi.typedef_field_list)
+       {
+         int i = fi.typedef_field_list_count;
+
+         TYPE_TYPEDEF_FIELD_ARRAY (type)
+           = TYPE_ALLOC (type, sizeof (TYPE_TYPEDEF_FIELD (type, 0)) * i);
+         TYPE_TYPEDEF_FIELD_COUNT (type) = i;
+
+         /* Reverse the list order to keep the debug info elements order.  */
+         while (--i >= 0)
+           {
+             struct typedef_field *dest, *src;
+             
+             dest = &TYPE_TYPEDEF_FIELD (type, i);
+             src = &fi.typedef_field_list->field;
+             fi.typedef_field_list = fi.typedef_field_list->next;
+             *dest = *src;
+           }
+       }
     }
 
   quirk_gcc_member_function_pointer (type, cu->objfile);
index ce79dc228f1d2726bad3e7de6ee99920f5ae4b3e..61c7f9ae86104406b664a0eacce20a74bb1064fc 100644 (file)
@@ -820,6 +820,19 @@ struct cplus_struct_type
        int line;
       }
      *localtype_ptr;
+
+    /* typedefs defined inside this class.  TYPEDEF_FIELD points to an array of
+       TYPEDEF_FIELD_COUNT elements.  */
+    struct typedef_field
+      {
+       /* Unqualified name to be prefixed by owning class qualified name.  */
+       const char *name;
+
+       /* Type this typedef named NAME represents.  */
+       struct type *type;
+      }
+    *typedef_field;
+    unsigned typedef_field_count;
   };
 
 /* Struct used in computing virtual base list */
@@ -1047,6 +1060,17 @@ extern void allocate_gnat_aux_type (struct type *);
 #define TYPE_LOCALTYPE_FILE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->file)
 #define TYPE_LOCALTYPE_LINE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->line)
 
+#define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \
+  TYPE_CPLUS_SPECIFIC (thistype)->typedef_field
+#define TYPE_TYPEDEF_FIELD(thistype, n) \
+  TYPE_CPLUS_SPECIFIC (thistype)->typedef_field[n]
+#define TYPE_TYPEDEF_FIELD_NAME(thistype, n) \
+  TYPE_TYPEDEF_FIELD (thistype, n).name
+#define TYPE_TYPEDEF_FIELD_TYPE(thistype, n) \
+  TYPE_TYPEDEF_FIELD (thistype, n).type
+#define TYPE_TYPEDEF_FIELD_COUNT(thistype) \
+  TYPE_CPLUS_SPECIFIC (thistype)->typedef_field_count
+
 #define TYPE_IS_OPAQUE(thistype) (((TYPE_CODE (thistype) == TYPE_CODE_STRUCT) ||        \
                                    (TYPE_CODE (thistype) == TYPE_CODE_UNION))        && \
                                   (TYPE_NFIELDS (thistype) == 0)                     && \
index 9f89500d62fb758ef5d22b6ec17aef8413132ef1..dd618c9a0079867db05ad12ff1cfa2bdae7db265 100644 (file)
@@ -1,3 +1,15 @@
+2010-06-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.cp/namespace.exp (ptype OtherFileClass typedefs)
+       (ptype ::C::OtherFileClass typedefs): New.
+       * gdb.cp/namespace1.cc (C::OtherFileClass::cOtherFileClassType2)
+       (C::OtherFileClass::cOtherFileClassVar2): New.
+       (C::OtherFileClass::cOtherFileClassVar_use): Use also
+       cOtherFileClassVar2.
+       (C::cOtherFileType2, C::cOtherFileVar2): New.
+       (C::cOtherFileVar_use): use also cOtherFileVar2.
+       * gdb.cp/userdef.exp (ptype &*c): Permit arbitrary trailing text.
+
 2010-06-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.cp/namespace.exp (whatis C::cOtherFileType)
index 452dcdce78ca842db150606e1b611a41d9bc1ee6..1eae62f2d640c34c966066d2cbae2c40a9ae17b5 100644 (file)
@@ -268,6 +268,21 @@ gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n  public:
 gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n  public:\r\n    int z;\r\n.*\}"
 gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"."
 
+# Test class typedefs printing.
+set expect "type = class C::OtherFileClass \{\r\n.*\r\n *typedef short cOtherFileClassType;\r\n *typedef long cOtherFileClassType2;\r\n\}"
+if {[test_compiler_info {gcc-[0-3]-*}]
+    || [test_compiler_info {gcc-4-[0-4]-*}]} {
+    # The type in class is missing in older GCCs.
+    setup_xfail *-*-* 
+}
+gdb_test "ptype OtherFileClass" $expect "ptype OtherFileClass typedefs"
+if {[test_compiler_info {gcc-[0-3]-*}]
+    || [test_compiler_info {gcc-4-[0-4]-*}]} {
+    # The type in class is missing in older GCCs.
+    setup_xfail *-*-* 
+}
+gdb_test "ptype ::C::OtherFileClass" $expect "ptype ::C::OtherFileClass typedefs"
+
 # Some anonymous namespace tests.
 
 gdb_test "print cX" "\\$\[0-9\].* = 6"
index 928e3574110d4090485cc801a187c1e9dfee188c..aad55e5ede468ada278c2cebdd321bafbfd41a4a 100644 (file)
@@ -23,12 +23,14 @@ namespace C
     int z;
 
     typedef short cOtherFileClassType;
+    typedef long cOtherFileClassType2;
     static const cOtherFileClassType cOtherFileClassVar = 318;
+    static const cOtherFileClassType2 cOtherFileClassVar2 = 320;
     cOtherFileClassType cOtherFileClassVar_use ();
   };
   OtherFileClass::cOtherFileClassType OtherFileClass::cOtherFileClassVar_use ()
   {
-    return cOtherFileClassVar;
+    return cOtherFileClassVar + cOtherFileClassVar2;
   }
 
   namespace {
@@ -45,10 +47,12 @@ namespace C
   }
 
   typedef short cOtherFileType;
+  typedef long cOtherFileType2;
   static const cOtherFileType cOtherFileVar = 319;
+  static const cOtherFileType2 cOtherFileVar2 = 321;
   cOtherFileType cOtherFileVar_use ()
   {
-    return cOtherFileVar;
+    return cOtherFileVar + cOtherFileVar2;
   }
 }
 
index 1a6fd2e32c0b87714204ae76b465ed962c24c049..050775a3d29c0abe97307cf7110770e9934b80eb 100644 (file)
@@ -148,7 +148,7 @@ gdb_test "break A2::'operator +'" ".*Breakpoint $decimal at.*"
 gdb_test "print c" "\\\$\[0-9\]* = {m = {z = .*}}"
 gdb_test "print *c" "\\\$\[0-9\]* = \\(Member &\\) @$hex: {z = .*}"
 gdb_test "print &*c" "\\\$\[0-9\]* = \\(Member \\*\\) $hex"
-gdb_test "ptype &*c" "type = (struct|class) Member {(\[\r\n \]+public:)?\[\r\n \]+int z;\[\r\n\]+} &\\*"
+gdb_test "ptype &*c" "type = (struct|class) Member {(\[\r\n \]+public:)?\[\r\n \]+int z;\[\r\n\].*} &\\*"
 
 gdb_test "print operator== (mem1, mem2)" " = false"
 gdb_test "print operator== (mem1, mem1)" " = true"