gdb: remove TYPE_NAME macro
[deliverable/binutils-gdb.git] / gdb / dwarf2 / read.c
index 198fac0f4164ffce5b197634b53095b66f4daeb5..719051bc5b2fa264afd659ef5071ac5805826754 100644 (file)
@@ -114,6 +114,12 @@ static int dwarf2_loclist_index;
 static int dwarf2_locexpr_block_index;
 static int dwarf2_loclist_block_index;
 
+/* Size of .debug_loclists section header for 32-bit DWARF format.  */
+#define LOCLIST_HEADER_SIZE32 12
+
+/* Size of .debug_loclists section header for 64-bit DWARF format.  */
+#define LOCLIST_HEADER_SIZE64 20
+
 /* An index into a (C++) symbol name component in a symbol name as
    recorded in the mapped_index's symbol table.  For each C++ symbol
    in the symbol table, we record one entry for the start of each
@@ -346,6 +352,30 @@ dwop_section_names =
 
 /* local data types */
 
+/* The location list section (.debug_loclists) begins with a header,
+   which contains the following information.  */
+struct loclist_header
+{
+  /* A 4-byte or 12-byte length containing the length of the
+     set of entries for this compilation unit, not including the
+     length field itself.  */
+  unsigned int length;
+
+  /* A 2-byte version identifier.  */
+  short version;
+
+  /* A 1-byte unsigned integer containing the size in bytes of an address on
+     the target system.  */
+  unsigned char addr_size;
+
+  /* A 1-byte unsigned integer containing the size in bytes of a segment selector
+     on the target system.  */
+  unsigned char segment_collector_size;
+
+  /* A 4-byte count of the number of offsets that follow the header.  */
+  unsigned int offset_entry_count;
+};
+
 /* Type used for delaying computation of method physnames.
    See comments for compute_delayed_physnames.  */
 struct delayed_method_info
@@ -493,6 +523,9 @@ public:
      whether the DW_AT_ranges attribute came from the skeleton or DWO.  */
   ULONGEST ranges_base = 0;
 
+  /* The DW_AT_loclists_base attribute if present.  */
+  ULONGEST loclist_base = 0;
+
   /* When reading debug info generated by older versions of rustc, we
      have to rewrite some union types to be struct types with a
      variant part.  This rewriting must be done after the CU is fully
@@ -1049,29 +1082,52 @@ struct partial_die_info : public allocate_on_obstack
    and friends.  */
 static int bits_per_byte = 8;
 
-/* When reading a variant or variant part, we track a bit more
-   information about the field, and store it in an object of this
-   type.  */
+struct variant_part_builder;
+
+/* When reading a variant, we track a bit more information about the
+   field, and store it in an object of this type.  */
 
 struct variant_field
 {
-  /* If we see a DW_TAG_variant, then this will be the discriminant
-     value.  */
-  ULONGEST discriminant_value;
+  int first_field = -1;
+  int last_field = -1;
+
+  /* A variant can contain other variant parts.  */
+  std::vector<variant_part_builder> variant_parts;
+
   /* If we see a DW_TAG_variant, then this will be set if this is the
      default branch.  */
-  bool default_branch;
-  /* While reading a DW_TAG_variant_part, this will be set if this
-     field is the discriminant.  */
-  bool is_discriminant;
+  bool default_branch = false;
+  /* If we see a DW_AT_discr_value, then this will be the discriminant
+     value.  */
+  ULONGEST discriminant_value = 0;
+  /* If we see a DW_AT_discr_list, then this is a pointer to the list
+     data.  */
+  struct dwarf_block *discr_list_data = nullptr;
+};
+
+/* This represents a DW_TAG_variant_part.  */
+
+struct variant_part_builder
+{
+  /* The offset of the discriminant field.  */
+  sect_offset discriminant_offset {};
+
+  /* Variants that are direct children of this variant part.  */
+  std::vector<variant_field> variants;
+
+  /* True if we're currently reading a variant.  */
+  bool processing_variant = false;
 };
 
 struct nextfield
 {
   int accessibility = 0;
   int virtuality = 0;
-  /* Extra information to describe a variant or variant part.  */
-  struct variant_field variant {};
+  /* Variant parts need to find the discriminant, which is a DIE
+     reference.  We track the section offset of each field to make
+     this link.  */
+  sect_offset offset;
   struct field field {};
 };
 
@@ -1106,6 +1162,13 @@ struct field_info
        list.  */
     std::vector<struct decl_field> nested_types_list;
 
+    /* If non-null, this is the variant part we are currently
+       reading.  */
+    variant_part_builder *current_variant_part = nullptr;
+    /* This holds all the top-level variant parts attached to the type
+       we're reading.  */
+    std::vector<variant_part_builder> variant_parts;
+
     /* Return the total number of fields (including baseclasses).  */
     int nfields () const
     {
@@ -1303,6 +1366,9 @@ static void read_variable (struct die_info *die, struct dwarf2_cu *cu);
 static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
                               struct dwarf2_cu *, dwarf2_psymtab *);
 
+/* Return the .debug_loclists section to use for cu.  */
+static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
+
 /* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
    values.  Keep the items ordered with increasing constraints compliance.  */
 enum pc_bounds_kind
@@ -1369,7 +1435,8 @@ static const char *namespace_name (struct die_info *die,
 
 static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
 
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
+                                bool * = nullptr);
 
 static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
                                                       struct dwarf2_cu *);
@@ -2531,7 +2598,7 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           struct mapped_index *index)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const gdb_byte *iter, *end;
   struct addrmap *mutable_map;
   CORE_ADDR baseaddr;
@@ -2588,7 +2655,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
 
   auto_obstack temp_obstack;
@@ -2818,8 +2885,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
    Returns true if all went well, false otherwise.  */
 
 static bool
-read_gdb_index_from_buffer (struct objfile *objfile,
-                           const char *filename,
+read_gdb_index_from_buffer (const char *filename,
                            bool deprecated_ok,
                            gdb::array_view<const gdb_byte> buffer,
                            struct mapped_index *map,
@@ -2947,7 +3013,7 @@ dwarf2_read_gdb_index
     return 0;
 
   std::unique_ptr<struct mapped_index> map (new struct mapped_index);
-  if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile),
+  if (!read_gdb_index_from_buffer (objfile_name (objfile),
                                   use_deprecated_index_sections,
                                   main_index_contents, map.get (), &cu_list,
                                   &cu_list_elements, &types_list,
@@ -2973,8 +3039,7 @@ dwarf2_read_gdb_index
       if (dwz_index_content.empty ())
        return 0;
 
-      if (!read_gdb_index_from_buffer (objfile,
-                                      bfd_get_filename (dwz->dwz_bfd.get ()),
+      if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
                                       1, dwz_index_content, &dwz_map,
                                       &dwz_list, &dwz_list_elements,
                                       &dwz_types_ignore,
@@ -3592,9 +3657,35 @@ dw2_map_matching_symbols
    gdb::function_view<symbol_found_callback_ftype> callback,
    symbol_compare_ftype *ordered_compare)
 {
-  /* Currently unimplemented; used for Ada.  The function can be called if the
-     current language is Ada for a non-Ada objfile using GNU index.  As Ada
-     does not look for non-Ada symbols this function should just return.  */
+  /* Used for Ada.  */
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = get_dwarf2_per_objfile (objfile);
+
+  if (dwarf2_per_objfile->index_table != nullptr)
+    {
+      /* Ada currently doesn't support .gdb_index (see PR24713).  We can get
+        here though if the current language is Ada for a non-Ada objfile
+        using GNU index.  As Ada does not look for non-Ada symbols this
+        function should just return.  */
+      return;
+    }
+
+  /* We have -readnow: no .gdb_index, but no partial symtabs either.  So,
+     inline psym_map_matching_symbols here, assuming all partial symtabs have
+     been read in.  */
+  const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+
+  for (compunit_symtab *cust : objfile->compunits ())
+    {
+      const struct block *block;
+
+      if (cust == NULL)
+       continue;
+      block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
+      if (!iterate_over_symbols_terminated (block, name,
+                                           domain, callback))
+       return;
+    }
 }
 
 /* Starting from a search name, return the string that finds the upper
@@ -3851,11 +3942,11 @@ dw2_expand_symtabs_matching_symbol
   struct name_and_matcher
   {
     symbol_name_matcher_ftype *matcher;
-    const std::string &name;
+    const char *name;
 
     bool operator== (const name_and_matcher &other) const
     {
-      return matcher == other.matcher && name == other.name;
+      return matcher == other.matcher && strcmp (name, other.name) == 0;
     }
   };
 
@@ -4543,7 +4634,7 @@ static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -4557,9 +4648,21 @@ dw2_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                          expansion_notify);
+       }
+      return;
+    }
+
   mapped_index &index = *dwarf2_per_objfile->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type idx)
     {
@@ -4618,7 +4721,7 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
 
   if (warn_if_readin && data->v.quick->compunit_symtab)
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
-            paddress (get_objfile_arch (objfile), pc));
+            paddress (objfile->arch (), pc));
 
   result
     = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
@@ -4748,7 +4851,7 @@ read_debug_names_from_section (struct objfile *objfile,
 
   section->read (objfile);
 
-  map.dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+  map.dwarf5_byte_order = gdbarch_byte_order (objfile->arch ());
 
   const gdb_byte *addr = section->buffer;
 
@@ -4919,6 +5022,26 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                                  dwarf2_section_info &section,
                                  bool is_dwz)
 {
+  if (!map.augmentation_is_gdb)
+    {
+    for (uint32_t i = 0; i < map.cu_count; ++i)
+      {
+       sect_offset sect_off
+         = (sect_offset) (extract_unsigned_integer
+                          (map.cu_table_reordered + i * map.offset_size,
+                           map.offset_size,
+                           map.dwarf5_byte_order));
+       /* We don't know the length of the CU, because the CU list in a
+          .debug_names index can be incomplete, so we can't use the start of
+          the next CU as end of this CU.  We create the CUs here with length 0,
+          and in cutu_reader::cutu_reader we'll fill in the actual length.  */
+       dwarf2_per_cu_data *per_cu
+         = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
+                                      sect_off, 0);
+       dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+      }
+    }
+
   sect_offset sect_off_prev;
   for (uint32_t i = 0; i <= map.cu_count; ++i)
     {
@@ -5249,6 +5372,18 @@ dw2_debug_names_iterator::next ()
          ull = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
          m_addr += bytes_read;
          break;
+       case DW_FORM_ref4:
+         ull = read_4_bytes (abfd, m_addr);
+         m_addr += 4;
+         break;
+       case DW_FORM_ref8:
+         ull = read_8_bytes (abfd, m_addr);
+         m_addr += 8;
+         break;
+       case DW_FORM_ref_sig8:
+         ull = read_8_bytes (abfd, m_addr);
+         m_addr += 8;
+         break;
        default:
          complaint (_("Unsupported .debug_names form %s [in module %s]"),
                     dwarf_form_name (attr.form),
@@ -5281,6 +5416,12 @@ dw2_debug_names_iterator::next ()
            }
          per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
          break;
+       case DW_IDX_die_offset:
+         /* In a per-CU index (as opposed to a per-module index), index
+            entries without CU attribute implicitly refer to the single CU.  */
+         if (per_cu == NULL)
+           per_cu = dwarf2_per_objfile->get_cu (0);
+         break;
        case DW_IDX_GNU_internal:
          if (!m_map.augmentation_is_gdb)
            break;
@@ -5552,7 +5693,7 @@ static void
 dw2_debug_names_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -5566,9 +5707,21 @@ dw2_debug_names_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                          expansion_notify);
+       }
+      return;
+    }
+
   mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type namei)
     {
@@ -5833,22 +5986,31 @@ struct dwarf2_include_psymtab : public partial_symtab
 
   void read_symtab (struct objfile *objfile) override
   {
-    expand_psymtab (objfile);
+    /* It's an include file, no symbols to read for it.
+       Everything is in the includer symtab.  */
+
+    /* The expansion of a dwarf2_include_psymtab is just a trigger for
+       expansion of the includer psymtab.  We use the dependencies[0] field to
+       model the includer.  But if we go the regular route of calling
+       expand_psymtab here, and having expand_psymtab call expand_dependencies
+       to expand the includer, we'll only use expand_psymtab on the includer
+       (making it a non-toplevel psymtab), while if we expand the includer via
+       another path, we'll use read_symtab (making it a toplevel psymtab).
+       So, don't pretend a dwarf2_include_psymtab is an actual toplevel
+       psymtab, and trigger read_symtab on the includer here directly.  */
+    includer ()->read_symtab (objfile);
   }
 
   void expand_psymtab (struct objfile *objfile) override
   {
-    if (m_readin)
-      return;
-    /* It's an include file, no symbols to read for it.
-       Everything is in the parent symtab.  */
-    expand_dependencies (objfile);
-    m_readin = true;
+    /* This is not called by read_symtab, and should not be called by any
+       expand_dependencies.  */
+    gdb_assert (false);
   }
 
   bool readin_p () const override
   {
-    return m_readin;
+    return includer ()->readin_p ();
   }
 
   struct compunit_symtab *get_compunit_symtab () const override
@@ -5857,8 +6019,13 @@ struct dwarf2_include_psymtab : public partial_symtab
   }
 
 private:
-
-  bool m_readin = false;
+  partial_symtab *includer () const
+  {
+    /* An include psymtab has exactly one dependency: the psymtab that
+       includes it.  */
+    gdb_assert (this->number_of_dependencies == 1);
+    return this->dependencies[0];
+  }
 };
 
 /* Allocate a new partial symtab for file named NAME and mark this new
@@ -6799,7 +6966,10 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
                                                    rcuh_kind::COMPILE);
 
          gdb_assert (this_cu->sect_off == cu->header.sect_off);
-         gdb_assert (this_cu->length == cu->header.get_length ());
+         if (this_cu->length == 0)
+           this_cu->length = cu->header.get_length ();
+         else
+           gdb_assert (this_cu->length == cu->header.get_length ());
          this_cu->dwarf_version = cu->header.version;
        }
     }
@@ -7135,12 +7305,11 @@ create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
   struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
   dwarf2_psymtab *pst;
 
-  pst = new dwarf2_psymtab (name, objfile, 0);
+  pst = new dwarf2_psymtab (name, objfile, per_cu);
 
   pst->psymtabs_addrmap_supported = true;
 
   /* This is the glue that links PST into GDB's symbol API.  */
-  pst->per_cu_data = per_cu;
   per_cu->v.psymtab = pst;
 
   return pst;
@@ -7156,7 +7325,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   CORE_ADDR baseaddr;
   CORE_ADDR best_lowpc = 0, best_highpc = 0;
@@ -7682,7 +7851,12 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
                           addrmap_create_mutable (&temp_obstack));
 
   for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
-    process_psymtab_comp_unit (per_cu, false, language_minimal);
+    {
+      if (per_cu->v.psymtab != NULL)
+       /* In case a forward DW_TAG_imported_unit has read the CU already.  */
+       continue;
+      process_psymtab_comp_unit (per_cu, false, language_minimal);
+    }
 
   /* This has to wait until we read the CUs, we need the list of DWOs.  */
   process_skeletonless_type_units (dwarf2_per_objfile);
@@ -7849,7 +8023,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
            case DW_TAG_variable:
            case DW_TAG_typedef:
            case DW_TAG_union_type:
-             if (!pdi->is_declaration)
+             if (!pdi->is_declaration
+                 || (pdi->tag == DW_TAG_variable && pdi->is_external))
                {
                  add_partial_symbol (pdi, cu);
                }
@@ -8070,7 +8245,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR addr = 0;
   const char *actual_name = NULL;
   CORE_ADDR baseaddr;
@@ -8085,6 +8260,15 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
   if (actual_name == NULL)
     actual_name = pdi->name;
 
+  partial_symbol psymbol;
+  memset (&psymbol, 0, sizeof (psymbol));
+  psymbol.ginfo.set_language (cu->language, &objfile->objfile_obstack);
+  psymbol.ginfo.section = -1;
+
+  /* The code below indicates that the psymbol should be installed by
+     setting this.  */
+  gdb::optional<psymbol_placement> where;
+
   switch (pdi->tag)
     {
     case DW_TAG_inlined_subroutine:
@@ -8101,34 +8285,25 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
              But in Ada and Fortran, we want to be able to access nested
              procedures globally.  So all Ada and Fortran subprograms are
              stored in the global scope.  */
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_BLOCK,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::GLOBAL,
-                              addr,
-                              cu->language, objfile);
+         where = psymbol_placement::GLOBAL;
        }
       else
-       {
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_BLOCK,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::STATIC,
-                              addr, cu->language, objfile);
-       }
+       where = psymbol_placement::STATIC;
+
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_BLOCK;
+      psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+      psymbol.ginfo.value.address = addr;
 
       if (pdi->main_subprogram && actual_name != NULL)
        set_objfile_main_name (objfile, actual_name, cu->language);
       break;
     case DW_TAG_constant:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
-                          -1, (pdi->is_external
-                               ? psymbol_placement::GLOBAL
-                               : psymbol_placement::STATIC),
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_STATIC;
+      where = (pdi->is_external
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     case DW_TAG_variable:
       if (pdi->d.locdesc)
@@ -8159,12 +8334,13 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
             table building.  */
 
          if (pdi->d.locdesc || pdi->has_type)
-           add_psymbol_to_list (actual_name,
-                                built_actual_name != NULL,
-                                VAR_DOMAIN, LOC_STATIC,
-                                SECT_OFF_TEXT (objfile),
-                                psymbol_placement::GLOBAL,
-                                addr, cu->language, objfile);
+           {
+             psymbol.domain = VAR_DOMAIN;
+             psymbol.aclass = LOC_STATIC;
+             psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+             psymbol.ginfo.value.address = addr;
+             where = psymbol_placement::GLOBAL;
+           }
        }
       else
        {
@@ -8175,42 +8351,37 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
          if (!has_loc && !pdi->has_const_value)
            return;
 
-         add_psymbol_to_list (actual_name,
-                              built_actual_name != NULL,
-                              VAR_DOMAIN, LOC_STATIC,
-                              SECT_OFF_TEXT (objfile),
-                              psymbol_placement::STATIC,
-                              has_loc ? addr : 0,
-                              cu->language, objfile);
+         psymbol.domain = VAR_DOMAIN;
+         psymbol.aclass = LOC_STATIC;
+         psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+         if (has_loc)
+           psymbol.ginfo.value.address = addr;
+         where = psymbol_placement::STATIC;
        }
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
     case DW_TAG_subrange_type:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_TYPEDEF, -1,
-                          psymbol_placement::STATIC,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = psymbol_placement::STATIC;
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_namespace:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_TYPEDEF, -1,
-                          psymbol_placement::GLOBAL,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = psymbol_placement::GLOBAL;
       break;
     case DW_TAG_module:
       /* With Fortran 77 there might be a "BLOCK DATA" module
          available without any name.  If so, we skip the module as it
          doesn't bring any value.  */
       if (actual_name != nullptr)
-       add_psymbol_to_list (actual_name,
-                            built_actual_name != NULL,
-                            MODULE_DOMAIN, LOC_TYPEDEF, -1,
-                            psymbol_placement::GLOBAL,
-                            0, cu->language, objfile);
+       {
+         psymbol.domain = MODULE_DOMAIN;
+         psymbol.aclass = LOC_TYPEDEF;
+         where = psymbol_placement::GLOBAL;
+       }
       break;
     case DW_TAG_class_type:
     case DW_TAG_interface_type:
@@ -8227,27 +8398,37 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
       /* NOTE: carlton/2003-10-07: See comment in new_symbol about
         static vs. global.  */
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          STRUCT_DOMAIN, LOC_TYPEDEF, -1,
-                          cu->language == language_cplus
-                          ? psymbol_placement::GLOBAL
-                          : psymbol_placement::STATIC,
-                          0, cu->language, objfile);
-
+      psymbol.domain = STRUCT_DOMAIN;
+      psymbol.aclass = LOC_TYPEDEF;
+      where = (cu->language == language_cplus
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (actual_name,
-                          built_actual_name != NULL,
-                          VAR_DOMAIN, LOC_CONST, -1,
-                          cu->language == language_cplus
-                          ? psymbol_placement::GLOBAL
-                          : psymbol_placement::STATIC,
-                          0, cu->language, objfile);
+      psymbol.domain = VAR_DOMAIN;
+      psymbol.aclass = LOC_CONST;
+      where = (cu->language == language_cplus
+              ? psymbol_placement::GLOBAL
+              : psymbol_placement::STATIC);
       break;
     default:
       break;
     }
+
+  if (where.has_value ())
+    {
+      if (built_actual_name != nullptr)
+       actual_name = objfile->intern (actual_name);
+      if (pdi->linkage_name == nullptr || cu->language == language_ada)
+       psymbol.ginfo.set_linkage_name (actual_name);
+      else
+       {
+         psymbol.ginfo.set_demangled_name (actual_name,
+                                           &objfile->objfile_obstack);
+         psymbol.ginfo.set_linkage_name (pdi->linkage_name);
+       }
+      add_psymbol_to_list (psymbol, *where, objfile);
+    }
 }
 
 /* Read a partial die corresponding to a namespace; also, add a symbol
@@ -8313,7 +8494,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
          if (set_addrmap)
            {
              struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-             struct gdbarch *gdbarch = get_objfile_arch (objfile);
+             struct gdbarch *gdbarch = objfile->arch ();
              CORE_ADDR baseaddr;
              CORE_ADDR this_highpc;
              CORE_ADDR this_lowpc;
@@ -8566,6 +8747,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
        case DW_FORM_GNU_addr_index:
        case DW_FORM_GNU_str_index:
        case DW_FORM_rnglistx:
+       case DW_FORM_loclistx:
          info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
          break;
        case DW_FORM_indirect:
@@ -8774,8 +8956,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 void
 dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 {
-  if (readin)
-    return;
+  gdb_assert (!readin);
 
   expand_dependencies (objfile);
 
@@ -8991,7 +9172,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
                                     saved_package_name);
       struct symbol *sym;
 
-      sym = allocate_symbol (objfile);
+      sym = new (&objfile->objfile_obstack) symbol;
       sym->set_language (language_go, &objfile->objfile_obstack);
       sym->compute_and_set_names (saved_package_name, false, objfile->per_bfd);
       /* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
@@ -9013,37 +9194,72 @@ rust_fully_qualify (struct obstack *obstack, const char *p1, const char *p2)
   return obconcat (obstack, p1, "::", p2, (char *) NULL);
 }
 
-/* A helper that allocates a struct discriminant_info to attach to a
-   union type.  */
+/* A helper that allocates a variant part to attach to a Rust enum
+   type.  OBSTACK is where the results should be allocated.  TYPE is
+   the type we're processing.  DISCRIMINANT_INDEX is the index of the
+   discriminant.  It must be the index of one of the fields of TYPE.
+   DEFAULT_INDEX is the index of the default field; or -1 if there is
+   no default.  RANGES is indexed by "effective" field number (the
+   field index, but omitting the discriminant and default fields) and
+   must hold the discriminant values used by the variants.  Note that
+   RANGES must have a lifetime at least as long as OBSTACK -- either
+   already allocated on it, or static.  */
 
-static struct discriminant_info *
-alloc_discriminant_info (struct type *type, int discriminant_index,
-                        int default_index)
-{
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
-  gdb_assert (discriminant_index == -1
-             || (discriminant_index >= 0
-                 && discriminant_index < TYPE_NFIELDS (type)));
+static void
+alloc_rust_variant (struct obstack *obstack, struct type *type,
+                   int discriminant_index, int default_index,
+                   gdb::array_view<discriminant_range> ranges)
+{
+  /* When DISCRIMINANT_INDEX == -1, we have a univariant enum.  Those
+     must be handled by the caller.  */
+  gdb_assert (discriminant_index >= 0
+             && discriminant_index < TYPE_NFIELDS (type));
   gdb_assert (default_index == -1
              || (default_index >= 0 && default_index < TYPE_NFIELDS (type)));
 
-  TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+  /* We have one variant for each non-discriminant field.  */
+  int n_variants = TYPE_NFIELDS (type) - 1;
 
-  struct discriminant_info *disc
-    = ((struct discriminant_info *)
-       TYPE_ZALLOC (type,
-                   offsetof (struct discriminant_info, discriminants)
-                   + TYPE_NFIELDS (type) * sizeof (disc->discriminants[0])));
-  disc->default_index = default_index;
-  disc->discriminant_index = discriminant_index;
+  variant *variants = new (obstack) variant[n_variants];
+  int var_idx = 0;
+  int range_idx = 0;
+  for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+    {
+      if (i == discriminant_index)
+       continue;
 
-  struct dynamic_prop prop;
-  prop.kind = PROP_UNDEFINED;
-  prop.data.baton = disc;
+      variants[var_idx].first_field = i;
+      variants[var_idx].last_field = i + 1;
+
+      /* The default field does not need a range, but other fields do.
+        We skipped the discriminant above.  */
+      if (i != default_index)
+       {
+         variants[var_idx].discriminants = ranges.slice (range_idx, 1);
+         ++range_idx;
+       }
+
+      ++var_idx;
+    }
+
+  gdb_assert (range_idx == ranges.size ());
+  gdb_assert (var_idx == n_variants);
+
+  variant_part *part = new (obstack) variant_part;
+  part->discriminant_index = discriminant_index;
+  part->is_unsigned = TYPE_UNSIGNED (TYPE_FIELD_TYPE (type,
+                                                     discriminant_index));
+  part->variants = gdb::array_view<variant> (variants, n_variants);
+
+  void *storage = obstack_alloc (obstack, sizeof (gdb::array_view<variant_part>));
+  gdb::array_view<variant_part> *prop_value
+    = new (storage) gdb::array_view<variant_part> (part, 1);
 
-  add_dyn_prop (DYN_PROP_DISCRIMINATED, prop, type);
+  struct dynamic_prop prop;
+  prop.kind = PROP_VARIANT_PARTS;
+  prop.data.variant_parts = prop_value;
 
-  return disc;
+  type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
 }
 
 /* Some versions of rustc emitted enums in an unusual way.
@@ -9069,7 +9285,7 @@ alloc_discriminant_info (struct type *type, int discriminant_index,
 static void
 quirk_rust_enum (struct type *type, struct objfile *objfile)
 {
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+  gdb_assert (type->code () == TYPE_CODE_UNION);
 
   /* We don't need to deal with empty enums.  */
   if (TYPE_NFIELDS (type) == 0)
@@ -9107,55 +9323,44 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
          field_type = TYPE_FIELD_TYPE (field_type, index);
        }
 
-      /* Make a union to hold the variants.  */
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = 3;
-      TYPE_FIELDS (union_type)
+      /* Smash this type to be a structure type.  We have to do this
+        because the type has already been recorded.  */
+      type->set_code (TYPE_CODE_STRUCT);
+      TYPE_NFIELDS (type) = 3;
+      /* Save the field we care about.  */
+      struct field saved_field = TYPE_FIELD (type, 0);
+      TYPE_FIELDS (type)
        = (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
 
-      /* Put the discriminant must at index 0.  */
-      TYPE_FIELD_TYPE (union_type, 0) = field_type;
-      TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
-      TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-      SET_FIELD_BITPOS (TYPE_FIELD (union_type, 0), bit_offset);
+      /* Put the discriminant at index 0.  */
+      TYPE_FIELD_TYPE (type, 0) = field_type;
+      TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), bit_offset);
 
       /* The order of fields doesn't really matter, so put the real
         field at index 1 and the data-less field at index 2.  */
-      struct discriminant_info *disc
-       = alloc_discriminant_info (union_type, 0, 1);
-      TYPE_FIELD (union_type, 1) = TYPE_FIELD (type, 0);
-      TYPE_FIELD_NAME (union_type, 1)
-       = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1)));
-      TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1))
-       = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
-                             TYPE_FIELD_NAME (union_type, 1));
+      TYPE_FIELD (type, 1) = saved_field;
+      TYPE_FIELD_NAME (type, 1)
+       = rust_last_path_segment (TYPE_FIELD_TYPE (type, 1)->name ());
+      TYPE_FIELD_TYPE (type, 1)->set_name
+       (rust_fully_qualify (&objfile->objfile_obstack, type->name (),
+                            TYPE_FIELD_NAME (type, 1)));
 
       const char *dataless_name
-       = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
+       = rust_fully_qualify (&objfile->objfile_obstack, type->name (),
                              name);
       struct type *dataless_type = init_type (objfile, TYPE_CODE_VOID, 0,
                                              dataless_name);
-      TYPE_FIELD_TYPE (union_type, 2) = dataless_type;
+      TYPE_FIELD_TYPE (type, 2) = dataless_type;
       /* NAME points into the original discriminant name, which
         already has the correct lifetime.  */
-      TYPE_FIELD_NAME (union_type, 2) = name;
-      SET_FIELD_BITPOS (TYPE_FIELD (union_type, 2), 0);
-      disc->discriminants[2] = 0;
-
-      /* Smash this type to be a structure type.  We have to do this
-        because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
-      TYPE_NFIELDS (type) = 1;
-      TYPE_FIELDS (type)
-       = (struct field *) TYPE_ZALLOC (type, sizeof (struct field));
+      TYPE_FIELD_NAME (type, 2) = name;
+      SET_FIELD_BITPOS (TYPE_FIELD (type, 2), 0);
 
-      /* Install the variant part.  */
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
+      /* Indicate that this is a variant type.  */
+      static discriminant_range ranges[1] = { { 0, 0 } };
+      alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1, ranges);
     }
   /* A union with a single anonymous field is probably an old-style
      univariant enum.  */
@@ -9163,33 +9368,15 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
     {
       /* Smash this type to be a structure type.  We have to do this
         because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
 
-      /* Make a union to hold the variants.  */
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
-      TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
-
-      struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
+      struct type *field_type = TYPE_FIELD_TYPE (type, 0);
       const char *variant_name
-       = rust_last_path_segment (TYPE_NAME (field_type));
-      TYPE_FIELD_NAME (union_type, 0) = variant_name;
-      TYPE_NAME (field_type)
-       = rust_fully_qualify (&objfile->objfile_obstack,
-                             TYPE_NAME (type), variant_name);
-
-      /* Install the union in the outer struct type.  */
-      TYPE_NFIELDS (type) = 1;
-      TYPE_FIELDS (type)
-       = (struct field *) TYPE_ZALLOC (union_type, sizeof (struct field));
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-
-      alloc_discriminant_info (union_type, -1, 0);
+       = rust_last_path_segment (field_type->name ());
+      TYPE_FIELD_NAME (type, 0) = variant_name;
+      field_type->set_name
+       (rust_fully_qualify (&objfile->objfile_obstack,
+                            type->name (), variant_name));
     }
   else
     {
@@ -9198,7 +9385,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
        {
          disr_type = TYPE_FIELD_TYPE (type, i);
 
-         if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+         if (disr_type->code () != TYPE_CODE_STRUCT)
            {
              /* All fields of a true enum will be structs.  */
              return;
@@ -9228,35 +9415,22 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
 
       /* Smash this type to be a structure type.  We have to do this
         because the type has already been recorded.  */
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
 
-      /* Make a union to hold the variants.  */
+      /* Make space for the discriminant field.  */
       struct field *disr_field = &TYPE_FIELD (disr_type, 0);
-      struct type *union_type = alloc_type (objfile);
-      TYPE_CODE (union_type) = TYPE_CODE_UNION;
-      TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
-      TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
-      set_type_align (union_type, TYPE_RAW_ALIGN (type));
-      TYPE_FIELDS (union_type)
-       = (struct field *) TYPE_ZALLOC (union_type,
-                                       (TYPE_NFIELDS (union_type)
-                                        * sizeof (struct field)));
-
-      memcpy (TYPE_FIELDS (union_type) + 1, TYPE_FIELDS (type),
+      field *new_fields
+       = (struct field *) TYPE_ZALLOC (type, (TYPE_NFIELDS (type)
+                                              * sizeof (struct field)));
+      memcpy (new_fields + 1, TYPE_FIELDS (type),
              TYPE_NFIELDS (type) * sizeof (struct field));
+      TYPE_FIELDS (type) = new_fields;
+      TYPE_NFIELDS (type) = TYPE_NFIELDS (type) + 1;
 
       /* Install the discriminant at index 0 in the union.  */
-      TYPE_FIELD (union_type, 0) = *disr_field;
-      TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
-      TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-
-      /* Install the union in the outer struct type.  */
-      TYPE_FIELD_TYPE (type, 0) = union_type;
-      TYPE_FIELD_NAME (type, 0) = "<<variants>>";
-      TYPE_NFIELDS (type) = 1;
-
-      /* Set the size and offset of the union type.  */
-      SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
+      TYPE_FIELD (type, 0) = *disr_field;
+      TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
 
       /* We need a way to find the correct discriminant given a
         variant name.  For convenience we build a map here.  */
@@ -9272,9 +9446,13 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
            }
        }
 
-      int n_fields = TYPE_NFIELDS (union_type);
-      struct discriminant_info *disc
-       = alloc_discriminant_info (union_type, 0, -1);
+      int n_fields = TYPE_NFIELDS (type);
+      /* We don't need a range entry for the discriminant, but we do
+        need one for every other field, as there is no default
+        variant.  */
+      discriminant_range *ranges = XOBNEWVEC (&objfile->objfile_obstack,
+                                             discriminant_range,
+                                             n_fields - 1);
       /* Skip the discriminant here.  */
       for (int i = 1; i < n_fields; ++i)
        {
@@ -9282,25 +9460,32 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
             That name can be used to look up the correct
             discriminant.  */
          const char *variant_name
-           = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type,
-                                                                 i)));
+           = rust_last_path_segment (TYPE_FIELD_TYPE (type, i)->name ());
 
          auto iter = discriminant_map.find (variant_name);
          if (iter != discriminant_map.end ())
-           disc->discriminants[i] = iter->second;
+           {
+             ranges[i].low = iter->second;
+             ranges[i].high = iter->second;
+           }
 
          /* Remove the discriminant field, if it exists.  */
-         struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
+         struct type *sub_type = TYPE_FIELD_TYPE (type, i);
          if (TYPE_NFIELDS (sub_type) > 0)
            {
              --TYPE_NFIELDS (sub_type);
              ++TYPE_FIELDS (sub_type);
            }
-         TYPE_FIELD_NAME (union_type, i) = variant_name;
-         TYPE_NAME (sub_type)
-           rust_fully_qualify (&objfile->objfile_obstack,
-                                 TYPE_NAME (type), variant_name);
+         TYPE_FIELD_NAME (type, i) = variant_name;
+         sub_type->set_name
+           (rust_fully_qualify (&objfile->objfile_obstack,
+                                type->name (), variant_name));
        }
+
+      /* Indicate that this is a variant type.  */
+      alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1,
+                         gdb::array_view<discriminant_range> (ranges,
+                                                              n_fields - 1));
     }
 }
 
@@ -9449,7 +9634,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
   struct dwarf2_cu *cu = per_cu->cu;
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct compunit_symtab *cust;
   CORE_ADDR baseaddr;
@@ -9894,6 +10079,12 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
   if (linkage_name == NULL)
     linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
 
+  /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
+     See https://github.com/rust-lang/rust/issues/32925.  */
+  if (cu->language == language_rust && linkage_name != NULL
+      && strchr (linkage_name, '{') != NULL)
+    linkage_name = NULL;
+
   return linkage_name;
 }
 
@@ -10108,7 +10299,7 @@ dwarf2_compute_name (const char *name,
                     the two cases.  */
                  if (TYPE_NFIELDS (type) > 0
                      && TYPE_FIELD_ARTIFICIAL (type, 0)
-                     && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
+                     && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_PTR
                      && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
                                                                        0))))
                    buf.puts (" const");
@@ -10168,13 +10359,8 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
   if (!die_needs_namespace (die, cu))
     return dwarf2_compute_name (name, die, cu, 1);
 
-  mangled = dw2_linkage_name (die, cu);
-
-  /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
-     See https://github.com/rust-lang/rust/issues/32925.  */
-  if (cu->language == language_rust && mangled != NULL
-      && strchr (mangled, '{') != NULL)
-    mangled = NULL;
+  if (cu->language != language_rust)
+    mangled = dw2_linkage_name (die, cu);
 
   /* DW_AT_linkage_name is missing in some cases - depend on what GDB
      has computed.  */
@@ -10297,7 +10483,7 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
          sect_offset sect_off = attr->get_ref_die_offset ();
 
          type = get_die_type_at_offset (sect_off, cu->per_cu);
-         if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+         if (type != NULL && type->code () == TYPE_CODE_NAMESPACE)
            {
              /* This declaration is a global namespace alias.  Add
                 a symbol for it whose type is the aliased namespace.  */
@@ -10654,7 +10840,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
@@ -10776,6 +10962,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
                            COMPUNIT_DIRNAME (cust),
                            compunit_language (cust),
                            0, cust));
+         list_in_scope = get_builder ()->get_file_symbols ();
        }
       return;
     }
@@ -10827,6 +11014,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
                        COMPUNIT_DIRNAME (cust),
                        compunit_language (cust),
                        0, cust));
+      list_in_scope = get_builder ()->get_file_symbols ();
 
       auto &file_names = line_header->file_names ();
       for (i = 0; i < file_names.size (); ++i)
@@ -12031,6 +12219,11 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
       dwo_sections->loc.s.section = sectp;
       dwo_sections->loc.size = bfd_section_size (sectp);
     }
+  else if (section_is_p (sectp->name, &names->loclists_dwo))
+    {
+      dwo_sections->loclists.s.section = sectp;
+      dwo_sections->loclists.size = bfd_section_size (sectp);
+    }
   else if (section_is_p (sectp->name, &names->macinfo_dwo))
     {
       dwo_sections->macinfo.s.section = sectp;
@@ -12728,7 +12921,7 @@ static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct context_stack *newobj;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
@@ -12790,7 +12983,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
       if (child_die->tag == DW_TAG_template_type_param
          || child_die->tag == DW_TAG_template_value_param)
        {
-         templ_func = allocate_template_symbol (objfile);
+         templ_func = new (&objfile->objfile_obstack) template_symbol;
          templ_func->subclass = SYMBOL_TEMPLATE;
          break;
        }
@@ -12929,7 +13122,7 @@ static void
 read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
   CORE_ADDR baseaddr;
@@ -12950,7 +13143,16 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
       for (child_die = die->child;
           child_die != NULL && child_die->tag;
           child_die = child_die->sibling)
-       process_die (child_die, cu);
+       {
+         /* We might already be processing this DIE.  This can happen
+            in an unusual circumstance -- where a subroutine A
+            appears lexically in another subroutine B, but A actually
+            inlines B.  The recursion is broken here, rather than in
+            inherit_abstract_dies, because it seems better to simply
+            drop concrete children here.  */
+         if (!child_die->in_process)
+           process_die (child_die, cu);
+       }
       return;
     case PC_BOUNDS_INVALID:
       return;
@@ -13000,7 +13202,7 @@ static void
 read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR pc, baseaddr;
   struct attribute *attr;
   struct call_site *call_site, call_site_local;
@@ -13106,7 +13308,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
            func_type = get_die_type (func_die, cu);
          if (func_type != NULL)
            {
-             gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+             gdb_assert (func_type->code () == TYPE_CODE_FUNC);
 
              /* Enlist this call site to the function.  */
              call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
@@ -13344,8 +13546,7 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
        {
          struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
 
-         storage = new (&objfile->objfile_obstack) rust_vtable_symbol ();
-         initialize_objfile_symbol (storage);
+         storage = new (&objfile->objfile_obstack) rust_vtable_symbol;
          storage->concrete_type = containing_type;
          storage->subclass = SYMBOL_RUST_VTABLE;
        }
@@ -13645,7 +13846,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
                    dwarf2_psymtab *ranges_pst)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
   int low_set = 0;
   CORE_ADDR low = 0;
@@ -13889,7 +14090,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
                             CORE_ADDR baseaddr, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct attribute *attr;
   struct attribute *attr_high;
 
@@ -14070,6 +14271,53 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
   return 0;
 }
 
+/* Look for DW_AT_data_member_location and store the results in FIELD.  */
+
+static void
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                            struct field *field)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+  if (attr != NULL)
+    {
+      if (attr->form_is_constant ())
+       {
+         LONGEST offset = attr->constant_value (0);
+         SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+       }
+      else if (attr->form_is_section_offset ())
+       dwarf2_complex_location_expr_complaint ();
+      else if (attr->form_is_block ())
+       {
+         bool handled;
+         CORE_ADDR offset = decode_locdesc (DW_BLOCK (attr), cu, &handled);
+         if (handled)
+           SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+         else
+           {
+             struct objfile *objfile
+               = cu->per_cu->dwarf2_per_objfile->objfile;
+             struct dwarf2_locexpr_baton *dlbaton
+               = XOBNEW (&objfile->objfile_obstack,
+                         struct dwarf2_locexpr_baton);
+             dlbaton->data = DW_BLOCK (attr)->data;
+             dlbaton->size = DW_BLOCK (attr)->size;
+             /* When using this baton, we want to compute the address
+                of the field, not the value.  This is why
+                is_reference is set to false here.  */
+             dlbaton->is_reference = false;
+             dlbaton->per_cu = cu->per_cu;
+
+             SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+           }
+       }
+      else
+       dwarf2_complex_location_expr_complaint ();
+    }
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -14077,7 +14325,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
                  struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct nextfield *new_field;
   struct attribute *attr;
   struct field *fp;
@@ -14094,6 +14342,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       new_field = &fip->fields.back ();
     }
 
+  new_field->offset = die->sect_off;
+
   attr = dwarf2_attr (die, DW_AT_accessibility, cu);
   if (attr != nullptr)
     new_field->accessibility = DW_UNSND (attr);
@@ -14112,8 +14362,6 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
     {
-      LONGEST offset;
-
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -14133,8 +14381,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      if (handle_data_member_location (die, cu, &offset))
-       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+      handle_data_member_location (die, cu, fp);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr != nullptr)
        {
@@ -14243,43 +14490,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
   else if (die->tag == DW_TAG_inheritance)
     {
-      LONGEST offset;
-
       /* C++ base class field.  */
-      if (handle_data_member_location (die, cu, &offset))
-       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+      handle_data_member_location (die, cu, fp);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
-      FIELD_NAME (*fp) = TYPE_NAME (fp->type);
-    }
-  else if (die->tag == DW_TAG_variant_part)
-    {
-      /* process_structure_scope will treat this DIE as a union.  */
-      process_structure_scope (die, cu);
-
-      /* The variant part is relative to the start of the enclosing
-        structure.  */
-      SET_FIELD_BITPOS (*fp, 0);
-      fp->type = get_die_type (die, cu);
-      fp->artificial = 1;
-      fp->name = "<<variant>>";
-
-      /* Normally a DW_TAG_variant_part won't have a size, but our
-        representation requires one, so set it to the maximum of the
-        child sizes, being sure to account for the offset at which
-        each child is seen.  */
-      if (TYPE_LENGTH (fp->type) == 0)
-       {
-         unsigned max = 0;
-         for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
-           {
-             unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8
-                             + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)));
-             if (len > max)
-               max = len;
-           }
-         TYPE_LENGTH (fp->type) = max;
-       }
+      FIELD_NAME (*fp) = fp->type->name ();
     }
   else
     gdb_assert_not_reached ("missing case in dwarf2_add_field");
@@ -14347,6 +14562,202 @@ dwarf2_add_type_defn (struct field_info *fip, struct die_info *die,
     fip->nested_types_list.push_back (fp);
 }
 
+/* A convenience typedef that's used when finding the discriminant
+   field for a variant part.  */
+typedef std::unordered_map<sect_offset, int, gdb::hash_enum<sect_offset>>
+  offset_map_type;
+
+/* Compute the discriminant range for a given variant.  OBSTACK is
+   where the results will be stored.  VARIANT is the variant to
+   process.  IS_UNSIGNED indicates whether the discriminant is signed
+   or unsigned.  */
+
+static const gdb::array_view<discriminant_range>
+convert_variant_range (struct obstack *obstack, const variant_field &variant,
+                      bool is_unsigned)
+{
+  std::vector<discriminant_range> ranges;
+
+  if (variant.default_branch)
+    return {};
+
+  if (variant.discr_list_data == nullptr)
+    {
+      discriminant_range r
+       = {variant.discriminant_value, variant.discriminant_value};
+      ranges.push_back (r);
+    }
+  else
+    {
+      gdb::array_view<const gdb_byte> data (variant.discr_list_data->data,
+                                           variant.discr_list_data->size);
+      while (!data.empty ())
+       {
+         if (data[0] != DW_DSC_range && data[0] != DW_DSC_label)
+           {
+             complaint (_("invalid discriminant marker: %d"), data[0]);
+             break;
+           }
+         bool is_range = data[0] == DW_DSC_range;
+         data = data.slice (1);
+
+         ULONGEST low, high;
+         unsigned int bytes_read;
+
+         if (data.empty ())
+           {
+             complaint (_("DW_AT_discr_list missing low value"));
+             break;
+           }
+         if (is_unsigned)
+           low = read_unsigned_leb128 (nullptr, data.data (), &bytes_read);
+         else
+           low = (ULONGEST) read_signed_leb128 (nullptr, data.data (),
+                                                &bytes_read);
+         data = data.slice (bytes_read);
+
+         if (is_range)
+           {
+             if (data.empty ())
+               {
+                 complaint (_("DW_AT_discr_list missing high value"));
+                 break;
+               }
+             if (is_unsigned)
+               high = read_unsigned_leb128 (nullptr, data.data (),
+                                            &bytes_read);
+             else
+               high = (LONGEST) read_signed_leb128 (nullptr, data.data (),
+                                                    &bytes_read);
+             data = data.slice (bytes_read);
+           }
+         else
+           high = low;
+
+         ranges.push_back ({ low, high });
+       }
+    }
+
+  discriminant_range *result = XOBNEWVEC (obstack, discriminant_range,
+                                         ranges.size ());
+  std::copy (ranges.begin (), ranges.end (), result);
+  return gdb::array_view<discriminant_range> (result, ranges.size ());
+}
+
+static const gdb::array_view<variant_part> create_variant_parts
+  (struct obstack *obstack,
+   const offset_map_type &offset_map,
+   struct field_info *fi,
+   const std::vector<variant_part_builder> &variant_parts);
+
+/* Fill in a "struct variant" for a given variant field.  RESULT is
+   the variant to fill in.  OBSTACK is where any needed allocations
+   will be done.  OFFSET_MAP holds the mapping from section offsets to
+   fields for the type.  FI describes the fields of the type we're
+   processing.  FIELD is the variant field we're converting.  */
+
+static void
+create_one_variant (variant &result, struct obstack *obstack,
+                   const offset_map_type &offset_map,
+                   struct field_info *fi, const variant_field &field)
+{
+  result.discriminants = convert_variant_range (obstack, field, false);
+  result.first_field = field.first_field + fi->baseclasses.size ();
+  result.last_field = field.last_field + fi->baseclasses.size ();
+  result.parts = create_variant_parts (obstack, offset_map, fi,
+                                      field.variant_parts);
+}
+
+/* Fill in a "struct variant_part" for a given variant part.  RESULT
+   is the variant part to fill in.  OBSTACK is where any needed
+   allocations will be done.  OFFSET_MAP holds the mapping from
+   section offsets to fields for the type.  FI describes the fields of
+   the type we're processing.  BUILDER is the variant part to be
+   converted.  */
+
+static void
+create_one_variant_part (variant_part &result,
+                        struct obstack *obstack,
+                        const offset_map_type &offset_map,
+                        struct field_info *fi,
+                        const variant_part_builder &builder)
+{
+  auto iter = offset_map.find (builder.discriminant_offset);
+  if (iter == offset_map.end ())
+    {
+      result.discriminant_index = -1;
+      /* Doesn't matter.  */
+      result.is_unsigned = false;
+    }
+  else
+    {
+      result.discriminant_index = iter->second;
+      result.is_unsigned
+       = TYPE_UNSIGNED (FIELD_TYPE
+                        (fi->fields[result.discriminant_index].field));
+    }
+
+  size_t n = builder.variants.size ();
+  variant *output = new (obstack) variant[n];
+  for (size_t i = 0; i < n; ++i)
+    create_one_variant (output[i], obstack, offset_map, fi,
+                       builder.variants[i]);
+
+  result.variants = gdb::array_view<variant> (output, n);
+}
+
+/* Create a vector of variant parts that can be attached to a type.
+   OBSTACK is where any needed allocations will be done.  OFFSET_MAP
+   holds the mapping from section offsets to fields for the type.  FI
+   describes the fields of the type we're processing.  VARIANT_PARTS
+   is the vector to convert.  */
+
+static const gdb::array_view<variant_part>
+create_variant_parts (struct obstack *obstack,
+                     const offset_map_type &offset_map,
+                     struct field_info *fi,
+                     const std::vector<variant_part_builder> &variant_parts)
+{
+  if (variant_parts.empty ())
+    return {};
+
+  size_t n = variant_parts.size ();
+  variant_part *result = new (obstack) variant_part[n];
+  for (size_t i = 0; i < n; ++i)
+    create_one_variant_part (result[i], obstack, offset_map, fi,
+                            variant_parts[i]);
+
+  return gdb::array_view<variant_part> (result, n);
+}
+
+/* Compute the variant part vector for FIP, attaching it to TYPE when
+   done.  */
+
+static void
+add_variant_property (struct field_info *fip, struct type *type,
+                     struct dwarf2_cu *cu)
+{
+  /* Map section offsets of fields to their field index.  Note the
+     field index here does not take the number of baseclasses into
+     account.  */
+  offset_map_type offset_map;
+  for (int i = 0; i < fip->fields.size (); ++i)
+    offset_map[fip->fields[i].offset] = i;
+
+  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  gdb::array_view<variant_part> parts
+    = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
+                           fip->variant_parts);
+
+  struct dynamic_prop prop;
+  prop.kind = PROP_VARIANT_PARTS;
+  prop.data.variant_parts
+    = ((gdb::array_view<variant_part> *)
+       obstack_copy (&objfile->objfile_obstack, &parts, sizeof (parts)));
+
+  type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
+}
+
 /* Create the vector of fields, and attach it to the type.  */
 
 static void
@@ -14392,22 +14803,8 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
       TYPE_N_BASECLASSES (type) = fip->baseclasses.size ();
     }
 
-  if (TYPE_FLAG_DISCRIMINATED_UNION (type))
-    {
-      struct discriminant_info *di = alloc_discriminant_info (type, -1, -1);
-
-      for (int index = 0; index < nfields; ++index)
-       {
-         struct nextfield &field = fip->fields[index];
-
-         if (field.variant.is_discriminant)
-           di->discriminant_index = index;
-         else if (field.variant.default_branch)
-           di->default_index = index;
-         else
-           di->discriminants[index] = field.variant.discriminant_value;
-       }
-    }
+  if (!fip->variant_parts.empty ())
+    add_variant_property (fip, type, cu);
 
   /* Copy the saved-up fields into the field vector.  */
   for (int i = 0; i < nfields; ++i)
@@ -14561,7 +14958,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 
   fnp->type = alloc_type (objfile);
   this_type = read_type_die (die, cu);
-  if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
+  if (this_type && this_type->code () == TYPE_CODE_FUNC)
     {
       int nparams = TYPE_NFIELDS (this_type);
 
@@ -14759,7 +15156,7 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   struct type *pfn_type, *self_type, *new_type;
 
   /* Check for a structure with no name and two children.  */
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+  if (type->code () != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
     return;
 
   /* Check for __pfn and __delta members.  */
@@ -14772,15 +15169,15 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   /* Find the type of the method.  */
   pfn_type = TYPE_FIELD_TYPE (type, 0);
   if (pfn_type == NULL
-      || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
-      || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+      || pfn_type->code () != TYPE_CODE_PTR
+      || TYPE_TARGET_TYPE (pfn_type)->code () != TYPE_CODE_FUNC)
     return;
 
   /* Look for the "this" argument.  */
   pfn_type = TYPE_TARGET_TYPE (pfn_type);
   if (TYPE_NFIELDS (pfn_type) == 0
       /* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
-      || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+      || TYPE_FIELD_TYPE (pfn_type, 0)->code () != TYPE_CODE_PTR)
     return;
 
   self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
@@ -14959,32 +15356,27 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
          if (get_die_type (die, cu) != NULL)
            return get_die_type (die, cu);
 
-         TYPE_NAME (type) = full_name;
+         type->set_name (full_name);
        }
       else
        {
          /* The name is already allocated along with this objfile, so
             we don't need to duplicate it for the type.  */
-         TYPE_NAME (type) = name;
+         type->set_name (name);
        }
     }
 
   if (die->tag == DW_TAG_structure_type)
     {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
     }
   else if (die->tag == DW_TAG_union_type)
     {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-    }
-  else if (die->tag == DW_TAG_variant_part)
-    {
-      TYPE_CODE (type) = TYPE_CODE_UNION;
-      TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+      type->set_code (TYPE_CODE_UNION);
     }
   else
     {
-      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      type->set_code (TYPE_CODE_STRUCT);
     }
 
   if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
@@ -15009,14 +15401,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
         TYPE_LENGTH (type) = DW_UNSND (attr);
       else
        {
-         /* For the moment, dynamic type sizes are not supported
-            by GDB's struct type.  The actual size is determined
-            on-demand when resolving the type of a given object,
-            so set the type's length to zero for now.  Otherwise,
-            we record an expression as the length, and that expression
-            could lead to a very large value, which could eventually
-            lead to us trying to allocate that much memory when creating
-            a value of that type.  */
+         struct dynamic_prop prop;
+         if (attr_to_dynamic_prop (attr, die, cu, &prop,
+                                   cu->per_cu->addr_type ()))
+           type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
           TYPE_LENGTH (type) = 0;
        }
     }
@@ -15055,6 +15443,130 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   return type;
 }
 
+static void handle_struct_member_die
+  (struct die_info *child_die,
+   struct type *type,
+   struct field_info *fi,
+   std::vector<struct symbol *> *template_args,
+   struct dwarf2_cu *cu);
+
+/* A helper for handle_struct_member_die that handles
+   DW_TAG_variant_part.  */
+
+static void
+handle_variant_part (struct die_info *die, struct type *type,
+                    struct field_info *fi,
+                    std::vector<struct symbol *> *template_args,
+                    struct dwarf2_cu *cu)
+{
+  variant_part_builder *new_part;
+  if (fi->current_variant_part == nullptr)
+    {
+      fi->variant_parts.emplace_back ();
+      new_part = &fi->variant_parts.back ();
+    }
+  else if (!fi->current_variant_part->processing_variant)
+    {
+      complaint (_("nested DW_TAG_variant_part seen "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return;
+    }
+  else
+    {
+      variant_field &current = fi->current_variant_part->variants.back ();
+      current.variant_parts.emplace_back ();
+      new_part = &current.variant_parts.back ();
+    }
+
+  /* When we recurse, we want callees to add to this new variant
+     part.  */
+  scoped_restore save_current_variant_part
+    = make_scoped_restore (&fi->current_variant_part, new_part);
+
+  struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
+  if (discr == NULL)
+    {
+      /* It's a univariant form, an extension we support.  */
+    }
+  else if (discr->form_is_ref ())
+    {
+      struct dwarf2_cu *target_cu = cu;
+      struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
+
+      new_part->discriminant_offset = target_die->sect_off;
+    }
+  else
+    {
+      complaint (_("DW_AT_discr does not have DIE reference form"
+                  " - DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+    }
+
+  for (die_info *child_die = die->child;
+       child_die != NULL;
+       child_die = child_die->sibling)
+    handle_struct_member_die (child_die, type, fi, template_args, cu);
+}
+
+/* A helper for handle_struct_member_die that handles
+   DW_TAG_variant.  */
+
+static void
+handle_variant (struct die_info *die, struct type *type,
+               struct field_info *fi,
+               std::vector<struct symbol *> *template_args,
+               struct dwarf2_cu *cu)
+{
+  if (fi->current_variant_part == nullptr)
+    {
+      complaint (_("saw DW_TAG_variant outside DW_TAG_variant_part "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return;
+    }
+  if (fi->current_variant_part->processing_variant)
+    {
+      complaint (_("nested DW_TAG_variant seen "
+                  "- DIE at %s [in module %s]"),
+                sect_offset_str (die->sect_off),
+                objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return;
+    }
+
+  scoped_restore save_processing_variant
+    = make_scoped_restore (&fi->current_variant_part->processing_variant,
+                          true);
+
+  fi->current_variant_part->variants.emplace_back ();
+  variant_field &variant = fi->current_variant_part->variants.back ();
+  variant.first_field = fi->fields.size ();
+
+  /* In a variant we want to get the discriminant and also add a
+     field for our sole member child.  */
+  struct attribute *discr = dwarf2_attr (die, DW_AT_discr_value, cu);
+  if (discr == nullptr)
+    {
+      discr = dwarf2_attr (die, DW_AT_discr_list, cu);
+      if (discr == nullptr || DW_BLOCK (discr)->size == 0)
+       variant.default_branch = true;
+      else
+       variant.discr_list_data = DW_BLOCK (discr);
+    }
+  else
+    variant.discriminant_value = DW_UNSND (discr);
+
+  for (die_info *variant_child = die->child;
+       variant_child != NULL;
+       variant_child = variant_child->sibling)
+    handle_struct_member_die (variant_child, type, fi, template_args, cu);
+
+  variant.last_field = fi->fields.size ();
+}
+
 /* A helper for process_structure_scope that handles a single member
    DIE.  */
 
@@ -15065,8 +15577,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
                          struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable
-      || child_die->tag == DW_TAG_variant_part)
+      || child_die->tag == DW_TAG_variable)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
         should be a DW_TAG_member that is a declaration, but
@@ -15103,41 +15614,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
       if (arg != NULL)
        template_args->push_back (arg);
     }
+  else if (child_die->tag == DW_TAG_variant_part)
+    handle_variant_part (child_die, type, fi, template_args, cu);
   else if (child_die->tag == DW_TAG_variant)
-    {
-      /* In a variant we want to get the discriminant and also add a
-        field for our sole member child.  */
-      struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
-
-      for (die_info *variant_child = child_die->child;
-          variant_child != NULL;
-          variant_child = variant_child->sibling)
-       {
-         if (variant_child->tag == DW_TAG_member)
-           {
-             handle_struct_member_die (variant_child, type, fi,
-                                       template_args, cu);
-             /* Only handle the one.  */
-             break;
-           }
-       }
-
-      /* We don't handle this but we might as well report it if we see
-        it.  */
-      if (dwarf2_attr (child_die, DW_AT_discr_list, cu) != nullptr)
-         complaint (_("DW_AT_discr_list is not supported yet"
-                      " - DIE at %s [in module %s]"),
-                    sect_offset_str (child_die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-
-      /* The first field was just added, so we can stash the
-        discriminant there.  */
-      gdb_assert (!fi->fields.empty ());
-      if (discr == NULL)
-       fi->fields.back ().variant.default_branch = true;
-      else
-       fi->fields.back ().variant.discriminant_value = DW_UNSND (discr);
-    }
+    handle_variant (child_die, type, fi, template_args, cu);
 }
 
 /* Finish creating a structure or union type, including filling in
@@ -15154,39 +15634,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (type == NULL)
     type = read_structure_type (die, cu);
 
-  /* When reading a DW_TAG_variant_part, we need to notice when we
-     read the discriminant member, so we can record it later in the
-     discriminant_info.  */
-  bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
-  sect_offset discr_offset {};
   bool has_template_parameters = false;
-
-  if (is_variant_part)
-    {
-      struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
-      if (discr == NULL)
-       {
-         /* Maybe it's a univariant form, an extension we support.
-            In this case arrange not to check the offset.  */
-         is_variant_part = false;
-       }
-      else if (discr->form_is_ref ())
-       {
-         struct dwarf2_cu *target_cu = cu;
-         struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
-
-         discr_offset = target_die->sect_off;
-       }
-      else
-       {
-         complaint (_("DW_AT_discr does not have DIE reference form"
-                      " - DIE at %s [in module %s]"),
-                    sect_offset_str (die->sect_off),
-                    objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-         is_variant_part = false;
-       }
-    }
-
   if (die->child != NULL && ! die_is_declaration (die, cu))
     {
       struct field_info fi;
@@ -15197,10 +15645,6 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       while (child_die && child_die->tag)
        {
          handle_struct_member_die (child_die, type, &fi, &template_args, cu);
-
-         if (is_variant_part && discr_offset == child_die->sect_off)
-           fi.fields.back ().variant.is_discriminant = true;
-
          child_die = child_die->sibling;
        }
 
@@ -15259,7 +15703,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                  if (i < TYPE_N_BASECLASSES (t))
                    complaint (_("virtual function table pointer "
                                 "not found when defining class '%s'"),
-                              TYPE_NAME (type) ? TYPE_NAME (type) : "");
+                              type->name () ? type->name () : "");
                }
              else
                {
@@ -15356,7 +15800,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
      these DIEs are identified by the fact that they have no byte_size
      attribute, and a declaration attribute.  */
   if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
-      || !die_is_declaration (die, cu))
+      || !die_is_declaration (die, cu)
+      || dwarf2_attr (die, DW_AT_signature, cu) != NULL)
     {
       struct symbol *sym = new_symbol (die, type, cu);
 
@@ -15394,8 +15839,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Assuming DIE is an enumeration type, and TYPE is its associated type,
-   update TYPE using some information only available in DIE's children.  */
+/* Assuming DIE is an enumeration type, and TYPE is its associated
+   type, update TYPE using some information only available in DIE's
+   children.  In particular, the fields are computed.  */
 
 static void
 update_enumeration_type_from_children (struct die_info *die,
@@ -15407,6 +15853,7 @@ update_enumeration_type_from_children (struct die_info *die,
   int flag_enum = 1;
 
   auto_obstack obstack;
+  std::vector<struct field> fields;
 
   for (child_die = die->child;
        child_die != NULL && child_die->tag;
@@ -15442,10 +15889,19 @@ update_enumeration_type_from_children (struct die_info *die,
            flag_enum = 0;
        }
 
-      /* If we already know that the enum type is neither unsigned, nor
-        a flag type, no need to look at the rest of the enumerates.  */
-      if (!unsigned_enum && !flag_enum)
-       break;
+      fields.emplace_back ();
+      struct field &field = fields.back ();
+      FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
+      SET_FIELD_ENUMVAL (field, value);
+    }
+
+  if (!fields.empty ())
+    {
+      TYPE_NFIELDS (type) = fields.size ();
+      TYPE_FIELDS (type) = (struct field *)
+       TYPE_ALLOC (type, sizeof (struct field) * fields.size ());
+      memcpy (TYPE_FIELDS (type), fields.data (),
+             sizeof (struct field) * fields.size ());
     }
 
   if (unsigned_enum)
@@ -15480,10 +15936,10 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = alloc_type (objfile);
 
-  TYPE_CODE (type) = TYPE_CODE_ENUM;
+  type->set_code (TYPE_CODE_ENUM);
   name = dwarf2_full_name (NULL, die, cu);
   if (name != NULL)
-    TYPE_NAME (type) = name;
+    type->set_name (name);
 
   attr = dwarf2_attr (die, DW_AT_type, cu);
   if (attr != NULL)
@@ -15513,11 +15969,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   if (die_is_declaration (die, cu))
     TYPE_STUB (type) = 1;
 
-  /* Finish the creation of this type by using the enum's children.
-     We must call this even when the underlying type has been provided
-     so that we can determine if we're looking at a "flag" enum.  */
-  update_enumeration_type_from_children (die, type, cu);
-
   /* If this type has an underlying type that is not a stub, then we
      may use its attributes.  We always use the "unsigned" attribute
      in this situation, because ordinarily we guess whether the type
@@ -15527,17 +15978,27 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
      the underlying type if needed.  */
   if (TYPE_TARGET_TYPE (type) != NULL && !TYPE_STUB (TYPE_TARGET_TYPE (type)))
     {
-      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
+      struct type *underlying_type = TYPE_TARGET_TYPE (type);
+      underlying_type = check_typedef (underlying_type);
+      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (underlying_type);
       if (TYPE_LENGTH (type) == 0)
-       TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+       TYPE_LENGTH (type) = TYPE_LENGTH (underlying_type);
       if (TYPE_RAW_ALIGN (type) == 0
-         && TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
-       set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
+         && TYPE_RAW_ALIGN (underlying_type) != 0)
+       set_type_align (type, TYPE_RAW_ALIGN (underlying_type));
     }
 
   TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
 
-  return set_die_type (die, type, cu);
+  set_die_type (die, type, cu);
+
+  /* Finish the creation of this type by using the enum's children.
+     Note that, as usual, this must come after set_die_type to avoid
+     infinite recursion when trying to compute the names of the
+     enumerators.  */
+  update_enumeration_type_from_children (die, type, cu);
+
+  return type;
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -15558,8 +16019,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (die->child != NULL)
     {
       struct die_info *child_die;
-      struct symbol *sym;
-      std::vector<struct field> fields;
       const char *name;
 
       child_die = die->child;
@@ -15573,30 +16032,11 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
            {
              name = dwarf2_name (child_die, cu);
              if (name)
-               {
-                 sym = new_symbol (child_die, this_type, cu);
-
-                 fields.emplace_back ();
-                 struct field &field = fields.back ();
-
-                 FIELD_NAME (field) = sym->linkage_name ();
-                 FIELD_TYPE (field) = NULL;
-                 SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
-                 FIELD_BITSIZE (field) = 0;
-               }
+               new_symbol (child_die, this_type, cu);
            }
 
          child_die = child_die->sibling;
        }
-
-      if (!fields.empty ())
-       {
-         TYPE_NFIELDS (this_type) = fields.size ();
-         TYPE_FIELDS (this_type) = (struct field *)
-           TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
-         memcpy (TYPE_FIELDS (this_type), fields.data (),
-                 sizeof (struct field) * fields.size ());
-       }
     }
 
   /* If we are reading an enum from a .debug_types unit, and the enum
@@ -15746,7 +16186,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 
   name = dwarf2_name (die, cu);
   if (name)
-    TYPE_NAME (type) = name;
+    type->set_name (name);
 
   maybe_set_alignment (cu, die, type);
 
@@ -15841,7 +16281,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
   struct dwarf2_locexpr_baton *baton;
   gdb_byte *ptr;
   unsigned int cu_off;
-  enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+  enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
   LONGEST offset = 0;
 
   gdb_assert (common_loc && member_loc);
@@ -16057,7 +16497,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 
          std::vector<const char *> excludes;
          add_using_directive (using_directives (cu),
-                              previous_prefix, TYPE_NAME (type), NULL,
+                              previous_prefix, type->name (), NULL,
                               NULL, excludes, 0, &objfile->objfile_obstack);
        }
     }
@@ -16149,7 +16589,7 @@ static struct type *
 read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct gdbarch *gdbarch
-    = get_objfile_arch (cu->per_cu->dwarf2_per_objfile->objfile);
+    = cu->per_cu->dwarf2_per_objfile->objfile->arch ();
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
@@ -16238,9 +16678,9 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+  if (check_typedef (to_type)->code () == TYPE_CODE_METHOD)
     type = lookup_methodptr_type (to_type);
-  else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+  else if (check_typedef (to_type)->code () == TYPE_CODE_FUNC)
     {
       struct type *new_type
        = alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
@@ -16305,7 +16745,7 @@ add_array_cv_type (struct die_info *die, struct dwarf2_cu *cu,
   base_type = copy_type (base_type);
   inner_array = base_type;
 
-  while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+  while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
     {
       TYPE_TARGET_TYPE (inner_array) =
        copy_type (TYPE_TARGET_TYPE (inner_array));
@@ -16334,7 +16774,7 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
 
   /* In case the const qualifier is applied to an array type, the element type
      is so qualified, not the array type (section 6.7.3 of C99).  */
-  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+  if (base_type->code () == TYPE_CODE_ARRAY)
     return add_array_cv_type (die, cu, base_type, 1, 0);
 
   cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
@@ -16356,7 +16796,7 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
   /* In case the volatile qualifier is applied to an array type, the
      element type is so qualified, not the array type (section 6.7.3
      of C99).  */
-  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+  if (base_type->code () == TYPE_CODE_ARRAY)
     return add_array_cv_type (die, cu, base_type, 0, 1);
 
   cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
@@ -16408,7 +16848,7 @@ static struct type *
 read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
   struct dynamic_prop prop;
@@ -16726,7 +17166,7 @@ static struct type *
 dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
                        const char *name_hint, enum bfd_endian byte_order)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   const struct floatformat **format;
   struct type *type;
 
@@ -16774,7 +17214,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
                                 int bits, const char *name_hint,
                                 enum bfd_endian byte_order)
 {
-  gdbarch *gdbarch = get_objfile_arch (objfile);
+  gdbarch *gdbarch = objfile->arch ();
   struct type *tt = nullptr;
 
   /* Try to find a suitable floating point builtin type of size BITS.
@@ -16820,7 +17260,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
   if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
     tt = nullptr;
 
-  const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
+  const char *name = (tt == nullptr) ? nullptr : tt->name ();
   return dwarf2_init_float_type (objfile, bits, name, name_hint, byte_order);
 }
 
@@ -16847,7 +17287,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!name)
     complaint (_("DW_AT_name missing from DW_TAG_base_type"));
 
-  arch = get_objfile_arch (objfile);
+  arch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (arch);
 
   attr = dwarf2_attr (die, DW_AT_endianity, cu);
@@ -16882,7 +17322,19 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
       case DW_ATE_complex_float:
        type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name,
                                                byte_order);
-       type = init_complex_type (name, type);
+       if (type->code () == TYPE_CODE_ERROR)
+         {
+           if (name == nullptr)
+             {
+               struct obstack *obstack
+                 = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+               name = obconcat (obstack, "_Complex ", type->name (),
+                                nullptr);
+             }
+           type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
+         }
+       else
+         type = init_complex_type (name, type);
        break;
       case DW_ATE_decimal_float:
        type = init_decfloat_type (objfile, bits, name);
@@ -17125,7 +17577,7 @@ read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu)
      GCC produces an empty range DIE.
      FIXME: muller/2010-05-28: Possible references to object for low bound,
      high bound or count are not yet handled by this code.  */
-  if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
+  if (index_type->code () == TYPE_CODE_VOID)
     index_type = cu->per_cu->addr_sized_int_type (false);
 
   return index_type;
@@ -17305,7 +17757,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   name = dwarf2_name (die, cu);
   if (name)
-    TYPE_NAME (range_type) = name;
+    range_type->set_name (name);
 
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr != nullptr)
@@ -17328,7 +17780,7 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
                    NULL);
-  TYPE_NAME (type) = dwarf2_name (die, cu);
+  type->set_name (dwarf2_name (die, cu));
 
   /* In Ada, an unspecified type is typically used when the description
      of the type is deferred to a different unit.  When encountering
@@ -17498,6 +17950,10 @@ read_full_die_1 (const struct die_reader_specs *reader,
   if (attr != nullptr)
     cu->str_offsets_base = DW_UNSND (attr);
 
+  attr = die->attr (DW_AT_loclists_base);
+  if (attr != nullptr)
+    cu->loclist_base = DW_UNSND (attr);
+
   auto maybe_addr_base = die->addr_base ();
   if (maybe_addr_base.has_value ())
     cu->addr_base = *maybe_addr_base;
@@ -17853,18 +18309,17 @@ partial_die_info::read (const struct die_reader_specs *reader,
   int has_high_pc_attr = 0;
   int high_pc_relative = 0;
 
-  std::vector<struct attribute> attr_vec (abbrev.num_attrs);
   for (i = 0; i < abbrev.num_attrs; ++i)
     {
+      attribute attr;
       bool need_reprocess;
-      info_ptr = read_attribute (reader, &attr_vec[i], &abbrev.attrs[i],
+      info_ptr = read_attribute (reader, &attr, &abbrev.attrs[i],
                                 info_ptr, &need_reprocess);
       /* String and address offsets that need to do the reprocessing have
          already been read at this point, so there is no need to wait until
         the loop terminates to do the reprocessing.  */
       if (need_reprocess)
-       read_attribute_reprocess (reader, &attr_vec[i]);
-      attribute &attr = attr_vec[i];
+       read_attribute_reprocess (reader, &attr);
       /* Store the data if it is of an attribute we want to keep in a
          partial symbol table.  */
       switch (attr.name)
@@ -17898,7 +18353,12 @@ partial_die_info::read (const struct die_reader_specs *reader,
          /* Note that both forms of linkage name might appear.  We
             assume they will be the same, and we only store the last
             one we see.  */
-         linkage_name = DW_STRING (&attr);
+         linkage_name = attr.value_as_string ();
+         /* rustc emits invalid values for DW_AT_linkage_name.  Ignore these.
+            See https://github.com/rust-lang/rust/issues/32925.  */
+         if (cu->language == language_rust && linkage_name != NULL
+             && strchr (linkage_name, '{') != NULL)
+           linkage_name = NULL;
          break;
        case DW_AT_low_pc:
          has_low_pc_attr = 1;
@@ -18054,7 +18514,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
       if (lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
        {
          struct objfile *objfile = dwarf2_per_objfile->objfile;
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct gdbarch *gdbarch = objfile->arch ();
 
          complaint (_("DW_AT_low_pc %s is zero "
                       "for DIE at %s [in module %s]"),
@@ -18066,7 +18526,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
       else if (lowpc >= highpc)
        {
          struct objfile *objfile = dwarf2_per_objfile->objfile;
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct gdbarch *gdbarch = objfile->arch ();
 
          complaint (_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
                       "for DIE at %s [in module %s]"),
@@ -18220,6 +18680,25 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
     }
 }
 
+/* Return true if a DIE with TAG may have the DW_AT_const_value
+   attribute.  */
+
+static bool
+can_have_DW_AT_const_value_p (enum dwarf_tag tag)
+{
+  switch (tag)
+    {
+    case DW_TAG_constant:
+    case DW_TAG_enumerator:
+    case DW_TAG_formal_parameter:
+    case DW_TAG_template_value_param:
+    case DW_TAG_variable:
+      return true;
+    }
+
+  return false;
+}
+
 void
 partial_die_info::fixup (struct dwarf2_cu *cu)
 {
@@ -18252,6 +18731,24 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
        }
     }
 
+  if (!has_const_value && has_specification
+      && can_have_DW_AT_const_value_p (tag))
+    {
+      struct partial_die_info *spec_die;
+
+      auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+      spec_die = res.pdi;
+      cu = res.cu;
+
+      spec_die->fixup (cu);
+
+      if (spec_die->has_const_value)
+       {
+         /* Copy DW_AT_const_value attribute if it is set.  */
+         has_const_value = spec_die->has_const_value;
+       }
+    }
+
   /* Set default names for some unnamed DIEs.  */
 
   if (name == NULL && tag == DW_TAG_namespace)
@@ -18300,6 +18797,84 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
   fixup_called = 1;
 }
 
+/* Read the .debug_loclists header contents from the given SECTION in the
+   HEADER.  */
+static void
+read_loclist_header (struct loclist_header *header,
+                     struct dwarf2_section_info *section)
+{
+  unsigned int bytes_read;
+  bfd *abfd = section->get_bfd_owner ();
+  const gdb_byte *info_ptr = section->buffer;
+  header->length = read_initial_length (abfd, info_ptr, &bytes_read);
+  info_ptr += bytes_read;
+  header->version = read_2_bytes (abfd, info_ptr);
+  info_ptr += 2;
+  header->addr_size = read_1_byte (abfd, info_ptr);
+  info_ptr += 1;
+  header->segment_collector_size = read_1_byte (abfd, info_ptr);
+  info_ptr += 1;
+  header->offset_entry_count = read_4_bytes (abfd, info_ptr);
+}
+
+/* Return the DW_AT_loclists_base value for the CU.  */
+static ULONGEST
+lookup_loclist_base (struct dwarf2_cu *cu)
+{
+  /* For the .dwo unit, the loclist_base points to the first offset following
+     the header. The header consists of the following entities-
+     1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+        bit format)
+     2. version (2 bytes)
+     3. address size (1 byte)
+     4. segment selector size (1 byte)
+     5. offset entry count (4 bytes)
+     These sizes are derived as per the DWARFv5 standard.  */
+  if (cu->dwo_unit != nullptr)
+    {
+      if (cu->header.initial_length_size == 4)
+        return LOCLIST_HEADER_SIZE32;
+      return LOCLIST_HEADER_SIZE64;
+    }
+  return cu->loclist_base;
+}
+
+/* Given a DW_FORM_loclistx value LOCLIST_INDEX, fetch the offset from the
+   array of offsets in the .debug_loclists section.  */
+static CORE_ADDR
+read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
+{
+  struct dwarf2_per_objfile *dwarf2_per_objfile
+    = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  bfd *abfd = objfile->obfd;
+  ULONGEST loclist_base = lookup_loclist_base (cu);
+  struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+  section->read (objfile);
+  if (section->buffer == NULL)
+    complaint (_("DW_FORM_loclistx used without .debug_loclists "
+               "section [in module %s]"), objfile_name (objfile));
+  struct loclist_header header;
+  read_loclist_header (&header, section);
+  if (loclist_index >= header.offset_entry_count)
+    complaint (_("DW_FORM_loclistx pointing outside of "
+               ".debug_loclists offset array [in module %s]"),
+               objfile_name (objfile));
+  if (loclist_base + loclist_index * cu->header.offset_size
+       >= section->size)
+    complaint (_("DW_FORM_loclistx pointing outside of "
+               ".debug_loclists section [in module %s]"),
+               objfile_name (objfile));
+  const gdb_byte *info_ptr
+    = section->buffer + loclist_base + loclist_index * cu->header.offset_size;
+
+  if (cu->header.offset_size == 4)
+    return bfd_get_32 (abfd, info_ptr) + loclist_base;
+  else
+    return bfd_get_64 (abfd, info_ptr) + loclist_base;
+}
+
 /* Process the attributes that had to be skipped in the first round. These
    attributes are the ones that need str_offsets_base or addr_base attributes.
    They could not have been processed in the first round, because at the time
@@ -18315,6 +18890,9 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
       case DW_FORM_GNU_addr_index:
         DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
         break;
+      case DW_FORM_loclistx:
+        DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
+        break;
       case DW_FORM_strx:
       case DW_FORM_strx1:
       case DW_FORM_strx2:
@@ -18352,7 +18930,6 @@ read_attribute_value (const struct die_reader_specs *reader,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = reader->abfd;
   struct comp_unit_head *cu_header = &cu->header;
   unsigned int bytes_read;
@@ -18376,9 +18953,12 @@ read_attribute_value (const struct die_reader_specs *reader,
       info_ptr += bytes_read;
       break;
     case DW_FORM_addr:
-      DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
-      DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
-      info_ptr += bytes_read;
+      {
+       struct gdbarch *gdbarch = objfile->arch ();
+       DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
+       DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
+       info_ptr += bytes_read;
+      }
       break;
     case DW_FORM_block2:
       blk = dwarf_alloc_block (cu);
@@ -18419,6 +18999,13 @@ read_attribute_value (const struct die_reader_specs *reader,
       DW_UNSND (attr) = cu->header.read_offset (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_loclistx:
+      {
+        *need_reprocess = true;
+        DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+        info_ptr += bytes_read;
+      }
+      break;
     case DW_FORM_string:
       DW_STRING (attr) = read_direct_string (abfd, info_ptr, &bytes_read);
       DW_STRING_IS_CANONICAL (attr) = 0;
@@ -18951,17 +19538,8 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
 
   if (attr != NULL)
     {
-      if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
-         || attr->form == DW_FORM_string
-         || attr->form == DW_FORM_strx
-         || attr->form == DW_FORM_strx1
-         || attr->form == DW_FORM_strx2
-         || attr->form == DW_FORM_strx3
-         || attr->form == DW_FORM_strx4
-         || attr->form == DW_FORM_GNU_str_index
-         || attr->form == DW_FORM_GNU_strp_alt)
-       str = DW_STRING (attr);
-      else
+      str = attr->value_as_string ();
+      if (str == nullptr)
         complaint (_("string type expected for attribute %s for "
                     "DIE at %s in module %s"),
                   dwarf_attr_name (name), sect_offset_str (die->sect_off),
@@ -19583,7 +20161,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   /* True if we're recording line info (as opposed to building partial
      symtabs and just interested in finding include files mentioned by
      the line number program).  */
@@ -20007,7 +20585,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct symbol *sym = NULL;
   const char *name;
   struct attribute *attr = NULL;
@@ -20022,27 +20600,31 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
   name = dwarf2_name (die, cu);
   if (name)
     {
-      const char *linkagename;
       int suppress_add = 0;
 
       if (space)
        sym = space;
       else
-       sym = allocate_symbol (objfile);
+       sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       sym->set_language (cu->language, &objfile->objfile_obstack);
-      linkagename = dwarf2_physname (name, die, cu);
-      sym->compute_and_set_names (linkagename, false, objfile->per_bfd);
-
       /* Fortran does not have mangling standard and the mangling does differ
         between gfortran, iFort etc.  */
-      if (cu->language == language_fortran
-          && symbol_get_demangled_name (sym) == NULL)
-       symbol_set_demangled_name (sym,
-                                  dwarf2_full_name (name, die, cu),
-                                  NULL);
+      const char *physname
+       = (cu->language == language_fortran
+          ? dwarf2_full_name (name, die, cu)
+          : dwarf2_physname (name, die, cu));
+      const char *linkagename = dw2_linkage_name (die, cu);
+
+      if (linkagename == nullptr || cu->language == language_ada)
+       sym->set_linkage_name (physname);
+      else
+       {
+         sym->set_demangled_name (physname, &objfile->objfile_obstack);
+         sym->set_linkage_name (linkagename);
+       }
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -20134,7 +20716,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
          /* Compilation with minimal debug info may result in
             variables with missing type entries.  Change the
             misleading `void' type to something sensible.  */
-         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+         if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
            SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
 
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
@@ -20322,8 +20904,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                    /* The symbol's name is already allocated along
                       with this objfile, so we don't need to
                       duplicate it for the type.  */
-                   if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
-                     TYPE_NAME (SYMBOL_TYPE (sym)) = sym->search_name ();
+                   if (SYMBOL_TYPE (sym)->name () == 0)
+                     SYMBOL_TYPE (sym)->set_name (sym->search_name ());
                  }
              }
          }
@@ -21074,18 +21656,18 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
           DW_TAG_namespace DIEs with a name of "::" for the global namespace.
           Work around this problem here.  */
        if (cu->language == language_cplus
-           && strcmp (TYPE_NAME (parent_type), "::") == 0)
+           && strcmp (parent_type->name (), "::") == 0)
          return "";
        /* We give a name to even anonymous namespaces.  */
-       return TYPE_NAME (parent_type);
+       return parent_type->name ();
       case DW_TAG_class_type:
       case DW_TAG_interface_type:
       case DW_TAG_structure_type:
       case DW_TAG_union_type:
       case DW_TAG_module:
        parent_type = read_type_die (parent, cu);
-       if (TYPE_NAME (parent_type) != NULL)
-         return TYPE_NAME (parent_type);
+       if (parent_type->name () != NULL)
+         return parent_type->name ();
        else
          /* An anonymous structure is only allowed non-static data
             members; no typedefs, no member functions, et cetera.
@@ -21120,8 +21702,8 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
        parent_type = read_type_die (parent, cu);
        if (TYPE_DECLARED_CLASS (parent_type))
          {
-           if (TYPE_NAME (parent_type) != NULL)
-             return TYPE_NAME (parent_type);
+           if (parent_type->name () != NULL)
+             return parent_type->name ();
            return "";
          }
        /* Fall through.  */
@@ -21203,13 +21785,11 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
 {
   if (name && cu->language == language_cplus)
     {
-      std::string canon_name = cp_canonicalize_string (name);
+      gdb::unique_xmalloc_ptr<char> canon_name
+       = cp_canonicalize_string (name);
 
-      if (!canon_name.empty ())
-       {
-         if (canon_name != name)
-           name = objfile->intern (canon_name);
-       }
+      if (canon_name != nullptr)
+       name = objfile->intern (canon_name.get ());
     }
 
   return name;
@@ -21654,7 +22234,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
     {
       CORE_ADDR pc = (*get_frame_pc) (baton);
       CORE_ADDR baseaddr = objfile->text_section_offset ();
-      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      struct gdbarch *gdbarch = objfile->arch ();
 
       for (const auto &cand_off
             : dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
@@ -22170,27 +22750,13 @@ read_signatured_type (struct signatured_type *sig_type)
 
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
-   the location and return the value.
-
-   NOTE drow/2003-11-18: This function is called in two situations
-   now: for the address of static or global variables (partial symbols
-   only) and for offsets into structures which are expected to be
-   (more or less) constant.  The partial symbol case should go away,
-   and only the constant case should remain.  That will let this
-   function complain more accurately.  A few special modes are allowed
-   without complaint for global variables (for instance, global
-   register values and thread-local values).
-
-   A location description containing no operations indicates that the
-   object is optimized out.  The return value is 0 for that case.
-   FIXME drow/2003-11-16: No callers check for this case any more; soon all
-   callers will only want a very basic result and this can become a
-   complaint.
-
-   Note that stack[0] is unused except as a default error return.  */
+   the location and return the value.  If COMPUTED is non-null, it is
+   set to true to indicate that decoding was successful, and false
+   otherwise.  If COMPUTED is null, then this function may emit a
+   complaint.  */
 
 static CORE_ADDR
-decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
+decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
 {
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   size_t i;
@@ -22201,6 +22767,9 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
   unsigned int bytes_read, unsnd;
   gdb_byte op;
 
+  if (computed != nullptr)
+    *computed = false;
+
   i = 0;
   stacki = 0;
   stack[stacki] = 0;
@@ -22280,7 +22849,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
        case DW_OP_reg31:
          stack[++stacki] = op - DW_OP_reg0;
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
        case DW_OP_regx:
@@ -22288,7 +22862,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          i += bytes_read;
          stack[++stacki] = unsnd;
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
        case DW_OP_addr:
@@ -22370,7 +22949,12 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
             global symbols, although the variable's address will be bogus
             in the psymtab.  */
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          break;
 
         case DW_OP_GNU_push_tls_address:
@@ -22384,11 +22968,18 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
             non-zero to not look as a variable garbage collected by linker
             which have DW_OP_addr 0.  */
          if (i < size)
-           dwarf2_complex_location_expr_complaint ();
+           {
+             if (computed == nullptr)
+               dwarf2_complex_location_expr_complaint ();
+             else
+               return 0;
+           }
          stack[stacki]++;
           break;
 
        case DW_OP_GNU_uninit:
+         if (computed != nullptr)
+           return 0;
          break;
 
        case DW_OP_addrx:
@@ -22400,16 +22991,17 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          break;
 
        default:
-         {
-           const char *name = get_DW_OP_name (op);
+         if (computed == nullptr)
+           {
+             const char *name = get_DW_OP_name (op);
 
-           if (name)
-             complaint (_("unsupported stack op: '%s'"),
-                        name);
-           else
-             complaint (_("unsupported stack op: '%02x'"),
-                        op);
-         }
+             if (name)
+               complaint (_("unsupported stack op: '%s'"),
+                          name);
+             else
+               complaint (_("unsupported stack op: '%02x'"),
+                          op);
+           }
 
          return (stack[stacki]);
        }
@@ -22418,16 +23010,21 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
          outside of the allocated space.  Also enforce minimum>0.  */
       if (stacki >= ARRAY_SIZE (stack) - 1)
        {
-         complaint (_("location description stack overflow"));
+         if (computed == nullptr)
+           complaint (_("location description stack overflow"));
          return 0;
        }
 
       if (stacki <= 0)
        {
-         complaint (_("location description stack underflow"));
+         if (computed == nullptr)
+           complaint (_("location description stack underflow"));
          return 0;
        }
     }
+
+  if (computed != nullptr)
+    *computed = true;
   return (stack[stacki]);
 }
 
@@ -23041,11 +23638,11 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
      But this is not a problem, because the gnat-specific information
      is actually not needed for these types.  */
   if (need_gnat_info (cu)
-      && TYPE_CODE (type) != TYPE_CODE_FUNC
-      && TYPE_CODE (type) != TYPE_CODE_FLT
-      && TYPE_CODE (type) != TYPE_CODE_METHODPTR
-      && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
-      && TYPE_CODE (type) != TYPE_CODE_METHOD
+      && type->code () != TYPE_CODE_FUNC
+      && type->code () != TYPE_CODE_FLT
+      && type->code () != TYPE_CODE_METHODPTR
+      && type->code () != TYPE_CODE_MEMBERPTR
+      && type->code () != TYPE_CODE_METHOD
       && !HAVE_GNAT_AUX_INFO (type))
     INIT_GNAT_SPECIFIC (type);
 
@@ -23055,7 +23652,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
     {
       struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
-        add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
+        type->add_dyn_prop (DYN_PROP_ALLOCATED, prop);
     }
   else if (attr != NULL)
     {
@@ -23070,7 +23667,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
     {
       struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
-        add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
+        type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
     }
   else if (attr != NULL)
     {
@@ -23083,7 +23680,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_data_location, cu);
   if (attr_to_dynamic_prop (attr, die, cu, &prop,
                            cu->per_cu->addr_type ()))
-    add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
+    type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
     dwarf2_per_objfile->die_type_hash
@@ -23237,19 +23834,6 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
 struct cmd_list_element *set_dwarf_cmdlist;
 struct cmd_list_element *show_dwarf_cmdlist;
 
-static void
-set_dwarf_cmd (const char *args, int from_tty)
-{
-  help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
-            gdb_stdout);
-}
-
-static void
-show_dwarf_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (show_dwarf_cmdlist, from_tty, "");
-}
-
 static void
 show_check_physname (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
@@ -23263,17 +23847,17 @@ void _initialize_dwarf2_read ();
 void
 _initialize_dwarf2_read ()
 {
-  add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+  add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
 Set DWARF specific variables.\n\
 Configure DWARF variables such as the cache size."),
-                  &set_dwarf_cmdlist, "maintenance set dwarf ",
-                  0/*allow-unknown*/, &maintenance_set_cmdlist);
+                       &set_dwarf_cmdlist, "maintenance set dwarf ",
+                       0/*allow-unknown*/, &maintenance_set_cmdlist);
 
-  add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+  add_show_prefix_cmd ("dwarf", class_maintenance, _("\
 Show DWARF specific variables.\n\
 Show DWARF variables such as the cache size."),
-                  &show_dwarf_cmdlist, "maintenance show dwarf ",
-                  0/*allow-unknown*/, &maintenance_show_cmdlist);
+                      &show_dwarf_cmdlist, "maintenance show dwarf ",
+                      0/*allow-unknown*/, &maintenance_show_cmdlist);
 
   add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
                            &dwarf_max_cache_age, _("\
This page took 0.104585 seconds and 4 git commands to generate.