OSDN Git Service

Add missing function name
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 7b5930e..fee5c60 100644 (file)
@@ -1,6 +1,6 @@
 /* Output Dwarf2 format symbol table information from GCC.
    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Gary Funck (gary@intrepid.com).
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
@@ -3302,11 +3302,12 @@ static int should_move_die_to_comdat (dw_die_ref);
 static dw_die_ref clone_as_declaration (dw_die_ref);
 static dw_die_ref clone_die (dw_die_ref);
 static dw_die_ref clone_tree (dw_die_ref);
-static void copy_declaration_context (dw_die_ref, dw_die_ref);
+static dw_die_ref copy_declaration_context (dw_die_ref, dw_die_ref);
 static void generate_skeleton_ancestor_tree (skeleton_chain_node *);
 static void generate_skeleton_bottom_up (skeleton_chain_node *);
 static dw_die_ref generate_skeleton (dw_die_ref);
 static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref,
+                                                         dw_die_ref,
                                                          dw_die_ref);
 static void break_out_comdat_types (dw_die_ref);
 static dw_die_ref copy_ancestor_tree (dw_die_ref, dw_die_ref, htab_t);
@@ -7070,16 +7071,18 @@ clone_as_declaration (dw_die_ref die)
   return clone;
 }
 
-/* Copy the declaration context to the new compile unit DIE.  This includes
+/* Copy the declaration context to the new type unit DIE.  This includes
    any surrounding namespace or type declarations.  If the DIE has an
    AT_specification attribute, it also includes attributes and children
-   attached to the specification.  */
+   attached to the specification, and returns a pointer to the original
+   parent of the declaration DIE.  Returns NULL otherwise.  */
 
-static void
+static dw_die_ref
 copy_declaration_context (dw_die_ref unit, dw_die_ref die)
 {
   dw_die_ref decl;
   dw_die_ref new_decl;
+  dw_die_ref orig_parent = NULL;
 
   decl = get_AT_ref (die, DW_AT_specification);
   if (decl == NULL)
@@ -7090,6 +7093,10 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die)
       dw_die_ref c;
       dw_attr_ref a;
 
+      /* The original DIE will be changed to a declaration, and must
+         be moved to be a child of the original declaration DIE.  */
+      orig_parent = decl->die_parent;
+
       /* Copy the type node pointer from the new DIE to the original
          declaration DIE so we can forward references later.  */
       decl->die_id.die_type_node = die->die_id.die_type_node;
@@ -7118,6 +7125,8 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die)
           add_AT_specification (die, new_decl);
         }
     }
+
+  return orig_parent;
 }
 
 /* Generate the skeleton ancestor tree for the given NODE, then clone
@@ -7201,17 +7210,23 @@ generate_skeleton (dw_die_ref die)
   return node.new_die;
 }
 
-/* Remove the DIE from its parent, possibly replacing it with a cloned
-   declaration.  The original DIE will be moved to a new compile unit
-   so that existing references to it follow it to the new location.  If
-   any of the original DIE's descendants is a declaration, we need to
-   replace the original DIE with a skeleton tree and move the
-   declarations back into the skeleton tree.  */
+/* Remove the CHILD DIE from its parent, possibly replacing it with a cloned
+   declaration.  The original DIE is moved to a new compile unit so that
+   existing references to it follow it to the new location.  If any of the
+   original DIE's descendants is a declaration, we need to replace the
+   original DIE with a skeleton tree and move the declarations back into the
+   skeleton tree.  */
 
 static dw_die_ref
-remove_child_or_replace_with_skeleton (dw_die_ref child, dw_die_ref prev)
+remove_child_or_replace_with_skeleton (dw_die_ref unit, dw_die_ref child,
+                                      dw_die_ref prev)
 {
-  dw_die_ref skeleton;
+  dw_die_ref skeleton, orig_parent;
+
+  /* Copy the declaration context to the type unit DIE.  If the returned
+     ORIG_PARENT is not NULL, the skeleton needs to be added as a child of
+     that DIE.  */
+  orig_parent = copy_declaration_context (unit, child);
 
   skeleton = generate_skeleton (child);
   if (skeleton == NULL)
@@ -7219,7 +7234,19 @@ remove_child_or_replace_with_skeleton (dw_die_ref child, dw_die_ref prev)
   else
     {
       skeleton->die_id.die_type_node = child->die_id.die_type_node;
-      replace_child (child, skeleton, prev);
+
+      /* If the original DIE was a specification, we need to put
+         the skeleton under the parent DIE of the declaration.
+        This leaves the original declaration in the tree, but
+        it will be pruned later since there are no longer any
+        references to it.  */
+      if (orig_parent != NULL)
+       {
+         remove_child_with_prev (child, prev);
+         add_child_die (orig_parent, skeleton);
+       }
+      else
+       replace_child (child, skeleton, prev);
     }
 
   return skeleton;
@@ -7264,11 +7291,9 @@ break_out_comdat_types (dw_die_ref die)
         generate_type_signature (c, type_node);
 
         /* Copy the declaration context, attributes, and children of the
-           declaration into the new compile unit DIE.  */
-       copy_declaration_context (unit, c);
-
-        /* Remove this DIE from the main CU.  */
-       replacement = remove_child_or_replace_with_skeleton (c, prev);
+           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);
 
         /* Break out nested types into their own type units.  */
         break_out_comdat_types (c);
@@ -8166,6 +8191,13 @@ output_loc_list (dw_loc_list_ref list_head)
       /* Don't output an entry that starts and ends at the same address.  */
       if (strcmp (curr->begin, curr->end) == 0 && !curr->force)
        continue;
+      size = size_of_locs (curr->expr);
+      /* If the expression is too large, drop it on the floor.  We could
+        perhaps put it into DW_TAG_dwarf_procedure and refer to that
+        in the expression, but >= 64KB expressions for a single value
+        in a single range are unlikely very useful.  */
+      if (size > 0xffff)
+       continue;
       if (!have_multiple_function_sections)
        {
          dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
@@ -8184,7 +8216,6 @@ output_loc_list (dw_loc_list_ref list_head)
                               "Location list end address (%s)",
                               list_head->ll_symbol);
        }
-      size = size_of_locs (curr->expr);
 
       /* Output the block length for this list of location operations.  */
       gcc_assert (size <= 0xffff);
@@ -9873,7 +9904,14 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
     }
   /* This probably indicates a bug.  */
   else if (mod_type_die && mod_type_die->die_tag == DW_TAG_base_type)
-    add_name_attribute (mod_type_die, "__unknown__");
+    {
+      name = TYPE_NAME (type);
+      if (name
+         && TREE_CODE (name) == TYPE_DECL)
+       name = DECL_NAME (name);
+      add_name_attribute (mod_type_die,
+                         name ? IDENTIFIER_POINTER (name) : "__unknown__");
+    }
 
   if (qualified_type)
     equate_type_number_to_die (qualified_type, mod_type_die);
@@ -10645,6 +10683,13 @@ const_ok_for_output_1 (rtx *rtlp, void *data ATTRIBUTE_UNUSED)
       return 1;
     }
 
+  if (targetm.const_not_ok_for_debug_p (rtl))
+    {
+      expansion_failed (NULL_TREE, rtl,
+                       "Expression rejected for debug by the backend.\n");
+      return 1;
+    }
+
   if (GET_CODE (rtl) != SYMBOL_REF)
     return 0;
 
@@ -18426,6 +18471,11 @@ gen_compile_unit_die (const char *filename)
        language = DW_LANG_ObjC;
       else if (strcmp (language_string, "GNU Objective-C++") == 0)
        language = DW_LANG_ObjC_plus_plus;
+      else if (dwarf_version >= 5 || !dwarf_strict)
+       {
+         if (strcmp (language_string, "GNU Go") == 0)
+           language = DW_LANG_Go;
+       }
     }
 
   add_AT_unsigned (die, DW_AT_language, language);
@@ -18842,8 +18892,9 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
 
       /* Use the DIE of the containing namespace as the parent DIE of
          the type description DIE we want to generate.  */
-      if (DECL_CONTEXT (TYPE_NAME (type))
-         && TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL)
+      if (DECL_FILE_SCOPE_P (TYPE_NAME (type))
+         || (DECL_CONTEXT (TYPE_NAME (type))
+             && TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL))
        context_die = get_context_die (DECL_CONTEXT (TYPE_NAME (type)));
 
       TREE_ASM_WRITTEN (type) = 1;
@@ -20472,12 +20523,27 @@ dwarf2out_source_line (unsigned int line, const char *filename,
   if (DWARF2_ASM_LINE_DEBUG_INFO)
     {
       /* Emit the .loc directive understood by GNU as.  */
-      fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
+      /* "\t.loc %u %u 0 is_stmt %u discriminator %u",
+        file_num, line, is_stmt, discriminator */
+      fputs ("\t.loc ", asm_out_file);
+      fprint_ul (asm_out_file, file_num);
+      putc (' ', asm_out_file);
+      fprint_ul (asm_out_file, line);
+      putc (' ', asm_out_file);
+      putc ('0', asm_out_file);
+
       if (is_stmt != table->is_stmt)
-       fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0);
+       {
+         fputs (" is_stmt ", asm_out_file);
+         putc (is_stmt ? '1' : '0', asm_out_file);
+       }
       if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
-       fprintf (asm_out_file, " discriminator %d", discriminator);
-      fputc ('\n', asm_out_file);
+       {
+         gcc_assert (discriminator > 0);
+         fputs (" discriminator ", asm_out_file);
+         fprint_ul (asm_out_file, (unsigned long) discriminator);
+       }
+      putc ('\n', asm_out_file);
     }
   else
     {
@@ -20521,7 +20587,7 @@ dwarf2out_start_source_file (unsigned int lineno, const char *filename)
       macinfo_entry e;
       e.code = DW_MACINFO_start_file;
       e.lineno = lineno;
-      e.info = xstrdup (filename);
+      e.info = ggc_strdup (filename);
       VEC_safe_push (macinfo_entry, gc, macinfo_table, &e);
     }
 }
@@ -20567,7 +20633,7 @@ dwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED,
        }
       e.code = DW_MACINFO_define;
       e.lineno = lineno;
-      e.info = xstrdup (buffer);;
+      e.info = ggc_strdup (buffer);
       VEC_safe_push (macinfo_entry, gc, macinfo_table, &e);
     }
 }
@@ -20594,7 +20660,7 @@ dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
        }
       e.code = DW_MACINFO_undef;
       e.lineno = lineno;
-      e.info = xstrdup (buffer);
+      e.info = ggc_strdup (buffer);
       VEC_safe_push (macinfo_entry, gc, macinfo_table, &e);
     }
 }
@@ -20634,8 +20700,6 @@ output_macinfo_op (macinfo_entry *ref)
     {
     case DW_MACINFO_start_file:
       fd = lookup_filename (ref->info);
-      if (fd->filename == ref->info)
-       fd->filename = ggc_strdup (fd->filename);
       file_num = maybe_emit_file (fd);
       dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
       dw2_asm_output_data_uleb128 (ref->lineno,
@@ -20774,8 +20838,8 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files,
   linebuf_len = strlen (linebuf);
 
   /* The group name format is: wmN.[<encoded filename>.]<lineno>.<md5sum>  */
-  grp_name = XNEWVEC (char, 4 + encoded_filename_len + linebuf_len + 1
-                     + 16 * 2 + 1);
+  grp_name = XALLOCAVEC (char, 4 + encoded_filename_len + linebuf_len + 1
+                        + 16 * 2 + 1);
   memcpy (grp_name, DWARF_OFFSET_SIZE == 4 ? "wm4." : "wm8.", 4);
   tail = grp_name + 4;
   if (encoded_filename_len)
@@ -20796,14 +20860,13 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files,
   inc = VEC_index (macinfo_entry, macinfo_table, idx - 1);
   inc->code = DW_MACRO_GNU_transparent_include;
   inc->lineno = 0;
-  inc->info = grp_name;
+  inc->info = ggc_strdup (grp_name);
   if (*macinfo_htab == NULL)
     *macinfo_htab = htab_create (10, htab_macinfo_hash, htab_macinfo_eq, NULL);
   /* Avoid emitting duplicates.  */
   slot = htab_find_slot (*macinfo_htab, inc, INSERT);
   if (*slot != NULL)
     {
-      free (CONST_CAST (char *, inc->info));
       inc->code = 0;
       inc->info = NULL;
       /* If such an entry has been used before, just emit
@@ -20818,7 +20881,6 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files,
           i++)
        {
          cur->code = 0;
-         free (CONST_CAST (char *, cur->info));
          cur->info = NULL;
        }
     }
@@ -20879,11 +20941,7 @@ output_macinfo (void)
          break;
        case DW_MACINFO_end_file:
          if (!VEC_empty (macinfo_entry, files))
-           {
-             macinfo_entry *file = VEC_last (macinfo_entry, files);
-             free (CONST_CAST (char *, file->info));
-             VEC_pop (macinfo_entry, files);
-           }
+           VEC_pop (macinfo_entry, files);
          break;
        case DW_MACINFO_define:
        case DW_MACINFO_undef:
@@ -20911,10 +20969,6 @@ output_macinfo (void)
          break;
        }
       output_macinfo_op (ref);
-      /* For DW_MACINFO_start_file ref->info has been copied into files
-        vector.  */
-      if (ref->code != DW_MACINFO_start_file)
-       free (CONST_CAST (char *, ref->info));
       ref->info = NULL;
       ref->code = 0;
     }
@@ -20948,7 +21002,6 @@ output_macinfo (void)
                                       ref->lineno);
          ASM_OUTPUT_LABEL (asm_out_file, label);
          ref->code = 0;
-         free (CONST_CAST (char *, ref->info));
          ref->info = NULL;
          dw2_asm_output_data (2, 4, "DWARF macro version number");
          if (DWARF_OFFSET_SIZE == 8)
@@ -20961,7 +21014,6 @@ output_macinfo (void)
       case DW_MACINFO_undef:
        output_macinfo_op (ref);
        ref->code = 0;
-       free (CONST_CAST (char *, ref->info));
        ref->info = NULL;
        break;
       default:
@@ -22473,15 +22525,8 @@ dwarf2out_finish (const char *filename)
              else if (TYPE_P (node->created_for))
                context = TYPE_CONTEXT (node->created_for);
 
-             gcc_assert (context
-                         && (TREE_CODE (context) == FUNCTION_DECL
-                             || TREE_CODE (context) == NAMESPACE_DECL));
-
-             origin = lookup_decl_die (context);
-             if (origin)
-               add_child_die (origin, die);
-             else
-               add_child_die (comp_unit_die (), die);
+             origin = get_context_die (context);
+             add_child_die (origin, die);
            }
        }
     }