]> gcc.gnu.org Git - gcc.git/commitdiff
dwarf2out.c (is_cu_die, [...]): New functions.
authorSterling Augustine <saugustine@google.com>
Thu, 21 Jun 2012 18:16:05 +0000 (18:16 +0000)
committerSterling Augustine <sterling@gcc.gnu.org>
Thu, 21 Jun 2012 18:16:05 +0000 (18:16 +0000)
2012-06-21   Sterling Augustine  <saugustine@google.com>
        Cary Coutant  <ccoutant@google.com>

* dwarf2out.c (is_cu_die, is_namespace_die, is_class_die,
add_AT_pubnames, add_enumerator_pubname, want_pubnames): New functions.
(comdat_type_struct): New field 'skeleton_die'.
(breakout_comdat_types): Update it.
(add_pubname): Rework logic.  Call is_class_die, is_cu_die and
is_namespace_die.  Fix minor style violation.  Call want_pubnames.
(add_pubname_string): Call want_pubnames.
(add_pubtype): Rework logic for calculating type name.  Call
is_namespace_die.  Call want_pubnames.
(output_pubnames): Move conditional logic deciding when to produce the
section from dwarf2out_finish.  Use new skeleton_die field.
(base_type_die): Call add_pubtype.
(gen_enumeration_type_die): Unconditionally call add_pubtype.
(gen_subprogram_die): Adjust calls to add_pubname.
(gen_namespace_die): Call add_pubname_string.
(dwarf2out_finish): Call add_AT_pubnames; Move logic on when to
produce pubnames and pubtypes sections to output_pubnames.
(common.opt): New option '-gpubnames'.
(invoke.texi): Document it.

Co-Authored-By: Cary Coutant <ccoutant@google.com>
From-SVN: r188857

gcc/ChangeLog
gcc/common.opt
gcc/doc/invoke.texi
gcc/dwarf2out.c

index 6ab476f5a597fbffb7fa7f9e4628c451dd4d35aa..baedb0f712dc97a4c5ad1c9ae2951a669244ec29 100644 (file)
@@ -1,3 +1,26 @@
+2012-06-21   Sterling Augustine  <saugustine@google.com>
+        Cary Coutant  <ccoutant@google.com>
+
+       * dwarf2out.c (is_cu_die, is_namespace_die, is_class_die,
+       add_AT_pubnames, add_enumerator_pubname, want_pubnames): New functions.
+       (comdat_type_struct): New field 'skeleton_die'.
+       (breakout_comdat_types): Update it.
+       (add_pubname): Rework logic.  Call is_class_die, is_cu_die and
+       is_namespace_die.  Fix minor style violation.  Call want_pubnames.
+       (add_pubname_string): Call want_pubnames.
+       (add_pubtype): Rework logic for calculating type name.  Call
+       is_namespace_die.  Call want_pubnames.
+       (output_pubnames): Move conditional logic deciding when to produce the
+       section from dwarf2out_finish.  Use new skeleton_die field.
+       (base_type_die): Call add_pubtype.
+       (gen_enumeration_type_die): Unconditionally call add_pubtype.
+       (gen_subprogram_die): Adjust calls to add_pubname.
+       (gen_namespace_die): Call add_pubname_string.
+       (dwarf2out_finish): Call add_AT_pubnames; Move logic on when to
+       produce pubnames and pubtypes sections to output_pubnames.
+       (common.opt): New option '-gpubnames'.
+       (invoke.texi): Document it.
+
 2012-06-21  Steven Bosscher  <steven@gcc.gnu.org>
 
        * config/m32c/m32c-pragma.c: Remove unnecessary includes.
index 2a14f18909739b5f2a4e9eb240e1623abbc35230..ad6db6105701ea9b0069ddb1d032969e49357d77 100644 (file)
@@ -2243,6 +2243,14 @@ ggdb
 Common JoinedOrMissing
 Generate debug information in default extended format
 
+gno-pubnames
+Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1)
+Don't generate DWARF pubnames and pubtypes sections.
+
+gpubnames
+Common RejectNegative Var(debug_generate_pub_sections, 1)
+Generate DWARF pubnames and pubtypes sections.
+
 gno-record-gcc-switches
 Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(1)
 Don't record gcc command line switches in DWARF DW_AT_producer.
index b74f9abd7d9ab57f38cf764f5fe4f47ebfbff02d..387d6922f89f06bcca5a1104932a638b5901fc80 100644 (file)
@@ -4795,6 +4795,10 @@ most expressive format available (DWARF 2, stabs, or the native format
 if neither of those are supported), including GDB extensions if at all
 possible.
 
+@item -gpubnames
+@opindex gpubnames
+Generate dwarf .debug_pubnames and .debug_pubtypes sections.
+
 @item -gstabs
 @opindex gstabs
 Produce debugging information in stabs format (if that is supported),
index 56730e31d28780a291d37f5b88e3e07c79761ad6..2b9971f1857a75634ada75001c447cb7065ff1ed 100644 (file)
@@ -2538,6 +2538,7 @@ typedef struct GTY(()) comdat_type_struct
 {
   dw_die_ref root_die;
   dw_die_ref type_die;
+  dw_die_ref skeleton_die;
   char signature[DWARF_TYPE_SIGNATURE_SIZE];
   struct comdat_type_struct *next;
 }
@@ -3012,6 +3013,7 @@ static void output_comp_unit (dw_die_ref, int);
 static void output_comdat_type_unit (comdat_type_node *);
 static const char *dwarf2_name (tree, int);
 static void add_pubname (tree, dw_die_ref);
+static void add_enumerator_pubname (const char *, dw_die_ref);
 static void add_pubname_string (const char *, dw_die_ref);
 static void add_pubtype (tree, dw_die_ref);
 static void output_pubnames (VEC (pubname_entry,gc) *);
@@ -3141,6 +3143,7 @@ static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
                                     const char *, const char *);
 static void output_loc_list (dw_loc_list_ref);
 static char *gen_internal_sym (const char *);
+static bool want_pubnames (void);
 
 static void prune_unmark_dies (dw_die_ref);
 static void prune_unused_types_mark_generic_parms_dies (dw_die_ref);
@@ -5981,6 +5984,23 @@ is_unit_die (dw_die_ref c)
               || c->die_tag == DW_TAG_type_unit);
 }
 
+/* Returns true iff C is a namespace DIE.  */
+
+static inline bool
+is_namespace_die (dw_die_ref c)
+{
+  return c && c->die_tag == DW_TAG_namespace;
+}
+
+/* Returns true iff C is a class or structure DIE.  */
+
+static inline bool
+is_class_die (dw_die_ref c)
+{
+  return c && (c->die_tag == DW_TAG_class_type
+               || c->die_tag == DW_TAG_structure_type);
+}
+
 static char *
 gen_internal_sym (const char *prefix)
 {
@@ -6567,6 +6587,7 @@ break_out_comdat_types (dw_die_ref die)
            declaration into the new type unit DIE, then remove this DIE
           from the main CU (or replace it with a skeleton if necessary).  */
        replacement = remove_child_or_replace_with_skeleton (unit, c, prev);
+       type_node->skeleton_die = replacement;
 
         /* Break out nested types into their own type units.  */
         break_out_comdat_types (c);
@@ -8040,6 +8061,27 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
     }
 }
 
+/* Whether to generate the DWARF accelerator tables in .debug_pubnames
+   and .debug_pubtypes.  This is configured per-target, but can be
+   overridden by the -gpubnames or -gno-pubnames options.  */
+
+static inline bool
+want_pubnames (void)
+{
+  return (debug_generate_pub_sections != -1
+         ? debug_generate_pub_sections
+         : targetm.want_debug_pub_sections);
+}
+
+/* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes.  */
+
+static void
+add_AT_pubnames (dw_die_ref die)
+{
+  if (want_pubnames ())
+    add_AT_flag (die, DW_AT_GNU_pubnames, 1);
+}
+
 /* Output a comdat type unit DIE and its children.  */
 
 static void
@@ -8110,7 +8152,7 @@ dwarf2_name (tree decl, int scope)
 static void
 add_pubname_string (const char *str, dw_die_ref die)
 {
-  if (targetm.want_debug_pub_sections)
+  if (want_pubnames ())
     {
       pubname_entry e;
 
@@ -8123,14 +8165,32 @@ add_pubname_string (const char *str, dw_die_ref die)
 static void
 add_pubname (tree decl, dw_die_ref die)
 {
-  if (targetm.want_debug_pub_sections && TREE_PUBLIC (decl))
+  if (!want_pubnames ())
+    return;
+
+  if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent))
+      || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent))
     {
       const char *name = dwarf2_name (decl, 1);
+
       if (name)
        add_pubname_string (name, die);
     }
 }
 
+/* Add an enumerator to the pubnames section.  */
+
+static void
+add_enumerator_pubname (const char *scope_name, dw_die_ref die)
+{
+  pubname_entry e;
+
+  gcc_assert (scope_name);
+  e.name = concat (scope_name, get_AT_string (die, DW_AT_name), NULL);
+  e.die = die;
+  VEC_safe_push (pubname_entry, gc, pubname_table, &e);
+}
+
 /* Add a new entry to .debug_pubtypes if appropriate.  */
 
 static void
@@ -8138,40 +8198,55 @@ add_pubtype (tree decl, dw_die_ref die)
 {
   pubname_entry e;
 
-  if (!targetm.want_debug_pub_sections)
+  if (!want_pubnames ())
     return;
 
-  e.name = NULL;
   if ((TREE_PUBLIC (decl)
-       || is_cu_die (die->die_parent))
+       || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent))
       && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl)))
     {
-      e.die = die;
-      if (TYPE_P (decl))
-       {
-         if (TYPE_NAME (decl))
+      tree scope = NULL;
+      const char *scope_name = "";
+      const char *sep = is_cxx () ? "::" : ".";
+      const char *name;
+
+      scope = TYPE_P (decl) ? TYPE_CONTEXT (decl) : NULL;
+      if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
            {
-             if (TREE_CODE (TYPE_NAME (decl)) == IDENTIFIER_NODE)
-               e.name = IDENTIFIER_POINTER (TYPE_NAME (decl));
-             else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL
-                      && DECL_NAME (TYPE_NAME (decl)))
-               e.name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (decl)));
+          scope_name = lang_hooks.dwarf_name (scope, 1);
+          if (scope_name != NULL && scope_name[0] != '\0')
+            scope_name = concat (scope_name, sep, NULL);
              else
-              e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name));
-           }
+            scope_name = "";
        }
+
+      if (TYPE_P (decl))
+        name = type_tag (decl);
       else
-       {
-         e.name = dwarf2_name (decl, 1);
-         if (e.name)
-           e.name = xstrdup (e.name);
-       }
+        name = lang_hooks.dwarf_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')
+      if (name != NULL && name[0] != '\0')
+        {
+          e.die = die;
+          e.name = concat (scope_name, name, NULL);
        VEC_safe_push (pubname_entry, gc, pubtype_table, &e);
     }
+
+      /* Although it might be more consistent to add the pubinfo for the
+         enumerators as their dies are created, they should only be added if the
+         enum type meets the criteria above.  So rather than re-check the parent
+         enum type whenever an enumerator die is created, just output them all
+         here.  This isn't protected by the name conditional because anonymous
+         enums don't have names.  */
+      if (die->die_tag == DW_TAG_enumeration_type)
+        {
+          dw_die_ref c;
+
+          FOR_EACH_CHILD (die, c, add_enumerator_pubname (scope_name, c));
+        }
+    }
 }
 
 /* Output the public names table used to speed up access to externally
@@ -8184,6 +8259,12 @@ output_pubnames (VEC (pubname_entry, gc) * names)
   unsigned long pubnames_length = size_of_pubnames (names);
   pubname_ref pub;
 
+  if (!want_pubnames () || !info_section_emitted)
+    return;
+  if (names == pubname_table)
+    switch_to_section (debug_pubnames_section);
+  else
+    switch_to_section (debug_pubtypes_section);
   if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
     dw2_asm_output_data (4, 0xffffffff,
       "Initial length escape value indicating 64-bit DWARF extension");
@@ -8211,8 +8292,23 @@ output_pubnames (VEC (pubname_entry, gc) * names)
          || pub->die->die_offset != 0
          || !flag_eliminate_unused_debug_types)
        {
-         dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset,
-                              "DIE offset");
+         dw_offset die_offset = pub->die->die_offset;
+
+         /* If we're putting types in their own .debug_types sections,
+            the .debug_pubtypes table will still point to the compile
+            unit (not the type unit), so we want to use the offset of
+            the skeleton DIE (if there is one).  */
+         if (pub->die->comdat_type_p && names == pubtype_table)
+           {
+             comdat_type_node_ref type_node = pub->die->die_id.die_type_node;
+
+             if (type_node != NULL)
+               die_offset = (type_node->skeleton_die != NULL
+                             ? type_node->skeleton_die->die_offset
+                             : 0);
+           }
+
+         dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
 
          dw2_asm_output_nstring (pub->name, -1, "external name");
        }
@@ -9097,6 +9193,7 @@ base_type_die (tree type)
   add_AT_unsigned (base_type_result, DW_AT_byte_size,
                   int_size_in_bytes (type));
   add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
+  add_pubtype (type, base_type_result);
 
   return base_type_result;
 }
@@ -16179,7 +16276,6 @@ 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;
@@ -16843,6 +16939,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
        {
          subr_die = new_die (DW_TAG_subprogram, context_die, decl);
          add_AT_specification (subr_die, old_die);
+          add_pubname (decl, subr_die);
          if (get_AT_file (old_die, DW_AT_decl_file) != file_index)
            add_AT_file (subr_die, DW_AT_decl_file, file_index);
          if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line)
@@ -16857,6 +16954,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
        add_AT_flag (subr_die, DW_AT_external, 1);
 
       add_name_and_src_coords_attributes (subr_die, decl);
+      add_pubname (decl, subr_die);
       if (debug_info_level > DINFO_LEVEL_TERSE)
        {
          add_prototyped_attribute (subr_die, TREE_TYPE (decl));
@@ -16968,7 +17066,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
       }
 #endif
 
-         add_pubname (decl, subr_die);
        }
       else
        {
@@ -16989,7 +17086,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
                  add_ranges_by_labels (subr_die, fde->dw_fde_second_begin,
                                        fde->dw_fde_second_end,
                                        &range_list_added);
-                 add_pubname (decl, subr_die);
                  if (range_list_added)
                    add_ranges (NULL);
                }
@@ -17011,8 +17107,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
                                 fde->dw_fde_begin);
                  add_AT_lbl_id (subr_die, DW_AT_high_pc,
                                 fde->dw_fde_end);
-                 /* Add it.   */
-                 add_pubname (decl, subr_die);
 
                  /* Build a minimal DIE for the secondary section.  */
                  seg_die = new_die (DW_TAG_subprogram,
@@ -17048,7 +17142,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
            {
              add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin);
              add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end);
-             add_pubname (decl, subr_die);
            }
        }
 
@@ -19089,6 +19182,8 @@ gen_namespace_die (tree decl, dw_die_ref context_die)
       add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
       equate_decl_number_to_die (decl, namespace_die);
     }
+  /* Bypass dwarf2_name's check for DECL_NAMELESS.  */
+  add_pubname_string (lang_hooks.dwarf_name (decl, 1), namespace_die);
 }
 
 /* Generate Dwarf debug information for a decl described by DECL.
@@ -22364,6 +22459,8 @@ dwarf2out_finish (const char *filename)
     }
   htab_delete (comdat_type_table);
 
+  add_AT_pubnames (comp_unit_die ());
+
   /* Output the main compilation unit if non-empty or if .debug_macinfo
      or .debug_macro will be emitted.  */
   output_comp_unit (comp_unit_die (), have_macinfo);
@@ -22387,42 +22484,12 @@ dwarf2out_finish (const char *filename)
       output_location_lists (comp_unit_die ());
     }
 
-  /* Output public names table if necessary.  */
-  if (!VEC_empty (pubname_entry, pubname_table))
-    {
-      gcc_assert (info_section_emitted);
-      switch_to_section (debug_pubnames_section);
-      output_pubnames (pubname_table);
-    }
-
-  /* Output public types table if necessary.  */
+  /* Output public names and types tables if necessary.  */
+  output_pubnames (pubname_table);
   /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
      It shouldn't hurt to emit it always, since pure DWARF2 consumers
      simply won't look for the section.  */
-  if (!VEC_empty (pubname_entry, pubtype_table))
-    {
-      bool empty = false;
-      
-      if (flag_eliminate_unused_debug_types)
-       {
-         /* The pubtypes table might be emptied by pruning unused items.  */
-         unsigned i;
-         pubname_ref p;
-         empty = true;
-         FOR_EACH_VEC_ELT (pubname_entry, pubtype_table, i, p)
-           if (p->die->die_offset != 0)
-             {
-               empty = false;
-               break;
-             }
-       }
-      if (!empty)
-       {
-         gcc_assert (info_section_emitted);
-         switch_to_section (debug_pubtypes_section);
-         output_pubnames (pubtype_table);
-       }
-    }
+  output_pubnames (pubtype_table);
 
   /* Output the address range information if a CU (.debug_info section)
      was emitted.  We output an empty table even if we had no functions
This page took 0.170646 seconds and 5 git commands to generate.