]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/dwarf2out.c
dwarf2out: Emit DW_AT_location for global register vars during early dwarf [PR101905]
[gcc.git] / gcc / dwarf2out.c
index 17be26fb97d036e31ad4ad797caed3d30a651dce..ecf01120381394f3c848077442702ee7b18f51d0 100644 (file)
@@ -1,5 +1,5 @@
 /* Output Dwarf2 format symbol table information from GCC.
-   Copyright (C) 1992-2019 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 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).
@@ -399,6 +399,9 @@ get_full_len (const wide_int &op)
 static bool
 should_emit_struct_debug (tree type, enum debug_info_usage usage)
 {
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return false;
+
   enum debug_struct_file criterion;
   tree type_decl;
   bool generic = lang_hooks.types.generic_p (type);
@@ -1115,7 +1118,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
         function anymore.  */
       if (personality && current_unit_personality != personality)
        sorry ("multiple EH personalities are supported only with assemblers "
-              "supporting .cfi_personality directive");
+              "supporting %<.cfi_personality%> directive");
     }
 }
 
@@ -1476,7 +1479,7 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b)
 
     case dw_val_class_vms_delta:
       return (!strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1)
-              && !strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1));
+             && !strcmp (a->v.val_vms_delta.lbl2, b->v.val_vms_delta.lbl2));
 
     case dw_val_class_discr_value:
       return (a->v.val_discr_value.pos == b->v.val_discr_value.pos
@@ -3104,7 +3107,8 @@ die_node;
 /* Set to TRUE while dwarf2out_early_global_decl is running.  */
 static bool early_dwarf;
 static bool early_dwarf_finished;
-struct set_early_dwarf {
+class set_early_dwarf {
+public:
   bool saved;
   set_early_dwarf () : saved(early_dwarf)
     {
@@ -3808,7 +3812,7 @@ 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_wide_int (const wide_int &, unsigned char *, int);
-static void insert_float (const_rtx, unsigned char *);
+static unsigned 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, bool);
 static bool tree_add_const_value_attribute (dw_die_ref, tree);
@@ -3907,6 +3911,8 @@ static void prune_unused_types (void);
 static int maybe_emit_file (struct dwarf_file_data *fd);
 static inline const char *AT_vms_delta1 (dw_attr_node *);
 static inline const char *AT_vms_delta2 (dw_attr_node *);
+static inline void add_AT_vms_delta (dw_die_ref, enum dwarf_attribute,
+                                    const char *, const char *);
 static void append_entry_to_tmpl_value_parm_die_table (dw_die_ref, tree);
 static void gen_remaining_tmpl_value_param_die_attribute (void);
 static bool generic_type_p (tree);
@@ -5142,6 +5148,22 @@ AT_file (dw_attr_node *a)
   return a->dw_attr_val.v.val_file;
 }
 
+/* Add a vms delta attribute value to a DIE.  */
+
+static inline void
+add_AT_vms_delta (dw_die_ref die, enum dwarf_attribute attr_kind,
+                 const char *lbl1, const char *lbl2)
+{
+  dw_attr_node attr;
+
+  attr.dw_attr = attr_kind;
+  attr.dw_attr_val.val_class = dw_val_class_vms_delta;
+  attr.dw_attr_val.val_entry = NULL;
+  attr.dw_attr_val.v.val_vms_delta.lbl1 = xstrdup (lbl1);
+  attr.dw_attr_val.v.val_vms_delta.lbl2 = xstrdup (lbl2);
+  add_dwarf_attr (die, &attr);
+}
+
 /* Add a symbolic view identifier attribute value to a DIE.  */
 
 static inline void
@@ -8558,11 +8580,12 @@ break_out_comdat_types (dw_die_ref die)
         /* Break out nested types into their own type units.  */
         break_out_comdat_types (c);
 
-        /* Create a new type unit DIE as the root for the new tree, and
-           add it to the list of comdat types.  */
+        /* Create a new type unit DIE as the root for the new tree.  */
         unit = new_die (DW_TAG_type_unit, NULL, NULL);
         add_AT_unsigned (unit, DW_AT_language,
                          get_AT_unsigned (comp_unit_die (), DW_AT_language));
+
+       /* Add the new unit's type DIE into the comdat type list.  */
         type_node = ggc_cleared_alloc<comdat_type_node> ();
         type_node->root_die = unit;
         type_node->next = comdat_type_list;
@@ -9351,7 +9374,6 @@ size_of_die (dw_die_ref die)
          }
          break;
        case dw_val_class_loc_list:
-       case dw_val_class_view_list:
          if (dwarf_split_debug_info && dwarf_version >= 5)
            {
              gcc_assert (AT_loc_list (a)->num_assigned);
@@ -9360,6 +9382,9 @@ size_of_die (dw_die_ref die)
           else
             size += DWARF_OFFSET_SIZE;
          break;
+       case dw_val_class_view_list:
+         size += DWARF_OFFSET_SIZE;
+         break;
        case dw_val_class_range_list:
          if (value_format (a) == DW_FORM_rnglistx)
            {
@@ -9733,12 +9758,12 @@ value_format (dw_attr_node *a)
          gcc_unreachable ();
        }
     case dw_val_class_loc_list:
-    case dw_val_class_view_list:
       if (dwarf_split_debug_info
          && dwarf_version >= 5
          && AT_loc_list (a)->num_assigned)
        return DW_FORM_loclistx;
       /* FALLTHRU */
+    case dw_val_class_view_list:
     case dw_val_class_range_list:
       /* For range lists in DWARF 5, use DW_FORM_rnglistx from .debug_info.dwo
         but in .debug_info use DW_FORM_sec_offset, which is shorter if we
@@ -10964,8 +10989,8 @@ output_dwarf_version ()
       static bool once;
       if (!once)
        {
-         warning (0,
-                  "-gdwarf-6 is output as version 5 with incompatibilities");
+         warning (0, "%<-gdwarf-6%> is output as version 5 with "
+                  "incompatibilities");
          once = true;
        }
       dw2_asm_output_data (2, 5, "DWARF version number");
@@ -11175,7 +11200,8 @@ add_top_level_skeleton_die_attrs (dw_die_ref die)
   if (comp_dir != NULL)
     add_skeleton_AT_string (die, DW_AT_comp_dir, comp_dir);
   add_AT_pubnames (die);
-  add_AT_lineptr (die, dwarf_AT (DW_AT_addr_base), debug_addr_section_label);
+  if (addr_index_table != NULL && addr_index_table->size () > 0)
+    add_AT_lineptr (die, dwarf_AT (DW_AT_addr_base), debug_addr_section_label);
 }
 
 /* Output skeleton debug sections that point to the dwo file.  */
@@ -11234,7 +11260,8 @@ output_skeleton_debug_sections (dw_die_ref comp_unit,
 /* Output a comdat type unit DIE and its children.  */
 
 static void
-output_comdat_type_unit (comdat_type_node *node, bool early_lto_debug)
+output_comdat_type_unit (comdat_type_node *node,
+                        bool early_lto_debug ATTRIBUTE_UNUSED)
 {
   const char *secname;
   char *tmp;
@@ -12077,8 +12104,9 @@ file_name_acquire (dwarf_file_data **slot, file_name_acquire_data *fnad)
 
   fi = fnad->files + fnad->used_files++;
 
+  f = remap_debug_filename (d->filename);
+
   /* Skip all leading "./".  */
-  f = d->filename;
   while (f[0] == '.' && IS_DIR_SEPARATOR (f[1]))
     f += 2;
 
@@ -13582,6 +13610,13 @@ generic_parameter_die (tree parm, tree arg,
   dw_die_ref tmpl_die = NULL;
   const char *name = NULL;
 
+  /* C++2a accepts class literals as template parameters, and var
+     decls with initializers represent them.  The VAR_DECLs would be
+     rejected, but we can take the DECL_INITIAL constructor and
+     attempt to expand it.  */
+  if (arg && VAR_P (arg))
+    arg = DECL_INITIAL (arg);
+
   if (!parm || !DECL_NAME (parm) || !arg)
     return NULL;
 
@@ -14481,11 +14516,10 @@ const_ok_for_output_1 (rtx rtl)
                "non-delegitimized UNSPEC %s (%d) found in variable location",
                ((XINT (rtl, 1) >= 0 && XINT (rtl, 1) < NUM_UNSPEC_VALUES)
                 ? unspec_strings[XINT (rtl, 1)] : "unknown"),
-               XINT (rtl, 1));
 #else
                "non-delegitimized UNSPEC %d found in variable location",
-               XINT (rtl, 1));
 #endif
+               XINT (rtl, 1));
       expansion_failed (NULL_TREE, rtl,
                        "UNSPEC hasn't been delegitimized.\n");
       return false;
@@ -15433,7 +15467,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
   if (mode != GET_MODE (rtl) && GET_MODE (rtl) != VOIDmode)
     return NULL;
 
-  scalar_int_mode int_mode, inner_mode, op1_mode;
+  scalar_int_mode int_mode = BImode, inner_mode, op1_mode;
   switch (GET_CODE (rtl))
     {
     case POST_INC:
@@ -16130,11 +16164,12 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
              scalar_float_mode float_mode = as_a <scalar_float_mode> (mode);
              unsigned int length = GET_MODE_SIZE (float_mode);
              unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+             unsigned int elt_size = insert_float (rtl, array);
 
-             insert_float (rtl, array);
              mem_loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
-             mem_loc_result->dw_loc_oprnd2.v.val_vec.length = length / 4;
-             mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4;
+             mem_loc_result->dw_loc_oprnd2.v.val_vec.length
+               = length / elt_size;
+             mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
              mem_loc_result->dw_loc_oprnd2.v.val_vec.array = array;
            }
        }
@@ -16400,7 +16435,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
     case CONST_FIXED:
     case CLRSB:
     case CLOBBER:
-    case CLOBBER_HIGH:
       break;
 
     case CONST_STRING:
@@ -16705,11 +16739,11 @@ loc_descriptor (rtx rtl, machine_mode mode,
            {
              unsigned int length = GET_MODE_SIZE (smode);
              unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+             unsigned int elt_size = insert_float (rtl, array);
 
-             insert_float (rtl, array);
              loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
-             loc_result->dw_loc_oprnd2.v.val_vec.length = length / 4;
-             loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4;
+             loc_result->dw_loc_oprnd2.v.val_vec.length = length / elt_size;
+             loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
              loc_result->dw_loc_oprnd2.v.val_vec.array = array;
            }
        }
@@ -16734,7 +16768,12 @@ loc_descriptor (rtx rtl, machine_mode mode,
       if (mode == VOIDmode)
        mode = GET_MODE (rtl);
 
-      if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
+      if (mode != VOIDmode
+         /* The combination of a length and byte elt_size doesn't extend
+            naturally to boolean vectors, where several elements are packed
+            into the same byte.  */
+         && GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL
+         && (dwarf_version >= 4 || !dwarf_strict))
        {
          unsigned int length;
          if (!CONST_VECTOR_NUNITS (rtl).is_constant (&length))
@@ -17878,6 +17917,8 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
        case DW_OP_push_object_address:
        case DW_OP_call_frame_cfa:
        case DW_OP_GNU_variable_value:
+       case DW_OP_GNU_addr_index:
+       case DW_OP_GNU_const_index:
          ++frame_offset_;
          break;
 
@@ -18536,6 +18577,24 @@ loc_list_from_tree_1 (tree loc, int want_address,
        }
       break;
 
+    case POLY_INT_CST:
+      {
+       if (want_address)
+         {
+           expansion_failed (loc, NULL_RTX,
+                             "constant address with a runtime component");
+           return 0;
+         }
+       poly_int64 value;
+       if (!poly_int_tree_p (loc, &value))
+         {
+           expansion_failed (loc, NULL_RTX, "constant too big");
+           return 0;
+         }
+       ret = int_loc_descriptor (value);
+      }
+      break;
+
     case CONSTRUCTOR:
     case REAL_CST:
     case STRING_CST:
@@ -18869,6 +18928,10 @@ loc_list_from_tree_1 (tree loc, int want_address,
     case FIX_TRUNC_EXPR:
       return 0;
 
+    case COMPOUND_LITERAL_EXPR:
+      return loc_list_from_tree_1 (COMPOUND_LITERAL_EXPR_DECL (loc),
+                                  0, context);
+
     default:
       /* Leave front-end specific codes as simply unknown.  This comes
         up, for instance, with the C STMT_EXPR.  */
@@ -19497,7 +19560,7 @@ insert_wide_int (const wide_int &val, unsigned char *dest, int elt_size)
 
 /* Writes floating point values to dw_vec_const array.  */
 
-static void
+static unsigned
 insert_float (const_rtx rtl, unsigned char *array)
 {
   long val[4];
@@ -19507,11 +19570,19 @@ insert_float (const_rtx rtl, unsigned char *array)
   real_to_target (val, CONST_DOUBLE_REAL_VALUE (rtl), mode);
 
   /* real_to_target puts 32-bit pieces in each long.  Pack them.  */
+  if (GET_MODE_SIZE (mode) < 4)
+    {
+      gcc_assert (GET_MODE_SIZE (mode) == 2);
+      insert_int (val[0], 2, array);
+      return 2;
+    }
+
   for (i = 0; i < GET_MODE_SIZE (mode) / 4; i++)
     {
       insert_int (val[i], 4, array);
       array += 4;
     }
+  return 4;
 }
 
 /* Attach a DW_AT_const_value attribute for a variable or a parameter which
@@ -19560,9 +19631,10 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
          scalar_float_mode mode = as_a <scalar_float_mode> (GET_MODE (rtl));
          unsigned int length = GET_MODE_SIZE (mode);
          unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+         unsigned int elt_size = insert_float (rtl, array);
 
-         insert_float (rtl, array);
-         add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
+         add_AT_vec (die, DW_AT_const_value, length / elt_size, elt_size,
+                     array);
        }
       return true;
 
@@ -19573,6 +19645,12 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
          return false;
 
        machine_mode mode = GET_MODE (rtl);
+       /* The combination of a length and byte elt_size doesn't extend
+          naturally to boolean vectors, where several elements are packed
+          into the same byte.  */
+       if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
+         return false;
+
        unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
        unsigned char *array
          = ggc_vec_alloc<unsigned char> (length * elt_size);
@@ -19649,6 +19727,10 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
 
     case HIGH:
     case CONST_FIXED:
+    case MINUS:
+    case SIGN_EXTEND:
+    case ZERO_EXTEND:
+    case CONST_POLY_INT:
       return false;
 
     case MEM:
@@ -19684,7 +19766,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
   /* ???  The C++ FE emits debug information for using decls, so
      putting gcc_unreachable here falls over.  See PR31899.  For now
      be conservative.  */
-  else if (!symtab->global_info_ready && VAR_OR_FUNCTION_DECL_P (*tp))
+  else if (!symtab->global_info_ready && VAR_P (*tp))
     return *tp;
   else if (VAR_P (*tp))
     {
@@ -19699,7 +19781,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
          optimizing and gimplifying the CU by now.
         So if *TP has no call graph node associated
         to it, it means *TP will not be emitted.  */
-      if (!cgraph_node::get (*tp))
+      if (!symtab->global_info_ready || !cgraph_node::get (*tp))
        return *tp;
     }
   else if (TREE_CODE (*tp) == STRING_CST && !TREE_ASM_WRITTEN (*tp))
@@ -20194,150 +20276,6 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p)
   return tree_add_const_value_attribute_for_decl (die, decl);
 }
 
-/* Helper function for tree_add_const_value_attribute.  Natively encode
-   initializer INIT into an array.  Return true if successful.  */
-
-static bool
-native_encode_initializer (tree init, unsigned char *array, int size)
-{
-  tree type;
-
-  if (init == NULL_TREE)
-    return false;
-
-  STRIP_NOPS (init);
-  switch (TREE_CODE (init))
-    {
-    case STRING_CST:
-      type = TREE_TYPE (init);
-      if (TREE_CODE (type) == ARRAY_TYPE)
-       {
-         tree enttype = TREE_TYPE (type);
-         scalar_int_mode mode;
-
-         if (!is_int_mode (TYPE_MODE (enttype), &mode)
-             || GET_MODE_SIZE (mode) != 1)
-           return false;
-         if (int_size_in_bytes (type) != size)
-           return false;
-         if (size > TREE_STRING_LENGTH (init))
-           {
-             memcpy (array, TREE_STRING_POINTER (init),
-                     TREE_STRING_LENGTH (init));
-             memset (array + TREE_STRING_LENGTH (init),
-                     '\0', size - TREE_STRING_LENGTH (init));
-           }
-         else
-           memcpy (array, TREE_STRING_POINTER (init), size);
-         return true;
-       }
-      return false;
-    case CONSTRUCTOR:
-      type = TREE_TYPE (init);
-      if (int_size_in_bytes (type) != size)
-       return false;
-      if (TREE_CODE (type) == ARRAY_TYPE)
-       {
-         HOST_WIDE_INT min_index;
-         unsigned HOST_WIDE_INT cnt;
-         int curpos = 0, fieldsize;
-         constructor_elt *ce;
-
-         if (TYPE_DOMAIN (type) == NULL_TREE
-             || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
-           return false;
-
-         fieldsize = int_size_in_bytes (TREE_TYPE (type));
-         if (fieldsize <= 0)
-           return false;
-
-         min_index = tree_to_shwi (TYPE_MIN_VALUE (TYPE_DOMAIN (type)));
-         memset (array, '\0', size);
-         FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce)
-           {
-             tree val = ce->value;
-             tree index = ce->index;
-             int pos = curpos;
-             if (index && TREE_CODE (index) == RANGE_EXPR)
-               pos = (tree_to_shwi (TREE_OPERAND (index, 0)) - min_index)
-                     * fieldsize;
-             else if (index)
-               pos = (tree_to_shwi (index) - min_index) * fieldsize;
-
-             if (val)
-               {
-                 STRIP_NOPS (val);
-                 if (!native_encode_initializer (val, array + pos, fieldsize))
-                   return false;
-               }
-             curpos = pos + fieldsize;
-             if (index && TREE_CODE (index) == RANGE_EXPR)
-               {
-                 int count = tree_to_shwi (TREE_OPERAND (index, 1))
-                             - tree_to_shwi (TREE_OPERAND (index, 0));
-                 while (count-- > 0)
-                   {
-                     if (val)
-                       memcpy (array + curpos, array + pos, fieldsize);
-                     curpos += fieldsize;
-                   }
-               }
-             gcc_assert (curpos <= size);
-           }
-         return true;
-       }
-      else if (TREE_CODE (type) == RECORD_TYPE
-              || TREE_CODE (type) == UNION_TYPE)
-       {
-         tree field = NULL_TREE;
-         unsigned HOST_WIDE_INT cnt;
-         constructor_elt *ce;
-
-         if (int_size_in_bytes (type) != size)
-           return false;
-
-         if (TREE_CODE (type) == RECORD_TYPE)
-           field = TYPE_FIELDS (type);
-
-         FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce)
-           {
-             tree val = ce->value;
-             int pos, fieldsize;
-
-             if (ce->index != 0)
-               field = ce->index;
-
-             if (val)
-               STRIP_NOPS (val);
-
-             if (field == NULL_TREE || DECL_BIT_FIELD (field))
-               return false;
-
-             if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
-                 && TYPE_DOMAIN (TREE_TYPE (field))
-                 && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
-               return false;
-             else if (DECL_SIZE_UNIT (field) == NULL_TREE
-                      || !tree_fits_shwi_p (DECL_SIZE_UNIT (field)))
-               return false;
-             fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field));
-             pos = int_byte_position (field);
-             gcc_assert (pos + fieldsize <= size);
-             if (val && fieldsize != 0
-                 && !native_encode_initializer (val, array + pos, fieldsize))
-               return false;
-           }
-         return true;
-       }
-      return false;
-    case VIEW_CONVERT_EXPR:
-    case NON_LVALUE_EXPR:
-      return native_encode_initializer (TREE_OPERAND (init, 0), array, size);
-    default:
-      return native_encode_expr (init, array, size) == size;
-    }
-}
-
 /* Attach a DW_AT_const_value attribute to DIE. The value of the
    attribute is the const value T.  */
 
@@ -20367,12 +20305,11 @@ tree_add_const_value_attribute (dw_die_ref die, tree t)
          return true;
        }
     }
-  if (! early_dwarf)
-    {
-      rtl = rtl_for_decl_init (init, type);
-      if (rtl)
-       return add_const_value_attribute (die, rtl);
-    }
+  /* Generate the RTL even if early_dwarf to force mangling of all refered to
+     symbols.  */
+  rtl = rtl_for_decl_init (init, type);
+  if (rtl && !early_dwarf)
+    return add_const_value_attribute (die, rtl);
   /* If the host and target are sane, try harder.  */
   if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
       && initializer_constant_valid_p (init, type))
@@ -20382,7 +20319,7 @@ tree_add_const_value_attribute (dw_die_ref die, tree t)
        {
          unsigned char *array = ggc_cleared_vec_alloc<unsigned char> (size);
 
-         if (native_encode_initializer (init, array, size))
+         if (native_encode_initializer (init, array, size) == size)
            {
              add_AT_vec (die, DW_AT_const_value, size, 1, array);
              return true;
@@ -20671,7 +20608,7 @@ static const char *
 comp_dir_string (void)
 {
   const char *wd;
-  char *wd1;
+  char *wd_plus_sep = NULL;
   static const char *cached_wd = NULL;
 
   if (cached_wd != NULL)
@@ -20683,17 +20620,26 @@ comp_dir_string (void)
 
   if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR)
     {
-      int wdlen;
-
-      wdlen = strlen (wd);
-      wd1 = ggc_vec_alloc<char> (wdlen + 2);
-      strcpy (wd1, wd);
-      wd1 [wdlen] = DIR_SEPARATOR;
-      wd1 [wdlen + 1] = 0;
-      wd = wd1;
+      size_t wdlen = strlen (wd);
+      wd_plus_sep = XNEWVEC (char, wdlen + 2);
+      strcpy (wd_plus_sep, wd);
+      wd_plus_sep [wdlen] = DIR_SEPARATOR;
+      wd_plus_sep [wdlen + 1] = 0;
+      wd = wd_plus_sep;
     }
 
   cached_wd = remap_debug_filename (wd);
+
+  /* remap_debug_filename can just pass through wd or return a new gc string.
+     These two types can't be both stored in a GTY(())-tagged string, but since
+     the cached value lives forever just copy it if needed.  */
+  if (cached_wd != wd)
+    {
+      cached_wd = xstrdup (cached_wd);
+      if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR && wd_plus_sep != NULL)
+        free (wd_plus_sep);
+    }
+
   return cached_wd;
 }
 
@@ -20763,12 +20709,23 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
          else
            add_AT_int (die, attr, TREE_INT_CST_LOW (value));
        }
-      else
+      else if (dwarf_version >= 5
+              && TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (value))) == 128)
        /* Otherwise represent the bound as an unsigned value with
           the precision of its type.  The precision and signedness
           of the type will be necessary to re-interpret it
           unambiguously.  */
        add_AT_wide (die, attr, wi::to_wide (value));
+      else
+       {
+         rtx v = immed_wide_int_const (wi::to_wide (value),
+                                       TYPE_MODE (TREE_TYPE (value)));
+         dw_loc_descr_ref loc
+           = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)),
+                             VAR_INIT_STATUS_INITIALIZED);
+         if (loc)
+           add_AT_loc (die, attr, loc);
+       }
       return;
     }
 
@@ -20803,6 +20760,7 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
          if (decl_die != NULL)
            {
              if (get_AT (decl_die, DW_AT_location)
+                 || get_AT (decl_die, DW_AT_data_member_location)
                  || get_AT (decl_die, DW_AT_const_value))
                {
                  add_AT_die_ref (die, attr, decl_die);
@@ -21632,6 +21590,9 @@ add_type_attribute (dw_die_ref object_die, tree type, int cv_quals,
   enum tree_code code  = TREE_CODE (type);
   dw_die_ref type_die  = NULL;
 
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return;
+
   /* ??? If this type is an unnamed subrange type of an integral, floating-point
      or fixed-point type, use the inner type.  This is because we have no
      support for unnamed types in base_type_die.  This can happen if this is
@@ -21808,8 +21769,8 @@ gen_array_type_die (tree type, dw_die_ref context_die)
 
   /* Emit DW_TAG_string_type for Fortran character types (with kind 1 only, as
      DW_TAG_string_type doesn't have DW_AT_type attribute).  */
-  if (TYPE_STRING_FLAG (type)
-      && TREE_CODE (type) == ARRAY_TYPE
+  if (TREE_CODE (type) == ARRAY_TYPE
+      && TYPE_STRING_FLAG (type)
       && is_fortran ()
       && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (char_type_node))
     {
@@ -22241,19 +22202,18 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
       /* If the contexts differ, we may not be talking about the same
         thing.
         ???  When in LTO the DIE parent is the "abstract" copy and the
-        context_die is the specification "copy".  But this whole block
-        should eventually be no longer needed.  */
-      if (parm_die && parm_die->die_parent != context_die && !in_lto_p)
+        context_die is the specification "copy".  */
+      if (parm_die
+         && parm_die->die_parent != context_die
+         && (parm_die->die_parent->die_tag != DW_TAG_GNU_formal_parameter_pack
+             || parm_die->die_parent->die_parent != context_die)
+         && !in_lto_p)
        {
-         if (!DECL_ABSTRACT_P (node))
-           {
-             /* This can happen when creating an inlined instance, in
-                which case we need to create a new DIE that will get
-                annotated with DW_AT_abstract_origin.  */
-             parm_die = NULL;
-           }
-         else
-           gcc_unreachable ();
+         gcc_assert (!DECL_ABSTRACT_P (node));
+         /* This can happen when creating a concrete instance, in
+            which case we need to create a new DIE that will get
+            annotated with DW_AT_abstract_origin.  */
+         parm_die = NULL;
        }
 
       if (parm_die && parm_die->die_parent == NULL)
@@ -22692,6 +22652,21 @@ premark_types_used_by_global_vars (void)
       ->traverse<void *, premark_types_used_by_global_vars_helper> (NULL);
 }
 
+/* Mark all variables used by the symtab as perennial.  */
+
+static void
+premark_used_variables (void)
+{
+  /* Mark DIEs in the symtab as used.  */
+  varpool_node *var;
+  FOR_EACH_VARIABLE (var)
+    {
+      dw_die_ref die = lookup_decl_die (var->decl);
+      if (die)
+       die->die_perennial_p = 1;
+    }
+}
+
 /* Generate a DW_TAG_call_site DIE in function DECL under SUBR_DIE
    for CA_LOC call arg loc node.  */
 
@@ -22738,6 +22713,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
   tree origin = decl_ultimate_origin (decl);
   dw_die_ref subr_die;
   dw_die_ref old_die = lookup_decl_die (decl);
+  bool old_die_had_no_children = false;
 
   /* This function gets called multiple times for different stages of
      the debug process.  For example, for func() in this code:
@@ -22821,6 +22797,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
           available.
   */
   int declaration = (current_function_decl != decl
+                    || (!DECL_INITIAL (decl) && !origin)
                     || class_or_namespace_scope_p (context_die));
 
   /* A declaration that has been previously dumped needs no
@@ -22828,6 +22805,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
   if (old_die && declaration)
     return;
 
+  if (in_lto_p && old_die && old_die->die_child == NULL)
+    old_die_had_no_children = true;
+
   /* Now that the C++ front end lazily declares artificial member fns, we
      might need to retrofit the declaration into its class.  */
   if (!declaration && !origin && !old_die
@@ -22954,11 +22934,22 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
                  != (unsigned) s.column))
            add_AT_unsigned (subr_die, DW_AT_decl_column, s.column);
 
-         /* If the prototype had an 'auto' or 'decltype(auto)' return type,
-            emit the real type on the definition die.  */
+         /* If the prototype had an 'auto' or 'decltype(auto)' in
+            the return type, emit the real type on the definition die.  */
          if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE)
            {
              dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
+             while (die
+                    && (die->die_tag == DW_TAG_reference_type
+                        || die->die_tag == DW_TAG_rvalue_reference_type
+                        || die->die_tag == DW_TAG_pointer_type
+                        || die->die_tag == DW_TAG_const_type
+                        || die->die_tag == DW_TAG_volatile_type
+                        || die->die_tag == DW_TAG_restrict_type
+                        || die->die_tag == DW_TAG_array_type
+                        || die->die_tag == DW_TAG_ptr_to_member_type
+                        || die->die_tag == DW_TAG_subroutine_type))
+               die = get_AT_ref (die, DW_AT_type);
              if (die == auto_die || die == decltype_auto_die)
                add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
                                    TYPE_UNQUALIFIED, false, context_die);
@@ -23336,6 +23327,10 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
          else if (DECL_INITIAL (decl) == NULL_TREE)
            gen_unspecified_parameters_die (decl, subr_die);
        }
+      else if ((subr_die != old_die || old_die_had_no_children)
+              && prototype_p (TREE_TYPE (decl))
+              && stdarg_p (TREE_TYPE (decl)))
+       gen_unspecified_parameters_die (decl, subr_die);
     }
 
   if (subr_die != old_die)
@@ -23627,6 +23622,34 @@ local_function_static (tree decl)
     && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL;
 }
 
+/* Return true iff DECL overrides (presumably completes) the type of
+   OLD_DIE within CONTEXT_DIE.  */
+
+static bool
+override_type_for_decl_p (tree decl, dw_die_ref old_die,
+                         dw_die_ref context_die)
+{
+  tree type = TREE_TYPE (decl);
+  int cv_quals;
+
+  if (decl_by_reference_p (decl))
+    {
+      type = TREE_TYPE (type);
+      cv_quals = TYPE_UNQUALIFIED;
+    }
+  else
+    cv_quals = decl_quals (decl);
+
+  dw_die_ref type_die = modified_type_die (type,
+                                          cv_quals | TYPE_QUALS (type),
+                                          false,
+                                          context_die);
+
+  dw_die_ref old_type_die = get_AT_ref (old_die, DW_AT_type);
+
+  return type_die != old_type_die;
+}
+
 /* Generate a DIE to represent a declared data object.
    Either DECL or ORIGIN must be non-null.  */
 
@@ -23879,7 +23902,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
          && !DECL_ABSTRACT_P (decl_or_origin)
          && variably_modified_type_p (TREE_TYPE (decl_or_origin),
                                       decl_function_context
-                                                       (decl_or_origin))))
+                                      (decl_or_origin)))
+      || (old_die && specialization_p
+         && override_type_for_decl_p (decl_or_origin, old_die, context_die)))
     {
       tree type = TREE_TYPE (decl_or_origin);
 
@@ -23922,7 +23947,26 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
              && DECL_RTL_SET_P (decl_or_origin))))
     {
       if (early_dwarf)
-       add_pubname (decl_or_origin, var_die);
+       {
+         add_pubname (decl_or_origin, var_die);
+         /* For global register variables, emit DW_AT_location if possible
+            already during early_dwarf, as late_global_decl won't be usually
+            called.  */
+         if (DECL_HARD_REGISTER (decl_or_origin)
+             && TREE_STATIC (decl_or_origin)
+             && !decl_by_reference_p (decl_or_origin)
+             && !get_AT (var_die, DW_AT_location)
+             && !get_AT (var_die, DW_AT_const_value)
+             && DECL_RTL_SET_P (decl_or_origin)
+             && REG_P (DECL_RTL (decl_or_origin)))
+           {
+             dw_loc_descr_ref descr
+               = reg_loc_descriptor (DECL_RTL (decl_or_origin),
+                                     VAR_INIT_STATUS_INITIALIZED);
+             if (descr)
+               add_AT_loc (var_die, DW_AT_location, descr);
+           }
+       }
       else
        add_location_or_const_value_attribute (var_die, decl_or_origin,
                                               decl == NULL);
@@ -24372,7 +24416,7 @@ gen_producer_string (void)
       case OPT_U:
       case OPT_SPECIAL_unknown:
       case OPT_SPECIAL_ignore:
-      case OPT_SPECIAL_deprecated:
+      case OPT_SPECIAL_warn_removed:
       case OPT_SPECIAL_program_name:
       case OPT_SPECIAL_input_file:
       case OPT_grecord_gcc_switches:
@@ -24400,6 +24444,13 @@ gen_producer_string (void)
       case OPT_fchecking_:
        /* Ignore these.  */
        continue;
+      case OPT_flto_:
+       {
+         const char *lto_canonical = "-flto";
+         switches.safe_push (lto_canonical);
+         len += strlen (lto_canonical) + 1;
+         break;
+       }
       default:
         if (cl_options[save_decoded_options[j].opt_index].flags
            & CL_NO_DWARF_RECORD)
@@ -25106,19 +25157,20 @@ gen_member_die (tree type, dw_die_ref context_die)
                             context_die);
     }
 
-  /* Now output info about the data members and type members.  */
+  /* Now output info about the members. */
   for (member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
     {
+      /* Ignore clones.  */
+      if (DECL_ABSTRACT_ORIGIN (member))
+       continue;
+
       struct vlr_context vlr_ctx = { type, NULL_TREE };
       bool static_inline_p
-       = (TREE_STATIC (member)
+       = (VAR_P (member)
+          && TREE_STATIC (member)
           && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline)
               != -1));
 
-      /* Ignore clones.  */
-      if (DECL_ABSTRACT_ORIGIN (member))
-       continue;
-
       /* If we thought we were generating minimal debug info for TYPE
         and then changed our minds, some of the member declarations
         may have already been defined.  Don't define them again, but
@@ -25128,11 +25180,14 @@ gen_member_die (tree type, dw_die_ref context_die)
        {
          /* Handle inline static data members, which only have in-class
             declarations.  */
-         dw_die_ref ref = NULL; 
+         bool splice = true;
+
+         dw_die_ref ref = NULL;
          if (child->die_tag == DW_TAG_variable
              && child->die_parent == comp_unit_die ())
            {
              ref = get_AT_ref (child, DW_AT_specification);
+
              /* For C++17 inline static data members followed by redundant
                 out of class redeclaration, we might get here with
                 child being the DIE created for the out of class
@@ -25151,17 +25206,17 @@ gen_member_die (tree type, dw_die_ref context_die)
                  ref = NULL;
                  static_inline_p = false;
                }
-           }
 
-         if (child->die_tag == DW_TAG_variable
-             && child->die_parent == comp_unit_die ()
-             && ref == NULL)
-           {
-             reparent_child (child, context_die);
-             if (dwarf_version < 5)
-               child->die_tag = DW_TAG_member;
+             if (!ref)
+               {
+                 reparent_child (child, context_die);
+                 if (dwarf_version < 5)
+                   child->die_tag = DW_TAG_member;
+                 splice = false;
+               }
            }
-         else
+
+         if (splice)
            splice_child_die (context_die, child);
        }
 
@@ -26369,39 +26424,44 @@ gen_decl_die (tree decl, tree origin, struct vlr_context *ctx,
     case VAR_DECL:
     case RESULT_DECL:
       /* If we are in terse mode, don't generate any DIEs to represent any
-        variable declarations or definitions.  */
-      if (debug_info_level <= DINFO_LEVEL_TERSE)
+        variable declarations or definitions unless it is external.  */
+      if (debug_info_level < DINFO_LEVEL_TERSE
+         || (debug_info_level == DINFO_LEVEL_TERSE
+             && !TREE_PUBLIC (decl_or_origin)))
        break;
 
-      /* Avoid generating stray type DIEs during late dwarf dumping.
-         All types have been dumped early.  */
-      if (early_dwarf
-         /* ???  But in LTRANS we cannot annotate early created variably
-            modified type DIEs without copying them and adjusting all
-            references to them.  Dump them again as happens for inlining
-            which copies both the decl and the types.  */
-         /* ???  And even non-LTO needs to re-visit type DIEs to fill
-            in VLA bound information for example.  */
-         || (decl && variably_modified_type_p (TREE_TYPE (decl),
-                                               current_function_decl)))
+      if (debug_info_level > DINFO_LEVEL_TERSE)
        {
-         /* Output any DIEs that are needed to specify the type of this data
-            object.  */
-         if (decl_by_reference_p (decl_or_origin))
-           gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
-         else
-           gen_type_die (TREE_TYPE (decl_or_origin), context_die);
-       }
+         /* Avoid generating stray type DIEs during late dwarf dumping.
+            All types have been dumped early.  */
+         if (early_dwarf
+             /* ???  But in LTRANS we cannot annotate early created variably
+                modified type DIEs without copying them and adjusting all
+                references to them.  Dump them again as happens for inlining
+                which copies both the decl and the types.  */
+             /* ???  And even non-LTO needs to re-visit type DIEs to fill
+                in VLA bound information for example.  */
+             || (decl && variably_modified_type_p (TREE_TYPE (decl),
+                                                   current_function_decl)))
+           {
+             /* Output any DIEs that are needed to specify the type of this data
+                object.  */
+             if (decl_by_reference_p (decl_or_origin))
+               gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
+             else
+               gen_type_die (TREE_TYPE (decl_or_origin), context_die);
+           }
 
-      if (early_dwarf)
-       {
-         /* And its containing type.  */
-         class_origin = decl_class_context (decl_or_origin);
-         if (class_origin != NULL_TREE)
-           gen_type_die_for_member (class_origin, decl_or_origin, context_die);
+         if (early_dwarf)
+           {
+             /* And its containing type.  */
+             class_origin = decl_class_context (decl_or_origin);
+             if (class_origin != NULL_TREE)
+               gen_type_die_for_member (class_origin, decl_or_origin, context_die);
 
-         /* And its containing namespace.  */
-         context_die = declare_in_namespace (decl_or_origin, context_die);
+             /* And its containing namespace.  */
+             context_die = declare_in_namespace (decl_or_origin, context_die);
+           }
        }
 
       /* Now output the DIE to represent the data object itself.  This gets
@@ -26589,16 +26649,12 @@ dwarf2out_late_global_decl (tree decl)
     {
       dw_die_ref die = lookup_decl_die (decl);
 
-      /* We may have to generate early debug late for LTO in case debug
+      /* We may have to generate full debug late for LTO in case debug
          was not enabled at compile-time or the target doesn't support
         the LTO early debug scheme.  */
       if (! die && in_lto_p)
-       {
-         dwarf2out_decl (decl);
-         die = lookup_decl_die (decl);
-       }
-
-      if (die)
+       dwarf2out_decl (decl);
+      else if (die)
        {
          /* We get called via the symtab code invoking late_global_decl
             for symbols that are optimized out.
@@ -26850,8 +26906,10 @@ dwarf2out_decl (tree decl)
        context_die = lookup_decl_die (DECL_CONTEXT (decl));
 
       /* If we are in terse mode, don't generate any DIEs to represent any
-        variable declarations or definitions.  */
-      if (debug_info_level <= DINFO_LEVEL_TERSE)
+        variable declarations or definitions unless it is external.  */
+      if (debug_info_level < DINFO_LEVEL_TERSE
+         || (debug_info_level == DINFO_LEVEL_TERSE
+             && !TREE_PUBLIC (decl)))
        return;
       break;
 
@@ -27004,6 +27062,9 @@ lookup_filename (const char *file_name)
   if (!file_name)
     return NULL;
 
+  if (!file_name[0])
+    file_name = "<stdin>";
+
   dwarf_file_data **slot
     = file_table->find_slot_with_hash (file_name, htab_hash_string (file_name),
                                       INSERT);
@@ -27195,7 +27256,7 @@ static bool maybe_at_text_label_p = true;
 /* One above highest N where .LVLN label might be equal to .Ltext0 label.  */
 static unsigned int first_loclabel_num_not_at_text_label;
 
-/* Look ahead for a real insn, or for a begin stmt marker.  */
+/* Look ahead for a real insn.  */
 
 static rtx_insn *
 dwarf2out_next_real_insn (rtx_insn *loc_note)
@@ -27220,7 +27281,7 @@ dwarf2out_var_location (rtx_insn *loc_note)
 {
   char loclabel[MAX_ARTIFICIAL_LABEL_BYTES + 2];
   struct var_loc_node *newloc;
-  rtx_insn *next_real, *next_note;
+  rtx_insn *next_real;
   rtx_insn *call_insn = NULL;
   static const char *last_label;
   static const char *last_postcall_label;
@@ -27245,7 +27306,6 @@ dwarf2out_var_location (rtx_insn *loc_note)
              var_loc_p = false;
 
              next_real = dwarf2out_next_real_insn (call_insn);
-             next_note = NULL;
              cached_next_real_insn = NULL;
              goto create_label;
            }
@@ -27273,7 +27333,6 @@ dwarf2out_var_location (rtx_insn *loc_note)
                  var_loc_p = false;
 
                  next_real = dwarf2out_next_real_insn (call_insn);
-                 next_note = NULL;
                  cached_next_real_insn = NULL;
                  goto create_label;
                }
@@ -27302,22 +27361,28 @@ dwarf2out_var_location (rtx_insn *loc_note)
        next_real = NULL;
     }
 
-  next_note = NEXT_INSN (loc_note);
-  if (! next_note
-      || next_note->deleted ()
-      || ! NOTE_P (next_note)
-      || (NOTE_KIND (next_note) != NOTE_INSN_VAR_LOCATION
-         && NOTE_KIND (next_note) != NOTE_INSN_BEGIN_STMT
-         && NOTE_KIND (next_note) != NOTE_INSN_INLINE_ENTRY))
-    next_note = NULL;
-
   if (! next_real)
     next_real = dwarf2out_next_real_insn (loc_note);
 
-  if (next_note)
+  if (next_real)
     {
-      expected_next_loc_note = next_note;
-      cached_next_real_insn = next_real;
+      rtx_insn *next_note = NEXT_INSN (loc_note);
+      while (next_note != next_real)
+       {
+         if (! next_note->deleted ()
+             && NOTE_P (next_note)
+             && NOTE_KIND (next_note) == NOTE_INSN_VAR_LOCATION)
+           break;
+         next_note = NEXT_INSN (next_note);
+       }
+
+      if (next_note == next_real)
+       cached_next_real_insn = NULL;
+      else
+       {
+         expected_next_loc_note = next_note;
+         cached_next_real_insn = next_real;
+       }
     }
   else
     cached_next_real_insn = NULL;
@@ -27434,7 +27499,7 @@ create_label:
       ca_loc->tail_call_p = SIBLING_CALL_P (prev);
 
       /* Look for a SYMBOL_REF in the "prev" instruction.  */
-      rtx x = get_call_rtx_from (PATTERN (prev));
+      rtx x = get_call_rtx_from (prev);
       if (x)
        {
          /* Try to get the call symbol, if any.  */
@@ -27615,11 +27680,8 @@ dwarf2out_inline_entry (tree block)
   if (cur_line_info_table)
     ied->view = cur_line_info_table->view;
 
-  char label[MAX_ARTIFICIAL_LABEL_BYTES];
-
-  ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_INLINE_ENTRY_LABEL,
-                              BLOCK_NUMBER (block));
-  ASM_OUTPUT_LABEL (asm_out_file, label);
+  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_INLINE_ENTRY_LABEL,
+                         BLOCK_NUMBER (block));
 }
 
 /* Called from finalize_size_functions for size functions so that their body
@@ -27629,6 +27691,7 @@ dwarf2out_inline_entry (tree block)
 static void
 dwarf2out_size_function (tree decl)
 {
+  set_early_dwarf s;
   function_to_dwarf_procedure (decl);
 }
 
@@ -29050,6 +29113,30 @@ output_addr_table (void)
     return;
 
   switch_to_section (debug_addr_section);
+  /* GNU DebugFission https://gcc.gnu.org/wiki/DebugFission
+     which GCC uses to implement -gsplit-dwarf as DWARF GNU extension
+     before DWARF5, didn't have a header for .debug_addr units.
+     DWARF5 specifies a small header when address tables are used.  */
+  if (dwarf_version >= 5)
+    {
+      unsigned int last_idx = 0;
+      unsigned long addrs_length;
+
+      addr_index_table->traverse_noresize
+       <unsigned int *, count_index_addrs> (&last_idx);
+      addrs_length = last_idx * DWARF2_ADDR_SIZE + 4;
+
+      if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+       dw2_asm_output_data (4, 0xffffffff,
+                            "Escape value for 64-bit DWARF extension");
+      dw2_asm_output_data (DWARF_OFFSET_SIZE, addrs_length,
+                          "Length of Address Unit");
+      dw2_asm_output_data (2, 5, "DWARF addr version");
+      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address");
+      dw2_asm_output_data (1, 0, "Size of Segment Descriptor");
+    }
+  ASM_OUTPUT_LABEL (asm_out_file, debug_addr_section_label);
+
   addr_index_table
     ->traverse_noresize<unsigned int *, output_addr_table_entry> (&index);
 }
@@ -29354,6 +29441,26 @@ prune_unused_types_walk (dw_die_ref die)
 
       return;
 
+    case DW_TAG_variable:
+      if (flag_debug_only_used_symbols)
+       {
+         if (die->die_perennial_p)
+           break;
+
+         /* premark_used_variables marks external variables --- don't mark
+            them here.  But function-local externals are always considered
+            used.  */
+         if (get_AT (die, DW_AT_external))
+           {
+             for (c = die->die_parent; c; c = c->die_parent)
+               if (c->die_tag == DW_TAG_subprogram)
+                 break;
+             if (!c)
+               return;
+           }
+       }
+      /* FALLTHROUGH */
+
     default:
       /* Mark everything else.  */
       break;
@@ -29480,6 +29587,10 @@ prune_unused_types (void)
   /* Mark types that are used in global variables.  */
   premark_types_used_by_global_vars ();
 
+  /* Mark variables used in the symtab.  */
+  if (flag_debug_only_used_symbols)
+    premark_used_variables ();
+
   /* Set the mark on nodes that are actually used.  */
   prune_unused_types_walk (comp_unit_die ());
   for (node = limbo_die_list; node; node = node->next)
@@ -29500,9 +29611,9 @@ prune_unused_types (void)
   for (i = 0; base_types.iterate (i, &base_type); i++)
     prune_unused_types_mark (base_type, 1);
 
-  /* For -fvar-tracking-assignments, also set the mark on nodes that could be
-     referenced by DW_TAG_call_site DW_AT_call_origin (i.e. direct call
-     callees).  */
+  /* Also set the mark on nodes that could be referenced by
+     DW_TAG_call_site DW_AT_call_origin (i.e. direct call callees) or
+     by DW_TAG_inlined_subroutine origins.  */
   cgraph_node *cnode;
   FOR_EACH_FUNCTION (cnode)
     if (cnode->referred_to_p (false))
@@ -29511,8 +29622,7 @@ prune_unused_types (void)
        if (die == NULL || die->die_mark)
          continue;
        for (cgraph_edge *e = cnode->callers; e; e = e->next_caller)
-         if (e->caller != cnode
-             && opt_for_fn (e->caller->decl, flag_var_tracking_assignments))
+         if (e->caller != cnode)
            {
              prune_unused_types_mark (die, 1);
              break;
@@ -31249,7 +31359,7 @@ dwarf2out_finish (const char *filename)
   flush_limbo_die_list ();
 
   if (inline_entry_data_table)
-    gcc_assert (inline_entry_data_table->elements () == 0);
+    gcc_assert (inline_entry_data_table->is_empty ());
 
   if (flag_checking)
     {
@@ -31548,30 +31658,6 @@ dwarf2out_finish (const char *filename)
                            ranges_section_label);
        }
 
-      switch_to_section (debug_addr_section);
-      /* GNU DebugFission https://gcc.gnu.org/wiki/DebugFission
-        which GCC uses to implement -gsplit-dwarf as DWARF GNU extension
-        before DWARF5, didn't have a header for .debug_addr units.
-        DWARF5 specifies a small header when address tables are used.  */
-      if (dwarf_version >= 5)
-       {
-         unsigned int last_idx = 0;
-         unsigned long addrs_length;
-
-         addr_index_table->traverse_noresize
-           <unsigned int *, count_index_addrs> (&last_idx);
-         addrs_length = last_idx * DWARF2_ADDR_SIZE + 4;
-
-         if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
-           dw2_asm_output_data (4, 0xffffffff,
-                                "Escape value for 64-bit DWARF extension");
-         dw2_asm_output_data (DWARF_OFFSET_SIZE, addrs_length,
-                              "Length of Address Unit");
-         dw2_asm_output_data (2, 5, "DWARF addr version");
-         dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address");
-         dw2_asm_output_data (1, 0, "Size of Segment Descriptor");
-       }
-      ASM_OUTPUT_LABEL (asm_out_file, debug_addr_section_label);
       output_addr_table ();
     }
 
@@ -32021,24 +32107,6 @@ dwarf2out_early_finish (const char *filename)
      sure to adjust the phase after annotating the LTRANS CU DIE.  */
   if (in_lto_p)
     {
-      /* Force DW_TAG_imported_unit to be created now, otherwise
-        we might end up without it or ordered after DW_TAG_inlined_subroutine
-        referencing DIEs from it.  */
-      if (! flag_wpa && flag_incremental_link != INCREMENTAL_LINK_LTO)
-       {
-         unsigned i;
-         tree tu;
-         if (external_die_map)
-           FOR_EACH_VEC_SAFE_ELT (all_translation_units, i, tu)
-             if (sym_off_pair *desc = external_die_map->get (tu))
-               {
-                 dw_die_ref import = new_die (DW_TAG_imported_unit,
-                                              comp_unit_die (), NULL_TREE);
-                 add_AT_external_die_ref (import, DW_AT_import,
-                                          desc->sym, desc->off);
-               }
-       }
-
       early_dwarf_finished = true;
       if (dump_file)
        {
@@ -32052,13 +32120,13 @@ dwarf2out_early_finish (const char *filename)
      emit full debugging info for them.  */
   retry_incomplete_types ();
 
+  gen_scheduled_generic_parms_dies ();
+  gen_remaining_tmpl_value_param_die_attribute ();
+
   /* The point here is to flush out the limbo list so that it is empty
      and we don't need to stream it for LTO.  */
   flush_limbo_die_list ();
 
-  gen_scheduled_generic_parms_dies ();
-  gen_remaining_tmpl_value_param_die_attribute ();
-
   /* Add DW_AT_linkage_name for all deferred DIEs.  */
   for (limbo_die_node *node = deferred_asm_name; node; node = node->next)
     {
@@ -32146,7 +32214,7 @@ dwarf2out_early_finish (const char *filename)
      location related output removed and some LTO specific changes.
      Some refactoring might make both smaller and easier to match up.  */
 
-  /* Traverse the DIE's and add add sibling attributes to those DIE's
+  /* Traverse the DIE's and add sibling attributes to those DIE's
      that have children.  */
   add_sibling_attributes (comp_unit_die ());
   for (limbo_die_node *node = limbo_die_list; node; node = node->next)
This page took 0.104547 seconds and 5 git commands to generate.