OSDN Git Service

* dwarf2out.c (lower_bound_default): For DW_LANG_Python return
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index fbf581b..6e76998 100644 (file)
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "version.h"
 #include "flags.h"
+#include "real.h"
 #include "rtl.h"
 #include "hard-reg-set.h"
 #include "regs.h"
@@ -78,11 +79,11 @@ 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"
 #include "diagnostic.h"
-#include "tree-pretty-print.h"
 #include "debug.h"
 #include "target.h"
 #include "langhooks.h"
@@ -91,7 +92,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "input.h"
 #include "gimple.h"
 #include "tree-pass.h"
-#include "tree-flow.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
@@ -1040,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
@@ -1056,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
@@ -3772,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");
@@ -4785,10 +4779,6 @@ size_of_loc_descr (dw_loc_descr_ref loc)
     case DW_OP_piece:
       size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
       break;
-    case DW_OP_bit_piece:
-      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
-      size += size_of_uleb128 (loc->dw_loc_oprnd2.v.val_unsigned);
-      break;
     case DW_OP_deref_size:
     case DW_OP_xderef_size:
       size += 1;
@@ -5013,10 +5003,6 @@ output_loc_operands (dw_loc_descr_ref loc)
     case DW_OP_piece:
       dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
       break;
-    case DW_OP_bit_piece:
-      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
-      dw2_asm_output_data_uleb128 (val2->v.val_unsigned, NULL);
-      break;
     case DW_OP_deref_size:
     case DW_OP_xderef_size:
       dw2_asm_output_data (1, val1->v.val_int, NULL);
@@ -5132,12 +5118,6 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
       dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
       break;
 
-    case DW_OP_bit_piece:
-      fputc (',', asm_out_file);
-      dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
-      dw2_asm_output_data_uleb128_raw (val2->v.val_unsigned);
-      break;
-
     case DW_OP_consts:
     case DW_OP_breg0:
     case DW_OP_breg1:
@@ -5730,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.  */
@@ -5754,15 +5735,7 @@ DEF_VEC_ALLOC_O(die_arg_entry,gc);
 
 /* Node of the variable location list.  */
 struct GTY ((chain_next ("%h.next"))) var_loc_node {
-  /* Either NOTE_INSN_VAR_LOCATION, or, for SRA optimized variables,
-     EXPR_LIST chain.  For small bitsizes, bitsize is encoded
-     in mode of the EXPR_LIST node and first EXPR_LIST operand
-     is either NOTE_INSN_VAR_LOCATION for a piece with a known
-     location or NULL for padding.  For larger bitsizes,
-     mode is 0 and first operand is a CONCAT with bitsize
-     as first CONCAT operand and NOTE_INSN_VAR_LOCATION resp.
-     NULL as second operand.  */
-  rtx GTY (()) loc;
+  rtx GTY (()) var_loc_note;
   const char * GTY (()) label;
   struct var_loc_node * GTY (()) next;
 };
@@ -5771,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.  */
@@ -6018,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 *);
@@ -6139,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,
@@ -6305,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.
@@ -7780,175 +7742,16 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
   decl_die->decl_id = decl_id;
 }
 
-/* Return how many bits covers PIECE EXPR_LIST.  */
-
-static int
-decl_piece_bitsize (rtx piece)
-{
-  int ret = (int) GET_MODE (piece);
-  if (ret)
-    return ret;
-  gcc_assert (GET_CODE (XEXP (piece, 0)) == CONCAT
-             && CONST_INT_P (XEXP (XEXP (piece, 0), 0)));
-  return INTVAL (XEXP (XEXP (piece, 0), 0));
-}
-
-/* Return pointer to the location of location note in PIECE EXPR_LIST.  */
-
-static rtx *
-decl_piece_varloc_ptr (rtx piece)
-{
-  if ((int) GET_MODE (piece))
-    return &XEXP (piece, 0);
-  else
-    return &XEXP (XEXP (piece, 0), 1);
-}
-
-/* Create an EXPR_LIST for location note LOC_NOTE covering BITSIZE bits.
-   Next is the chain of following piece nodes.  */
-
-static rtx
-decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next)
-{
-  if (bitsize <= (int) MAX_MACHINE_MODE)
-    return alloc_EXPR_LIST (bitsize, loc_note, next);
-  else
-    return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode,
-                                              GEN_INT (bitsize),
-                                              loc_note), next);
-}
-
-/* Return rtx that should be stored into loc field for
-   LOC_NOTE and BITPOS/BITSIZE.  */
-
-static rtx
-construct_piece_list (rtx loc_note, HOST_WIDE_INT bitpos,
-                     HOST_WIDE_INT bitsize)
-{
-  if (bitsize != -1)
-    {
-      loc_note = decl_piece_node (loc_note, bitsize, NULL_RTX);
-      if (bitpos != 0)
-       loc_note = decl_piece_node (NULL_RTX, bitpos, loc_note);
-    }
-  return loc_note;
-}
-
-/* This function either modifies location piece list *DEST in
-   place (if SRC and INNER is NULL), or copies location piece list
-   *SRC to *DEST while modifying it.  Location BITPOS is modified
-   to contain LOC_NOTE, any pieces overlapping it are removed resp.
-   not copied and if needed some padding around it is added.
-   When modifying in place, DEST should point to EXPR_LIST where
-   earlier pieces cover PIECE_BITPOS bits, when copying SRC points
-   to the start of the whole list and INNER points to the EXPR_LIST
-   where earlier pieces cover PIECE_BITPOS bits.  */
-
-static void
-adjust_piece_list (rtx *dest, rtx *src, rtx *inner,
-                  HOST_WIDE_INT bitpos, HOST_WIDE_INT piece_bitpos,
-                  HOST_WIDE_INT bitsize, rtx loc_note)
-{
-  int diff;
-  bool copy = inner != NULL;
-
-  if (copy)
-    {
-      /* First copy all nodes preceeding the current bitpos.  */
-      while (src != inner)
-       {
-         *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
-                                  decl_piece_bitsize (*src), NULL_RTX);
-         dest = &XEXP (*dest, 1);
-         src = &XEXP (*src, 1);
-       }
-    }
-  /* Add padding if needed.  */
-  if (bitpos != piece_bitpos)
-    {
-      *dest = decl_piece_node (NULL_RTX, bitpos - piece_bitpos,
-                              copy ? NULL_RTX : *dest);
-      dest = &XEXP (*dest, 1);
-    }
-  else if (*dest && decl_piece_bitsize (*dest) == bitsize)
-    {
-      gcc_assert (!copy);
-      /* A piece with correct bitpos and bitsize already exist,
-        just update the location for it and return.  */
-      *decl_piece_varloc_ptr (*dest) = loc_note;
-      return;
-    }
-  /* Add the piece that changed.  */
-  *dest = decl_piece_node (loc_note, bitsize, copy ? NULL_RTX : *dest);
-  dest = &XEXP (*dest, 1);
-  /* Skip over pieces that overlap it.  */
-  diff = bitpos - piece_bitpos + bitsize;
-  if (!copy)
-    src = dest;
-  while (diff > 0 && *src)
-    {
-      rtx piece = *src;
-      diff -= decl_piece_bitsize (piece);
-      if (copy)
-       src = &XEXP (piece, 1);
-      else
-       {
-         *src = XEXP (piece, 1);
-         free_EXPR_LIST_node (piece);
-       }
-    }
-  /* Add padding if needed.  */
-  if (diff < 0 && *src)
-    {
-      if (!copy)
-       dest = src;
-      *dest = decl_piece_node (NULL_RTX, -diff, copy ? NULL_RTX : *dest);
-      dest = &XEXP (*dest, 1);
-    }
-  if (!copy)
-    return;
-  /* Finally copy all nodes following it.  */
-  while (*src)
-    {
-      *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
-                              decl_piece_bitsize (*src), NULL_RTX);
-      dest = &XEXP (*dest, 1);
-      src = &XEXP (*src, 1);
-    }
-}
-
 /* 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;
+  unsigned int decl_id = DECL_UID (decl);
   var_loc_list *temp;
   void **slot;
   struct var_loc_node *loc = NULL;
-  HOST_WIDE_INT bitsize = -1, bitpos = -1;
 
-  if (DECL_DEBUG_EXPR_IS_FROM (decl))
-    {
-      tree realdecl = DECL_DEBUG_EXPR (decl);
-      if (realdecl && handled_component_p (realdecl))
-       {
-         HOST_WIDE_INT maxsize;
-         tree innerdecl;
-         innerdecl
-           = get_ref_base_and_extent (realdecl, &bitpos, &bitsize, &maxsize);
-         if (!DECL_P (innerdecl)
-             || DECL_IGNORED_P (innerdecl)
-             || TREE_STATIC (innerdecl)
-             || bitsize <= 0
-             || bitpos + bitsize > 256
-             || bitsize != maxsize)
-           return NULL;
-         decl = innerdecl;
-       }
-    }
-
-  decl_id = DECL_UID (decl);
   slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT);
   if (*slot == NULL)
     {
@@ -7961,108 +7764,29 @@ 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;
-      rtx *piece_loc = NULL, last_loc_note;
-      int piece_bitpos = 0;
-      if (last->next)
-       {
-         last = last->next;
-         gcc_assert (last->next == NULL);
-       }
-      if (bitsize != -1 && GET_CODE (last->loc) == EXPR_LIST)
-       {
-         piece_loc = &last->loc;
-         do
-           {
-             int cur_bitsize = decl_piece_bitsize (*piece_loc);
-             if (piece_bitpos + cur_bitsize > bitpos)
-               break;
-             piece_bitpos += cur_bitsize;
-             piece_loc = &XEXP (*piece_loc, 1);
-           }
-         while (*piece_loc);
-       }
-      /* 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 (label && strcmp (last->label, label) == 0)
-       {
-         /* For SRA optimized variables if there weren't any real
-            insns since last note, just modify the last node.  */
-         if (piece_loc != NULL)
-           {
-             adjust_piece_list (piece_loc, NULL, NULL,
-                                bitpos, piece_bitpos, bitsize, loc_note);
-             return NULL;
-           }
-         /* If the last note doesn't cover any instructions, remove it.  */
-         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));
-             temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize);
-             return temp->last;
-           }
-       }
-      if (bitsize == -1 && NOTE_P (last->loc))
-       last_loc_note = last->loc;
-      else if (piece_loc != NULL
-              && *piece_loc != NULL_RTX
-              && piece_bitpos == bitpos
-              && decl_piece_bitsize (*piece_loc) == bitsize)
-       last_loc_note = *decl_piece_varloc_ptr (*piece_loc);
-      else
-       last_loc_note = NULL_RTX;
       /* 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 (last_loc_note == NULL_RTX
-         || (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last_loc_note),
-                           NOTE_VAR_LOCATION_LOC (loc_note)))
-         || ((NOTE_VAR_LOCATION_STATUS (last_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 (temp->last->var_loc_note)
               != NOTE_VAR_LOCATION_STATUS (loc_note))
-             && ((NOTE_VAR_LOCATION_STATUS (last_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);
-         if (bitsize == -1 || piece_loc == NULL)
-           loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
-         else
-           adjust_piece_list (&loc->loc, &last->loc, piece_loc,
-                              bitpos, piece_bitpos, bitsize, loc_note);
-         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
     {
       loc = GGC_CNEW (struct var_loc_node);
       temp->first = loc;
       temp->last = loc;
-      loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
     }
   return loc;
 }
@@ -8521,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))
@@ -9236,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:
@@ -9274,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)
     {
@@ -9523,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:
@@ -9607,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;
@@ -12295,6 +12014,10 @@ base_type_die (tree type)
 
   base_type_result = new_die (DW_TAG_base_type, comp_unit_die, type);
 
+  /* This probably indicates a bug.  */
+  if (! TYPE_NAME (type))
+    add_name_attribute (base_type_result, "__unknown__");
+
   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);
@@ -12412,21 +12135,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
                          ((is_const_type ? TYPE_QUAL_CONST : 0)
                           | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));
 
-  if (qualified_type == sizetype
-      && TYPE_NAME (qualified_type)
-      && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL)
-    {
-#ifdef ENABLE_CHECKING
-      gcc_assert (TREE_CODE (TREE_TYPE (TYPE_NAME (qualified_type)))
-                 == INTEGER_TYPE
-                 && TYPE_PRECISION (TREE_TYPE (TYPE_NAME (qualified_type)))
-                    == TYPE_PRECISION (qualified_type)
-                 && TYPE_UNSIGNED (TREE_TYPE (TYPE_NAME (qualified_type)))
-                    == TYPE_UNSIGNED (qualified_type));
-#endif
-      qualified_type = TREE_TYPE (TYPE_NAME (qualified_type));
-    }
-
   /* If we do, then we can just use its DIE, if it exists.  */
   if (qualified_type)
     {
@@ -12484,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);
@@ -12543,9 +12247,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
        name = DECL_NAME (name);
       add_name_attribute (mod_type_die, IDENTIFIER_POINTER (name));
     }
-  /* 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__");
 
   if (qualified_type)
     equate_type_number_to_die (qualified_type, mod_type_die);
@@ -14124,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;
@@ -14149,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;
@@ -14306,11 +14034,7 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address,
     }
   else
     {
-      if (GET_CODE (varloc) == VAR_LOCATION)
-       mode = DECL_MODE (PAT_VAR_LOCATION_DECL (varloc));
-      else
-       mode = DECL_MODE (loc);
-      descr = loc_descriptor (varloc, mode, initialized);
+      descr = loc_descriptor (varloc, DECL_MODE (loc), initialized);
       have_address = 1;
     }
 
@@ -14360,165 +14084,6 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address,
   return descr;
 }
 
-/* Create a DW_OP_piece or DW_OP_bit_piece for bitsize, or return NULL
-   if it is not possible.  */
-
-static dw_loc_descr_ref
-new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize, HOST_WIDE_INT offset)
-{
-  if ((bitsize % BITS_PER_UNIT) == 0 && offset == 0)
-    return new_loc_descr (DW_OP_piece, bitsize / BITS_PER_UNIT, 0);
-  else if (dwarf_version >= 3 || !dwarf_strict)
-    return new_loc_descr (DW_OP_bit_piece, bitsize, offset);
-  else
-    return NULL;
-}
-
-/* Helper function for dw_loc_list.  Compute proper Dwarf location descriptor
-   for VAR_LOC_NOTE for variable DECL that has been optimized by SRA.  */
-
-static dw_loc_descr_ref
-dw_sra_loc_expr (tree decl, rtx loc)
-{
-  rtx p;
-  unsigned int padsize = 0;
-  dw_loc_descr_ref descr, *descr_tail;
-  unsigned HOST_WIDE_INT decl_size;
-  rtx varloc;
-  enum var_init_status initialized;
-
-  if (DECL_SIZE (decl) == NULL
-      || !host_integerp (DECL_SIZE (decl), 1))
-    return NULL;
-
-  decl_size = tree_low_cst (DECL_SIZE (decl), 1);
-  descr = NULL;
-  descr_tail = &descr;
-
-  for (p = loc; p; p = XEXP (p, 1))
-    {
-      unsigned int bitsize = decl_piece_bitsize (p);
-      rtx loc_note = *decl_piece_varloc_ptr (p);
-      dw_loc_descr_ref cur_descr;
-      dw_loc_descr_ref *tail, last = NULL;
-      unsigned int opsize = 0;
-
-      if (loc_note == NULL_RTX
-         || NOTE_VAR_LOCATION_LOC (loc_note) == NULL_RTX)
-       {
-         padsize += bitsize;
-         continue;
-       }
-      initialized = NOTE_VAR_LOCATION_STATUS (loc_note);
-      varloc = NOTE_VAR_LOCATION (loc_note);
-      cur_descr = dw_loc_list_1 (decl, varloc, 2, initialized);
-      if (cur_descr == NULL)
-       {
-         padsize += bitsize;
-         continue;
-       }
-
-      /* Check that cur_descr either doesn't use
-        DW_OP_*piece operations, or their sum is equal
-        to bitsize.  Otherwise we can't embed it.  */
-      for (tail = &cur_descr; *tail != NULL;
-          tail = &(*tail)->dw_loc_next)
-       if ((*tail)->dw_loc_opc == DW_OP_piece)
-         {
-           opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned
-                     * BITS_PER_UNIT;
-           last = *tail;
-         }
-       else if ((*tail)->dw_loc_opc == DW_OP_bit_piece)
-         {
-           opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned;
-           last = *tail;
-         }
-
-      if (last != NULL && opsize != bitsize)
-       {
-         padsize += bitsize;
-         continue;
-       }
-
-      /* If there is a hole, add DW_OP_*piece after empty DWARF
-        expression, which means that those bits are optimized out.  */
-      if (padsize)
-       {
-         if (padsize > decl_size)
-           return NULL;
-         decl_size -= padsize;
-         *descr_tail = new_loc_descr_op_bit_piece (padsize, 0);
-         if (*descr_tail == NULL)
-           return NULL;
-         descr_tail = &(*descr_tail)->dw_loc_next;
-         padsize = 0;
-       }
-      *descr_tail = cur_descr;
-      descr_tail = tail;
-      if (bitsize > decl_size)
-       return NULL;
-      decl_size -= bitsize;
-      if (last == NULL)
-       {
-         HOST_WIDE_INT offset = 0;
-         if (GET_CODE (varloc) == VAR_LOCATION
-             && GET_CODE (PAT_VAR_LOCATION_LOC (varloc)) != PARALLEL)
-           {
-             varloc = PAT_VAR_LOCATION_LOC (varloc);
-             if (GET_CODE (varloc) == EXPR_LIST)
-               varloc = XEXP (varloc, 0);
-           }
-         do 
-           {
-             if (GET_CODE (varloc) == CONST
-                 || GET_CODE (varloc) == SIGN_EXTEND
-                 || GET_CODE (varloc) == ZERO_EXTEND)
-               varloc = XEXP (varloc, 0);
-             else if (GET_CODE (varloc) == SUBREG)
-               varloc = SUBREG_REG (varloc);
-             else
-               break;
-           }
-         while (1);
-         /* DW_OP_bit_size offset should be zero for register
-            or implicit location descriptions and empty location
-            descriptions, but for memory addresses needs big endian
-            adjustment.  */
-         if (MEM_P (varloc))
-           {
-             unsigned HOST_WIDE_INT memsize
-               = INTVAL (MEM_SIZE (varloc)) * BITS_PER_UNIT;
-             if (memsize != bitsize)
-               {
-                 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
-                     && (memsize > BITS_PER_WORD || bitsize > BITS_PER_WORD))
-                   return NULL;
-                 if (memsize < bitsize)
-                   return NULL;
-                 if (BITS_BIG_ENDIAN)
-                   offset = memsize - bitsize;
-               }
-           }
-
-         *descr_tail = new_loc_descr_op_bit_piece (bitsize, offset);
-         if (*descr_tail == NULL)
-           return NULL;
-         descr_tail = &(*descr_tail)->dw_loc_next;
-       }
-    }
-
-  /* If there were any non-empty expressions, add padding till the end of
-     the decl.  */
-  if (descr != NULL && decl_size != 0)
-    {
-      *descr_tail = new_loc_descr_op_bit_piece (decl_size, 0);
-      if (*descr_tail == NULL)
-       return NULL;
-    }
-  return descr;
-}
-
 /* Return the dwarf representation of the location list LOC_LIST of
    DECL.  WANT_ADDRESS has the same meaning as in loc_list_from_tree
    function.  */
@@ -14548,48 +14113,45 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   secname = secname_for_decl (decl);
 
-  for (node = loc_list->first; node; node = node->next)
-    if (GET_CODE (node->loc) == EXPR_LIST
-       || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
+  for (node = loc_list->first; node->next; node = node->next)
+    if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
       {
-       if (GET_CODE (node->loc) == EXPR_LIST)
-         {
-           /* This requires DW_OP_{,bit_}piece, which is not usable
-              inside DWARF expressions.  */
-           if (want_address != 2)
-             continue;
-           descr = dw_sra_loc_expr (decl, node->loc);
-           if (descr == NULL)
-             continue;
-         }
-       else
-         {
-           initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
-           varloc = NOTE_VAR_LOCATION (node->loc);
-           descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
-         }
+       /* The variable has a location between NODE->LABEL and
+          NODE->NEXT->LABEL.  */
+       initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+       descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
        if (descr)
          {
-           /* The variable has a location between NODE->LABEL and
-              NODE->NEXT->LABEL.  */
-           if (node->next)
-             endname = node->next->label;
-           /* If the variable has a location at the last label
-              it keeps its location until the end of function.  */
-           else if (!current_function_decl)
-             endname = text_end_label;
-           else
-             {
-               ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
-                                            current_function_funcdef_no);
-               endname = ggc_strdup (label_id);
-             }
-
-           *listp = new_loc_list (descr, node->label, endname, secname);
+           *listp = new_loc_list (descr, node->label, node->next->label,
+                                  secname);
            listp = &(*listp)->dw_loc_next;
          }
       }
 
+  /* If the variable has a location at the last label
+     it keeps its location until the end of function.  */
+  if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
+    {
+      initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+      descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
+      if (descr)
+       {
+         if (!current_function_decl)
+           endname = text_end_label;
+         else
+           {
+             ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+                                          current_function_funcdef_no);
+             endname = ggc_strdup (label_id);
+           }
+
+         *listp = new_loc_list (descr, node->label, endname, secname);
+         listp = &(*listp)->dw_loc_next;
+       }
+    }
+
   /* Try to avoid the overhead of a location list emitting a location
      expression instead, but only if we didn't have more than one
      location entry in the first place.  If some entries were not
@@ -15710,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
@@ -15807,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;
@@ -16337,15 +15906,14 @@ 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
-      && NOTE_P (loc_list->first->loc)
-      && NOTE_VAR_LOCATION (loc_list->first->loc)
-      && NOTE_VAR_LOCATION_LOC (loc_list->first->loc))
+      && 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))
     {
       struct var_loc_node *node;
 
       node = loc_list->first;
-      rtl = NOTE_VAR_LOCATION_LOC (node->loc);
+      rtl = NOTE_VAR_LOCATION_LOC (node->var_loc_note);
       if (GET_CODE (rtl) == EXPR_LIST)
        rtl = XEXP (rtl, 0);
       if ((CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
@@ -17178,7 +16746,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))
@@ -17192,7 +16761,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)));
        }
     }
@@ -19065,12 +18634,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);
@@ -19150,20 +18715,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;
 }
 
@@ -19584,19 +19135,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
       break;
 
     case LANG_TYPE:
-      /* Just use DW_TAG_unspecified_type.  */
-      {
-        dw_die_ref type_die = lookup_type_die (type);
-        if (type_die == NULL)
-          {
-           tree name = TYPE_NAME (type);
-           if (TREE_CODE (name) == TYPE_DECL)
-             name = DECL_NAME (name);
-            type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type);
-            add_name_attribute (type_die, IDENTIFIER_POINTER (name));
-            equate_type_number_to_die (type, type_die);
-          }
-      }
+      /* No Dwarf representation currently defined.  */
       break;
 
     default:
@@ -20218,7 +19757,10 @@ dwarf2out_imported_module_or_decl_1 (tree decl,
 
   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
     {
-      at_import_die = force_type_die (TREE_TYPE (decl));
+      if (is_base_type (TREE_TYPE (decl)))
+       at_import_die = base_type_die (TREE_TYPE (decl));
+      else
+       at_import_die = force_type_die (TREE_TYPE (decl));
       /* For namespace N { typedef void T; } using N::T; base_type_die
         returns NULL, but DW_TAG_imported_declaration requires
         the DW_AT_import tag.  Force creation of DW_TAG_typedef.  */
@@ -20819,34 +20361,25 @@ 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;
 
   if (!NOTE_DURING_CALL_P (loc_note))
     newloc->label = last_label;
@@ -21374,7 +20907,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:
@@ -21594,7 +21126,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
@@ -21607,7 +21139,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)
     {
@@ -21651,6 +21183,7 @@ resolve_one_addr (rtx *addr, void *data ATTRIBUTE_UNUSED)
 
   if (GET_CODE (rtl) == SYMBOL_REF
       && SYMBOL_REF_DECL (rtl)
+      && TREE_CODE (SYMBOL_REF_DECL (rtl)) == VAR_DECL
       && !TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
     return 1;
 
@@ -21840,7 +21373,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);
        }