re PR debug/65549 (crash in htab_hash_string with -flto -g)
[gcc.git] / gcc / dwarf2out.c
index 601be8532b2384a022da4b8e9b01c64af404ad4b..1116f86a13701f6a195808a95b3a923b3c6a89e2 100644 (file)
@@ -1,5 +1,5 @@
 /* Output Dwarf2 format symbol table information from GCC.
-   Copyright (C) 1992-2014 Free Software Foundation, Inc.
+   Copyright (C) 1992-2015 Free Software Foundation, Inc.
    Contributed by Gary Funck (gary@intrepid.com).
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
    Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -60,16 +60,23 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "rtl.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "vec.h"
+#include "double-int.h"
+#include "input.h"
+#include "alias.h"
+#include "symtab.h"
+#include "wide-int.h"
+#include "inchash.h"
+#include "real.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "stringpool.h"
 #include "stor-layout.h"
 #include "varasm.h"
 #include "hashtab.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "machmode.h"
 #include "hard-reg-set.h"
-#include "input.h"
 #include "function.h"
 #include "emit-rtl.h"
 #include "hash-table.h"
@@ -80,6 +87,13 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-config.h"
 #include "reload.h"
 #include "output.h"
+#include "statistics.h"
+#include "fixed-value.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "stmt.h"
 #include "expr.h"
 #include "except.h"
 #include "dwarf2.h"
@@ -2894,10 +2908,6 @@ static int call_site_count = -1;
 /* Number of tail call sites in the current function.  */
 static int tail_call_site_count = -1;
 
-/* Vector mapping block numbers to DW_TAG_{lexical_block,inlined_subroutine}
-   DIEs.  */
-static vec<dw_die_ref> block_map;
-
 /* A cached location list.  */
 struct GTY ((for_user)) cached_dw_loc_list_def {
   /* The DECL_UID of the decl that this entry describes.  */
@@ -3872,7 +3882,8 @@ add_AT_wide (dw_die_ref die, enum dwarf_attribute attr_kind,
 
   attr.dw_attr = attr_kind;
   attr.dw_attr_val.val_class = dw_val_class_wide_int;
-  attr.dw_attr_val.v.val_wide = ggc_cleared_alloc<wide_int> ();
+  attr.dw_attr_val.val_entry = NULL;
+  attr.dw_attr_val.v.val_wide = ggc_alloc<wide_int> ();
   *attr.dw_attr_val.v.val_wide = w;
   add_dwarf_attr (die, &attr);
 }
@@ -4722,7 +4733,9 @@ is_fortran (void)
 
   return (lang == DW_LANG_Fortran77
          || lang == DW_LANG_Fortran90
-         || lang == DW_LANG_Fortran95);
+         || lang == DW_LANG_Fortran95
+         || lang == DW_LANG_Fortran03
+         || lang == DW_LANG_Fortran08);
 }
 
 /* Return TRUE if the language is Ada.  */
@@ -5048,7 +5061,7 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
 
 /* Return how many bits covers PIECE EXPR_LIST.  */
 
-static int
+static HOST_WIDE_INT
 decl_piece_bitsize (rtx piece)
 {
   int ret = (int) GET_MODE (piece);
@@ -5076,7 +5089,7 @@ decl_piece_varloc_ptr (rtx piece)
 static rtx_expr_list *
 decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next)
 {
-  if (bitsize <= (int) MAX_MACHINE_MODE)
+  if (bitsize > 0 && bitsize <= (int) MAX_MACHINE_MODE)
     return alloc_EXPR_LIST (bitsize, loc_note, next);
   else
     return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode,
@@ -5115,7 +5128,7 @@ 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;
+  HOST_WIDE_INT diff;
   bool copy = inner != NULL;
 
   if (copy)
@@ -5255,7 +5268,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
     {
       struct var_loc_node *last = temp->last, *unused = NULL;
       rtx *piece_loc = NULL, last_loc_note;
-      int piece_bitpos = 0;
+      HOST_WIDE_INT piece_bitpos = 0;
       if (last->next)
        {
          last = last->next;
@@ -5266,7 +5279,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
          piece_loc = &last->loc;
          do
            {
-             int cur_bitsize = decl_piece_bitsize (*piece_loc);
+             HOST_WIDE_INT cur_bitsize = decl_piece_bitsize (*piece_loc);
              if (piece_bitpos + cur_bitsize > bitpos)
                break;
              piece_bitpos += cur_bitsize;
@@ -5429,7 +5442,7 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
       fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, val->v.val_unsigned);
       break;
     case dw_val_class_const_double:
-      fprintf (outfile, "constant ("HOST_WIDE_INT_PRINT_DEC","\
+      fprintf (outfile, "constant (" HOST_WIDE_INT_PRINT_DEC","\
                        HOST_WIDE_INT_PRINT_UNSIGNED")",
               val->v.val_double.high,
               val->v.val_double.low);
@@ -5712,7 +5725,9 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
       CHECKSUM (at->dw_attr_val.v.val_double);
       break;
     case dw_val_class_wide_int:
-      CHECKSUM (*at->dw_attr_val.v.val_wide);
+      CHECKSUM_BLOCK (at->dw_attr_val.v.val_wide->get_val (),
+                     get_full_len (*at->dw_attr_val.v.val_wide)
+                     * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
       break;
     case dw_val_class_vec:
       CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
@@ -5995,8 +6010,11 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at,
 
     case dw_val_class_wide_int:
       CHECKSUM_ULEB128 (DW_FORM_block);
-      CHECKSUM_ULEB128 (sizeof (*at->dw_attr_val.v.val_wide));
-      CHECKSUM (*at->dw_attr_val.v.val_wide);
+      CHECKSUM_ULEB128 (get_full_len (*at->dw_attr_val.v.val_wide)
+                       * HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT);
+      CHECKSUM_BLOCK (at->dw_attr_val.v.val_wide->get_val (),
+                     get_full_len (*at->dw_attr_val.v.val_wide)
+                     * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
       break;
 
     case dw_val_class_vec:
@@ -6844,28 +6862,28 @@ struct cu_hash_table_entry
 
 struct cu_hash_table_entry_hasher
 {
-  typedef cu_hash_table_entry value_type;
-  typedef die_struct compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
-  static inline void remove (value_type *);
+  typedef cu_hash_table_entry *value_type;
+  typedef die_struct *compare_type;
+  static inline hashval_t hash (const cu_hash_table_entry *);
+  static inline bool equal (const cu_hash_table_entry *, const die_struct *);
+  static inline void remove (cu_hash_table_entry *);
 };
 
 inline hashval_t
-cu_hash_table_entry_hasher::hash (const value_type *entry)
+cu_hash_table_entry_hasher::hash (const cu_hash_table_entry *entry)
 {
   return htab_hash_string (entry->cu->die_id.die_symbol);
 }
 
 inline bool
-cu_hash_table_entry_hasher::equal (const value_type *entry1,
-                                  const compare_type *entry2)
+cu_hash_table_entry_hasher::equal (const cu_hash_table_entry *entry1,
+                                  const die_struct *entry2)
 {
   return !strcmp (entry1->cu->die_id.die_symbol, entry2->die_id.die_symbol);
 }
 
 inline void
-cu_hash_table_entry_hasher::remove (value_type *entry)
+cu_hash_table_entry_hasher::remove (cu_hash_table_entry *entry)
 {
   struct cu_hash_table_entry *next;
 
@@ -7181,21 +7199,21 @@ struct decl_table_entry
 
 struct decl_table_entry_hasher : typed_free_remove <decl_table_entry>
 {
-  typedef decl_table_entry value_type;
-  typedef die_struct compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  typedef decl_table_entry *value_type;
+  typedef die_struct *compare_type;
+  static inline hashval_t hash (const decl_table_entry *);
+  static inline bool equal (const decl_table_entry *, const die_struct *);
 };
 
 inline hashval_t
-decl_table_entry_hasher::hash (const value_type *entry)
+decl_table_entry_hasher::hash (const decl_table_entry *entry)
 {
   return htab_hash_pointer (entry->orig);
 }
 
 inline bool
-decl_table_entry_hasher::equal (const value_type *entry1,
-                               const compare_type *entry2)
+decl_table_entry_hasher::equal (const decl_table_entry *entry1,
+                               const die_struct *entry2)
 {
   return entry1->orig == entry2;
 }
@@ -7723,14 +7741,14 @@ struct external_ref
 
 struct external_ref_hasher : typed_free_remove <external_ref>
 {
-  typedef external_ref value_type;
-  typedef external_ref compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  typedef external_ref *value_type;
+  typedef external_ref *compare_type;
+  static inline hashval_t hash (const external_ref *);
+  static inline bool equal (const external_ref *, const external_ref *);
 };
 
 inline hashval_t
-external_ref_hasher::hash (const value_type *r)
+external_ref_hasher::hash (const external_ref *r)
 {
   dw_die_ref die = r->type;
   hashval_t h = 0;
@@ -7751,7 +7769,7 @@ external_ref_hasher::hash (const value_type *r)
 }
 
 inline bool
-external_ref_hasher::equal (const value_type *r1, const compare_type *r2)
+external_ref_hasher::equal (const external_ref *r1, const external_ref *r2)
 {
   return r1->type == r2->type;
 }
@@ -8876,14 +8894,14 @@ output_die (dw_die_ref die)
              for (i = len - 1; i >= 0; --i)
                {
                  dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
-                                      name);
+                                      "%s", name);
                  name = NULL;
                }
            else
              for (i = 0; i < len; ++i)
                {
                  dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
-                                      name);
+                                      "%s", name);
                  name = NULL;
                }
          }
@@ -8981,9 +8999,15 @@ output_die (dw_die_ref die)
          break;
 
        case dw_val_class_vms_delta:
+#ifdef ASM_OUTPUT_DWARF_VMS_DELTA
          dw2_asm_output_vms_delta (DWARF_OFFSET_SIZE,
                                    AT_vms_delta2 (a), AT_vms_delta1 (a),
                                    "%s", name);
+#else
+         dw2_asm_output_delta (DWARF_OFFSET_SIZE,
+                               AT_vms_delta2 (a), AT_vms_delta1 (a),
+                               "%s", name);
+#endif
          break;
 
        case dw_val_class_lbl_id:
@@ -11119,7 +11143,7 @@ reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
 
   regs = targetm.dwarf_register_span (rtl);
 
-  if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
+  if (REG_NREGS (rtl) > 1 || regs)
     return multiple_reg_loc_descriptor (rtl, regs, initialized);
   else
     {
@@ -11176,7 +11200,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
 #endif
 
       gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl));
-      nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)];
+      nregs = REG_NREGS (rtl);
 
       size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
 
@@ -12772,7 +12796,12 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
        }
 
       if (!const_ok_for_output (rtl))
-       break;
+       {
+         if (GET_CODE (rtl) == CONST)
+           mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
+                                                initialized);
+         break;
+       }
 
     symref:
       mem_loc_result = new_addr_loc_descr (rtl, dtprel_false);
@@ -13146,7 +13175,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
          mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0;
          mem_loc_result->dw_loc_oprnd2.val_class
            = dw_val_class_wide_int;
-         mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_cleared_alloc<wide_int> ();
+         mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
          *mem_loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
        }
       break;
@@ -13649,7 +13678,7 @@ loc_descriptor (rtx rtl, machine_mode mode,
          loc_result = new_loc_descr (DW_OP_implicit_value,
                                      GET_MODE_SIZE (mode), 0);
          loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int;
-         loc_result->dw_loc_oprnd2.v.val_wide = ggc_cleared_alloc<wide_int> ();
+         loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
          *loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
        }
       break;
@@ -13910,7 +13939,7 @@ static dw_loc_descr_ref
 dw_sra_loc_expr (tree decl, rtx loc)
 {
   rtx p;
-  unsigned int padsize = 0;
+  unsigned HOST_WIDE_INT padsize = 0;
   dw_loc_descr_ref descr, *descr_tail;
   unsigned HOST_WIDE_INT decl_size;
   rtx varloc;
@@ -13926,11 +13955,11 @@ dw_sra_loc_expr (tree decl, rtx loc)
 
   for (p = loc; p; p = XEXP (p, 1))
     {
-      unsigned int bitsize = decl_piece_bitsize (p);
+      unsigned HOST_WIDE_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;
+      unsigned HOST_WIDE_INT opsize = 0;
 
       if (loc_note == NULL_RTX
          || NOTE_VAR_LOCATION_LOC (loc_note) == NULL_RTX)
@@ -14615,6 +14644,7 @@ loc_list_from_tree (tree loc, int want_address,
 
     case TARGET_MEM_REF:
     case SSA_NAME:
+    case DEBUG_EXPR_DECL:
       return NULL;
 
     case COMPOUND_EXPR:
@@ -15086,7 +15116,6 @@ field_byte_offset (const_tree decl)
 
   bitpos_int = wi::to_offset (bit_position (decl));
 
-#ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS)
     {
       tree type;
@@ -15184,7 +15213,6 @@ field_byte_offset (const_tree decl)
        }
     }
   else
-#endif /* PCC_BITFIELD_TYPE_MATTERS */
     object_offset_in_bits = bitpos_int;
 
   object_offset_in_bytes
@@ -16287,12 +16315,12 @@ tree_add_const_value_attribute_for_decl (dw_die_ref var_die, tree decl)
          && !TREE_STATIC (decl)))
     return false;
 
-    if (TREE_READONLY (decl)
-       && ! TREE_THIS_VOLATILE (decl)
-       && DECL_INITIAL (decl))
-      /* OK */;
-    else
-      return false;
+  if (TREE_READONLY (decl)
+      && ! TREE_THIS_VOLATILE (decl)
+      && DECL_INITIAL (decl))
+    /* OK */;
+  else
+    return false;
 
   /* Don't add DW_AT_const_value if abstract origin already has one.  */
   if (get_AT (var_die, DW_AT_const_value))
@@ -16706,6 +16734,8 @@ lower_bound_default (void)
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
+    case DW_LANG_Fortran03:
+    case DW_LANG_Fortran08:
       return 1;
     case DW_LANG_UPC:
     case DW_LANG_D:
@@ -18039,7 +18069,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
 /* Forward declare these functions, because they are mutually recursive
   with their set_block_* pairing functions.  */
 static void set_decl_origin_self (tree);
-static void set_decl_abstract_flags (tree, int);
+static void set_decl_abstract_flags (tree, vec<tree> &);
 
 /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
    given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
@@ -18112,59 +18142,72 @@ set_decl_origin_self (tree decl)
     }
 }
 \f
-/* Given a pointer to some BLOCK node, and a boolean value to set the
-   "abstract" flags to, set that value into the BLOCK_ABSTRACT flag for
-   the given block, and for all local decls and all local sub-blocks
-   (recursively) which are contained therein.  */
+/* Given a pointer to some BLOCK node, set the BLOCK_ABSTRACT flag to 1
+   and if it wasn't 1 before, push it to abstract_vec vector.
+   For all local decls and all local sub-blocks (recursively) do it
+   too.  */
 
 static void
-set_block_abstract_flags (tree stmt, int setting)
+set_block_abstract_flags (tree stmt, vec<tree> &abstract_vec)
 {
   tree local_decl;
   tree subblock;
   unsigned int i;
 
-  BLOCK_ABSTRACT (stmt) = setting;
+  if (!BLOCK_ABSTRACT (stmt))
+    {
+      abstract_vec.safe_push (stmt);
+      BLOCK_ABSTRACT (stmt) = 1;
+    }
 
   for (local_decl = BLOCK_VARS (stmt);
        local_decl != NULL_TREE;
        local_decl = DECL_CHAIN (local_decl))
     if (! DECL_EXTERNAL (local_decl))
-      set_decl_abstract_flags (local_decl, setting);
+      set_decl_abstract_flags (local_decl, abstract_vec);
 
   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
     {
       local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i);
       if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl))
          || TREE_CODE (local_decl) == PARM_DECL)
-       set_decl_abstract_flags (local_decl, setting);
+       set_decl_abstract_flags (local_decl, abstract_vec);
     }
 
   for (subblock = BLOCK_SUBBLOCKS (stmt);
        subblock != NULL_TREE;
        subblock = BLOCK_CHAIN (subblock))
-    set_block_abstract_flags (subblock, setting);
+    set_block_abstract_flags (subblock, abstract_vec);
 }
 
-/* Given a pointer to some ..._DECL node, and a boolean value to set the
-   "abstract" flags to, set that value into the DECL_ABSTRACT_P flag for the
-   given decl, and (in the case where the decl is a FUNCTION_DECL) also
-   set the abstract flags for all of the parameters, local vars, local
-   blocks and sub-blocks (recursively) to the same setting.  */
+/* Given a pointer to some ..._DECL node, set DECL_ABSTRACT_P flag on it
+   to 1 and if it wasn't 1 before, push to abstract_vec vector.
+   In the case where the decl is a FUNCTION_DECL also set the abstract
+   flags for all of the parameters, local vars, local
+   blocks and sub-blocks (recursively).  */
 
 static void
-set_decl_abstract_flags (tree decl, int setting)
+set_decl_abstract_flags (tree decl, vec<tree> &abstract_vec)
 {
-  DECL_ABSTRACT_P (decl) = setting;
+  if (!DECL_ABSTRACT_P (decl))
+    {
+      abstract_vec.safe_push (decl);
+      DECL_ABSTRACT_P (decl) = 1;
+    }
+
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
       tree arg;
 
       for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
-       DECL_ABSTRACT_P (arg) = setting;
+       if (!DECL_ABSTRACT_P (arg))
+         {
+           abstract_vec.safe_push (arg);
+           DECL_ABSTRACT_P (arg) = 1;
+         }
       if (DECL_INITIAL (decl) != NULL_TREE
          && DECL_INITIAL (decl) != error_mark_node)
-       set_block_abstract_flags (DECL_INITIAL (decl), setting);
+       set_block_abstract_flags (DECL_INITIAL (decl), abstract_vec);
     }
 }
 
@@ -18177,7 +18220,6 @@ dwarf2out_abstract_function (tree decl)
   dw_die_ref old_die;
   tree save_fn;
   tree context;
-  int was_abstract;
   hash_table<decl_loc_hasher> *old_decl_loc_table;
   hash_table<dw_loc_list_hasher> *old_cached_dw_loc_list_table;
   int old_call_site_count, old_tail_call_site_count;
@@ -18219,11 +18261,16 @@ dwarf2out_abstract_function (tree decl)
   save_fn = current_function_decl;
   current_function_decl = decl;
 
-  was_abstract = DECL_ABSTRACT_P (decl);
-  set_decl_abstract_flags (decl, 1);
+  auto_vec<tree, 64> abstract_vec;
+  set_decl_abstract_flags (decl, abstract_vec);
   dwarf2out_decl (decl);
-  if (! was_abstract)
-    set_decl_abstract_flags (decl, 0);
+  unsigned int i;
+  tree t;
+  FOR_EACH_VEC_ELT (abstract_vec, i, t)
+    if (TREE_CODE (t) == BLOCK)
+      BLOCK_ABSTRACT (t) = 0;
+    else
+      DECL_ABSTRACT_P (t) = 0;
 
   current_function_decl = save_fn;
   decl_loc_table = old_decl_loc_table;
@@ -18317,8 +18364,7 @@ gen_call_site_die (tree decl, dw_die_ref subr_die,
         && block != DECL_INITIAL (decl)
         && TREE_CODE (block) == BLOCK)
     {
-      if (block_map.length () > BLOCK_NUMBER (block))
-       stmt_die = block_map[BLOCK_NUMBER (block)];
+      stmt_die = BLOCK_DIE (block);
       if (stmt_die)
        break;
       block = BLOCK_SUPERCONTEXT (block);
@@ -19418,11 +19464,7 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die)
   dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
 
   if (call_arg_locations)
-    {
-      if (block_map.length () <= BLOCK_NUMBER (stmt))
-       block_map.safe_grow_cleared (BLOCK_NUMBER (stmt) + 1);
-      block_map[BLOCK_NUMBER (stmt)] = stmt_die;
-    }
+    BLOCK_DIE (stmt) = stmt_die;
 
   if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
     add_high_low_attributes (stmt, stmt_die);
@@ -19455,11 +19497,7 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die)
        = new_die (DW_TAG_inlined_subroutine, context_die, stmt);
 
       if (call_arg_locations)
-       {
-         if (block_map.length () <= BLOCK_NUMBER (stmt))
-           block_map.safe_grow_cleared (BLOCK_NUMBER (stmt) + 1);
-         block_map[BLOCK_NUMBER (stmt)] = subr_die;
-       }
+       BLOCK_DIE (stmt) = subr_die;
       add_abstract_origin_attribute (subr_die, decl);
       if (TREE_ASM_WRITTEN (stmt))
         add_high_low_attributes (stmt, subr_die);
@@ -19610,6 +19648,9 @@ gen_producer_string (void)
       case OPT__sysroot_:
       case OPT_nostdinc:
       case OPT_nostdinc__:
+      case OPT_fpreprocessed:
+      case OPT_fltrans_output_list_:
+      case OPT_fresolution_:
        /* Ignore these.  */
        continue;
       default:
@@ -19766,8 +19807,17 @@ gen_compile_unit_die (const char *filename)
     {
       if (strcmp (language_string, "GNU Ada") == 0)
        language = DW_LANG_Ada95;
-      else if (strcmp (language_string, "GNU Fortran") == 0)
-       language = DW_LANG_Fortran95;
+      else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+       {
+         language = DW_LANG_Fortran95;
+         if (dwarf_version >= 5 /* || !dwarf_strict */)
+           {
+             if (strcmp (language_string, "GNU Fortran2003") == 0)
+               language = DW_LANG_Fortran03;
+             else if (strcmp (language_string, "GNU Fortran2008") == 0)
+               language = DW_LANG_Fortran08;
+           }
+       }
       else if (strcmp (language_string, "GNU Java") == 0)
        language = DW_LANG_Java;
       else if (strcmp (language_string, "GNU Objective-C") == 0)
@@ -19781,7 +19831,7 @@ gen_compile_unit_die (const char *filename)
        }
     }
   /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
-  else if (strcmp (language_string, "GNU Fortran") == 0)
+  else if (strncmp (language_string, "GNU Fortran", 11) == 0)
     language = DW_LANG_Fortran90;
 
   add_AT_unsigned (die, DW_AT_language, language);
@@ -19791,6 +19841,8 @@ gen_compile_unit_die (const char *filename)
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
     case DW_LANG_Fortran95:
+    case DW_LANG_Fortran03:
+    case DW_LANG_Fortran08:
       /* Fortran has case insensitive identifiers and the front-end
         lowercases everything.  */
       add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case);
@@ -19880,19 +19932,26 @@ gen_member_die (tree type, dw_die_ref context_die)
        gen_decl_die (member, NULL, context_die);
     }
 
+  /* We do not keep type methods in type variants.  */
+  gcc_assert (TYPE_MAIN_VARIANT (type) == type);
   /* Now output info about the function members (if any).  */
-  for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member))
-    {
-      /* Don't include clones in the member list.  */
-      if (DECL_ABSTRACT_ORIGIN (member))
-       continue;
+  if (TYPE_METHODS (type) != error_mark_node)
+    for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member))
+      {
+       /* Don't include clones in the member list.  */
+       if (DECL_ABSTRACT_ORIGIN (member))
+         continue;
+       /* Nor constructors for anonymous classes.  */
+       if (DECL_ARTIFICIAL (member)
+           && dwarf2_name (member, 0) == NULL)
+         continue;
 
-      child = lookup_decl_die (member);
-      if (child)
-       splice_child_die (context_die, child);
-      else
-       gen_decl_die (member, NULL, context_die);
-    }
+       child = lookup_decl_die (member);
+       if (child)
+         splice_child_die (context_die, child);
+       else
+         gen_decl_die (member, NULL, context_die);
+      }
 }
 
 /* Generate a DIE for a structure or union type.  If TYPE_DECL_SUPPRESS_DEBUG
@@ -20173,6 +20232,11 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
   if (type == NULL_TREE || type == error_mark_node)
     return;
 
+#ifdef ENABLE_CHECKING
+  if (type)
+     verify_type (type);
+#endif
+
   if (TYPE_NAME (type) != NULL_TREE
       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
       && is_redundant_typedef (TYPE_NAME (type))
@@ -20557,6 +20621,28 @@ is_naming_typedef_decl (const_tree decl)
              != TYPE_NAME (TREE_TYPE (decl))));
 }
 
+/* Looks up the DIE for a context.  */
+
+static inline dw_die_ref
+lookup_context_die (tree context)
+{
+  if (context)
+    {
+      /* Find die that represents this context.  */
+      if (TYPE_P (context))
+       {
+         context = TYPE_MAIN_VARIANT (context);
+         dw_die_ref ctx = lookup_type_die (context);
+         if (!ctx)
+           return NULL;
+         return strip_naming_typedef (context, ctx);
+       }
+      else
+       return lookup_decl_die (context);
+    }
+  return comp_unit_die ();
+}
+
 /* Returns the DIE for a context.  */
 
 static inline dw_die_ref
@@ -21330,7 +21416,6 @@ dwarf2out_function_decl (tree decl)
   call_arg_loc_last = NULL;
   call_site_count = -1;
   tail_call_site_count = -1;
-  block_map.release ();
   decl_loc_table->empty ();
   cached_dw_loc_list_table->empty ();
 }
@@ -22164,21 +22249,21 @@ dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
 
 struct macinfo_entry_hasher : typed_noop_remove <macinfo_entry>
 {
-  typedef macinfo_entry value_type;
-  typedef macinfo_entry compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  typedef macinfo_entry *value_type;
+  typedef macinfo_entry *compare_type;
+  static inline hashval_t hash (const macinfo_entry *);
+  static inline bool equal (const macinfo_entry *, const macinfo_entry *);
 };
 
 inline hashval_t
-macinfo_entry_hasher::hash (const value_type *entry)
+macinfo_entry_hasher::hash (const macinfo_entry *entry)
 {
   return htab_hash_string (entry->info);
 }
 
 inline bool
-macinfo_entry_hasher::equal (const value_type *entry1,
-                            const compare_type *entry2)
+macinfo_entry_hasher::equal (const macinfo_entry *entry1,
+                            const macinfo_entry *entry2)
 {
   return !strcmp (entry1->info, entry2->info);
 }
@@ -22561,6 +22646,14 @@ output_macinfo (void)
 static void
 dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
 {
+  /* This option is currently broken, see (PR53118 and PR46102).  */
+  if (flag_eliminate_dwarf2_dups
+      && strstr (lang_hooks.name, "C++"))
+    {
+      warning (0, "-feliminate-dwarf2-dups is broken for C++, ignoring");
+      flag_eliminate_dwarf2_dups = 0;
+    }
+
   /* Allocate the file_table.  */
   file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
 
@@ -23234,14 +23327,14 @@ file_table_relative_p (dwarf_file_data **slot, bool *p)
 
 struct comdat_type_hasher : typed_noop_remove <comdat_type_node>
 {
-  typedef comdat_type_node value_type;
-  typedef comdat_type_node compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  typedef comdat_type_node *value_type;
+  typedef comdat_type_node *compare_type;
+  static inline hashval_t hash (const comdat_type_node *);
+  static inline bool equal (const comdat_type_node *, const comdat_type_node *);
 };
 
 inline hashval_t
-comdat_type_hasher::hash (const value_type *type_node)
+comdat_type_hasher::hash (const comdat_type_node *type_node)
 {
   hashval_t h;
   memcpy (&h, type_node->signature, sizeof (h));
@@ -23249,8 +23342,8 @@ comdat_type_hasher::hash (const value_type *type_node)
 }
 
 inline bool
-comdat_type_hasher::equal (const value_type *type_node_1,
-                          const compare_type *type_node_2)
+comdat_type_hasher::equal (const comdat_type_node *type_node_1,
+                          const comdat_type_node *type_node_2)
 {
   return (! memcmp (type_node_1->signature, type_node_2->signature,
                     DWARF_TYPE_SIGNATURE_SIZE));
@@ -23878,12 +23971,22 @@ resolve_addr (dw_die_ref die)
          {
            tree tdecl = SYMBOL_REF_DECL (a->dw_attr_val.v.val_addr);
            dw_die_ref tdie = lookup_decl_die (tdecl);
+           dw_die_ref cdie;
            if (tdie == NULL
                && DECL_EXTERNAL (tdecl)
-               && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE)
+               && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE
+               && (cdie = lookup_context_die (DECL_CONTEXT (tdecl))))
              {
-               force_decl_die (tdecl);
-               tdie = lookup_decl_die (tdecl);
+               /* Creating a full DIE for tdecl is overly expensive and
+                  at this point even wrong when in the LTO phase
+                  as it can end up generating new type DIEs we didn't
+                  output and thus optimize_external_refs will crash.  */
+               tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE);
+               add_AT_flag (tdie, DW_AT_external, 1);
+               add_AT_flag (tdie, DW_AT_declaration, 1);
+               add_linkage_attr (tdie, tdecl);
+               add_name_and_src_coords_attributes (tdie, tdecl);
+               equate_decl_number_to_die (tdecl, tdie);
              }
            if (tdie)
              {
@@ -24007,7 +24110,9 @@ hash_loc_operands (dw_loc_descr_ref loc, inchash::hash &hstate)
          hstate.add_object (val2->v.val_double.high);
          break;
        case dw_val_class_wide_int:
-         hstate.add_object (*val2->v.val_wide);
+         hstate.add (val2->v.val_wide->get_val (),
+                     get_full_len (*val2->v.val_wide)
+                     * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
          break;
        case dw_val_class_addr: 
          inchash::add_rtx (val2->v.val_addr, hstate);
@@ -24098,7 +24203,9 @@ hash_loc_operands (dw_loc_descr_ref loc, inchash::hash &hstate)
            hstate.add_object (val2->v.val_double.high);
            break;
          case dw_val_class_wide_int:
-           hstate.add_object (*val2->v.val_wide);
+           hstate.add (val2->v.val_wide->get_val (),
+                       get_full_len (*val2->v.val_wide)
+                       * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
            break;
          default:
            gcc_unreachable ();
@@ -24333,16 +24440,17 @@ compare_locs (dw_loc_descr_ref x, dw_loc_descr_ref y)
 
 struct loc_list_hasher : typed_noop_remove <dw_loc_list_struct>
 {
-  typedef dw_loc_list_struct value_type;
-  typedef dw_loc_list_struct compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  typedef dw_loc_list_struct *value_type;
+  typedef dw_loc_list_struct *compare_type;
+  static inline hashval_t hash (const dw_loc_list_struct *);
+  static inline bool equal (const dw_loc_list_struct *,
+                           const dw_loc_list_struct *);
 };
 
 /* Return precomputed hash of location list X.  */
 
 inline hashval_t
-loc_list_hasher::hash (const value_type *x)
+loc_list_hasher::hash (const dw_loc_list_struct *x)
 {
   return x->hash;
 }
@@ -24350,7 +24458,8 @@ loc_list_hasher::hash (const value_type *x)
 /* Return true if location lists A and B are the same.  */
 
 inline bool
-loc_list_hasher::equal (const value_type *a, const compare_type *b)
+loc_list_hasher::equal (const dw_loc_list_struct *a,
+                       const dw_loc_list_struct *b)
 {
   if (a == b)
     return 1;
@@ -24463,8 +24572,13 @@ dwarf2out_finish (const char *filename)
   gen_remaining_tmpl_value_param_die_attribute ();
 
   /* Add the name for the main input file now.  We delayed this from
-     dwarf2out_init to avoid complications with PCH.  */
-  add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+     dwarf2out_init to avoid complications with PCH.
+     For LTO produced units use a fixed artificial name to avoid
+     leaking tempfile names into the dwarf.  */
+  if (!in_lto_p)
+    add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+  else
+    add_name_attribute (comp_unit_die (), "<artificial>");
   if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
     add_comp_dir_attribute (comp_unit_die ());
   else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
@@ -24912,7 +25026,6 @@ dwarf2out_c_finalize (void)
   call_arg_loc_last = NULL;
   call_site_count = -1;
   tail_call_site_count = -1;
-  //block_map = NULL;
   cached_dw_loc_list_table = NULL;
   abbrev_die_table = NULL;
   abbrev_die_table_allocated = 0;