OSDN Git Service

PR debug/43762
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 66ac5eb..5a9a3b8 100644 (file)
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "dwarf2asm.h"
 #include "toplev.h"
+#include "varray.h"
 #include "ggc.h"
 #include "md5.h"
 #include "tm_p.h"
@@ -1039,7 +1040,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
 
   cfi = new_cfi ();
 
-  if (loc.reg == old_cfa.reg && !loc.indirect && !old_cfa.indirect)
+  if (loc.reg == old_cfa.reg && !loc.indirect)
     {
       /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, indicating
         the CFA register did not change but the offset did.  The data
@@ -1055,8 +1056,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
 #ifndef MIPS_DEBUGGING_INFO  /* SGI dbx thinks this means no offset.  */
   else if (loc.offset == old_cfa.offset
           && old_cfa.reg != INVALID_REGNUM
-          && !loc.indirect
-          && !old_cfa.indirect)
+          && !loc.indirect)
     {
       /* Construct a "DW_CFA_def_cfa_register <register>" instruction,
         indicating the CFA register has changed to <register> but the
@@ -3771,11 +3771,6 @@ output_call_frame_info (int for_eh)
     }
 
   dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation");
-  if (dw_cie_version >= 4)
-    {
-      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "CIE Address Size");
-      dw2_asm_output_data (1, 0, "CIE Segment Size");
-    }
   dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor");
   dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT,
                               "CIE Data Alignment Factor");
@@ -5715,7 +5710,8 @@ static GTY(()) comdat_type_node *comdat_type_list;
 static GTY(()) limbo_die_node *limbo_die_list;
 
 /* A list of DIEs for which we may have to generate
-   DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set.  */
+   DW_AT_MIPS_linkage_name once their DECL_ASSEMBLER_NAMEs are
+   set.  */
 static GTY(()) limbo_die_node *deferred_asm_name;
 
 /* Filenames referenced by this compilation unit.  */
@@ -5748,12 +5744,8 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node {
 struct GTY (()) var_loc_list_def {
   struct var_loc_node * GTY (()) first;
 
-  /* Pointer to the last but one or last element of the
-     chained list.  If the list is empty, both first and
-     last are NULL, if the list contains just one node
-     or the last node certainly is not redundant, it points
-     to the last node, otherwise points to the last but one.
-     Do not mark it for GC because it is marked through the chain.  */
+  /* Do not mark the last element of the chained list because
+     it is marked through the chain.  */
   struct var_loc_node * GTY ((skip ("%h"))) last;
 
   /* DECL_UID of the variable decl.  */
@@ -5995,7 +5987,7 @@ static hashval_t decl_loc_table_hash (const void *);
 static int decl_loc_table_eq (const void *, const void *);
 static var_loc_list *lookup_decl_loc (const_tree);
 static void equate_decl_number_to_die (tree, dw_die_ref);
-static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *);
+static struct var_loc_node *add_var_loc_to_decl (tree, rtx);
 static void print_spaces (FILE *);
 static void print_die (dw_die_ref, FILE *);
 static void print_dwarf_line_table (FILE *);
@@ -6116,7 +6108,6 @@ static void add_AT_location_description   (dw_die_ref, enum dwarf_attribute,
 static void add_data_member_location_attribute (dw_die_ref, tree);
 static bool add_const_value_attribute (dw_die_ref, rtx);
 static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
-static void insert_double (double_int, unsigned char *);
 static void insert_float (const_rtx, unsigned char *);
 static rtx rtl_for_decl_location (tree);
 static bool add_location_or_const_value_attribute (dw_die_ref, tree,
@@ -6282,12 +6273,6 @@ static void gen_remaining_tmpl_value_param_die_attribute (void);
 #define DEBUG_MACINFO_SECTION_LABEL     "Ldebug_macinfo"
 #endif
 
-/* Mangled name attribute to use.  This used to be a vendor extension
-   until DWARF 4 standardized it.  */
-#define AT_linkage_name \
-  (dwarf_version >= 4 ? DW_AT_linkage_name : DW_AT_MIPS_linkage_name)
-
-
 /* Definitions of defaults for formats and names of various special
    (artificial) labels which may be generated within this file (when the -g
    options is used and DWARF2_DEBUGGING_INFO is in effect.
@@ -7760,7 +7745,7 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
 /* Add a variable location node to the linked list for DECL.  */
 
 static struct var_loc_node *
-add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
+add_var_loc_to_decl (tree decl, rtx loc_note)
 {
   unsigned int decl_id = DECL_UID (decl);
   var_loc_list *temp;
@@ -7779,62 +7764,23 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
 
   if (temp->last)
     {
-      struct var_loc_node *last = temp->last, *unused = NULL;
-      if (last->next)
-       {
-         last = last->next;
-         gcc_assert (last->next == NULL);
-       }
-      /* TEMP->LAST here is either pointer to the last but one or
-        last element in the chained list, LAST is pointer to the
-        last element.  */
-      /* If the last note doesn't cover any instructions, remove it.  */
-      if (label && strcmp (last->label, label) == 0)
-       {
-         if (temp->last != last)
-           {
-             temp->last->next = NULL;
-             unused = last;
-             last = temp->last;
-             gcc_assert (strcmp (last->label, label) != 0);
-           }
-         else
-           {
-             gcc_assert (temp->first == temp->last);
-             memset (temp->last, '\0', sizeof (*temp->last));
-             return temp->last;
-           }
-       }
       /* If the current location is the same as the end of the list,
         and either both or neither of the locations is uninitialized,
         we have nothing to do.  */
-      if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note),
+      if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
                         NOTE_VAR_LOCATION_LOC (loc_note)))
-         || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
+         || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
               != NOTE_VAR_LOCATION_STATUS (loc_note))
-             && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
+             && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
                   == VAR_INIT_STATUS_UNINITIALIZED)
                  || (NOTE_VAR_LOCATION_STATUS (loc_note)
                      == VAR_INIT_STATUS_UNINITIALIZED))))
        {
-         /* Add LOC to the end of list and update LAST.  If the last
-            element of the list has been removed above, reuse its
-            memory for the new node, otherwise allocate a new one.  */
-         if (unused)
-           {
-             loc = unused;
-             memset (loc, '\0', sizeof (*loc));
-           }
-         else
-           loc = GGC_CNEW (struct var_loc_node);
-         last->next = loc;
-         /* Ensure TEMP->LAST will point either to the new last but one
-            element of the chain, or to the last element in it.  */
-         if (last != temp->last)
-           temp->last = last;
+         /* Add LOC to the end of list and update LAST.  */
+         loc = GGC_CNEW (struct var_loc_node);
+         temp->last->next = loc;
+         temp->last = loc;
        }
-      else if (unused)
-       ggc_free (unused);
     }
   else
     {
@@ -8299,7 +8245,6 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at,
       if ((at->dw_attr == DW_AT_type
           && (tag == DW_TAG_pointer_type
               || tag == DW_TAG_reference_type
-              || tag == DW_TAG_rvalue_reference_type
               || tag == DW_TAG_ptr_to_member_type))
          || (at->dw_attr == DW_AT_friend
              && tag == DW_TAG_friend))
@@ -9014,7 +8959,6 @@ is_type_die (dw_die_ref die)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
     case DW_TAG_string_type:
     case DW_TAG_structure_type:
     case DW_TAG_subroutine_type:
@@ -9052,7 +8996,6 @@ is_comdat_die (dw_die_ref c)
 
   if (c->die_tag == DW_TAG_pointer_type
       || c->die_tag == DW_TAG_reference_type
-      || c->die_tag == DW_TAG_rvalue_reference_type
       || c->die_tag == DW_TAG_const_type
       || c->die_tag == DW_TAG_volatile_type)
     {
@@ -9301,7 +9244,6 @@ should_move_die_to_comdat (dw_die_ref die)
     case DW_TAG_interface_type:
     case DW_TAG_pointer_type:
     case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
     case DW_TAG_string_type:
     case DW_TAG_subroutine_type:
     case DW_TAG_ptr_to_member_type:
@@ -9385,7 +9327,6 @@ clone_as_declaration (dw_die_ref die)
         case DW_AT_name:
         case DW_AT_type:
         case DW_AT_virtuality:
-        case DW_AT_linkage_name:
         case DW_AT_MIPS_linkage_name:
           add_dwarf_attr (clone, a);
           break;
@@ -12108,7 +12049,6 @@ is_base_type (tree type)
     case ENUMERAL_TYPE:
     case FUNCTION_TYPE:
     case METHOD_TYPE:
-    case NULLPTR_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case OFFSET_TYPE:
@@ -12252,11 +12192,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
     }
   else if (code == REFERENCE_TYPE)
     {
-      if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
-       mod_type_die = new_die (DW_TAG_rvalue_reference_type, comp_unit_die,
-                               type);
-      else
-       mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type);
+      mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type);
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
                       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
@@ -13889,8 +13825,10 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
          else
            {
              loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double;
-             loc_result->dw_loc_oprnd2.v.val_double
-               = rtx_to_double_int (rtl);
+             loc_result->dw_loc_oprnd2.v.val_double.high
+               = CONST_DOUBLE_HIGH (rtl);
+             loc_result->dw_loc_oprnd2.v.val_double.low
+               = CONST_DOUBLE_LOW (rtl);
            }
        }
       break;
@@ -13914,14 +13852,39 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
              for (i = 0, p = array; i < length; i++, p += elt_size)
                {
                  rtx elt = CONST_VECTOR_ELT (rtl, i);
-                 double_int val = rtx_to_double_int (elt);
+                 HOST_WIDE_INT lo, hi;
+
+                 switch (GET_CODE (elt))
+                   {
+                   case CONST_INT:
+                     lo = INTVAL (elt);
+                     hi = -(lo < 0);
+                     break;
+
+                   case CONST_DOUBLE:
+                     lo = CONST_DOUBLE_LOW (elt);
+                     hi = CONST_DOUBLE_HIGH (elt);
+                     break;
+
+                   default:
+                     gcc_unreachable ();
+                   }
 
                  if (elt_size <= sizeof (HOST_WIDE_INT))
-                   insert_int (double_int_to_shwi (val), elt_size, p);
+                   insert_int (lo, elt_size, p);
                  else
                    {
+                     unsigned char *p0 = p;
+                     unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
                      gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT));
-                     insert_double (val, p);
+                     if (WORDS_BIG_ENDIAN)
+                       {
+                         p0 = p1;
+                         p1 = p;
+                       }
+                     insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+                     insert_int (hi, sizeof (HOST_WIDE_INT), p1);
                    }
                }
              break;
@@ -15309,24 +15272,6 @@ extract_int (const unsigned char *src, unsigned int size)
   return val;
 }
 
-/* Writes double_int values to dw_vec_const array.  */
-
-static void
-insert_double (double_int val, unsigned char *dest)
-{
-  unsigned char *p0 = dest;
-  unsigned char *p1 = dest + sizeof (HOST_WIDE_INT);
-
-  if (WORDS_BIG_ENDIAN)
-    {
-      p0 = p1;
-      p1 = dest;
-    }
-
-  insert_int ((HOST_WIDE_INT) val.low, sizeof (HOST_WIDE_INT), p0);
-  insert_int ((HOST_WIDE_INT) val.high, sizeof (HOST_WIDE_INT), p1);
-}
-
 /* Writes floating point values to dw_vec_const array.  */
 
 static void
@@ -15406,14 +15351,39 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
            for (i = 0, p = array; i < length; i++, p += elt_size)
              {
                rtx elt = CONST_VECTOR_ELT (rtl, i);
-               double_int val = rtx_to_double_int (elt);
+               HOST_WIDE_INT lo, hi;
+
+               switch (GET_CODE (elt))
+                 {
+                 case CONST_INT:
+                   lo = INTVAL (elt);
+                   hi = -(lo < 0);
+                   break;
+
+                 case CONST_DOUBLE:
+                   lo = CONST_DOUBLE_LOW (elt);
+                   hi = CONST_DOUBLE_HIGH (elt);
+                   break;
+
+                 default:
+                   gcc_unreachable ();
+                 }
 
                if (elt_size <= sizeof (HOST_WIDE_INT))
-                 insert_int (double_int_to_shwi (val), elt_size, p);
+                 insert_int (lo, elt_size, p);
                else
                  {
+                   unsigned char *p0 = p;
+                   unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
                    gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT));
-                   insert_double (val, p);
+                   if (WORDS_BIG_ENDIAN)
+                     {
+                       p0 = p1;
+                       p1 = p;
+                     }
+                   insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+                   insert_int (hi, sizeof (HOST_WIDE_INT), p1);
                  }
              }
            break;
@@ -15936,7 +15906,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
   loc_list = lookup_decl_loc (decl);
   if (loc_list
       && loc_list->first
-      && loc_list->first->next == NULL
+      && loc_list->first == loc_list->last
       && NOTE_VAR_LOCATION (loc_list->first->var_loc_note)
       && NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note))
     {
@@ -16365,7 +16335,6 @@ lower_bound_default (void)
       return 1;
     case DW_LANG_UPC:
     case DW_LANG_D:
-    case DW_LANG_Python:
       return dwarf_version >= 4 ? 0 : -1;
     case DW_LANG_Ada95:
     case DW_LANG_Ada83:
@@ -16776,7 +16745,8 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
       if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
          && TREE_PUBLIC (decl)
          && !DECL_ABSTRACT (decl)
-         && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)))
+         && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
+         && !is_fortran ())
        {
          /* Defer until we have an assembler name set.  */
          if (!DECL_ASSEMBLER_NAME_SET_P (decl))
@@ -16790,7 +16760,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
              deferred_asm_name = asm_name;
            }
          else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
-           add_AT_string (die, AT_linkage_name,
+           add_AT_string (die, DW_AT_MIPS_linkage_name,
                           IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
        }
     }
@@ -17415,9 +17385,6 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
                          scope_die_for (type, context_die), type);
       equate_type_number_to_die (type, type_die);
       add_name_attribute (type_die, type_tag (type));
-      if ((dwarf_version >= 4 || !dwarf_strict)
-         && ENUM_IS_SCOPED (type))
-       add_AT_flag (type_die, DW_AT_enum_class, 1);
     }
   else if (! TYPE_SIZE (type))
     return type_die;
@@ -18663,12 +18630,8 @@ gen_pointer_type_die (tree type, dw_die_ref context_die)
 static void
 gen_reference_type_die (tree type, dw_die_ref context_die)
 {
-  dw_die_ref ref_die, scope_die = scope_die_for (type, context_die);
-
-  if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
-    ref_die = new_die (DW_TAG_rvalue_reference_type, scope_die, type);
-  else
-    ref_die = new_die (DW_TAG_reference_type, scope_die, type);
+  dw_die_ref ref_die
+    = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type);
 
   equate_type_number_to_die (type, ref_die);
   add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die);
@@ -18748,20 +18711,6 @@ gen_compile_unit_die (const char *filename)
     }
 
   add_AT_unsigned (die, DW_AT_language, language);
-
-  switch (language)
-    {
-    case DW_LANG_Fortran77:
-    case DW_LANG_Fortran90:
-    case DW_LANG_Fortran95:
-      /* Fortran has case insensitive identifiers and the front-end
-        lowercases everything.  */
-      add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case);
-      break;
-    default:
-      /* The default DW_ID_case_sensitive doesn't need to be specified.  */
-      break;
-    }
   return die;
 }
 
@@ -19172,18 +19121,6 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
         when appropriate.  */
       return;
 
-    case NULLPTR_TYPE:
-      {
-        dw_die_ref type_die = lookup_type_die (type);
-        if (type_die == NULL)
-          {
-            type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type);
-            add_name_attribute (type_die, "decltype(nullptr)");
-            equate_type_number_to_die (type, type_die);
-          }
-      }
-      return;
-
     case VOID_TYPE:
     case INTEGER_TYPE:
     case REAL_TYPE:
@@ -20420,33 +20357,22 @@ dwarf2out_var_location (rtx loc_note)
   if (next_real == NULL_RTX)
     return;
 
-  /* If there were any real insns between note we processed last time
-     and this note (or if it is the first note), clear
-     last_{,postcall_}label so that they are not reused this time.  */
-  if (last_var_location_insn == NULL_RTX
-      || last_var_location_insn != next_real
-      || last_in_cold_section_p != in_cold_section_p)
-    {
-      last_label = NULL;
-      last_postcall_label = NULL;
-    }
-
   decl = NOTE_VAR_LOCATION_DECL (loc_note);
-  newloc = add_var_loc_to_decl (decl, loc_note,
-                               NOTE_DURING_CALL_P (loc_note)
-                               ? last_postcall_label : last_label);
+  newloc = add_var_loc_to_decl (decl, loc_note);
   if (newloc == NULL)
     return;
 
   /* If there were no real insns between note we processed last time
-     and this note, use the label we emitted last time.  Otherwise
-     create a new label and emit it.  */
-  if (last_label == NULL)
+     and this note, use the label we emitted last time.  */
+  if (last_var_location_insn == NULL_RTX
+      || last_var_location_insn != next_real
+      || last_in_cold_section_p != in_cold_section_p)
     {
       ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);
       ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num);
       loclabel_num++;
       last_label = ggc_strdup (loclabel);
+      last_postcall_label = NULL;
     }
   newloc->var_loc_note = loc_note;
   newloc->next = NULL;
@@ -20977,7 +20903,6 @@ prune_unused_types_walk (dw_die_ref die)
     case DW_TAG_packed_type:
     case DW_TAG_pointer_type:
     case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
     case DW_TAG_volatile_type:
     case DW_TAG_typedef:
     case DW_TAG_array_type:
@@ -21197,7 +21122,7 @@ htab_ct_eq (const void *of1, const void *of2)
                     DWARF_TYPE_SIGNATURE_SIZE));
 }
 
-/* Move a DW_AT_{,MIPS_}linkage_name attribute just added to dw_die_ref
+/* Move a DW_AT_MIPS_linkage_name attribute just added to dw_die_ref
    to the location it would have been added, should we know its
    DECL_ASSEMBLER_NAME when we added other attributes.  This will
    probably improve compactness of debug info, removing equivalent
@@ -21210,7 +21135,7 @@ move_linkage_attr (dw_die_ref die)
   unsigned ix = VEC_length (dw_attr_node, die->die_attr);
   dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1);
 
-  gcc_assert (linkage.dw_attr == AT_linkage_name);
+  gcc_assert (linkage.dw_attr == DW_AT_MIPS_linkage_name);
 
   while (--ix > 0)
     {
@@ -21444,7 +21369,7 @@ dwarf2out_finish (const char *filename)
       tree decl = node->created_for;
       if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
        {
-         add_AT_string (node->die, AT_linkage_name,
+         add_AT_string (node->die, DW_AT_MIPS_linkage_name,
                         IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
          move_linkage_attr (node->die);
        }