]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add ability to generate DWARF pubtypes section if DEBUG_PUBTYPES_SECTION is defined.
authorCaroline Tice <ctice@apple.com>
Tue, 14 Nov 2006 20:55:56 +0000 (20:55 +0000)
committerCaroline Tice <ctice@gcc.gnu.org>
Tue, 14 Nov 2006 20:55:56 +0000 (12:55 -0800)
Add ability to generate DWARF pubtypes section if DEBUG_PUBTYPES_SECTION
is defined.  Also add dejagnu testcases for pubtypes.

From-SVN: r118826

gcc/ChangeLog
gcc/config/darwin.c
gcc/config/darwin.h
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pubtypes.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/pubtypes-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pubtypes-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pubtypes-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pubtypes-4.c [new file with mode: 0644]

index 2458b0ecdf0c1e9c841a8f51b44747af7944b740..8e2c89c7ac440239d0138f511997dd6cf2ef98c8 100644 (file)
@@ -1,3 +1,34 @@
+2006-11-14  Caroline Tice  <ctice@apple.com>
+               
+       * dwarf2out.c (debug_pubtypes_section): New static global variable.
+       (pubname_entry):  Add DEF_VEC_O and DEF_VEC_ALLOC_O statements for
+       this type.
+       (pubname_table):  Redefine as a vector.
+       (pubtype_table):  New static global variable, defined as a vector.
+       (pubname_table_allocated): Remove static global variable.
+       (pubname_table_in_use): Remove static global variable.
+       (PUBNAME_TABLE_INCREMENT): Remove constant.
+       (size_of_pubnames): Add parameter to deal with either pubnames or 
+       pubtypes, and change code to deal with table being a vector.
+       (add_pubname):  Change to deal with table being a vector.
+       (add_pubtype):  New function.
+       (output_pubnames): Add parameter to deal with either pubnames or 
+       pubtypes, and change code to deal with table being a vector.
+       (gen_array_type_die):  Add call to add_pubtype.
+       (gen_enumeration_type_die): Add call to add_pubtype.
+       (gen_struct_or_union_type_die): Add call to add_pubtype.
+       (gen_subroutine_type_die): Add call to add_pubtype.
+       (gen_typedef_die):  Add call to add_pubtype.
+       (dwarf2out_init): Add code to initialize pubname_table and 
+       pubtype_table vectors; also initialize debug_pubtypes_section.
+       (prune_unused_types):  Change to deal with pubnames being a vector.
+       (dwarf2out_finish): Change to deal with pubnames being a vector; add 
+       pubnames table to call to output_pubnames;  Add code to output pubtypes 
+       table if DEBUG_PUBTYPES_SECTION is defined.
+       * config/darwin.c (darwin_file_start):  Add DEBUG_PUBTYPES_SECTION to 
+       debugnames.
+       * config/darwin.h (DEBUG_PUBTYPES_SECTION): Define new global variable.
+
 2006-11-14  Joseph Myers  <joseph@codesourcery.com>
 
        * config/arm/arm.h (FUNCTION_ARG_ADVANCE): Only adjust
index 7475b1a5e990923332cc1496aee7a33144028309..9332cc14c1861df97fae7fdc5760008bced6cbfb 100644 (file)
@@ -1516,6 +1516,7 @@ darwin_file_start (void)
          DEBUG_LINE_SECTION,
          DEBUG_LOC_SECTION,
          DEBUG_PUBNAMES_SECTION,
+         DEBUG_PUBTYPES_SECTION,
          DEBUG_STR_SECTION,
          DEBUG_RANGES_SECTION
        };
index bbb1f890dbeb8576d97029a6336420f3dfd97884..a518a2c7dc9d76445a6a3938e35431ec33850868 100644 (file)
@@ -407,6 +407,7 @@ extern GTY(()) int darwin_ms_struct;
 #define DEBUG_LINE_SECTION     "__DWARF,__debug_line,regular,debug"
 #define DEBUG_LOC_SECTION      "__DWARF,__debug_loc,regular,debug"
 #define DEBUG_PUBNAMES_SECTION "__DWARF,__debug_pubnames,regular,debug"
+#define DEBUG_PUBTYPES_SECTION "__DWARF,__debug_pubtypes,regular,debug"
 #define DEBUG_STR_SECTION      "__DWARF,__debug_str,regular,debug"
 #define DEBUG_RANGES_SECTION   "__DWARF,__debug_ranges,regular,debug"
 
index 28108ece3ddbf80a6bd3bc13c3e6f0be998b2e1a..c61f3d8bd92bcf21e64071c907a647a0c62631c6 100644 (file)
@@ -156,6 +156,7 @@ static GTY(()) section *debug_macinfo_section;
 static GTY(()) section *debug_line_section;
 static GTY(()) section *debug_loc_section;
 static GTY(()) section *debug_pubnames_section;
+static GTY(()) section *debug_pubtypes_section;
 static GTY(()) section *debug_str_section;
 static GTY(()) section *debug_ranges_section;
 static GTY(()) section *debug_frame_section;
@@ -3759,6 +3760,9 @@ typedef struct pubname_struct GTY(())
 }
 pubname_entry;
 
+DEF_VEC_O(pubname_entry);
+DEF_VEC_ALLOC_O(pubname_entry, gc);
+
 struct dw_ranges_struct GTY(())
 {
   int block_num;
@@ -3940,17 +3944,11 @@ static GTY(()) unsigned separate_line_info_table_in_use;
 
 /* A pointer to the base of a table that contains a list of publicly
    accessible names.  */
-static GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table;
-
-/* Number of elements currently allocated for pubname_table.  */
-static GTY(()) unsigned pubname_table_allocated;
-
-/* Number of elements in pubname_table currently in use.  */
-static GTY(()) unsigned pubname_table_in_use;
+static GTY (()) VEC (pubname_entry, gc) *  pubname_table;
 
-/* Size (in elements) of increments by which we may expand the
-   pubname_table.  */
-#define PUBNAME_TABLE_INCREMENT 64
+/* A pointer to the base of a table that contains a list of publicly
+   accessible types.  */
+static GTY (()) VEC (pubname_entry, gc) * pubtype_table;
 
 /* Array of dies for which we should generate .debug_arange info.  */
 static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table;
@@ -4115,7 +4113,7 @@ static void calc_die_sizes (dw_die_ref);
 static void mark_dies (dw_die_ref);
 static void unmark_dies (dw_die_ref);
 static void unmark_all_dies (dw_die_ref);
-static unsigned long size_of_pubnames (void);
+static unsigned long size_of_pubnames (VEC (pubname_entry,gc) *);
 static unsigned long size_of_aranges (void);
 static enum dwarf_form value_format (dw_attr_ref);
 static void output_value_format (dw_attr_ref);
@@ -4126,7 +4124,8 @@ static void output_compilation_unit_header (void);
 static void output_comp_unit (dw_die_ref, int);
 static const char *dwarf2_name (tree, int);
 static void add_pubname (tree, dw_die_ref);
-static void output_pubnames (void);
+static void add_pubtype (tree, dw_die_ref);
+static void output_pubnames (VEC (pubname_entry,gc) *);
 static void add_arange (tree, dw_die_ref);
 static void output_aranges (void);
 static unsigned int add_ranges (tree);
@@ -6749,21 +6748,22 @@ unmark_all_dies (dw_die_ref die)
       unmark_all_dies (AT_ref (a));
 }
 
-/* Return the size of the .debug_pubnames table  generated for the
-   compilation unit.  */
+/* Return the size of the .debug_pubnames or .debug_pubtypes table  
+   generated for the compilation unit.  */
 
 static unsigned long
-size_of_pubnames (void)
+size_of_pubnames (VEC (pubname_entry, gc) * names)
 {
   unsigned long size;
   unsigned i;
+  pubname_ref p;
 
   size = DWARF_PUBNAMES_HEADER_SIZE;
-  for (i = 0; i < pubname_table_in_use; i++)
-    {
-      pubname_ref p = &pubname_table[i];
-      size += DWARF_OFFSET_SIZE + strlen (p->name) + 1;
-    }
+  for (i = 0; VEC_iterate (pubname_entry, names, i, p); i++)
+    if (names != pubtype_table
+       || p->die->die_offset != 0
+       || !flag_eliminate_unused_debug_types)
+      size += strlen (p->name) + DWARF_OFFSET_SIZE + 1;
 
   size += DWARF_OFFSET_SIZE;
   return size;
@@ -7330,41 +7330,73 @@ dwarf2_name (tree decl, int scope)
 static void
 add_pubname (tree decl, dw_die_ref die)
 {
-  pubname_ref p;
+  pubname_entry e;
 
   if (! TREE_PUBLIC (decl))
     return;
 
-  if (pubname_table_in_use == pubname_table_allocated)
+  e.die = die;
+  e.name = xstrdup (dwarf2_name (decl, 1));
+  VEC_safe_push (pubname_entry, gc, pubname_table, &e);
+}
+
+/* Add a new entry to .debug_pubtypes if appropriate.  */
+
+static void
+add_pubtype (tree decl, dw_die_ref die)
+{
+  pubname_entry e;
+
+  e.name = NULL;
+  if ((TREE_PUBLIC (decl)
+       || die->die_parent == comp_unit_die)
+      && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl)))
     {
-      pubname_table_allocated += PUBNAME_TABLE_INCREMENT;
-      pubname_table
-       = ggc_realloc (pubname_table,
-                      (pubname_table_allocated * sizeof (pubname_entry)));
-      memset (pubname_table + pubname_table_in_use, 0,
-             PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry));
-    }
+      e.die = die;
+      if (TYPE_P (decl))
+       {
+         if (TYPE_NAME (decl))
+           {
+             if (TREE_CODE (TYPE_NAME (decl)) == IDENTIFIER_NODE)
+               e.name = xstrdup ((const char *) IDENTIFIER_POINTER 
+                                                             (TYPE_NAME (decl)));
+             else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL
+                      && DECL_NAME (TYPE_NAME (decl)))
+               e.name = xstrdup ((const char *) IDENTIFIER_POINTER 
+                                                 (DECL_NAME (TYPE_NAME (decl))));
+             else
+              e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name));
+           }
+       }
+      else 
+       e.name = xstrdup (dwarf2_name (decl, 1));
 
-  p = &pubname_table[pubname_table_in_use++];
-  p->die = die;
-  p->name = xstrdup (dwarf2_name (decl, 1));
+      /* If we don't have a name for the type, there's no point in adding
+        it to the table.  */
+      if (e.name && e.name[0] != '\0')
+       VEC_safe_push (pubname_entry, gc, pubtype_table, &e);
+    }
 }
 
 /* Output the public names table used to speed up access to externally
-   visible names.  For now, only generate entries for externally
-   visible procedures.  */
+   visible names; or the public types table used to find type definitions.  */
 
 static void
-output_pubnames (void)
+output_pubnames (VEC (pubname_entry, gc) * names)
 {
   unsigned i;
-  unsigned long pubnames_length = size_of_pubnames ();
+  unsigned long pubnames_length = size_of_pubnames (names);
+  pubname_ref pub;
 
   if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
     dw2_asm_output_data (4, 0xffffffff,
       "Initial length escape value indicating 64-bit DWARF extension");
-  dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
-                      "Length of Public Names Info");
+  if (names == pubname_table)
+    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
+                        "Length of Public Names Info");
+  else
+    dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
+                        "Length of Public Type Names Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label,
                         debug_info_section,
@@ -7372,17 +7404,21 @@ output_pubnames (void)
   dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset,
                       "Compilation Unit Length");
 
-  for (i = 0; i < pubname_table_in_use; i++)
+  for (i = 0; VEC_iterate (pubname_entry, names, i, pub); i++)
     {
-      pubname_ref pub = &pubname_table[i];
-
-      /* We shouldn't see pubnames for DIEs outside of the main CU.  */
-      gcc_assert (pub->die->die_mark);
+      /* We shouldn't see pubnames for DIEs outside of the main CU.  */      
+      if (names == pubname_table)
+       gcc_assert (pub->die->die_mark);
 
-      dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset,
-                          "DIE offset");
+      if (names != pubtype_table
+         || pub->die->die_offset != 0
+         || !flag_eliminate_unused_debug_types)
+       {
+         dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset,
+                              "DIE offset");
 
-      dw2_asm_output_nstring (pub->name, -1, "external name");
+         dw2_asm_output_nstring (pub->name, -1, "external name");
+       }
     }
 
   dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL);
@@ -11250,6 +11286,9 @@ gen_array_type_die (tree type, dw_die_ref context_die)
 #endif
 
   add_type_attribute (array_die, element_type, 0, 0, context_die);
+
+  if (get_AT (array_die, DW_AT_name))
+    add_pubtype (type, array_die);
 }
 
 #if 0
@@ -11385,6 +11424,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
   else
     add_AT_flag (type_die, DW_AT_declaration, 1);
 
+  if (get_AT (type_die, DW_AT_name))
+    add_pubtype (type, type_die);
+
   return type_die;
 }
 
@@ -12502,6 +12544,9 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
          && ! decl_function_context (TYPE_STUB_DECL (type)))
        VEC_safe_push (tree, gc, incomplete_types, type);
     }
+
+  if (get_AT (type_die, DW_AT_name))
+    add_pubtype (type, type_die);
 }
 
 /* Generate a DIE for a subroutine _type_.  */
@@ -12518,6 +12563,9 @@ gen_subroutine_type_die (tree type, dw_die_ref context_die)
   add_prototyped_attribute (subr_die, type);
   add_type_attribute (subr_die, return_type, 0, 0, context_die);
   gen_formal_types_die (type, subr_die);
+
+  if (get_AT (subr_die, DW_AT_name))
+    add_pubtype (type, subr_die);
 }
 
 /* Generate a DIE for a type definition.  */
@@ -12557,6 +12605,9 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
 
   if (DECL_ABSTRACT (decl))
     equate_decl_number_to_die (decl, type_die);
+
+  if (get_AT (type_die, DW_AT_name))
+    add_pubtype (decl, type_die);
 }
 
 /* Generate a type description DIE.  */
@@ -13848,6 +13899,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
   /* Zero-th entry is allocated, but unused.  */
   line_info_table_in_use = 1;
 
+  /* Allocate the pubtypes and pubnames vectors.  */
+  pubname_table = VEC_alloc (pubname_entry, gc, 32);
+  pubtype_table = VEC_alloc (pubname_entry, gc, 32);
+
   /* Generate the initial DIE for the .debug section.  Note that the (string)
      value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
      will (typically) be a relative pathname and that this pathname should be
@@ -13874,6 +13929,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
                                   SECTION_DEBUG, NULL);
   debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION,
                                        SECTION_DEBUG, NULL);
+#ifdef DEBUG_PUBTYPES_SECTION
+  debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION,
+                                       SECTION_DEBUG, NULL);
+#endif
   debug_str_section = get_section (DEBUG_STR_SECTION,
                                   DEBUG_STR_SECTION_FLAGS, NULL);
   debug_ranges_section = get_section (DEBUG_RANGES_SECTION,
@@ -14157,6 +14216,7 @@ prune_unused_types (void)
 {
   unsigned int i;
   limbo_die_node *node;
+  pubname_ref pub;
 
 #if ENABLE_ASSERT_CHECKING
   /* All the marks should already be clear.  */
@@ -14172,8 +14232,8 @@ prune_unused_types (void)
 
   /* Also set the mark on nodes referenced from the
      pubname_table or arange_table.  */
-  for (i = 0; i < pubname_table_in_use; i++)
-    prune_unused_types_mark (pubname_table[i].die, 1);
+  for (i = 0; VEC_iterate (pubname_entry, pubname_table, i, pub); i++)
+    prune_unused_types_mark (pub->die, 1);
   for (i = 0; i < arange_table_in_use; i++)
     prune_unused_types_mark (arange_table[i], 1);
 
@@ -14352,12 +14412,21 @@ dwarf2out_finish (const char *filename)
   output_abbrev_section ();
 
   /* Output public names table if necessary.  */
-  if (pubname_table_in_use)
+  if (!VEC_empty (pubname_entry, pubname_table))
     {
       switch_to_section (debug_pubnames_section);
-      output_pubnames ();
+      output_pubnames (pubname_table);
     }
 
+#ifdef DEBUG_PUBTYPES_SECTION
+  /* Output public types table if necessary.  */
+  if (!VEC_empty (pubname_entry, pubtype_table))
+    {
+      switch_to_section (debug_pubtypes_section);
+      output_pubnames (pubtype_table);
+    }
+#endif
+  
   /* Output the address range information.  We only put functions in the arange
      table, so don't write it out if we don't have any.  */
   if (fde_table_in_use)
index 49e77ab5edaba688ff8835ed4095aad42877be4e..2ad8fb323aba5a3e959375169f287929f0f4bc08 100644 (file)
@@ -1,3 +1,11 @@
+2006-11-14  Caroline Tice  <ctice@apple.com>
+
+       * gcc.dg/pubtypes-1.c: New file/testcase.
+       * gcc.dg/pubtypes-2.c: New file/testcase.
+       * gcc.dg/pubtypes-3.c: New file/testcase.
+       * gcc.dg/pubtypes-4.c: New file/testcase.
+       * g++.dg/pubtypes.C: New file/testcase.
+
 2006-11-14  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/29106
diff --git a/gcc/testsuite/g++.dg/pubtypes.C b/gcc/testsuite/g++.dg/pubtypes.C
new file mode 100644 (file)
index 0000000..a17ad20
--- /dev/null
@@ -0,0 +1,64 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0 -gdwarf-2 -dA -fno-eliminate-unused-debug-types" } */
+/* { dg-final { scan-assembler "__debug_pubtypes" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x24+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */
+/* { dg-final { scan-assembler "\"empty\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "\"A\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "\"B\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+
+
+struct A
+{
+  virtual ~A ();
+  int a1;
+};
+
+A::~A()
+{
+  a1 = 800;
+}
+
+struct B : public A
+{
+  virtual ~B ();
+  int b1;
+  int b2;
+};
+
+B::~B()
+{
+  a1 = 900;
+  b1 = 901;
+  b2 = 902;
+}
+
+// Stop the compiler from optimizing away data.
+void refer (A *)
+{
+  ;
+}
+
+struct empty {};
+
+// Stop the compiler from optimizing away data.
+void refer (empty *)
+{
+  ;
+}
+
+int main (void)
+{
+  A alpha, *aap, *abp;
+  B beta, *bbp;
+  empty e;
+
+  alpha.a1 = 100;
+  beta.a1 = 200; beta.b1 = 201; beta.b2 = 202;
+
+  aap = &alpha; refer (aap);
+  abp = &beta;  refer (abp);
+  bbp = &beta;  refer (bbp);
+  refer (&e);
+
+  return 0;  // marker return 0
+} // marker close brace
diff --git a/gcc/testsuite/gcc.dg/pubtypes-1.c b/gcc/testsuite/gcc.dg/pubtypes-1.c
new file mode 100644 (file)
index 0000000..5c6767e
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0 -gdwarf-2 -dA -fno-eliminate-unused-debug-types" } */
+/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
+/* { dg-final { scan-assembler "__debug_pubtypes" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x\[0-9a-f]+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */
+/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct used_struct 
+{
+  int key;
+  char *name;
+};
+
+struct unused_struct
+{
+  int key1;
+  int f2;
+  double f3;
+  char *f4;
+  struct unused_struct *next;
+};
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct used_struct *my_list;
+
+  my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct));
+  
+  for (i = 0; i < 10; i++)
+    {
+      my_list[i].key = i;
+      my_list[i].name = (char *) malloc (11);
+      sprintf (my_list[i].name, "Alice_%d", i);
+    }
+
+  for (i = 0; i < 10; i++)
+    fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name);
+  
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pubtypes-2.c b/gcc/testsuite/gcc.dg/pubtypes-2.c
new file mode 100644 (file)
index 0000000..fec4661
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
+/* { dg-final { scan-assembler "__debug_pubtypes" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x6a+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */
+/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct used_struct 
+{
+  int key;
+  char *name;
+};
+
+struct unused_struct
+{
+  int key1;
+  int f2;
+  double f3;
+  char *f4;
+  struct unused_struct *next;
+};
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct used_struct *my_list;
+
+  my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct));
+  
+  for (i = 0; i < 10; i++)
+    {
+      my_list[i].key = i;
+      my_list[i].name = (char *) malloc (11);
+      sprintf (my_list[i].name, "Alice_%d", i);
+    }
+
+  for (i = 0; i < 10; i++)
+    fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name);
+  
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pubtypes-3.c b/gcc/testsuite/gcc.dg/pubtypes-3.c
new file mode 100644 (file)
index 0000000..455dadf
--- /dev/null
@@ -0,0 +1,83 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
+/* { dg-final { scan-assembler "__debug_pubtypes" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x6a+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */
+/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler-not "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct used_struct 
+{
+  int key;
+  char *name;
+};
+
+struct unused_struct
+{
+  int key1;
+  int f2;
+  double f3;
+  char *f4;
+  struct unused_struct *next;
+};
+
+void 
+foo (struct used_struct *list)
+{
+  enum list_name_type {
+    boy_name,
+    girl_name,
+    unknown
+  };
+
+  int b_count = 0;
+  int g_count = 0;
+  int i;
+  enum list_name_type *enum_list;
+
+  enum_list = (enum list_name_type *) malloc (10 * sizeof (enum list_name_type));
+  
+  for (i = 0; i < 10; i++)
+    {
+      if (strncmp (list[i].name, "Alice", 5) == 0)
+       {
+         enum_list[i] = girl_name;
+         g_count++;
+       }
+      else if (strncmp (list[i].name, "David", 5) == 0)
+       {
+         enum_list[i] = boy_name;
+         b_count++;
+       }
+      else
+       enum_list[i] = unknown;
+    }
+
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct used_struct *my_list;
+
+  my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct));
+  
+  for (i = 0; i < 10; i++)
+    {
+      my_list[i].key = i;
+      my_list[i].name = (char *) malloc (11);
+      sprintf (my_list[i].name, "Alice_%d", i);
+    }
+
+  foo (my_list);
+
+  for (i = 0; i < 10; i++)
+    fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name);
+  
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pubtypes-4.c b/gcc/testsuite/gcc.dg/pubtypes-4.c
new file mode 100644 (file)
index 0000000..db222da
--- /dev/null
@@ -0,0 +1,96 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
+/* { dg-final { scan-assembler "__debug_pubtypes" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0xa1+\[ \t\]+\[#;]+\[ \t\]+Length of Public Type Names Info" } } */
+/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "\"enum_list_array\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+/* { dg-final { scan-assembler "\"field_union\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct used_struct 
+{
+  int key;
+  char *name;
+  union field_union
+  {
+    char  u_c;
+    int   u_i;
+    long  u_l;
+    double u_d;
+  } u;
+};
+
+struct unused_struct
+{
+  int key1;
+  int f2;
+  double f3;
+  char *f4;
+  struct unused_struct *next;
+};
+
+enum list_name_type {
+  boy_name,
+  girl_name,
+  unknown
+};
+
+
+typedef enum list_name_type *enum_list_array;
+
+enum_list_array enum_list;
+
+void 
+foo (struct used_struct *list)
+{
+  int b_count = 0;
+  int g_count = 0;
+  int i;
+
+  enum_list = (enum_list_array) malloc (10 * sizeof (enum list_name_type));
+
+  for (i = 0; i < 10; i++)
+    {
+      if (strncmp (list[i].name, "Alice", 5) == 0)
+       {
+         enum_list[i] = girl_name;
+         g_count++;
+       }
+      else if (strncmp (list[i].name, "David", 5) == 0)
+       {
+         enum_list[i] = boy_name;
+         b_count++;
+       }
+      else
+       enum_list[i] = unknown;
+    }
+
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct used_struct *my_list;
+
+  my_list = (struct used_struct *) malloc (10 * sizeof (struct used_struct));
+  
+  for (i = 0; i < 10; i++)
+    {
+      my_list[i].key = i;
+      my_list[i].name = (char *) malloc (11);
+      sprintf (my_list[i].name, "Alice_%d", i);
+    }
+
+  foo (my_list);
+
+  for (i = 0; i < 10; i++)
+    fprintf (stdout, "Key: %d, Name: %s\n", my_list[i].key, my_list[i].name);
+  
+  return 0;
+}