OSDN Git Service

* Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Oct 2002 09:14:04 +0000 (09:14 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Oct 2002 09:14:04 +0000 (09:14 +0000)
* dwarf2out.c: Include hashtab.h.
(is_main_source): New static variable.
(attr_checksum, die_checksum): Modified to handle die references.
(same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
record_comdat_symbol_number): New static functions.
(output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
* toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
declarations added.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58578 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/dwarf2out.c
gcc/toplev.c

index 61f3bfb..ef1dbff 100644 (file)
@@ -1,3 +1,17 @@
+2002-10-27  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
+       * dwarf2out.c: Include hashtab.h.
+       (is_main_source): New static variable.
+       (attr_checksum, die_checksum): Modified to handle die references.
+       (same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
+       unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
+       record_comdat_symbol_number): New static functions.
+       (output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
+       mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
+       * toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
+       declarations added.
+
 2002-10-26  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/h8300/h8300.c (initial_offset): Change to
index eb4596e..e97c302 100644 (file)
@@ -1455,7 +1455,7 @@ dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \
 dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf2.h \
    debug.h flags.h insn-config.h reload.h output.h diagnostic.h real.h \
    hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
-   $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h gt-dwarf2out.h
+   $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h
 dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
    output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
 vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
index b8bf06b..ed2a0ec 100644 (file)
@@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "langhooks.h"
 #include "hashtable.h"
+#include "hashtab.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
 static void dwarf2out_source_line      PARAMS ((unsigned int, const char *));
@@ -3333,6 +3334,10 @@ static unsigned long next_die_offset;
 /* Record the root of the DIE's built for the current compilation unit.  */
 static dw_die_ref comp_unit_die;
 
+/* We need special handling in dwarf2out_start_source_file if it is
+   first one.  */
+static int is_main_source;
+
 /* A list of DIEs with a NULL parent waiting to be relocated.  */
 static limbo_die_node *limbo_die_list = 0;
 
@@ -3569,15 +3574,29 @@ static dw_die_ref pop_compile_unit      PARAMS ((dw_die_ref));
 static void loc_checksum               PARAMS ((dw_loc_descr_ref,
                                                 struct md5_ctx *));
 static void attr_checksum              PARAMS ((dw_attr_ref,
-                                                struct md5_ctx *));
+                                                struct md5_ctx *,
+                                                int *));
 static void die_checksum               PARAMS ((dw_die_ref,
-                                                struct md5_ctx *));
+                                                struct md5_ctx *,
+                                                int *));
+static int same_loc_p                  PARAMS ((dw_loc_descr_ref,
+                                                dw_loc_descr_ref, int *));
+static int same_dw_val_p               PARAMS ((dw_val_node *, dw_val_node *,
+                                                int *));
+static int same_attr_p                 PARAMS ((dw_attr_ref, dw_attr_ref, int *));
+static int same_die_p                  PARAMS ((dw_die_ref, dw_die_ref, int *));
+static int same_die_p_wrap             PARAMS ((dw_die_ref, dw_die_ref));
 static void compute_section_prefix     PARAMS ((dw_die_ref));
 static int is_type_die                 PARAMS ((dw_die_ref));
 static int is_comdat_die               PARAMS ((dw_die_ref));
 static int is_symbol_die               PARAMS ((dw_die_ref));
 static void assign_symbol_names                PARAMS ((dw_die_ref));
 static void break_out_includes         PARAMS ((dw_die_ref));
+static hashval_t htab_cu_hash          PARAMS ((const void *));
+static int htab_cu_eq                  PARAMS ((const void *, const void *));
+static void htab_cu_del                        PARAMS ((void *));
+static int check_duplicate_cu          PARAMS ((dw_die_ref, htab_t, unsigned *));
+static void record_comdat_symbol_number        PARAMS ((dw_die_ref, htab_t, unsigned));
 static void add_sibling_attributes     PARAMS ((dw_die_ref));
 static void build_abbrev_table         PARAMS ((dw_die_ref));
 static void output_location_lists      PARAMS ((dw_die_ref));
@@ -3586,6 +3605,7 @@ static unsigned long size_of_die  PARAMS ((dw_die_ref));
 static void calc_die_sizes             PARAMS ((dw_die_ref));
 static void mark_dies                  PARAMS ((dw_die_ref));
 static void unmark_dies                        PARAMS ((dw_die_ref));
+static void unmark_all_dies             PARAMS ((dw_die_ref));
 static unsigned long size_of_pubnames  PARAMS ((void));
 static unsigned long size_of_aranges   PARAMS ((void));
 static enum dwarf_form value_format    PARAMS ((dw_attr_ref));
@@ -3594,7 +3614,7 @@ static void output_abbrev_section PARAMS ((void));
 static void output_die_symbol          PARAMS ((dw_die_ref));
 static void output_die                 PARAMS ((dw_die_ref));
 static void output_compilation_unit_header PARAMS ((void));
-static void output_comp_unit           PARAMS ((dw_die_ref));
+static void output_comp_unit           PARAMS ((dw_die_ref, int));
 static const char *dwarf2_name         PARAMS ((tree, int));
 static void add_pubname                        PARAMS ((tree, dw_die_ref));
 static void output_pubnames            PARAMS ((void));
@@ -5420,9 +5440,10 @@ loc_checksum (loc, ctx)
 /* Calculate the checksum of an attribute.  */
 
 static void
-attr_checksum (at, ctx)
+attr_checksum (at, ctx, mark)
      dw_attr_ref at;
      struct md5_ctx *ctx;
+     int *mark;
 {
   dw_loc_descr_ref loc;
   rtx r;
@@ -5480,9 +5501,8 @@ attr_checksum (at, ctx)
       break;
 
     case dw_val_class_die_ref:
-      if (AT_ref (at)->die_offset)
-       CHECKSUM (AT_ref (at)->die_offset);
-      /* FIXME else use target die name or something.  */
+      die_checksum (AT_ref (at), ctx, mark);
+      break;
 
     case dw_val_class_fde_ref:
     case dw_val_class_lbl_id:
@@ -5497,25 +5517,195 @@ attr_checksum (at, ctx)
 /* Calculate the checksum of a DIE.  */
 
 static void
-die_checksum (die, ctx)
+die_checksum (die, ctx, mark)
      dw_die_ref die;
      struct md5_ctx *ctx;
+     int *mark;
 {
   dw_die_ref c;
   dw_attr_ref a;
 
+  /* To avoid infinite recursion.  */
+  if (die->die_mark)
+    {
+      CHECKSUM (die->die_mark);
+      return;
+    }
+  die->die_mark = ++(*mark);
+
   CHECKSUM (die->die_tag);
 
   for (a = die->die_attr; a; a = a->dw_attr_next)
-    attr_checksum (a, ctx);
+    attr_checksum (a, ctx, mark);
 
   for (c = die->die_child; c; c = c->die_sib)
-    die_checksum (c, ctx);
+    die_checksum (c, ctx, mark);
 }
 
 #undef CHECKSUM
 #undef CHECKSUM_STRING
 
+/* Do the location expressions look same?  */
+static inline int
+same_loc_p (loc1, loc2, mark)
+     dw_loc_descr_ref loc1;
+     dw_loc_descr_ref loc2;
+     int *mark;
+{
+  return loc1->dw_loc_opc == loc2->dw_loc_opc
+        && same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
+        && same_dw_val_p (&loc1->dw_loc_oprnd2, &loc2->dw_loc_oprnd2, mark);
+}
+
+/* Do the values look the same?  */
+static int
+same_dw_val_p (v1, v2, mark)
+     dw_val_node *v1;
+     dw_val_node *v2;
+     int *mark;
+{
+  dw_loc_descr_ref loc1, loc2;
+  rtx r1, r2;
+  unsigned i;
+
+  if (v1->val_class != v2->val_class)
+    return 0;
+
+  switch (v1->val_class)
+    {
+    case dw_val_class_const:
+      return v1->v.val_int == v2->v.val_int;
+    case dw_val_class_unsigned_const:
+      return v1->v.val_unsigned == v2->v.val_unsigned;
+    case dw_val_class_long_long:
+      return v1->v.val_long_long.hi == v2->v.val_long_long.hi
+             && v1->v.val_long_long.low == v2->v.val_long_long.low;
+    case dw_val_class_float:
+      if (v1->v.val_float.length != v2->v.val_float.length)
+       return 0;
+      for (i = 0; i < v1->v.val_float.length; i++)
+        if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
+         return 0;
+      return 1;
+    case dw_val_class_flag:
+      return v1->v.val_flag == v2->v.val_flag;
+    case dw_val_class_str:
+      return !strcmp((const char *) HT_STR (&v1->v.val_str->id),
+                    (const char *) HT_STR (&v2->v.val_str->id));
+
+    case dw_val_class_addr:
+      r1 = v1->v.val_addr;
+      r2 = v2->v.val_addr;
+      if (GET_CODE (r1) != GET_CODE (r2))
+       return 0;
+      switch (GET_CODE (r1))
+       {
+       case SYMBOL_REF:
+         return !strcmp (XSTR (r1, 0), XSTR (r2, 0));
+
+       default:
+         abort ();
+       }
+
+    case dw_val_class_offset:
+      return v1->v.val_offset == v2->v.val_offset;
+
+    case dw_val_class_loc:
+      for (loc1 = v1->v.val_loc, loc2 = v2->v.val_loc;
+          loc1 && loc2;
+          loc1 = loc1->dw_loc_next, loc2 = loc2->dw_loc_next)
+       if (!same_loc_p (loc1, loc2, mark))
+         return 0;
+      return !loc1 && !loc2;
+
+    case dw_val_class_die_ref:
+      return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark);
+
+    case dw_val_class_fde_ref:
+    case dw_val_class_lbl_id:
+    case dw_val_class_lbl_offset:
+      return 1;
+
+    default:
+      return 1;
+    }
+}
+
+/* Do the attributes look the same?  */
+
+static int
+same_attr_p (at1, at2, mark)
+     dw_attr_ref at1;
+     dw_attr_ref at2;
+     int *mark;
+{
+  if (at1->dw_attr != at2->dw_attr)
+    return 0;
+
+  /* We don't care about differences in file numbering.  */
+  if (at1->dw_attr == DW_AT_decl_file
+      /* Or that this was compiled with a different compiler snapshot; if
+        the output is the same, that's what matters.  */
+      || at1->dw_attr == DW_AT_producer)
+    return 1;
+
+  return same_dw_val_p (&at1->dw_attr_val, &at2->dw_attr_val, mark);
+}
+
+/* Do the dies look the same?  */
+
+static int
+same_die_p (die1, die2, mark)
+     dw_die_ref die1;
+     dw_die_ref die2;
+     int *mark;
+{
+  dw_die_ref c1, c2;
+  dw_attr_ref a1, a2;
+
+  /* To avoid infinite recursion.  */
+  if (die1->die_mark)
+    return die1->die_mark == die2->die_mark;
+  die1->die_mark = die2->die_mark = ++(*mark);
+
+  if (die1->die_tag != die2->die_tag)
+    return 0;
+
+  for (a1 = die1->die_attr, a2 = die2->die_attr;
+       a1 && a2;
+       a1 = a1->dw_attr_next, a2 = a2->dw_attr_next)
+    if (!same_attr_p (a1, a2, mark))
+      return 0;
+  if (a1 || a2)
+    return 0;
+
+  for (c1 = die1->die_child, c2 = die2->die_child;
+       c1 && c2;
+       c1 = c1->die_sib, c2 = c2->die_sib)
+    if (!same_die_p (c1, c2, mark))
+      return 0;
+  if (c1 || c2)
+    return 0;
+
+  return 1;
+}
+
+/* Do the dies look the same?  Wrapper around same_die_p.  */
+
+static int
+same_die_p_wrap (die1, die2)
+     dw_die_ref die1;
+     dw_die_ref die2;
+{
+  int mark = 0;
+  int ret = same_die_p (die1, die2, &mark);
+
+  unmark_all_dies (die1);
+  unmark_all_dies (die2);
+
+  return ret;
+}
+
 /* The prefix to attach to symbols on DIEs in the current comdat debug
    info section.  */
 static char *comdat_symbol_id;
@@ -5530,10 +5720,11 @@ static void
 compute_section_prefix (unit_die)
      dw_die_ref unit_die;
 {
-  const char *base = lbasename (get_AT_string (unit_die, DW_AT_name));
+  const char *die_name = get_AT_string (unit_die, DW_AT_name);
+  const char *base = die_name ? lbasename (die_name) : "anonymous";
   char *name = (char *) alloca (strlen (base) + 64);
   char *p;
-  int i;
+  int i, mark;
   unsigned char checksum[16];
   struct md5_ctx ctx;
 
@@ -5541,7 +5732,9 @@ compute_section_prefix (unit_die)
      the name filename of the unit.  */
 
   md5_init_ctx (&ctx);
-  die_checksum (unit_die, &ctx);
+  mark = 0;
+  die_checksum (unit_die, &ctx, &mark);
+  unmark_all_dies (unit_die);
   md5_finish_ctx (&ctx, checksum);
 
   sprintf (name, "%s.", base);
@@ -5583,6 +5776,7 @@ is_type_die (die)
     case DW_TAG_file_type:
     case DW_TAG_packed_type:
     case DW_TAG_volatile_type:
+    case DW_TAG_typedef:
       return 1;
     default:
       return 0;
@@ -5668,6 +5862,104 @@ assign_symbol_names (die)
     assign_symbol_names (c);
 }
 
+struct cu_hash_table_entry
+{
+  dw_die_ref cu;
+  unsigned min_comdat_num, max_comdat_num;
+  struct cu_hash_table_entry *next;
+};
+
+/* Routines to manipulate hash table of CUs.  */
+static hashval_t
+htab_cu_hash (of)
+     const void *of;
+{
+  const struct cu_hash_table_entry *entry = of;
+
+  return htab_hash_string (entry->cu->die_symbol);
+}
+
+static int
+htab_cu_eq (of1, of2)
+     const void *of1;
+     const void *of2;
+{
+  const struct cu_hash_table_entry *entry1 = of1;
+  const struct die_struct *entry2 = of2;
+
+  return !strcmp (entry1->cu->die_symbol, entry2->die_symbol);
+}
+
+static void
+htab_cu_del (what)
+     void *what;
+{
+  struct cu_hash_table_entry *next, *entry = what;
+
+  while (entry)
+    {
+      next = entry->next;
+      free (entry);
+      entry = next;
+    }
+}
+
+/* Check whether we have already seen this CU and set up SYM_NUM
+   accordingly.  */
+static int
+check_duplicate_cu (cu, htable, sym_num)
+     dw_die_ref cu;
+     htab_t htable;
+     unsigned *sym_num;
+{
+  struct cu_hash_table_entry dummy;
+  struct cu_hash_table_entry **slot, *entry, *last = &dummy;
+
+  dummy.max_comdat_num = 0;
+
+  slot = (struct cu_hash_table_entry **)
+    htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol),
+       INSERT);
+  entry = *slot;
+
+  for (; entry; last = entry, entry = entry->next)
+    {
+      if (same_die_p_wrap (cu, entry->cu))
+       break;
+    }
+
+  if (entry)
+    {
+      *sym_num = entry->min_comdat_num;
+      return 1;
+    }
+
+  entry = xcalloc (1, sizeof (struct cu_hash_table_entry));
+  entry->cu = cu;
+  entry->min_comdat_num = *sym_num = last->max_comdat_num;
+  entry->next = *slot;
+  *slot = entry;
+
+  return 0;
+}
+
+/* Record SYM_NUM to record of CU in HTABLE.  */
+static void
+record_comdat_symbol_number (cu, htable, sym_num)
+     dw_die_ref cu;
+     htab_t htable;
+     unsigned sym_num;
+{
+  struct cu_hash_table_entry **slot, *entry;
+
+  slot = (struct cu_hash_table_entry **)
+    htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol),
+       NO_INSERT);
+  entry = *slot;
+
+  entry->max_comdat_num = sym_num;
+}
+
 /* Traverse the DIE (which is always comp_unit_die), and set up
    additional compilation units for each of the include files we see
    bracketed by BINCL/EINCL.  */
@@ -5678,7 +5970,8 @@ break_out_includes (die)
 {
   dw_die_ref *ptr;
   dw_die_ref unit = NULL;
-  limbo_die_node *node;
+  limbo_die_node *node, **pnode;
+  htab_t cu_hash_table;
 
   for (ptr = &(die->die_child); *ptr;)
     {
@@ -5719,11 +6012,27 @@ break_out_includes (die)
 #endif
 
   assign_symbol_names (die);
-  for (node = limbo_die_list; node; node = node->next)
+  cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del);
+  for (node = limbo_die_list, pnode = &limbo_die_list;
+       node;
+       node = node->next)
     {
+      int is_dupl;
+
       compute_section_prefix (node->die);
+      is_dupl = check_duplicate_cu (node->die, cu_hash_table,
+                       &comdat_symbol_number);
       assign_symbol_names (node->die);
+      if (is_dupl)
+       *pnode = node->next;
+      else
+        {
+         pnode = &node->next;
+         record_comdat_symbol_number (node->die, cu_hash_table,
+               comdat_symbol_number);
+       }
     }
+  htab_delete (cu_hash_table);
 }
 
 /* Traverse the DIE and add a sibling attribute if it may have the
@@ -5968,6 +6277,9 @@ mark_dies (die)
 {
   dw_die_ref c;
 
+  if (die->die_mark)
+    abort ();
+  
   die->die_mark = 1;
   for (c = die->die_child; c; c = c->die_sib)
     mark_dies (c);
@@ -5981,11 +6293,35 @@ unmark_dies (die)
 {
   dw_die_ref c;
 
+  if (!die->die_mark)
+    abort ();
+  
   die->die_mark = 0;
   for (c = die->die_child; c; c = c->die_sib)
     unmark_dies (c);
 }
 
+/* Clear the marks for a die, its children and referred dies.  */
+
+static void
+unmark_all_dies (die)
+     dw_die_ref die;
+{
+  dw_die_ref c;
+  dw_attr_ref a;
+
+  if (!die->die_mark)
+    return;
+  die->die_mark = 0;
+
+  for (c = die->die_child; c; c = c->die_sib)
+    unmark_all_dies (c);
+
+  for (a = die->die_attr; a; a = a->dw_attr_next)
+    if (AT_class (a) == dw_val_class_die_ref)
+      unmark_all_dies (AT_ref (a));
+}
+
 /* Return the size of the .debug_pubnames table  generated for the
    compilation unit.  */
 
@@ -6455,10 +6791,16 @@ output_compilation_unit_header ()
 /* Output the compilation unit DIE and its children.  */
 
 static void
-output_comp_unit (die)
+output_comp_unit (die, output_if_empty)
      dw_die_ref die;
+     int output_if_empty;
 {
   const char *secname;
+  char *oldsym, *tmp;
+
+  /* Unless we are outputting main CU, we may throw away empty ones.  */
+  if (!output_if_empty && die->die_child == NULL)
+    return;
 
   /* Even if there are no children of this DIE, we must output the information
      about the compilation unit.  Otherwise, on an empty translation unit, we
@@ -6473,11 +6815,12 @@ output_comp_unit (die)
   next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
   calc_die_sizes (die);
 
-  if (die->die_symbol)
+  oldsym = die->die_symbol;
+  if (oldsym)
     {
-      char *tmp = (char *) alloca (strlen (die->die_symbol) + 24);
+      tmp = (char *) alloca (strlen (oldsym) + 24);
 
-      sprintf (tmp, ".gnu.linkonce.wi.%s", die->die_symbol);
+      sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
       secname = tmp;
       die->die_symbol = NULL;
     }
@@ -6491,8 +6834,11 @@ output_comp_unit (die)
 
   /* Leave the marks on the main CU, so we can check them in
      output_pubnames.  */
-  if (die->die_symbol)
-    unmark_dies (die);
+  if (oldsym)
+    {
+      unmark_dies (die);
+      die->die_symbol = oldsym;
+    }
 }
 
 /* The DWARF2 pubname for a nested thingy looks like "A::f".  The
@@ -11981,13 +12327,17 @@ dwarf2out_start_source_file (lineno, filename)
      unsigned int lineno;
      const char *filename;
 {
-  if (flag_eliminate_dwarf2_dups)
+  if (flag_eliminate_dwarf2_dups && !is_main_source)
     {
       /* Record the beginning of the file for break_out_includes.  */
-      dw_die_ref bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL);
+      dw_die_ref bincl_die;
+
+      bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL);
       add_AT_string (bincl_die, DW_AT_name, filename);
     }
 
+  is_main_source = 0;
+
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
       named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
@@ -12100,6 +12450,7 @@ dwarf2out_init (main_input_filename)
      taken as being relative to the directory from which the compiler was
      invoked when the given (base) source file was compiled.  */
   comp_unit_die = gen_compile_unit_die (main_input_filename);
+  is_main_source = 1;
 
   VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
 
@@ -12317,9 +12668,9 @@ dwarf2out_finish (input_filename)
   /* Output all of the compilation units.  We put the main one last so that
      the offsets are available to output_pubnames.  */
   for (node = limbo_die_list; node; node = node->next)
-    output_comp_unit (node->die);
+    output_comp_unit (node->die, 0);
 
-  output_comp_unit (comp_unit_die);
+  output_comp_unit (comp_unit_die, 0);
 
   /* Output the abbreviation table.  */
   named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG);
index 8e94326..a811c4b 100644 (file)
@@ -2316,6 +2316,17 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
       timevar_pop (TV_SYMOUT);
     }
 #endif
+#ifdef DWARF2_DEBUGGING_INFO
+  else if ((write_symbols == DWARF2_DEBUG
+          || write_symbols == VMS_AND_DWARF2_DEBUG)
+          && top_level
+          && TREE_CODE (decl) == TYPE_DECL)
+    {
+      timevar_push (TV_SYMOUT);
+      dwarf2out_decl (decl);
+      timevar_pop (TV_SYMOUT);
+    }
+#endif
 }
 
 /* Called after finishing a record, union or enumeral type.  */