Parallelize DWARF indexing
[binutils-gdb.git] / gdb / dwarf2 / read.c
index 95246cbd02335be7a25813beee849099233d3d2a..fce465e4dab8ecb28084a0f8efc961fcb3dc9784 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 debugging format support for GDB.
 
-   Copyright (C) 1994-2021 Free Software Foundation, Inc.
+   Copyright (C) 1994-2022 Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
    Inc.  with support from Florida State University (under contract
 #include "gdbsupport/pathstuff.h"
 #include "count-one-bits.h"
 #include <unordered_set>
+#include "dwarf2/abbrev-cache.h"
+#include "cooked-index.h"
+#include "split-name.h"
+#include "gdbsupport/parallel-for.h"
+#include "gdbsupport/thread-pool.h"
 
 /* When == 1, print basic high level tracing messages.
    When > 1, be more verbose.
@@ -362,7 +367,7 @@ struct mapped_debug_names final : public mapped_index_base
   { return this->name_count; }
 };
 
-/* See dwarf2read.h.  */
+/* See dwarf2/read.h.  */
 
 dwarf2_per_objfile *
 get_dwarf2_per_objfile (struct objfile *objfile)
@@ -791,7 +796,8 @@ public:
               dwarf2_per_objfile *per_objfile,
               struct abbrev_table *abbrev_table,
               dwarf2_cu *existing_cu,
-              bool skip_partial);
+              bool skip_partial,
+              abbrev_cache *cache = nullptr);
 
   explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
                        dwarf2_per_objfile *per_objfile,
@@ -800,6 +806,8 @@ public:
 
   DISABLE_COPY_AND_ASSIGN (cutu_reader);
 
+  cutu_reader (cutu_reader &&) = default;
+
   const gdb_byte *info_ptr = nullptr;
   struct die_info *comp_unit_die = nullptr;
   bool dummy_p = false;
@@ -808,6 +816,13 @@ public:
      for dummy CUs.  */
   void keep ();
 
+  /* Release the abbrev table, transferring ownership to the
+     caller.  */
+  abbrev_table_up release_abbrev_table ()
+  {
+    return std::move (m_abbrev_table_holder);
+  }
+
 private:
   void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
                                  dwarf2_per_objfile *per_objfile,
@@ -863,6 +878,7 @@ struct partial_die_info : public allocate_on_obstack
     unsigned int has_type : 1;
     unsigned int has_specification : 1;
     unsigned int has_pc_info : 1;
+    unsigned int has_range_info : 1;
     unsigned int may_be_inlined : 1;
 
     /* This DIE has been marked DW_AT_main_subprogram.  */
@@ -914,9 +930,17 @@ struct partial_die_info : public allocate_on_obstack
       sect_offset sect_off;
     } d {};
 
-    /* If HAS_PC_INFO, the PC range associated with this DIE.  */
-    CORE_ADDR lowpc = 0;
-    CORE_ADDR highpc = 0;
+    union
+    {
+      /* If HAS_PC_INFO, the PC range associated with this DIE.  */
+      struct
+      {
+       CORE_ADDR lowpc;
+       CORE_ADDR highpc;
+      };
+      /* If HAS_RANGE_INFO, the ranges offset associated with this DIE.  */
+      ULONGEST ranges_offset;
+    };
 
     /* Pointer into the info_buffer (or types_buffer) pointing at the target of
        DW_AT_sibling, if any.  */
@@ -954,6 +978,7 @@ struct partial_die_info : public allocate_on_obstack
       has_type = 0;
       has_specification = 0;
       has_pc_info = 0;
+      has_range_info = 0;
       may_be_inlined = 0;
       main_subprogram = 0;
       scope_set = 0;
@@ -964,6 +989,10 @@ struct partial_die_info : public allocate_on_obstack
       is_dwz = 0;
       spec_is_dwz = 0;
       canonical_name = 0;
+      /* Don't set these using NSDMI (Non-static data member initialisation),
+        because g++-4.8 will error out.  */
+      lowpc = 0;
+      highpc = 0;
     }
   };
 
@@ -1076,9 +1105,9 @@ static void
 show_dwarf_max_cache_age (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("The upper bound on the age of cached "
-                           "DWARF compilation units is %s.\n"),
-                   value);
+  gdb_printf (file, _("The upper bound on the age of cached "
+                     "DWARF compilation units is %s.\n"),
+             value);
 }
 \f
 /* local function prototypes */
@@ -1090,9 +1119,9 @@ static dwarf2_psymtab *create_partial_symtab
   (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
    const char *name);
 
-static void build_type_psymtabs_reader (const struct die_reader_specs *reader,
-                                       const gdb_byte *info_ptr,
-                                       struct die_info *type_unit_die);
+class cooked_index_storage;
+static void build_type_psymtabs_reader (cutu_reader *reader,
+                                       cooked_index_storage *storage);
 
 static void dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile);
 
@@ -1192,7 +1221,6 @@ static struct die_info *die_specification (struct die_info *die,
 static line_header_up dwarf_decode_line_header (sect_offset sect_off,
                                                struct dwarf2_cu *cu);
 
-struct file_and_directory;
 static void dwarf_decode_lines (struct line_header *,
                                const file_and_directory &,
                                struct dwarf2_cu *, dwarf2_psymtab *,
@@ -1284,7 +1312,8 @@ enum pc_bounds_kind
 static enum pc_bounds_kind dwarf2_get_pc_bounds (struct die_info *,
                                                 CORE_ADDR *, CORE_ADDR *,
                                                 struct dwarf2_cu *,
-                                                dwarf2_psymtab *);
+                                                addrmap *,
+                                                void *);
 
 static void get_scope_pc_bounds (struct die_info *,
                                 CORE_ADDR *, CORE_ADDR *,
@@ -1428,7 +1457,8 @@ static void dwarf2_symbol_mark_computed (const struct attribute *attr,
 
 static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
                                     const gdb_byte *info_ptr,
-                                    const struct abbrev_info *abbrev);
+                                    const struct abbrev_info *abbrev,
+                                    bool do_skip_children = true);
 
 static hashval_t partial_die_hash (const void *item);
 
@@ -1436,7 +1466,7 @@ static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
   (sect_offset sect_off, unsigned int offset_in_dwz,
-   dwarf2_per_objfile *per_objfile);
+   dwarf2_per_bfd *per_bfd);
 
 static void prepare_one_comp_unit (struct dwarf2_cu *cu,
                                   struct die_info *comp_unit_die,
@@ -1524,27 +1554,14 @@ dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
     delete data;
 }
 
-/* The return type of find_file_and_directory.  Note, the enclosed
-   string pointers are only valid while this object is valid.  */
-
-struct file_and_directory
-{
-  /* The filename.  This is never NULL.  */
-  const char *name;
-
-  /* The compilation directory.  NULL if not known.  If we needed to
-     compute a new string, this points to COMP_DIR_STORAGE, otherwise,
-     points directly to the DW_AT_comp_dir string attribute owned by
-     the obstack that owns the DIE.  */
-  const char *comp_dir;
-
-  /* If we needed to build a new string for comp_dir, this is what
-     owns the storage.  */
-  std::string comp_dir_storage;
-};
+static file_and_directory &find_file_and_directory
+     (struct die_info *die, struct dwarf2_cu *cu);
 
-static file_and_directory find_file_and_directory (struct die_info *die,
-                                                  struct dwarf2_cu *cu);
+static const char *compute_include_file_name
+     (const struct line_header *lh,
+      const file_entry &fe,
+      const file_and_directory &cu_info,
+      gdb::unique_xmalloc_ptr<char> *name_holder);
 
 static htab_up allocate_signatured_type_table ();
 
@@ -1641,6 +1658,73 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
 
 \f
 
+/* An iterator for all_comp_units that is based on index.  This
+   approach makes it possible to iterate over all_comp_units safely,
+   when some caller in the loop may add new units.  */
+
+class all_comp_units_iterator
+{
+public:
+
+  all_comp_units_iterator (dwarf2_per_bfd *per_bfd, bool start)
+    : m_per_bfd (per_bfd),
+      m_index (start ? 0 : per_bfd->all_comp_units.size ())
+  {
+  }
+
+  all_comp_units_iterator &operator++ ()
+  {
+    ++m_index;
+    return *this;
+  }
+
+  dwarf2_per_cu_data *operator* () const
+  {
+    return m_per_bfd->get_cu (m_index);
+  }
+
+  bool operator== (const all_comp_units_iterator &other) const
+  {
+    return m_index == other.m_index;
+  }
+
+
+  bool operator!= (const all_comp_units_iterator &other) const
+  {
+    return m_index != other.m_index;
+  }
+
+private:
+
+  dwarf2_per_bfd *m_per_bfd;
+  size_t m_index;
+};
+
+/* A range adapter for the all_comp_units_iterator.  */
+class all_comp_units_range
+{
+public:
+
+  all_comp_units_range (dwarf2_per_bfd *per_bfd)
+    : m_per_bfd (per_bfd)
+  {
+  }
+
+  all_comp_units_iterator begin ()
+  {
+    return all_comp_units_iterator (m_per_bfd, true);
+  }
+
+  all_comp_units_iterator end ()
+  {
+    return all_comp_units_iterator (m_per_bfd, false);
+  }
+
+private:
+
+  dwarf2_per_bfd *m_per_bfd;
+};
+
 /* See declaration.  */
 
 dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
@@ -1658,7 +1742,10 @@ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
 dwarf2_per_bfd::~dwarf2_per_bfd ()
 {
   for (auto &per_cu : all_comp_units)
-    per_cu->imported_symtabs_free ();
+    {
+      per_cu->imported_symtabs_free ();
+      per_cu->free_cached_file_names ();
+    }
 
   /* Everything else should be on this->obstack.  */
 }
@@ -1705,9 +1792,9 @@ private:
 bool
 dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
 {
-  gdb_assert (per_cu->index < this->m_symtabs.size ());
-
-  return this->m_symtabs[per_cu->index] != nullptr;
+  if (per_cu->index < this->m_symtabs.size ())
+    return this->m_symtabs[per_cu->index] != nullptr;
+  return false;
 }
 
 /* See read.h.  */
@@ -1715,9 +1802,9 @@ dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
 compunit_symtab *
 dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
 {
-  gdb_assert (per_cu->index < this->m_symtabs.size ());
-
-  return this->m_symtabs[per_cu->index];
+  if (per_cu->index < this->m_symtabs.size ())
+    return this->m_symtabs[per_cu->index];
+  return nullptr;
 }
 
 /* See read.h.  */
@@ -1726,9 +1813,9 @@ void
 dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
                                compunit_symtab *symtab)
 {
-  gdb_assert (per_cu->index < this->m_symtabs.size ());
+  if (per_cu->index >= this->m_symtabs.size ())
+    this->m_symtabs.resize (per_cu->index + 1);
   gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
-
   this->m_symtabs[per_cu->index] = symtab;
 }
 
@@ -1954,6 +2041,25 @@ dwarf2_get_section_info (struct objfile *objfile,
   *sizep = info->size;
 }
 
+/* See dwarf2/read.h.  */
+
+void
+dwarf2_per_bfd::map_info_sections (struct objfile *objfile)
+{
+  info.read (objfile);
+  abbrev.read (objfile);
+  line.read (objfile);
+  str.read (objfile);
+  str_offsets.read (objfile);
+  line_str.read (objfile);
+  ranges.read (objfile);
+  rnglists.read (objfile);
+  addr.read (objfile);
+
+  for (auto &section : types)
+    section.read (objfile);
+}
+
 \f
 /* DWARF quick_symbol_functions support.  */
 
@@ -1970,6 +2076,10 @@ struct quick_file_names
   /* The number of entries in file_names, real_names.  */
   unsigned int num_file_names;
 
+  /* The CU directory, as given by DW_AT_comp_dir.  May be
+     nullptr.  */
+  const char *comp_dir;
+
   /* The file names from the line table, after being run through
      file_full_name.  */
   const char **file_names;
@@ -1993,9 +2103,9 @@ struct dwarf2_per_cu_quick_data
      expand_symtabs_matching.  */
   unsigned int mark : 1;
 
-  /* True if we've tried to read the file table and found there isn't one.
-     There will be no point in trying to read it again next time.  */
-  unsigned int no_file_data : 1;
+  /* True if we've tried to read the file table.  There will be no
+     point in trying to read it again next time.  */
+  bool files_read : 1;
 };
 
 /* A subclass of psymbol_functions that arranges to read the DWARF
@@ -2166,25 +2276,6 @@ eq_file_name_entry (const void *a, const void *b)
   return eq_stmt_list_entry (&ea->hash, &eb->hash);
 }
 
-/* Delete function for a quick_file_names.  */
-
-static void
-delete_file_name_entry (void *e)
-{
-  struct quick_file_names *file_data = (struct quick_file_names *) e;
-  int i;
-
-  for (i = 0; i < file_data->num_file_names; ++i)
-    {
-      xfree ((void*) file_data->file_names[i]);
-      if (file_data->real_names)
-       xfree ((void*) file_data->real_names[i]);
-    }
-
-  /* The space for the struct itself lives on the obstack, so we don't
-     free it here.  */
-}
-
 /* Create a quick_file_names hash table.  */
 
 static htab_up
@@ -2192,7 +2283,7 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
 {
   return htab_up (htab_create_alloc (nr_initial_entries,
                                     hash_file_name_entry, eq_file_name_entry,
-                                    delete_file_name_entry, xcalloc, xfree));
+                                    nullptr, xcalloc, xfree));
 }
 
 /* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE.  This
@@ -2524,12 +2615,14 @@ create_addrmap_from_index (dwarf2_per_objfile *per_objfile,
                                                 &per_bfd->obstack);
 }
 
-/* Read the address map data from DWARF-5 .debug_aranges, and use it to
-   populate the psymtabs_addrmap.  */
+/* Read the address map data from DWARF-5 .debug_aranges, and use it
+   to populate given addrmap.  Returns true on success, false on
+   failure.  */
 
-static void
-create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
-                            struct dwarf2_section_info *section)
+static bool
+read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
+                          struct dwarf2_section_info *section,
+                          addrmap *mutable_map)
 {
   struct objfile *objfile = per_objfile->objfile;
   bfd *abfd = objfile->obfd;
@@ -2537,15 +2630,19 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
-  auto_obstack temp_obstack;
-  addrmap *mutable_map = addrmap_create_mutable (&temp_obstack);
-
   std::unordered_map<sect_offset,
                     dwarf2_per_cu_data *,
                     gdb::hash_enum<sect_offset>>
     debug_info_offset_to_per_cu;
   for (const auto &per_cu : per_bfd->all_comp_units)
     {
+      /* A TU will not need aranges, and skipping them here is an easy
+        way of ignoring .debug_types -- and possibly seeing a
+        duplicate section offset -- entirely.  The same applies to
+        units coming from a dwz file.  */
+      if (per_cu->is_debug_types || per_cu->is_dwz)
+       continue;
+
       const auto insertpair
        = debug_info_offset_to_per_cu.emplace (per_cu->sect_off,
                                               per_cu.get ());
@@ -2554,7 +2651,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
          warning (_("Section .debug_aranges in %s has duplicate "
                     "debug_info_offset %s, ignoring .debug_aranges."),
                   objfile_name (objfile), sect_offset_str (per_cu->sect_off));
-         return;
+         return false;
        }
     }
 
@@ -2585,7 +2682,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                   plongest (entry_addr - section->buffer),
                   plongest (bytes_read + entry_length),
                   pulongest (section->size));
-         return;
+         return false;
        }
 
       /* The version number.  */
@@ -2597,7 +2694,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                     "has unsupported version %d, ignoring .debug_aranges."),
                   objfile_name (objfile),
                   plongest (entry_addr - section->buffer), version);
-         return;
+         return false;
        }
 
       const uint64_t debug_info_offset
@@ -2613,7 +2710,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                   objfile_name (objfile),
                   plongest (entry_addr - section->buffer),
                   pulongest (debug_info_offset));
-         return;
+         return false;
        }
       dwarf2_per_cu_data *const per_cu = per_cu_it->second;
 
@@ -2624,7 +2721,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                     "address_size %u is invalid, ignoring .debug_aranges."),
                   objfile_name (objfile),
                   plongest (entry_addr - section->buffer), address_size);
-         return;
+         return false;
        }
 
       const uint8_t segment_selector_size = *addr++;
@@ -2636,7 +2733,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                   objfile_name (objfile),
                   plongest (entry_addr - section->buffer),
                   segment_selector_size);
-         return;
+         return false;
        }
 
       /* Must pad to an alignment boundary that is twice the address
@@ -2657,7 +2754,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                         "ignoring .debug_aranges."),
                       objfile_name (objfile),
                       plongest (entry_addr - section->buffer));
-             return;
+             return false;
            }
          ULONGEST start = extract_unsigned_integer (addr, address_size,
                                                     dwarf5_byte_order);
@@ -2679,10 +2776,28 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
                 - baseaddr);
          addrmap_set_empty (mutable_map, start, end - 1, per_cu);
        }
+
+      per_cu->addresses_seen = true;
     }
 
-  per_bfd->index_addrmap = addrmap_create_fixed (mutable_map,
-                                                &per_bfd->obstack);
+  return true;
+}
+
+/* Read the address map data from DWARF-5 .debug_aranges, and use it to
+   populate the psymtabs_addrmap.  */
+
+static void
+create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
+                            struct dwarf2_section_info *section)
+{
+  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+
+  auto_obstack temp_obstack;
+  addrmap *mutable_map = addrmap_create_mutable (&temp_obstack);
+
+  if (read_addrmap_from_aranges (per_objfile, section, mutable_map))
+    per_bfd->index_addrmap = addrmap_create_fixed (mutable_map,
+                                                  &per_bfd->obstack);
 }
 
 /* A helper function that reads the .gdb_index from BUFFER and fills
@@ -2787,6 +2902,15 @@ to use the section anyway."),
   ++i;
   map->constant_pool = buffer.slice (metadata[i]);
 
+  if (map->constant_pool.empty () && !map->symbol_table.empty ())
+    {
+      /* An empty constant pool implies that all symbol table entries are
+        empty.  Make map->symbol_table.empty () == true.  */
+      map->symbol_table
+       = offset_view (gdb::array_view<const gdb_byte> (symbol_table,
+                                                       symbol_table));
+    }
+
   return 1;
 }
 
@@ -2901,13 +3025,11 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   gdb_assert (! this_cu->is_debug_types);
 
+  this_cu->v.quick->files_read = true;
   /* Our callers never want to match partial units -- instead they
      will match the enclosing full CU.  */
   if (comp_unit_die->tag == DW_TAG_partial_unit)
-    {
-      this_cu->v.quick->no_file_data = 1;
-      return;
-    }
+    return;
 
   lh_cu = this_cu;
   slot = NULL;
@@ -2936,33 +3058,50 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
       lh = dwarf_decode_line_header (line_offset, cu);
     }
-  if (lh == NULL)
-    {
-      lh_cu->v.quick->no_file_data = 1;
-      return;
-    }
+
+  file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+
+  int offset = 0;
+  if (!fnd.is_unknown ())
+    ++offset;
+  else if (lh == nullptr)
+    return;
 
   qfn = XOBNEW (&per_objfile->per_bfd->obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
   qfn->hash.line_sect_off = line_offset;
-  gdb_assert (slot != NULL);
-  *slot = qfn;
+  /* There may not be a DW_AT_stmt_list.  */
+  if (slot != nullptr)
+    *slot = qfn;
 
-  file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
-
-  int offset = 0;
-  if (strcmp (fnd.name, "<unknown>") != 0)
-    ++offset;
+  std::vector<const char *> include_names;
+  if (lh != nullptr)
+    {
+      for (const auto &entry : lh->file_names ())
+       {
+         gdb::unique_xmalloc_ptr<char> name_holder;
+         const char *include_name =
+           compute_include_file_name (lh.get (), entry, fnd, &name_holder);
+         if (include_name != nullptr)
+           {
+             include_name = per_objfile->objfile->intern (include_name);
+             include_names.push_back (include_name);
+           }
+       }
+    }
 
-  qfn->num_file_names = offset + lh->file_names_size ();
+  qfn->num_file_names = offset + include_names.size ();
+  qfn->comp_dir = fnd.intern_comp_dir (per_objfile->objfile);
   qfn->file_names =
     XOBNEWVEC (&per_objfile->per_bfd->obstack, const char *,
               qfn->num_file_names);
   if (offset != 0)
-    qfn->file_names[0] = xstrdup (fnd.name);
-  for (int i = 0; i < lh->file_names_size (); ++i)
-    qfn->file_names[i + offset] = lh->file_full_name (i + 1,
-                                                     fnd.comp_dir).release ();
+    qfn->file_names[0] = xstrdup (fnd.get_name ());
+
+  if (!include_names.empty ())
+    memcpy (&qfn->file_names[offset], include_names.data (),
+           include_names.size () * sizeof (const char *));
+
   qfn->real_names = NULL;
 
   lh_cu->v.quick->file_names = qfn;
@@ -2980,18 +3119,13 @@ dw2_get_file_names (dwarf2_per_cu_data *this_cu,
   /* Nor type unit groups.  */
   gdb_assert (! this_cu->type_unit_group_p ());
 
-  if (this_cu->v.quick->file_names != NULL)
+  if (this_cu->v.quick->files_read)
     return this_cu->v.quick->file_names;
-  /* If we know there is no line data, no point in looking again.  */
-  if (this_cu->v.quick->no_file_data)
-    return NULL;
 
   cutu_reader reader (this_cu, per_objfile);
   if (!reader.dummy_p)
     dw2_get_file_names_reader (&reader, reader.comp_unit_die);
 
-  if (this_cu->v.quick->no_file_data)
-    return NULL;
   return this_cu->v.quick->file_names;
 }
 
@@ -3007,7 +3141,17 @@ dw2_get_real_path (dwarf2_per_objfile *per_objfile,
                                      qfn->num_file_names, const char *);
 
   if (qfn->real_names[index] == NULL)
-    qfn->real_names[index] = gdb_realpath (qfn->file_names[index]).release ();
+    {
+      const char *dirname = nullptr;
+
+      if (!IS_ABSOLUTE_PATH (qfn->file_names[index]))
+       dirname = qfn->comp_dir;
+
+      gdb::unique_xmalloc_ptr<char> fullname;
+      fullname = find_source_or_rewrite (qfn->file_names[index], dirname);
+
+      qfn->real_names[index] = fullname.release ();
+    }
 
   return qfn->real_names[index];
 }
@@ -3023,28 +3167,29 @@ dwarf2_base_index_functions::find_last_source_symtab (struct objfile *objfile)
   if (cust == NULL)
     return NULL;
 
-  return compunit_primary_filetab (cust);
+  return cust->primary_filetab ();
 }
 
-/* Traversal function for dw2_forget_cached_source_info.  */
+/* See read.h.  */
 
-static int
-dw2_free_cached_file_names (void **slot, void *info)
+void
+dwarf2_per_cu_data::free_cached_file_names ()
 {
-  struct quick_file_names *file_data = (struct quick_file_names *) *slot;
+  if (fnd != nullptr)
+    fnd->forget_fullname ();
 
-  if (file_data->real_names)
-    {
-      int i;
+  if (per_bfd == nullptr || !per_bfd->using_index || v.quick == nullptr)
+    return;
 
-      for (i = 0; i < file_data->num_file_names; ++i)
+  struct quick_file_names *file_data = v.quick->file_names;
+  if (file_data != nullptr && file_data->real_names != nullptr)
+    {
+      for (int i = 0; i < file_data->num_file_names; ++i)
        {
-         xfree ((void*) file_data->real_names[i]);
-         file_data->real_names[i] = NULL;
+         xfree ((void *) file_data->real_names[i]);
+         file_data->real_names[i] = nullptr;
        }
     }
-
-  return 1;
 }
 
 void
@@ -3053,8 +3198,8 @@ dwarf2_base_index_functions::forget_cached_source_info
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
-  htab_traverse_noresize (per_objfile->per_bfd->quick_file_names_table.get (),
-                         dw2_free_cached_file_names, NULL);
+  for (auto &per_cu : per_objfile->per_bfd->all_comp_units)
+    per_cu->free_cached_file_names ();
 }
 
 /* Struct used to manage iterating over all CUs looking for a symbol.  */
@@ -3223,8 +3368,8 @@ dwarf2_base_index_functions::print_stats (struct objfile *objfile,
       if (!per_objfile->symtab_set_p (per_cu))
        ++count;
     }
-  printf_filtered (_("  Number of read CUs: %d\n"), total - count);
-  printf_filtered (_("  Number of unread CUs: %d\n"), count);
+  gdb_printf (_("  Number of read CUs: %d\n"), total - count);
+  gdb_printf (_("  Number of unread CUs: %d\n"), count);
 }
 
 /* This dumps minimal information about the index.
@@ -3238,15 +3383,15 @@ dwarf2_gdb_index::dump (struct objfile *objfile)
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
   gdb_assert (per_objfile->per_bfd->using_index);
-  printf_filtered (".gdb_index:");
+  gdb_printf (".gdb_index:");
   if (per_objfile->per_bfd->index_table != NULL)
     {
-      printf_filtered (" version %d\n",
-                      per_objfile->per_bfd->index_table->version);
+      gdb_printf (" version %d\n",
+                 per_objfile->per_bfd->index_table->version);
     }
   else
-    printf_filtered (" faked for \"readnow\"\n");
-  printf_filtered ("\n");
+    gdb_printf (" faked for \"readnow\"\n");
+  gdb_printf ("\n");
 }
 
 void
@@ -4256,6 +4401,27 @@ dw_expand_symtabs_matching_file_matcher
       if (per_objfile->symtab_set_p (per_cu.get ()))
        continue;
 
+      if (per_cu->fnd != nullptr)
+       {
+         file_and_directory *fnd = per_cu->fnd.get ();
+
+         if (file_matcher (fnd->get_name (), false))
+           {
+             per_cu->v.quick->mark = 1;
+             continue;
+           }
+
+         /* Before we invoke realpath, which can get expensive when many
+            files are involved, do a quick comparison of the basenames.  */
+         if ((basenames_may_differ
+              || file_matcher (lbasename (fnd->get_name ()), true))
+             && file_matcher (fnd->get_fullname (), false))
+           {
+             per_cu->v.quick->mark = 1;
+             continue;
+           }
+       }
+
       quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
                                                        per_objfile);
       if (file_data == NULL)
@@ -4325,11 +4491,12 @@ dwarf2_gdb_index::expand_symtabs_matching
   gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
   if (lookup_name == nullptr)
     {
-      for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu
+            : all_comp_units_range (per_objfile->per_bfd))
        {
          QUIT;
 
-         if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
+         if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
                                                file_matcher,
                                                expansion_notify))
            return false;
@@ -4362,8 +4529,8 @@ recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
 {
   int i;
 
-  if (COMPUNIT_BLOCKVECTOR (cust) != NULL
-      && blockvector_contains_pc (COMPUNIT_BLOCKVECTOR (cust), pc))
+  if (cust->blockvector () != nullptr
+      && blockvector_contains_pc (cust->blockvector (), pc))
     return cust;
 
   if (cust->includes == NULL)
@@ -4434,21 +4601,40 @@ dwarf2_base_index_functions::map_symbol_filenames
 
   for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
     {
-      if (per_objfile->symtab_set_p (per_cu.get ()))
+      if (!per_cu->is_debug_types
+         && per_objfile->symtab_set_p (per_cu.get ()))
        {
          if (per_cu->v.quick->file_names != nullptr)
            qfn_cache.insert (per_cu->v.quick->file_names);
        }
     }
 
-  for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu
+        : all_comp_units_range (per_objfile->per_bfd))
     {
       /* We only need to look at symtabs not already expanded.  */
-      if (per_objfile->symtab_set_p (per_cu.get ()))
+      if (per_cu->is_debug_types || per_objfile->symtab_set_p (per_cu))
        continue;
 
-      quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
-                                                       per_objfile);
+      if (per_cu->fnd != nullptr)
+       {
+         file_and_directory *fnd = per_cu->fnd.get ();
+
+         const char *filename = fnd->get_name ();
+         const char *key = filename;
+         const char *fullname = nullptr;
+
+         if (need_fullname)
+           {
+             fullname = fnd->get_fullname ();
+             key = fullname;
+           }
+
+         if (!filenames_cache.seen (key))
+           fun (filename, fullname);
+       }
+
+      quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
       if (file_data == nullptr
          || qfn_cache.find (file_data) != qfn_cache.end ())
        continue;
@@ -4456,18 +4642,19 @@ dwarf2_base_index_functions::map_symbol_filenames
       for (int j = 0; j < file_data->num_file_names; ++j)
        {
          const char *filename = file_data->file_names[j];
-         filenames_cache.seen (filename);
-       }
-    }
+         const char *key = filename;
+         const char *fullname = nullptr;
 
-  filenames_cache.traverse ([&] (const char *filename)
-    {
-      gdb::unique_xmalloc_ptr<char> this_real_name;
+         if (need_fullname)
+           {
+             fullname = dw2_get_real_path (per_objfile, file_data, j);
+             key = fullname;
+           }
 
-      if (need_fullname)
-       this_real_name = gdb_realpath (filename);
-      fun (filename, this_real_name.get ());
-    });
+         if (!filenames_cache.seen (key))
+           fun (filename, fullname);
+       }
+    }
 }
 
 bool
@@ -5243,12 +5430,12 @@ dwarf2_debug_names_index::dump (struct objfile *objfile)
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
   gdb_assert (per_objfile->per_bfd->using_index);
-  printf_filtered (".debug_names:");
+  gdb_printf (".debug_names:");
   if (per_objfile->per_bfd->debug_names_table)
-    printf_filtered (" exists\n");
+    gdb_printf (" exists\n");
   else
-    printf_filtered (" faked for \"readnow\"\n");
-  printf_filtered ("\n");
+    gdb_printf (" faked for \"readnow\"\n");
+  gdb_printf ("\n");
 }
 
 void
@@ -5315,11 +5502,12 @@ dwarf2_debug_names_index::expand_symtabs_matching
   gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
   if (lookup_name == nullptr)
     {
-      for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu
+            : all_comp_units_range (per_objfile->per_bfd))
        {
          QUIT;
 
-         if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
+         if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
                                                file_matcher,
                                                expansion_notify))
            return false;
@@ -5404,6 +5592,8 @@ get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
   return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res);
 }
 
+static quick_symbol_functions_up make_cooked_index_funcs ();
+
 /* See dwarf2/public.h.  */
 
 void
@@ -5427,7 +5617,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
       if (per_bfd->using_index)
        {
          dwarf_read_debug_printf ("using_index already set");
-         per_objfile->resize_symtabs ();
          objfile->qf.push_front (make_dwarf_gdb_index ());
          return;
        }
@@ -5436,7 +5625,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
       create_all_comp_units (per_objfile);
       per_bfd->quick_file_names_table
        = create_quick_file_names_table (per_bfd->all_comp_units.size ());
-      per_objfile->resize_symtabs ();
 
       for (int i = 0; i < per_bfd->all_comp_units.size (); ++i)
        {
@@ -5458,7 +5646,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
   if (per_bfd->debug_names_table != nullptr)
     {
       dwarf_read_debug_printf ("re-using shared debug names table");
-      per_objfile->resize_symtabs ();
       objfile->qf.push_front (make_dwarf_debug_names ());
       return;
     }
@@ -5468,11 +5655,17 @@ dwarf2_initialize_objfile (struct objfile *objfile)
   if (per_bfd->index_table != nullptr)
     {
       dwarf_read_debug_printf ("re-using shared index table");
-      per_objfile->resize_symtabs ();
       objfile->qf.push_front (make_dwarf_gdb_index ());
       return;
     }
 
+  if (per_bfd->cooked_index_table != nullptr)
+    {
+      dwarf_read_debug_printf ("re-using cooked index table");
+      objfile->qf.push_front (make_cooked_index_funcs ());
+      return;
+    }
+
   /* There might already be partial symtabs built for this BFD.  This happens
      when loading the same binary twice with the index-cache enabled.  If so,
      don't try to read an index.  The objfile / per_objfile initialization will
@@ -5488,7 +5681,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
   if (dwarf2_read_debug_names (per_objfile))
     {
       dwarf_read_debug_printf ("found debug names");
-      per_objfile->resize_symtabs ();
       objfile->qf.push_front (make_dwarf_debug_names ());
       return;
     }
@@ -5498,7 +5690,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
                             get_gdb_index_contents_from_section<dwz_file>))
     {
       dwarf_read_debug_printf ("found gdb index from file");
-      per_objfile->resize_symtabs ();
       objfile->qf.push_front (make_dwarf_gdb_index ());
       return;
     }
@@ -5510,7 +5701,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
     {
       dwarf_read_debug_printf ("found gdb index from cache");
       global_index_cache.hit ();
-      per_objfile->resize_symtabs ();
       objfile->qf.push_front (make_dwarf_gdb_index ());
       return;
     }
@@ -5540,7 +5730,6 @@ dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
        }
       else
        psf->set_partial_symtabs (per_bfd->partial_symtabs);
-      per_objfile->resize_symtabs ();
       return;
     }
 
@@ -5567,8 +5756,6 @@ dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
       dwarf2_build_psymtabs_hard (per_objfile);
       psymtabs.keep ();
 
-      per_objfile->resize_symtabs ();
-
       /* (maybe) store an index in the cache.  */
       global_index_cache.store (per_objfile);
     }
@@ -5689,7 +5876,10 @@ struct dwarf2_include_psymtab : public partial_symtab
 
   compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
   {
-    return nullptr;
+    compunit_symtab *cust = includer ()->get_compunit_symtab (objfile);
+    while (cust != nullptr && cust->user != nullptr)
+      cust = cust->user;
+    return cust;
   }
 
 private:
@@ -5911,8 +6101,6 @@ add_type_unit (dwarf2_per_objfile *per_objfile, ULONGEST sig, void **slot)
     = per_objfile->per_bfd->allocate_signatured_type (sig);
   signatured_type *sig_type = sig_type_holder.get ();
 
-  per_objfile->resize_symtabs ();
-
   per_objfile->per_bfd->all_comp_units.emplace_back
     (sig_type_holder.release ());
   if (per_objfile->per_bfd->using_index)
@@ -5954,9 +6142,12 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile,
   else
       gdb_assert (sig_entry->v.psymtab == NULL);
   gdb_assert (sig_entry->signature == dwo_entry->signature);
-  gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0);
+  gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0
+             || (to_underlying (sig_entry->type_offset_in_section)
+                 == to_underlying (dwo_entry->type_offset_in_tu)));
   gdb_assert (sig_entry->type_unit_group == NULL);
-  gdb_assert (sig_entry->dwo_unit == NULL);
+  gdb_assert (sig_entry->dwo_unit == NULL
+             || sig_entry->dwo_unit == dwo_entry);
 
   sig_entry->section = dwo_entry->section;
   sig_entry->sect_off = dwo_entry->sect_off;
@@ -6034,7 +6225,8 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
   if (sig_entry == NULL)
     sig_entry = add_type_unit (per_objfile, sig, slot);
 
-  fill_in_sig_entry_from_dwo_entry (per_objfile, sig_entry, dwo_entry);
+  if (sig_entry->dwo_unit == nullptr)
+    fill_in_sig_entry_from_dwo_entry (per_objfile, sig_entry, dwo_entry);
   sig_entry->tu_read = 1;
   return sig_entry;
 }
@@ -6307,11 +6499,11 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
 
   if (dwarf_die_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Read die from %s@0x%x of %s:\n",
-                         section->get_name (),
-                         (unsigned) (begin_info_ptr - section->buffer),
-                         bfd_get_filename (abfd));
+      gdb_printf (gdb_stdlog,
+                 "Read die from %s@0x%x of %s:\n",
+                 section->get_name (),
+                 (unsigned) (begin_info_ptr - section->buffer),
+                 bfd_get_filename (abfd));
       dump_die (comp_unit_die, dwarf_die_debug);
     }
 
@@ -6346,6 +6538,14 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
 static struct dwo_unit *
 lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
 {
+#if CXX_STD_THREAD
+  /* We need a lock here both to handle the DWO hash table, and BFD,
+     which is not thread-safe.  */
+  static std::mutex dwo_lock;
+
+  std::lock_guard<std::mutex> guard (dwo_lock);
+#endif
+
   dwarf2_per_cu_data *per_cu = cu->per_cu;
   struct dwo_unit *dwo_unit;
   const char *comp_dir;
@@ -6438,7 +6638,8 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
                          dwarf2_per_objfile *per_objfile,
                          struct abbrev_table *abbrev_table,
                          dwarf2_cu *existing_cu,
-                         bool skip_partial)
+                         bool skip_partial,
+                         abbrev_cache *cache)
   : die_reader_specs {},
     m_this_cu (this_cu)
 {
@@ -6454,9 +6655,9 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
   int rereading_dwo_cu = 0;
 
   if (dwarf_die_debug)
-    fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset %s\n",
-                       this_cu->is_debug_types ? "type" : "comp",
-                       sect_offset_str (this_cu->sect_off));
+    gdb_printf (gdb_stdlog, "Reading %s unit at offset %s\n",
+               this_cu->is_debug_types ? "type" : "comp",
+               sect_offset_str (this_cu->sect_off));
 
   /* If we're reading a TU directly from a DWO file, including a virtual DWO
      file (instead of going through the stub), short-circuit all of this.  */
@@ -6492,9 +6693,14 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
-        in per_objfile yet.  */
-      gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
+      /* If an existing_cu is provided, a dwarf2_cu must not exist for
+        this_cu in per_objfile yet.  Here, CACHE doubles as a flag to
+        let us know that the CU is being scanned using the parallel
+        indexer.  This assert is avoided in this case because (1) it
+        is irrelevant, and (2) the get_cu method is not
+        thread-safe.  */
+      gdb_assert (cache != nullptr
+                 || per_objfile->get_cu (this_cu) == nullptr);
       m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
       cu = m_new_cu.get ();
     }
@@ -6562,10 +6768,16 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
     gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
   else
     {
-      abbrev_section->read (objfile);
-      m_abbrev_table_holder
-       = abbrev_table::read (abbrev_section, cu->header.abbrev_sect_off);
-      abbrev_table = m_abbrev_table_holder.get ();
+      if (cache != nullptr)
+       abbrev_table = cache->find (abbrev_section,
+                                   cu->header.abbrev_sect_off);
+      if (abbrev_table == nullptr)
+       {
+         abbrev_section->read (objfile);
+         m_abbrev_table_holder
+           = abbrev_table::read (abbrev_section, cu->header.abbrev_sect_off);
+         abbrev_table = m_abbrev_table_holder.get ();
+       }
     }
 
   /* Read the top level CU/TU die.  */
@@ -6669,9 +6881,9 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
   const gdb_byte *begin_info_ptr, *info_ptr;
 
   if (dwarf_die_debug)
-    fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset %s\n",
-                       this_cu->is_debug_types ? "type" : "comp",
-                       sect_offset_str (this_cu->sect_off));
+    gdb_printf (gdb_stdlog, "Reading %s unit at offset %s\n",
+               this_cu->is_debug_types ? "type" : "comp",
+               sect_offset_str (this_cu->sect_off));
 
   gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
 
@@ -6878,45 +7090,277 @@ create_partial_symtab (dwarf2_per_cu_data *per_cu,
 
   return pst;
 }
+\f
 
-/* DIE reader function for process_psymtab_comp_unit.  */
+/* An instance of this is created when scanning DWARF to create a
+   cooked index.  */
 
-static void
-process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
-                                 const gdb_byte *info_ptr,
-                                 struct die_info *comp_unit_die,
-                                 enum language pretend_language)
+class cooked_index_storage
 {
-  struct dwarf2_cu *cu = reader->cu;
-  dwarf2_per_objfile *per_objfile = cu->per_objfile;
-  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
-  struct objfile *objfile = per_objfile->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;
-  dwarf2_psymtab *pst;
-  enum pc_bounds_kind cu_bounds_kind;
+public:
 
-  gdb_assert (! per_cu->is_debug_types);
+  cooked_index_storage ()
+    : m_reader_hash (htab_create_alloc (10, hash_cutu_reader,
+                                       eq_cutu_reader,
+                                       htab_delete_entry<cutu_reader>,
+                                       xcalloc, xfree)),
+      m_index (new cooked_index),
+      m_addrmap_storage (),
+      m_addrmap (addrmap_create_mutable (&m_addrmap_storage))
+  {
+  }
 
-  prepare_one_comp_unit (cu, comp_unit_die, pretend_language);
+  DISABLE_COPY_AND_ASSIGN (cooked_index_storage);
 
-  /* Allocate a new partial symbol table structure.  */
-  gdb::unique_xmalloc_ptr<char> debug_filename;
-  static const char artificial[] = "<artificial>";
-  file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
-  if (strcmp (fnd.name, artificial) == 0)
-    {
-      debug_filename.reset (concat (artificial, "@",
-                                   sect_offset_str (per_cu->sect_off),
-                                   (char *) NULL));
-      fnd.name = debug_filename.get ();
-    }
+  /* Return the current abbrev cache.  */
+  abbrev_cache *get_abbrev_cache ()
+  {
+    return &m_abbrev_cache;
+  }
 
-  pst = create_partial_symtab (per_cu, per_objfile, fnd.name);
+  /* Return the DIE reader corresponding to PER_CU.  If no such reader
+     has been registered, return NULL.  */
+  cutu_reader *get_reader (dwarf2_per_cu_data *per_cu)
+  {
+    int index = per_cu->index;
+    return (cutu_reader *) htab_find_with_hash (m_reader_hash.get (),
+                                               &index, index);
+  }
 
-  /* This must be done before calling dwarf2_build_include_psymtabs.  */
+  /* Preserve READER by storing it in the local hash table.  */
+  cutu_reader *preserve (std::unique_ptr<cutu_reader> reader)
+  {
+    m_abbrev_cache.add (reader->release_abbrev_table ());
+
+    int index = reader->cu->per_cu->index;
+    void **slot = htab_find_slot_with_hash (m_reader_hash.get (), &index,
+                                           index, INSERT);
+    gdb_assert (*slot == nullptr);
+    cutu_reader *result = reader.get ();
+    *slot = reader.release ();
+    return result;
+  }
+
+  /* Add an entry to the index.  The arguments describe the entry; see
+     cooked-index.h.  The new entry is returned.  */
+  const cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
+                                cooked_index_flag flags,
+                                const char *name,
+                                const cooked_index_entry *parent_entry,
+                                dwarf2_per_cu_data *per_cu)
+  {
+    return m_index->add (die_offset, tag, flags, name, parent_entry, per_cu);
+  }
+
+  /* Install the current addrmap into the index being constructed,
+     then transfer ownership of the index to the caller.  */
+  std::unique_ptr<cooked_index> release ()
+  {
+    m_index->install_addrmap (m_addrmap);
+    return std::move (m_index);
+  }
+
+  /* Return the mutable addrmap that is currently being created.  */
+  addrmap *get_addrmap ()
+  {
+    return m_addrmap;
+  }
+
+private:
+
+  /* Hash function for a cutu_reader.  */
+  static hashval_t hash_cutu_reader (const void *a)
+  {
+    const cutu_reader *reader = (const cutu_reader *) a;
+    return reader->cu->per_cu->index;
+  }
+
+  /* Equality function for cutu_reader.  */
+  static int eq_cutu_reader (const void *a, const void *b)
+  {
+    const cutu_reader *ra = (const cutu_reader *) a;
+    const int *rb = (const int *) b;
+    return ra->cu->per_cu->index == *rb;
+  }
+
+  /* The abbrev cache used by this indexer.  */
+  abbrev_cache m_abbrev_cache;
+  /* A hash table of cutu_reader objects.  */
+  htab_up m_reader_hash;
+  /* The index that is being constructed.  */
+  std::unique_ptr<cooked_index> m_index;
+
+  /* Storage for the writeable addrmap.  */
+  auto_obstack m_addrmap_storage;
+  /* A writeable addrmap being constructed by this scanner.  */
+  addrmap *m_addrmap;
+};
+
+/* An instance of this is created to index a CU.  */
+
+class cooked_indexer
+{
+public:
+
+  cooked_indexer (cooked_index_storage *storage,
+                 dwarf2_per_cu_data *per_cu,
+                 enum language language)
+    : m_index_storage (storage),
+      m_per_cu (per_cu),
+      m_language (language),
+      m_obstack (),
+      m_die_range_map (addrmap_create_mutable (&m_obstack))
+  {
+  }
+
+  DISABLE_COPY_AND_ASSIGN (cooked_indexer);
+
+  /* Index the given CU.  */
+  void make_index (cutu_reader *reader);
+
+private:
+
+  /* A helper function to turn a section offset into an address that
+     can be used in an addrmap.  */
+  CORE_ADDR form_addr (sect_offset offset, bool is_dwz)
+  {
+    CORE_ADDR value = to_underlying (offset);
+    if (is_dwz)
+      value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1);
+    return value;
+  }
+
+  /* A helper function to scan the PC bounds of READER and record them
+     in the storage's addrmap.  */
+  void check_bounds (cutu_reader *reader);
+
+  /* Ensure that the indicated CU exists.  The cutu_reader for it is
+     returned.  FOR_SCANNING is true if the caller intends to scan all
+     the DIEs in the CU; when false, this use is assumed to be to look
+     up just a single DIE.  */
+  cutu_reader *ensure_cu_exists (cutu_reader *reader,
+                                dwarf2_per_objfile *per_objfile,
+                                sect_offset sect_off,
+                                bool is_dwz,
+                                bool for_scanning);
+
+  /* Index DIEs in the READER starting at INFO_PTR.  PARENT_ENTRY is
+     the entry for the enclosing scope (nullptr at top level).  FULLY
+     is true when a full scan must be done -- in some languages,
+     function scopes must be fully explored in order to find nested
+     functions.  This returns a pointer to just after the spot where
+     reading stopped.  */
+  const gdb_byte *index_dies (cutu_reader *reader,
+                             const gdb_byte *info_ptr,
+                             const cooked_index_entry *parent_entry,
+                             bool fully);
+
+  /* Scan the attributes for a given DIE and update the out
+     parameters.  Returns a pointer to the byte after the DIE.  */
+  const gdb_byte *scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
+                                  cutu_reader *reader,
+                                  const gdb_byte *watermark_ptr,
+                                  const gdb_byte *info_ptr,
+                                  const abbrev_info *abbrev,
+                                  const char **name,
+                                  const char **linkage_name,
+                                  cooked_index_flag *flags,
+                                  sect_offset *sibling_offset,
+                                  const cooked_index_entry **parent_entry,
+                                  CORE_ADDR *maybe_defer,
+                                  bool for_specification);
+
+  /* Handle DW_TAG_imported_unit, by scanning the DIE to find
+     DW_AT_import, and then scanning the referenced CU.  Returns a
+     pointer to the byte after the DIE.  */
+  const gdb_byte *index_imported_unit (cutu_reader *reader,
+                                      const gdb_byte *info_ptr,
+                                      const abbrev_info *abbrev);
+
+  /* Recursively read DIEs, recording the section offsets in
+     m_die_range_map and then calling index_dies.  */
+  const gdb_byte *recurse (cutu_reader *reader,
+                          const gdb_byte *info_ptr,
+                          const cooked_index_entry *parent_entry,
+                          bool fully);
+
+  /* The storage object, where the results are kept.  */
+  cooked_index_storage *m_index_storage;
+  /* The CU that we are reading on behalf of.  This object might be
+     asked to index one CU but to treat the results as if they come
+     from some including CU; in this case the including CU would be
+     recorded here.  */
+  dwarf2_per_cu_data *m_per_cu;
+  /* The language that we're assuming when reading.  */
+  enum language m_language;
+
+  /* Temporary storage.  */
+  auto_obstack m_obstack;
+  /* An addrmap that maps from section offsets (see the form_addr
+     method) to newly-created entries.  See m_deferred_entries to
+     understand this.  */
+  addrmap *m_die_range_map;
+
+  /* A single deferred entry.  */
+  struct deferred_entry
+  {
+    sect_offset die_offset;
+    const char *name;
+    CORE_ADDR spec_offset;
+    dwarf_tag tag;
+    cooked_index_flag flags;
+  };
+
+  /* The generated DWARF can sometimes have the declaration for a
+     method in a class (or perhaps namespace) scope, with the
+     definition appearing outside this scope... just one of the many
+     bad things about DWARF.  In order to handle this situation, we
+     defer certain entries until the end of scanning, at which point
+     we'll know the containing context of all the DIEs that we might
+     have scanned.  This vector stores these deferred entries.  */
+  std::vector<deferred_entry> m_deferred_entries;
+};
+
+
+
+/* DIE reader function for process_psymtab_comp_unit.  */
+
+static void
+process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
+                                 const gdb_byte *info_ptr,
+                                 struct die_info *comp_unit_die,
+                                 enum language pretend_language)
+{
+  struct dwarf2_cu *cu = reader->cu;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+  struct objfile *objfile = per_objfile->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;
+  dwarf2_psymtab *pst;
+  enum pc_bounds_kind cu_bounds_kind;
+
+  gdb_assert (! per_cu->is_debug_types);
+
+  prepare_one_comp_unit (cu, comp_unit_die, pretend_language);
+
+  /* Allocate a new partial symbol table structure.  */
+  static const char artificial[] = "<artificial>";
+  file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+  if (strcmp (fnd.get_name (), artificial) == 0)
+    {
+      gdb::unique_xmalloc_ptr<char> debug_filename
+       (concat (artificial, "@",
+                sect_offset_str (per_cu->sect_off),
+                (char *) NULL));
+      fnd.set_name (std::move (debug_filename));
+    }
+
+  pst = create_partial_symtab (per_cu, per_objfile, fnd.get_name ());
+
+  /* This must be done before calling dwarf2_build_include_psymtabs.  */
   pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
 
   baseaddr = objfile->text_section_offset ();
@@ -6925,8 +7369,11 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 
   /* Possibly set the default values of LOWPC and HIGHPC from
      `DW_AT_ranges'.  */
-  cu_bounds_kind = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
-                                        &best_highpc, cu, pst);
+  cu_bounds_kind
+    = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
+                           &best_highpc, cu,
+                           per_bfd->partial_symtabs->psymtabs_addrmap,
+                           pst);
   if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
     {
       CORE_ADDR low
@@ -7019,16 +7466,21 @@ static void
 process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
                           dwarf2_per_objfile *per_objfile,
                           bool want_partial_unit,
-                          enum language pretend_language)
+                          enum language pretend_language,
+                          cooked_index_storage *storage)
 {
   /* If this compilation unit was already read in, free the
      cached copy in order to read it in again. This is
      necessary because we skipped some symbols when we first
      read in the compilation unit (see load_partial_dies).
      This problem could be avoided, but the benefit is unclear.  */
-  per_objfile->remove_cu (this_cu);
+  if (!per_objfile->per_bfd->using_index)
+    per_objfile->remove_cu (this_cu);
 
-  cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
+  cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false,
+                     (storage == nullptr
+                      ? nullptr
+                      : storage->get_abbrev_cache ()));
 
   if (reader.comp_unit_die == nullptr)
     return;
@@ -7056,13 +7508,28 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
       /* Nothing.  */
     }
   else if (this_cu->is_debug_types)
-    build_type_psymtabs_reader (&reader, reader.info_ptr,
-                               reader.comp_unit_die);
+    build_type_psymtabs_reader (&reader, storage);
   else if (want_partial_unit
           || reader.comp_unit_die->tag != DW_TAG_partial_unit)
-    process_psymtab_comp_unit_reader (&reader, reader.info_ptr,
-                                     reader.comp_unit_die,
-                                     pretend_language);
+    {
+      if (per_objfile->per_bfd->using_index)
+       {
+         bool nope = false;
+         if (this_cu->scanned.compare_exchange_strong (nope, true))
+           {
+             prepare_one_comp_unit (reader.cu, reader.comp_unit_die,
+                                    pretend_language);
+             gdb_assert (storage != nullptr);
+             cooked_indexer indexer (storage, this_cu,
+                                     reader.cu->per_cu->lang);
+             indexer.make_index (&reader);
+           }
+       }
+      else
+       process_psymtab_comp_unit_reader (&reader, reader.info_ptr,
+                                         reader.comp_unit_die,
+                                         pretend_language);
+    }
 
   /* Age out any secondary CUs.  */
   per_objfile->age_comp_units ();
@@ -7071,9 +7538,8 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
 /* Reader function for build_type_psymtabs.  */
 
 static void
-build_type_psymtabs_reader (const struct die_reader_specs *reader,
-                           const gdb_byte *info_ptr,
-                           struct die_info *type_unit_die)
+build_type_psymtabs_reader (cutu_reader *reader,
+                           cooked_index_storage *storage)
 {
   dwarf2_per_objfile *per_objfile = reader->cu->per_objfile;
   struct dwarf2_cu *cu = reader->cu;
@@ -7084,6 +7550,8 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
   struct partial_die_info *first_die;
   CORE_ADDR lowpc, highpc;
   dwarf2_psymtab *pst;
+  const gdb_byte *info_ptr = reader->info_ptr;
+  struct die_info *type_unit_die = reader->comp_unit_die;
 
   gdb_assert (per_cu->is_debug_types);
   sig_type = (struct signatured_type *) per_cu;
@@ -7099,16 +7567,26 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
   tu_group->tus->push_back (sig_type);
 
   prepare_one_comp_unit (cu, type_unit_die, language_minimal);
-  pst = create_partial_symtab (per_cu, per_objfile, "");
-  pst->anonymous = true;
 
-  first_die = load_partial_dies (reader, info_ptr, 1);
+  if (per_objfile->per_bfd->using_index)
+    {
+      gdb_assert (storage != nullptr);
+      cooked_indexer indexer (storage, per_cu, cu->per_cu->lang);
+      indexer.make_index (reader);
+    }
+  else
+    {
+      pst = create_partial_symtab (per_cu, per_objfile, "");
+      pst->anonymous = true;
+
+      first_die = load_partial_dies (reader, info_ptr, 1);
 
-  lowpc = (CORE_ADDR) -1;
-  highpc = (CORE_ADDR) 0;
-  scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
+      lowpc = (CORE_ADDR) -1;
+      highpc = (CORE_ADDR) 0;
+      scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
 
-  pst->end ();
+      pst->end ();
+    }
 }
 
 /* Struct used to sort TUs by their abbreviation table offset.  */
@@ -7147,7 +7625,8 @@ struct tu_abbrev_offset
    dwarf2_per_objfile->per_bfd->type_unit_groups.  */
 
 static void
-build_type_psymtabs (dwarf2_per_objfile *per_objfile)
+build_type_psymtabs (dwarf2_per_objfile *per_objfile,
+                    cooked_index_storage *storage)
 {
   struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
   abbrev_table_up abbrev_table;
@@ -7216,8 +7695,7 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile)
       cutu_reader reader (tu.sig_type, per_objfile,
                          abbrev_table.get (), nullptr, false);
       if (!reader.dummy_p)
-       build_type_psymtabs_reader (&reader, reader.info_ptr,
-                                   reader.comp_unit_die);
+       build_type_psymtabs_reader (&reader, storage);
     }
 }
 
@@ -7273,6 +7751,12 @@ build_type_psymtab_dependencies (void **slot, void *info)
   return 1;
 }
 
+struct skeleton_data
+{
+  dwarf2_per_objfile *per_objfile;
+  cooked_index_storage *storage;
+};
+
 /* Traversal function for process_skeletonless_type_unit.
    Read a TU in a DWO file and build partial symbols for it.  */
 
@@ -7280,15 +7764,16 @@ static int
 process_skeletonless_type_unit (void **slot, void *info)
 {
   struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
-  dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) info;
+  skeleton_data *data = (skeleton_data *) info;
 
   /* If this TU doesn't exist in the global table, add it and read it in.  */
 
-  if (per_objfile->per_bfd->signatured_types == NULL)
-    per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
+  if (data->per_objfile->per_bfd->signatured_types == NULL)
+    data->per_objfile->per_bfd->signatured_types
+      = allocate_signatured_type_table ();
 
   signatured_type find_entry (dwo_unit->signature);
-  slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
+  slot = htab_find_slot (data->per_objfile->per_bfd->signatured_types.get (),
                         &find_entry, INSERT);
   /* If we've already seen this type there's nothing to do.  What's happening
      is we're doing our own version of comdat-folding here.  */
@@ -7298,15 +7783,14 @@ process_skeletonless_type_unit (void **slot, void *info)
   /* This does the job that create_all_comp_units would have done for
      this TU.  */
   signatured_type *entry
-    = add_type_unit (per_objfile, dwo_unit->signature, slot);
-  fill_in_sig_entry_from_dwo_entry (per_objfile, entry, dwo_unit);
+    = add_type_unit (data->per_objfile, dwo_unit->signature, slot);
+  fill_in_sig_entry_from_dwo_entry (data->per_objfile, entry, dwo_unit);
   *slot = entry;
 
   /* This does the job that build_type_psymtabs would have done.  */
-  cutu_reader reader (entry, per_objfile, nullptr, nullptr, false);
+  cutu_reader reader (entry, data->per_objfile, nullptr, nullptr, false);
   if (!reader.dummy_p)
-    build_type_psymtabs_reader (&reader, reader.info_ptr,
-                               reader.comp_unit_die);
+    build_type_psymtabs_reader (&reader, data->storage);
 
   return 1;
 }
@@ -7330,15 +7814,18 @@ process_dwo_file_for_skeletonless_type_units (void **slot, void *info)
    Note: This can't be done until we know what all the DWO files are.  */
 
 static void
-process_skeletonless_type_units (dwarf2_per_objfile *per_objfile)
+process_skeletonless_type_units (dwarf2_per_objfile *per_objfile,
+                                cooked_index_storage *storage)
 {
+  skeleton_data data { per_objfile, storage };
+
   /* Skeletonless TUs in DWP files without .gdb_index is not supported yet.  */
   if (get_dwp_file (per_objfile) == NULL
       && per_objfile->per_bfd->dwo_files != NULL)
     {
       htab_traverse_noresize (per_objfile->per_bfd->dwo_files.get (),
                              process_dwo_file_for_skeletonless_type_units,
-                             per_objfile);
+                             &data);
     }
 }
 
@@ -7378,15 +7865,12 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
   scoped_restore restore_reading_psyms
     = make_scoped_restore (&per_bfd->reading_partial_symbols, true);
 
-  per_bfd->info.read (objfile);
+  per_bfd->map_info_sections (objfile);
 
   /* Any cached compilation units will be linked by the per-objfile
      read_in_chain.  Make sure to free them when we're done.  */
   free_cached_comp_units freer (per_objfile);
 
-  create_all_comp_units (per_objfile);
-  build_type_psymtabs (per_objfile);
-
   /* Create a temporary address map on a temporary obstack.  We later
      copy this to the final obstack.  */
   auto_obstack temp_obstack;
@@ -7395,20 +7879,91 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
     = make_scoped_restore (&per_bfd->partial_symtabs->psymtabs_addrmap,
                           addrmap_create_mutable (&temp_obstack));
 
-  for (const auto &per_cu : per_bfd->all_comp_units)
+  cooked_index_storage index_storage;
+  cooked_index_storage *index_storage_ptr
+    = per_bfd->using_index ? &index_storage : nullptr;
+  create_all_comp_units (per_objfile);
+  build_type_psymtabs (per_objfile, index_storage_ptr);
+  std::vector<std::unique_ptr<cooked_index>> indexes;
+  if (per_bfd->using_index)
     {
-      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.get (), per_objfile, false,
-                                language_minimal);
+      per_bfd->quick_file_names_table
+       = create_quick_file_names_table (per_bfd->all_comp_units.size ());
+
+      if (!per_bfd->debug_aranges.empty ())
+       read_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges,
+                                  index_storage.get_addrmap ());
+
+      {
+       /* Ensure that complaints are handled correctly.  */
+       complaint_interceptor complaint_handler;
+
+       using iter_type = typeof (per_bfd->all_comp_units.begin ());
+
+       /* Each thread returns a pair holding a cooked index, and a vector
+          of errors that should be printed.  The latter is done because
+          GDB's I/O system is not thread-safe.  run_on_main_thread could be
+          used, but that would mean the messages are printed after the
+          prompt, which looks weird.  */
+       using result_type = std::pair<std::unique_ptr<cooked_index>,
+                                     std::vector<gdb_exception>>;
+       std::vector<result_type> results
+         = gdb::parallel_for_each (1, per_bfd->all_comp_units.begin (),
+                                   per_bfd->all_comp_units.end (),
+                                   [=] (iter_type iter, iter_type end)
+                                   {
+                                     std::vector<gdb_exception> errors;
+                                     cooked_index_storage thread_storage;
+                                     for (; iter != end; ++iter)
+                                       {
+                                         dwarf2_per_cu_data *per_cu = iter->get ();
+                                         try
+                                           {
+                                             process_psymtab_comp_unit (per_cu, per_objfile,
+                                                                        false,
+                                                                        language_minimal,
+                                                                        &thread_storage);
+                                           }
+                                         catch (gdb_exception &except)
+                                           {
+                                             errors.push_back (std::move (except));
+                                           }
+                                       }
+                                     return result_type (thread_storage.release (),
+                                                         std::move (errors));
+                                   });
+
+       /* Only show a given exception a single time.  */
+       std::unordered_set<gdb_exception> seen_exceptions;
+       for (auto &one_result : results)
+         {
+           indexes.push_back (std::move (one_result.first));
+           for (auto &one_exc : one_result.second)
+             {
+               if (seen_exceptions.insert (one_exc).second)
+                 exception_print (gdb_stderr, one_exc);
+             }
+         }
+      }
+    }
+  else
+    {
+      for (const auto &per_cu : per_bfd->all_comp_units)
+       {
+         if (!per_bfd->using_index && 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.get (), per_objfile, false,
+                                    language_minimal, nullptr);
+       }
     }
 
   /* This has to wait until we read the CUs, we need the list of DWOs.  */
-  process_skeletonless_type_units (per_objfile);
+  process_skeletonless_type_units (per_objfile, &index_storage);
 
   /* Now that all TUs have been processed we can fill in the dependencies.  */
-  if (per_bfd->type_unit_groups != NULL)
+  if (!per_bfd->using_index && per_bfd->type_unit_groups != NULL)
     {
       htab_traverse_noresize (per_bfd->type_unit_groups.get (),
                              build_type_psymtab_dependencies, per_objfile);
@@ -7417,14 +7972,39 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
   if (dwarf_read_debug > 0)
     print_tu_stats (per_objfile);
 
-  set_partial_user (per_objfile);
-
-  per_bfd->partial_symtabs->psymtabs_addrmap
-    = addrmap_create_fixed (per_bfd->partial_symtabs->psymtabs_addrmap,
-                           per_bfd->partial_symtabs->obstack ());
-  /* At this point we want to keep the address map.  */
-  save_psymtabs_addrmap.release ();
+  if (per_bfd->using_index)
+    {
+      indexes.push_back (index_storage.release ());
+      /* Remove any NULL entries.  This might happen if parallel-for
+        decides to throttle the number of threads that were used.  */
+      indexes.erase
+       (std::remove_if (indexes.begin (),
+                        indexes.end (),
+                        [] (const std::unique_ptr<cooked_index> &entry)
+                        {
+                          return entry == nullptr;
+                        }),
+        indexes.end ());
+      indexes.shrink_to_fit ();
+      per_bfd->cooked_index_table.reset
+       (new cooked_index_vector (std::move (indexes)));
+
+      const cooked_index_entry *main_entry
+       = per_bfd->cooked_index_table->get_main ();
+      if (main_entry != nullptr)
+       set_objfile_main_name (objfile, main_entry->name,
+                              main_entry->per_cu->lang);
+    }
+  else
+    {
+      set_partial_user (per_objfile);
 
+      per_bfd->partial_symtabs->psymtabs_addrmap
+       = addrmap_create_fixed (per_bfd->partial_symtabs->psymtabs_addrmap,
+                               per_bfd->partial_symtabs->obstack ());
+      /* At this point we want to keep the address map.  */
+      save_psymtabs_addrmap.release ();
+    }
   dwarf_read_debug_printf ("Done building psymtabs of %s",
                           objfile_name (objfile));
 }
@@ -7513,6 +8093,10 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
       this_cu->is_dwz = is_dwz;
       this_cu->section = section;
 
+      if (per_objfile->per_bfd->using_index)
+       this_cu->v.quick = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack,
+                                          struct dwarf2_per_cu_quick_data);
+
       info_ptr = info_ptr + this_cu->length;
       per_objfile->per_bfd->all_comp_units.push_back (std::move (this_cu));
     }
@@ -7536,8 +8120,16 @@ create_all_comp_units (dwarf2_per_objfile *per_objfile)
 
   dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
   if (dwz != NULL)
-    read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1,
-                                 types_htab, rcuh_kind::COMPILE);
+    {
+      /* Pre-read the sections we'll need to construct an index.  */
+      struct objfile *objfile = per_objfile->objfile;
+      dwz->abbrev.read (objfile);
+      dwz->info.read (objfile);
+      dwz->str.read (objfile);
+      dwz->line.read (objfile);
+      read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1,
+                                   types_htab, rcuh_kind::COMPILE);
+    }
 
   per_objfile->per_bfd->signatured_types = std::move (types_htab);
 }
@@ -7611,6 +8203,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
                add_partial_enumeration (pdi, cu);
              break;
            case DW_TAG_base_type:
+           case DW_TAG_generic_subrange:
            case DW_TAG_subrange_type:
              /* File scope base type definitions are added to the partial
                 symbol table.  */
@@ -7636,12 +8229,13 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
                  }
 
                per_cu = dwarf2_find_containing_comp_unit
-                          (pdi->d.sect_off, pdi->is_dwz, cu->per_objfile);
+                          (pdi->d.sect_off, pdi->is_dwz,
+                           cu->per_objfile->per_bfd);
 
                /* Go read the partial unit, if needed.  */
                if (per_cu->v.psymtab == NULL)
                  process_psymtab_comp_unit (per_cu, cu->per_objfile, true,
-                                            cu->per_cu->lang);
+                                            cu->per_cu->lang, nullptr);
 
                if (pdi->die_parent == nullptr
                    && per_cu->unit_type == DW_UT_compile
@@ -7866,7 +8460,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       psymbol.domain = VAR_DOMAIN;
       psymbol.aclass = LOC_BLOCK;
       psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
-      psymbol.ginfo.value.address = addr;
+      psymbol.ginfo.set_value_address (addr);
 
       if (pdi->main_subprogram && actual_name != NULL)
        set_objfile_main_name (objfile, actual_name, cu->per_cu->lang);
@@ -7911,7 +8505,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
              psymbol.domain = VAR_DOMAIN;
              psymbol.aclass = LOC_STATIC;
              psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
-             psymbol.ginfo.value.address = addr;
+             psymbol.ginfo.set_value_address (addr);
              where = psymbol_placement::GLOBAL;
            }
        }
@@ -7928,7 +8522,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
          psymbol.aclass = LOC_STATIC;
          psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
          if (has_loc)
-           psymbol.ginfo.value.address = addr;
+           psymbol.ginfo.set_value_address (addr);
          where = psymbol_placement::STATIC;
        }
       break;
@@ -7936,6 +8530,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
     case DW_TAG_typedef:
     case DW_TAG_base_type:
     case DW_TAG_subrange_type:
+    case DW_TAG_generic_subrange:
       psymbol.domain = VAR_DOMAIN;
       psymbol.aclass = LOC_TYPEDEF;
       where = psymbol_placement::STATIC;
@@ -8043,6 +8638,10 @@ add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
     scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
 }
 
+static int dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
+                              CORE_ADDR *high_return, struct dwarf2_cu *cu,
+                              addrmap *map, void *datum, dwarf_tag tag);
+
 /* Read a partial die corresponding to a subprogram or an inlined
    subprogram and create a partial symbol for that subprogram.
    When the CU language allows it, this routine also defines a partial
@@ -8092,7 +8691,23 @@ add_partial_subprogram (struct partial_die_info *pdi,
            }
        }
 
-      if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+      if (pdi->has_range_info
+         && dwarf2_ranges_read (pdi->ranges_offset, &pdi->lowpc, &pdi->highpc,
+                                cu,
+                                (set_addrmap
+                                 ? cu->per_objfile->per_bfd->partial_symtabs->psymtabs_addrmap
+                                 : nullptr),
+                                set_addrmap ? cu->per_cu->v.psymtab : nullptr,
+                                pdi->tag))
+       {
+         if (pdi->lowpc < *lowpc)
+           *lowpc = pdi->lowpc;
+         if (pdi->highpc > *highpc)
+           *highpc = pdi->highpc;
+       }
+
+      if (pdi->has_pc_info || pdi->has_range_info
+         || (!pdi->is_external && pdi->may_be_inlined))
        {
          if (!pdi->is_declaration)
            /* Ignore subprogram DIEs that do not have a name, they are
@@ -8209,12 +8824,15 @@ skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
 /* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
    INFO_PTR should point just after the initial uleb128 of a DIE, and the
    abbrev corresponding to that skipped uleb128 should be passed in
-   ABBREV.  Returns a pointer to this DIE's sibling, skipping any
-   children.  */
+   ABBREV.
+   
+   If DO_SKIP_CHILDREN is true, or if the DIE has no children, this
+   returns a pointer to this DIE's sibling, skipping any children.
+   Otherwise, returns a pointer to the DIE's first child.  */
 
 static const gdb_byte *
 skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
-             const struct abbrev_info *abbrev)
+             const struct abbrev_info *abbrev, bool do_skip_children)
 {
   unsigned int bytes_read;
   struct attribute attr;
@@ -8224,10 +8842,29 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
   const gdb_byte *buffer_end = reader->buffer_end;
   unsigned int form, i;
 
+  if (do_skip_children && abbrev->sibling_offset != (unsigned short) -1)
+    {
+      /* We only handle DW_FORM_ref4 here.  */
+      const gdb_byte *sibling_data = info_ptr + abbrev->sibling_offset;
+      unsigned int offset = read_4_bytes (abfd, sibling_data);
+      const gdb_byte *sibling_ptr
+       = buffer + to_underlying (cu->header.sect_off) + offset;
+      if (sibling_ptr >= info_ptr && sibling_ptr < reader->buffer_end)
+       return sibling_ptr;
+      /* Fall through to the slow way.  */
+    }
+  else if (abbrev->size_if_constant != 0)
+    {
+      info_ptr += abbrev->size_if_constant;
+      if (do_skip_children && abbrev->has_children)
+       return skip_children (reader, info_ptr);
+      return info_ptr;
+    }
+
   for (i = 0; i < abbrev->num_attrs; i++)
     {
       /* The only abbrev we care about is DW_AT_sibling.  */
-      if (abbrev->attrs[i].name == DW_AT_sibling)
+      if (do_skip_children && abbrev->attrs[i].name == DW_AT_sibling)
        {
          read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
          if (attr.form == DW_FORM_ref_addr)
@@ -8344,7 +8981,7 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
        }
     }
 
-  if (abbrev->has_children)
+  if (do_skip_children && abbrev->has_children)
     return skip_children (reader, info_ptr);
   else
     return info_ptr;
@@ -8778,7 +9415,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
          struct symbol *sym = list->symbol[i];
 
          if (sym->language () == language_go
-             && SYMBOL_CLASS (sym) == LOC_BLOCK)
+             && sym->aclass () == LOC_BLOCK)
            {
              gdb::unique_xmalloc_ptr<char> this_package_name
                (go_symbol_package_name (sym));
@@ -8815,9 +9452,9 @@ fixup_go_packaging (struct dwarf2_cu *cu)
       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,
         e.g., "main" finds the "main" module and not C's main().  */
-      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-      SYMBOL_TYPE (sym) = type;
+      sym->set_domain (STRUCT_DOMAIN);
+      sym->set_aclass_index (LOC_TYPEDEF);
+      sym->set_type (type);
 
       add_symbol_to_list (sym, cu->get_builder ()->get_global_symbols ());
     }
@@ -8937,9 +9574,9 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
 
 #define RUST_ENUM_PREFIX "RUST$ENCODED$ENUM$"
   if (type->num_fields () == 1
-      && startswith (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX))
+      && startswith (type->field (0).name (), RUST_ENUM_PREFIX))
     {
-      const char *name = TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX);
+      const char *name = type->field (0).name () + strlen (RUST_ENUM_PREFIX);
 
       /* Decode the field name to find the offset of the
         discriminant.  */
@@ -8952,18 +9589,18 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
          name = tail;
          if (*name != '$'
              || index >= field_type->num_fields ()
-             || (TYPE_FIELD_LOC_KIND (field_type, index)
+             || (field_type->field (index).loc_kind ()
                  != FIELD_LOC_KIND_BITPOS))
            {
              complaint (_("Could not parse Rust enum encoding string \"%s\""
                           "[in module %s]"),
-                        TYPE_FIELD_NAME (type, 0),
+                        type->field (0).name (),
                         objfile_name (objfile));
              return;
            }
          ++name;
 
-         bit_offset += TYPE_FIELD_BITPOS (field_type, index);
+         bit_offset += field_type->field (index).loc_bitpos ();
          field_type = field_type->field (index).type ();
        }
 
@@ -8979,17 +9616,17 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       /* Put the discriminant at index 0.  */
       type->field (0).set_type (field_type);
       TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
-      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
-      SET_FIELD_BITPOS (type->field (0), bit_offset);
+      type->field (0).set_name ("<<discriminant>>");
+      type->field (0).set_loc_bitpos (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.  */
       type->field (1) = saved_field;
-      TYPE_FIELD_NAME (type, 1)
-       = rust_last_path_segment (type->field (1).type ()->name ());
+      type->field (1).set_name
+       (rust_last_path_segment (type->field (1).type ()->name ()));
       type->field (1).type ()->set_name
        (rust_fully_qualify (&objfile->objfile_obstack, type->name (),
-                            TYPE_FIELD_NAME (type, 1)));
+                            type->field (1).name ()));
 
       const char *dataless_name
        = rust_fully_qualify (&objfile->objfile_obstack, type->name (),
@@ -8999,8 +9636,8 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       type->field (2).set_type (dataless_type);
       /* NAME points into the original discriminant name, which
         already has the correct lifetime.  */
-      TYPE_FIELD_NAME (type, 2) = name;
-      SET_FIELD_BITPOS (type->field (2), 0);
+      type->field (2).set_name (name);
+      type->field (2).set_loc_bitpos (0);
 
       /* Indicate that this is a variant type.  */
       static discriminant_range ranges[1] = { { 0, 0 } };
@@ -9008,7 +9645,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
     }
   /* A union with a single anonymous field is probably an old-style
      univariant enum.  */
-  else if (type->num_fields () == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
+  else if (type->num_fields () == 1 && streq (type->field (0).name (), ""))
     {
       /* Smash this type to be a structure type.  We have to do this
         because the type has already been recorded.  */
@@ -9017,7 +9654,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       struct type *field_type = type->field (0).type ();
       const char *variant_name
        = rust_last_path_segment (field_type->name ());
-      TYPE_FIELD_NAME (type, 0) = variant_name;
+      type->field (0).set_name (variant_name);
       field_type->set_name
        (rust_fully_qualify (&objfile->objfile_obstack,
                             type->name (), variant_name));
@@ -9041,7 +9678,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
              /* Could be data-less variant, so keep going.  */
              disr_type = nullptr;
            }
-         else if (strcmp (TYPE_FIELD_NAME (disr_type, 0),
+         else if (strcmp (disr_type->field (0).name (),
                           "RUST$ENUM$DISR") != 0)
            {
              /* Not a Rust enum.  */
@@ -9076,7 +9713,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       /* Install the discriminant at index 0 in the union.  */
       type->field (0) = *disr_field;
       TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
-      TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+      type->field (0).set_name ("<<discriminant>>");
 
       /* We need a way to find the correct discriminant given a
         variant name.  For convenience we build a map here.  */
@@ -9084,11 +9721,11 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       std::unordered_map<std::string, ULONGEST> discriminant_map;
       for (int i = 0; i < enum_type->num_fields (); ++i)
        {
-         if (TYPE_FIELD_LOC_KIND (enum_type, i) == FIELD_LOC_KIND_ENUMVAL)
+         if (enum_type->field (i).loc_kind () == FIELD_LOC_KIND_ENUMVAL)
            {
              const char *name
-               = rust_last_path_segment (TYPE_FIELD_NAME (enum_type, i));
-             discriminant_map[name] = TYPE_FIELD_ENUMVAL (enum_type, i);
+               = rust_last_path_segment (enum_type->field (i).name ());
+             discriminant_map[name] = enum_type->field (i).loc_enumval ();
            }
        }
 
@@ -9126,7 +9763,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
              sub_type->set_num_fields (sub_type->num_fields () - 1);
              sub_type->set_fields (sub_type->fields () + 1);
            }
-         TYPE_FIELD_NAME (type, i) = variant_name;
+         type->field (i).set_name (variant_name);
          sub_type->set_name
            (rust_fully_qualify (&objfile->objfile_obstack,
                                 type->name (), variant_name));
@@ -9355,7 +9992,8 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
   get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
   addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
-  static_block = cu->get_builder ()->end_symtab_get_static_block (addr, 0, 1);
+  static_block
+    = cu->get_builder ()->end_compunit_symtab_get_static_block (addr, 0, 1);
 
   /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
      Also, DW_AT_ranges may record ranges not belonging to any child DIEs
@@ -9364,9 +10002,8 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
      this comp unit.  */
   dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
 
-  cust = cu->get_builder ()->end_symtab_from_static_block (static_block,
-                                                   SECT_OFF_TEXT (objfile),
-                                                   0);
+  cust = cu->get_builder ()->end_compunit_symtab_from_static_block
+    (static_block, SECT_OFF_TEXT (objfile), 0);
 
   if (cust != NULL)
     {
@@ -9376,8 +10013,8 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
         compilation is from a C file generated by language preprocessors, do
         not set the language if it was already deduced by start_subfile.  */
       if (!(cu->per_cu->lang == language_c
-           && COMPUNIT_FILETABS (cust)->language != language_unknown))
-       COMPUNIT_FILETABS (cust)->language = cu->per_cu->lang;
+           && cust->primary_filetab ()->language () != language_unknown))
+       cust->primary_filetab ()->set_language (cu->per_cu->lang);
 
       /* GCC-4.0 has started to support -fvar-tracking.  GCC-3.x still can
         produce DW_AT_location with location lists but it can be possibly
@@ -9392,12 +10029,12 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
         options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
         */
       if (cu->has_loclist && gcc_4_minor >= 5)
-       cust->locations_valid = 1;
+       cust->set_locations_valid (true);
 
       if (gcc_4_minor >= 5)
-       cust->epilogue_unwind_valid = 1;
+       cust->set_epilogue_unwind_valid (true);
 
-      cust->call_site_htab = cu->call_site_htab;
+      cust->set_call_site_htab (cu->call_site_htab);
     }
 
   per_objfile->set_symtab (cu->per_cu, cust);
@@ -9461,8 +10098,8 @@ process_full_type_unit (dwarf2_cu *cu,
             do not set the language if it was already deduced by
             start_subfile.  */
          if (!(cu->per_cu->lang == language_c
-               && COMPUNIT_FILETABS (cust)->language != language_c))
-           COMPUNIT_FILETABS (cust)->language = cu->per_cu->lang;
+               && cust->primary_filetab ()->language () != language_c))
+           cust->primary_filetab ()->set_language (cu->per_cu->lang);
        }
     }
   else
@@ -9499,7 +10136,8 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
       bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
       dwarf2_per_objfile *per_objfile = cu->per_objfile;
       dwarf2_per_cu_data *per_cu
-       = dwarf2_find_containing_comp_unit (sect_off, is_dwz, per_objfile);
+       = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
+                                           per_objfile->per_bfd);
 
       /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
         into another compilation unit, at root level.  Regard this as a hint,
@@ -9592,6 +10230,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -9619,6 +10258,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       /* FALLTHROUGH */
     case DW_TAG_base_type:
     case DW_TAG_subrange_type:
+    case DW_TAG_generic_subrange:
     case DW_TAG_typedef:
       /* Add a typedef symbol for the type definition, if it has a
         DW_AT_name.  */
@@ -9932,7 +10572,7 @@ dwarf2_compute_name (const char *name,
                      else if (bytes != NULL)
                        {
                          v = allocate_value (type);
-                         memcpy (value_contents_writeable (v), bytes,
+                         memcpy (value_contents_writeable (v).data (), bytes,
                                  TYPE_LENGTH (type));
                        }
                      else
@@ -10061,9 +10701,8 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
             to look up their definition from their declaration so
             the only disadvantage remains the minimal symbol variant
             `long name(params)' does not have the proper inferior type.  */
-         demangled.reset (gdb_demangle (mangled,
-                                        (DMGL_PARAMS | DMGL_ANSI
-                                         | DMGL_RET_DROP)));
+         demangled = gdb_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI
+                                             | DMGL_RET_DROP));
        }
       if (demangled)
        canon = demangled.get ();
@@ -10373,38 +11012,25 @@ producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
   return cu->producer_is_gcc_lt_4_3;
 }
 
-static file_and_directory
+static file_and_directory &
 find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
 {
-  file_and_directory res;
+  if (cu->per_cu->fnd != nullptr)
+    return *cu->per_cu->fnd;
 
   /* Find the filename.  Do not use dwarf2_name here, since the filename
      is not a source language identifier.  */
-  res.name = dwarf2_string_attr (die, DW_AT_name, cu);
-  res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
-
-  if (res.comp_dir == NULL
-      && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
-      && IS_ABSOLUTE_PATH (res.name))
-    {
-      res.comp_dir_storage = ldirname (res.name);
-      if (!res.comp_dir_storage.empty ())
-       res.comp_dir = res.comp_dir_storage.c_str ();
-    }
-  if (res.comp_dir != NULL)
-    {
-      /* Irix 6.2 native cc prepends <machine>.: to the compilation
-        directory, get rid of it.  */
-      const char *cp = strchr (res.comp_dir, ':');
-
-      if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
-       res.comp_dir = cp + 1;
-    }
+  file_and_directory res (dwarf2_string_attr (die, DW_AT_name, cu),
+                         dwarf2_string_attr (die, DW_AT_comp_dir, cu));
 
-  if (res.name == NULL)
-    res.name = "<unknown>";
+  if (res.get_comp_dir () == nullptr
+      && producer_is_gcc_lt_4_3 (cu)
+      && res.get_name () != nullptr
+      && IS_ABSOLUTE_PATH (res.get_name ()))
+    res.set_comp_dir (ldirname (res.get_name ()));
 
-  return res;
+  cu->per_cu->fnd.reset (new file_and_directory (std::move (res)));
+  return *cu->per_cu->fnd;
 }
 
 /* Handle DW_AT_stmt_list for a compilation unit.
@@ -10532,9 +11158,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
     lowpc = highpc;
   lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
 
-  file_and_directory fnd = find_file_and_directory (die, cu);
+  file_and_directory &fnd = find_file_and_directory (die, cu);
 
-  cu->start_symtab (fnd.name, fnd.comp_dir, lowpc);
+  cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile),
+                            lowpc);
 
   gdb_assert (per_objfile->sym_cu == nullptr);
   scoped_restore restore_sym_cu
@@ -10542,8 +11169,13 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* Decode line number information if present.  We do this before
      processing child DIEs, so that the line header table is available
-     for DW_AT_decl_file.  */
-  handle_DW_AT_stmt_list (die, cu, fnd, lowpc);
+     for DW_AT_decl_file.  The PC check is here because, if LOWPC and
+     HIGHPC are both 0x0, then there won't be any interesting code in
+     the CU, but a check later on (in
+     lnp_state_machine::check_line_address) will fail to properly
+     exclude an entry that was removed via --gc-sections.  */
+  if (lowpc != highpc)
+    handle_DW_AT_stmt_list (die, cu, fnd, lowpc);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -10622,15 +11254,15 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
   if (lh == NULL)
     {
       if (first_time)
-       start_symtab ("", NULL, 0);
+       start_compunit_symtab ("", NULL, 0);
       else
        {
          gdb_assert (tug_unshare->symtabs == NULL);
          gdb_assert (m_builder == nullptr);
          struct compunit_symtab *cust = tug_unshare->compunit_symtab;
          m_builder.reset (new struct buildsym_compunit
-                          (COMPUNIT_OBJFILE (cust), "",
-                           COMPUNIT_DIRNAME (cust),
+                          (cust->objfile (), "",
+                           cust->dirname (),
                            compunit_language (cust),
                            0, cust));
          list_in_scope = get_builder ()->get_file_symbols ();
@@ -10643,7 +11275,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 
   if (first_time)
     {
-      struct compunit_symtab *cust = start_symtab ("", NULL, 0);
+      struct compunit_symtab *cust = start_compunit_symtab ("", NULL, 0);
 
       /* Note: We don't assign tu_group->compunit_symtab yet because we're
         still initializing it, and our caller (a few levels up)
@@ -10651,7 +11283,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
         time.  */
 
       tug_unshare->symtabs
-       = XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
+       = XOBNEWVEC (&cust->objfile ()->objfile_obstack,
                     struct symtab *, line_header->file_names_size ());
 
       auto &file_names = line_header->file_names ();
@@ -10681,8 +11313,8 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
       gdb_assert (m_builder == nullptr);
       struct compunit_symtab *cust = tug_unshare->compunit_symtab;
       m_builder.reset (new struct buildsym_compunit
-                      (COMPUNIT_OBJFILE (cust), "",
-                       COMPUNIT_DIRNAME (cust),
+                      (cust->objfile (), "",
+                       cust->dirname (),
                        compunit_language (cust),
                        0, cust));
       list_in_scope = get_builder ()->get_file_symbols ();
@@ -12020,10 +12652,10 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
   gdb::unique_xmalloc_ptr<char> search_path_holder;
   if (search_cwd)
     {
-      if (*debug_file_directory != '\0')
+      if (!debug_file_directory.empty ())
        {
          search_path_holder.reset (concat (".", dirname_separator_string,
-                                           debug_file_directory,
+                                           debug_file_directory.c_str (),
                                            (char *) NULL));
          search_path = search_path_holder.get ();
        }
@@ -12031,7 +12663,7 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
        search_path = ".";
     }
   else
-    search_path = debug_file_directory;
+    search_path = debug_file_directory.c_str ();
 
   /* Add the path for the executable binary to the list of search paths.  */
   std::string objfile_dir = ldirname (objfile_name (per_objfile->objfile));
@@ -12102,7 +12734,7 @@ open_dwo_file (dwarf2_per_objfile *per_objfile,
   /* That didn't work, try debug-file-directory, which, despite its name,
      is a list of paths.  */
 
-  if (*debug_file_directory == '\0')
+  if (debug_file_directory.empty ())
     return NULL;
 
   return try_open_dwop_file (per_objfile, file_name,
@@ -12113,69 +12745,47 @@ open_dwo_file (dwarf2_per_objfile *per_objfile,
    size of each of the DWO debugging sections we are interested in.  */
 
 static void
-dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp,
-                           dwo_sections *dwo_sections)
+dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
+                           asection *sectp, dwo_sections *dwo_sections)
 {
   const struct dwop_section_names *names = &dwop_section_names;
 
+  struct dwarf2_section_info *dw_sect = nullptr;
+
   if (names->abbrev_dwo.matches (sectp->name))
-    {
-      dwo_sections->abbrev.s.section = sectp;
-      dwo_sections->abbrev.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->abbrev;
   else if (names->info_dwo.matches (sectp->name))
-    {
-      dwo_sections->info.s.section = sectp;
-      dwo_sections->info.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->info;
   else if (names->line_dwo.matches (sectp->name))
-    {
-      dwo_sections->line.s.section = sectp;
-      dwo_sections->line.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->line;
   else if (names->loc_dwo.matches (sectp->name))
-    {
-      dwo_sections->loc.s.section = sectp;
-      dwo_sections->loc.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->loc;
   else if (names->loclists_dwo.matches (sectp->name))
-    {
-      dwo_sections->loclists.s.section = sectp;
-      dwo_sections->loclists.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->loclists;
   else if (names->macinfo_dwo.matches (sectp->name))
-    {
-      dwo_sections->macinfo.s.section = sectp;
-      dwo_sections->macinfo.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->macinfo;
   else if (names->macro_dwo.matches (sectp->name))
-    {
-      dwo_sections->macro.s.section = sectp;
-      dwo_sections->macro.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->macro;
   else if (names->rnglists_dwo.matches (sectp->name))
-    {
-      dwo_sections->rnglists.s.section = sectp;
-      dwo_sections->rnglists.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->rnglists;
   else if (names->str_dwo.matches (sectp->name))
-    {
-      dwo_sections->str.s.section = sectp;
-      dwo_sections->str.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->str;
   else if (names->str_offsets_dwo.matches (sectp->name))
-    {
-      dwo_sections->str_offsets.s.section = sectp;
-      dwo_sections->str_offsets.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwo_sections->str_offsets;
   else if (names->types_dwo.matches (sectp->name))
     {
       struct dwarf2_section_info type_section;
 
       memset (&type_section, 0, sizeof (type_section));
-      type_section.s.section = sectp;
-      type_section.size = bfd_section_size (sectp);
       dwo_sections->types.push_back (type_section);
+      dw_sect = &dwo_sections->types.back ();
+    }
+
+  if (dw_sect != nullptr)
+    {
+      dw_sect->s.section = sectp;
+      dw_sect->size = bfd_section_size (sectp);
+      dw_sect->read (objfile);
     }
 }
 
@@ -12203,8 +12813,8 @@ open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
   dwo_file->dbfd = std::move (dbfd);
 
   for (asection *sec : gdb_bfd_sections (dwo_file->dbfd))
-    dwarf2_locate_dwo_sections (dwo_file->dbfd.get (), sec,
-                               &dwo_file->sections);
+    dwarf2_locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (),
+                               sec, &dwo_file->sections);
 
   create_cus_hash_table (per_objfile, cu, *dwo_file, dwo_file->sections.info,
                         dwo_file->cus);
@@ -12231,8 +12841,8 @@ open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
    we are interested in.  */
 
 static void
-dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
-                                  dwp_file *dwp_file)
+dwarf2_locate_common_dwp_sections (struct objfile *objfile, bfd *abfd,
+                                  asection *sectp, dwp_file *dwp_file)
 {
   const struct dwop_section_names *names = &dwop_section_names;
   unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
@@ -12243,20 +12853,19 @@ dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
+  struct dwarf2_section_info *dw_sect = nullptr;
   if (names->str_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.str.s.section = sectp;
-      dwp_file->sections.str.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.str;
   else if (names->cu_index.matches (sectp->name))
-    {
-      dwp_file->sections.cu_index.s.section = sectp;
-      dwp_file->sections.cu_index.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.cu_index;
   else if (names->tu_index.matches (sectp->name))
+    dw_sect = &dwp_file->sections.tu_index;
+
+  if (dw_sect != nullptr)
     {
-      dwp_file->sections.tu_index.s.section = sectp;
-      dwp_file->sections.tu_index.size = bfd_section_size (sectp);
+      dw_sect->s.section = sectp;
+      dw_sect->size = bfd_section_size (sectp);
+      dw_sect->read (objfile);
     }
 }
 
@@ -12266,7 +12875,8 @@ dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
    have version 1 or 2 or 5 until we parse the cu_index/tu_index sections.  */
 
 static void
-dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
+dwarf2_locate_v2_dwp_sections (struct objfile *objfile, bfd *abfd,
+                              asection *sectp, void *dwp_file_ptr)
 {
   struct dwp_file *dwp_file = (struct dwp_file *) dwp_file_ptr;
   const struct dwop_section_names *names = &dwop_section_names;
@@ -12278,45 +12888,29 @@ dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
+  struct dwarf2_section_info *dw_sect = nullptr;
   if (names->abbrev_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.abbrev.s.section = sectp;
-      dwp_file->sections.abbrev.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.abbrev;
   else if (names->info_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.info.s.section = sectp;
-      dwp_file->sections.info.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.info;
   else if (names->line_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.line.s.section = sectp;
-      dwp_file->sections.line.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.line;
   else if (names->loc_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.loc.s.section = sectp;
-      dwp_file->sections.loc.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.loc;
   else if (names->macinfo_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.macinfo.s.section = sectp;
-      dwp_file->sections.macinfo.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.macinfo;
   else if (names->macro_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.macro.s.section = sectp;
-      dwp_file->sections.macro.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.macro;
   else if (names->str_offsets_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.str_offsets.s.section = sectp;
-      dwp_file->sections.str_offsets.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.str_offsets;
   else if (names->types_dwo.matches (sectp->name))
+    dw_sect = &dwp_file->sections.types;
+
+  if (dw_sect != nullptr)
     {
-      dwp_file->sections.types.s.section = sectp;
-      dwp_file->sections.types.size = bfd_section_size (sectp);
+      dw_sect->s.section = sectp;
+      dw_sect->size = bfd_section_size (sectp);
+      dw_sect->read (objfile);
     }
 }
 
@@ -12326,7 +12920,8 @@ dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
    have version 1 or 2 or 5 until we parse the cu_index/tu_index sections.  */
 
 static void
-dwarf2_locate_v5_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
+dwarf2_locate_v5_dwp_sections (struct objfile *objfile, bfd *abfd,
+                              asection *sectp, void *dwp_file_ptr)
 {
   struct dwp_file *dwp_file = (struct dwp_file *) dwp_file_ptr;
   const struct dwop_section_names *names = &dwop_section_names;
@@ -12338,40 +12933,27 @@ dwarf2_locate_v5_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
   dwp_file->elf_sections[elf_section_nr] = sectp;
 
   /* Look for specific sections that we need.  */
+  struct dwarf2_section_info *dw_sect = nullptr;
   if (names->abbrev_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.abbrev.s.section = sectp;
-      dwp_file->sections.abbrev.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.abbrev;
   else if (names->info_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.info.s.section = sectp;
-      dwp_file->sections.info.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.info;
   else if (names->line_dwo.matches (sectp->name))
-   {
-     dwp_file->sections.line.s.section = sectp;
-     dwp_file->sections.line.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.line;
   else if (names->loclists_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.loclists.s.section = sectp;
-      dwp_file->sections.loclists.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.loclists;
   else if (names->macro_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.macro.s.section = sectp;
-      dwp_file->sections.macro.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.macro;
   else if (names->rnglists_dwo.matches (sectp->name))
-    {
-      dwp_file->sections.rnglists.s.section = sectp;
-      dwp_file->sections.rnglists.size = bfd_section_size (sectp);
-    }
+    dw_sect = &dwp_file->sections.rnglists;
   else if (names->str_offsets_dwo.matches (sectp->name))
+    dw_sect = &dwp_file->sections.str_offsets;
+
+  if (dw_sect != nullptr)
     {
-      dwp_file->sections.str_offsets.s.section = sectp;
-      dwp_file->sections.str_offsets.size = bfd_section_size (sectp);
+      dw_sect->s.section = sectp;
+      dw_sect->size = bfd_section_size (sectp);
+      dw_sect->read (objfile);
     }
 }
 
@@ -12431,7 +13013,7 @@ open_dwp_file (dwarf2_per_objfile *per_objfile, const char *file_name)
      [IWBN if the dwp file name was recorded in the executable, akin to
      .gnu_debuglink, but that doesn't exist yet.]
      Strip the directory from FILE_NAME and search again.  */
-  if (*debug_file_directory != '\0')
+  if (!debug_file_directory.empty ())
     {
       /* Don't implicitly search the current directory here.
         If the user wants to search "." to handle this case,
@@ -12498,7 +13080,7 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
                    dwp_file->num_sections, asection *);
 
   for (asection *sec : gdb_bfd_sections (dwp_file->dbfd))
-    dwarf2_locate_common_dwp_sections (dwp_file->dbfd.get (), sec,
+    dwarf2_locate_common_dwp_sections (objfile, dwp_file->dbfd.get (), sec,
                                       dwp_file.get ());
 
   dwp_file->cus = create_dwp_hash_table (per_objfile, dwp_file.get (), 0);
@@ -12528,10 +13110,10 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
   for (asection *sec : gdb_bfd_sections (dwp_file->dbfd))
     {
       if (dwp_file->version == 2)
-       dwarf2_locate_v2_dwp_sections (dwp_file->dbfd.get (), sec,
+       dwarf2_locate_v2_dwp_sections (objfile, dwp_file->dbfd.get (), sec,
                                       dwp_file.get ());
       else
-       dwarf2_locate_v5_dwp_sections (dwp_file->dbfd.get (), sec,
+       dwarf2_locate_v5_dwp_sections (objfile, dwp_file->dbfd.get (), sec,
                                       dwp_file.get ());
     }
 
@@ -12982,7 +13564,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   /* Ignore functions with missing or invalid low and high pc attributes.  */
-  if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
+  if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, nullptr, nullptr)
       <= PC_BOUNDS_INVALID)
     {
       attr = dwarf2_attr (die, DW_AT_external, cu);
@@ -13155,7 +13737,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
      as multiple lexical blocks?  Handling children in a sane way would
      be nasty.  Might be easier to properly extend generic blocks to
      describe ranges.  */
-  switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
+  switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, nullptr, nullptr))
     {
     case PC_BOUNDS_NOT_PRESENT:
       /* DW_TAG_lexical_block has no attributes, process its children as if
@@ -13217,6 +13799,11 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
   cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
 }
 
+static void dwarf2_ranges_read_low_addrs (unsigned offset,
+                                         struct dwarf2_cu *cu,
+                                         dwarf_tag tag,
+                                         std::vector<CORE_ADDR> &result);
+
 /* Read in DW_TAG_call_site and insert it to CU->call_site_htab.  */
 
 static void
@@ -13227,7 +13814,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR pc, baseaddr;
   struct attribute *attr;
-  struct call_site *call_site, call_site_local;
   void **slot;
   int nparams;
   struct die_info *child_die;
@@ -13250,12 +13836,14 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
   pc = attr->as_address () + baseaddr;
   pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
+  pc -= baseaddr;
 
   if (cu->call_site_htab == NULL)
-    cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq,
-                                              NULL, &objfile->objfile_obstack,
+    cu->call_site_htab = htab_create_alloc_ex (16, call_site::hash,
+                                              call_site::eq, NULL,
+                                              &objfile->objfile_obstack,
                                               hashtab_obstack_allocate, NULL);
-  call_site_local.pc = pc;
+  struct call_site call_site_local (pc, nullptr, nullptr);
   slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT);
   if (*slot != NULL)
     {
@@ -13285,14 +13873,16 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       nparams++;
     }
 
-  call_site
-    = ((struct call_site *)
-       obstack_alloc (&objfile->objfile_obstack,
-                     sizeof (*call_site)
-                     + (sizeof (*call_site->parameter) * (nparams - 1))));
+  struct call_site *call_site
+    = new (XOBNEWVAR (&objfile->objfile_obstack,
+                     struct call_site,
+                     sizeof (*call_site) + sizeof (call_site->parameter[0]) * nparams))
+    struct call_site (pc, cu->per_cu, per_objfile);
   *slot = call_site;
-  memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
-  call_site->pc = pc;
+
+  /* We never call the destructor of call_site, so we must ensure it is
+     trivially destructible.  */
+  gdb_static_assert(std::is_trivially_destructible<struct call_site>::value);
 
   if (dwarf2_flag_true_p (die, DW_AT_call_tail_call, cu)
       || dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
@@ -13353,7 +13943,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       /* This was a pre-DWARF-5 GNU extension alias for DW_AT_call_origin.  */
       attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
     }
-  SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
+
+  call_site->target.set_loc_dwarf_block (nullptr);
   if (!attr || (attr->form_is_block () && attr->as_block ()->size == 0))
     /* Keep NULL DWARF_BLOCK.  */;
   else if (attr->form_is_block ())
@@ -13367,7 +13958,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       dlbaton->per_objfile = per_objfile;
       dlbaton->per_cu = cu->per_cu;
 
-      SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
+      call_site->target.set_loc_dwarf_block (dlbaton);
     }
   else if (attr->form_is_ref ())
     {
@@ -13376,6 +13967,10 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 
       target_die = follow_die_ref (die, attr, &target_cu);
       gdb_assert (target_cu->per_objfile->objfile == objfile);
+
+      struct attribute *ranges_attr
+       = dwarf2_attr (target_die, DW_AT_ranges, target_cu);
+
       if (die_is_declaration (target_die, target_cu))
        {
          const char *target_physname;
@@ -13389,22 +13984,36 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
                         "physname, for referencing DIE %s [in module %s]"),
                       sect_offset_str (die->sect_off), objfile_name (objfile));
          else
-           SET_FIELD_PHYSNAME (call_site->target, target_physname);
+           call_site->target.set_loc_physname (target_physname);
+       }
+      else if (ranges_attr != nullptr && ranges_attr->form_is_unsigned ())
+       {
+         ULONGEST ranges_offset = (ranges_attr->as_unsigned ()
+                                   + target_cu->gnu_ranges_base);
+         std::vector<CORE_ADDR> addresses;
+         dwarf2_ranges_read_low_addrs (ranges_offset, target_cu,
+                                       target_die->tag, addresses);
+         CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
+                                       addresses.size ());
+         std::copy (addresses.begin (), addresses.end (), saved);
+         call_site->target.set_loc_array (addresses.size (), saved);
        }
       else
        {
          CORE_ADDR lowpc;
 
          /* DW_AT_entry_pc should be preferred.  */
-         if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
+         if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu,
+                                   nullptr, nullptr)
              <= PC_BOUNDS_INVALID)
            complaint (_("DW_AT_call_target target DIE has invalid "
                         "low pc, for referencing DIE %s [in module %s]"),
                       sect_offset_str (die->sect_off), objfile_name (objfile));
          else
            {
-             lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
-             SET_FIELD_PHYSADDR (call_site->target, lowpc);
+             lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr)
+                      - baseaddr);
+             call_site->target.set_loc_physaddr (lowpc);
            }
        }
     }
@@ -13413,9 +14022,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
                 "block nor reference, for DIE %s [in module %s]"),
               sect_offset_str (die->sect_off), objfile_name (objfile));
 
-  call_site->per_cu = cu->per_cu;
-  call_site->per_objfile = per_objfile;
-
   for (child_die = die->child;
        child_die && child_die->tag;
        child_die = child_die->sibling)
@@ -13619,7 +14225,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   /* Base address selection entry.  */
   gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
   bool overflow = false;
   ULONGEST addr_index;
   struct dwarf2_section_info *rnglists_section;
@@ -13636,8 +14241,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     }
   buffer = rnglists_section->buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
@@ -13779,7 +14382,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
       /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
@@ -13821,7 +14424,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
 
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, tag, callback);
@@ -13837,8 +14439,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
     }
   buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -13889,7 +14489,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
       /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_ranges entry has start address of zero"
@@ -13905,15 +14505,15 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
 /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
    Return 1 if the attributes are present and valid, otherwise, return 0.
-   If RANGES_PST is not NULL we should set up the `psymtabs_addrmap'.  */
+   TAG is passed to dwarf2_ranges_process.  If MAP is not NULL, then
+   ranges in MAP are set, using DATUM as the value.  */
 
 static int
 dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
                    CORE_ADDR *high_return, struct dwarf2_cu *cu,
-                   dwarf2_psymtab *ranges_pst, dwarf_tag tag)
+                   addrmap *map, void *datum, dwarf_tag tag)
 {
   struct objfile *objfile = cu->per_objfile->objfile;
-  dwarf2_per_bfd *per_bfd = cu->per_objfile->per_bfd;
   struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
   int low_set = 0;
@@ -13924,7 +14524,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
   retval = dwarf2_ranges_process (offset, cu, tag,
     [&] (CORE_ADDR range_beginning, CORE_ADDR range_end)
     {
-      if (ranges_pst != NULL)
+      if (map != nullptr)
        {
          CORE_ADDR lowpc;
          CORE_ADDR highpc;
@@ -13935,8 +14535,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
          highpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
                                                range_end + baseaddr)
                    - baseaddr);
-         addrmap_set_empty (per_bfd->partial_symtabs->psymtabs_addrmap,
-                            lowpc, highpc - 1, ranges_pst);
+         addrmap_set_empty (map, lowpc, highpc - 1, datum);
        }
 
       /* FIXME: This is recording everything as a low-high
@@ -13972,6 +14571,20 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
   return 1;
 }
 
+/* Process ranges and fill in a vector of the low PC values only.  */
+
+static void
+dwarf2_ranges_read_low_addrs (unsigned offset, struct dwarf2_cu *cu,
+                             dwarf_tag tag,
+                             std::vector<CORE_ADDR> &result)
+{
+  dwarf2_ranges_process (offset, cu, tag,
+                        [&] (CORE_ADDR start, CORE_ADDR end)
+    {
+      result.push_back (start);
+    });
+}
+
 /* Get low and high pc attributes from a die.  See enum pc_bounds_kind
    definition for the return value.  *LOWPC and *HIGHPC are set iff
    neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned.  */
@@ -13979,7 +14592,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 static enum pc_bounds_kind
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                      CORE_ADDR *highpc, struct dwarf2_cu *cu,
-                     dwarf2_psymtab *pst)
+                     addrmap *map, void *datum)
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct attribute *attr;
@@ -14022,8 +14635,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 
          /* Value of the DW_AT_ranges attribute is the offset in the
             .debug_ranges section.  */
-         if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst,
-                                  die->tag))
+         if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu,
+                                  map, datum, die->tag))
            return PC_BOUNDS_INVALID;
          /* Found discontinuous range of addresses.  */
          ret = PC_BOUNDS_RANGES;
@@ -14066,7 +14679,8 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
   CORE_ADDR low, high;
   struct die_info *child = die->child;
 
-  if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL) >= PC_BOUNDS_RANGES)
+  if (dwarf2_get_pc_bounds (die, &low, &high, cu, nullptr, nullptr)
+      >= PC_BOUNDS_RANGES)
     {
       *lowpc = std::min (*lowpc, low);
       *highpc = std::max (*highpc, high);
@@ -14103,7 +14717,8 @@ get_scope_pc_bounds (struct die_info *die,
   CORE_ADDR best_high = (CORE_ADDR) 0;
   CORE_ADDR current_low, current_high;
 
-  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu, NULL)
+  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu,
+                           nullptr, nullptr)
       >= PC_BOUNDS_RANGES)
     {
       best_low = current_low;
@@ -14231,6 +14846,7 @@ check_producer (struct dwarf2_cu *cu)
     {
       cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
       cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
+      cu->producer_is_gcc_11 = major == 11;
     }
   else if (producer_is_icc (cu->producer, &major, &minor))
     {
@@ -14316,14 +14932,14 @@ dwarf2_access_attribute (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Look for DW_AT_data_member_location.  Set *OFFSET to the byte
-   offset.  If the attribute was not found return 0, otherwise return
-   1.  If it was found but could not properly be handled, set *OFFSET
-   to 0.  */
+/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset.  Set
+   *OFFSET to the byte offset.  If the attribute was not found return
+   0, otherwise return 1.  If it was found but could not properly be
+   handled, set *OFFSET to 0.  */
 
 static int
-handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
-                            LONGEST *offset)
+handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                       LONGEST *offset)
 {
   struct attribute *attr;
 
@@ -14347,15 +14963,25 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
 
       return 1;
     }
+  else
+    {
+      attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
+      if (attr != nullptr)
+       {
+         *offset = attr->constant_value (0);
+         return 1;
+       }
+    }
 
   return 0;
 }
 
-/* Look for DW_AT_data_member_location and store the results in FIELD.  */
+/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset and
+   store the results in FIELD.  */
 
 static void
-handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
-                            struct field *field)
+handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                       struct field *field)
 {
   struct attribute *attr;
 
@@ -14365,7 +14991,20 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
       if (attr->form_is_constant ())
        {
          LONGEST offset = attr->constant_value (0);
-         SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+
+         /* Work around this GCC 11 bug, where it would erroneously use -1
+            data member locations, instead of 0:
+
+              Negative DW_AT_data_member_location
+              https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101378
+            */
+         if (offset == -1 && cu->producer_is_gcc_11)
+           {
+             complaint (_("DW_AT_data_member_location value of -1, assuming 0"));
+             offset = 0;
+           }
+
+         field->set_loc_bitpos (offset * bits_per_byte);
        }
       else if (attr->form_is_section_offset ())
        dwarf2_complex_location_expr_complaint ();
@@ -14374,7 +15013,7 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
          bool handled;
          CORE_ADDR offset = decode_locdesc (attr->as_block (), cu, &handled);
          if (handled)
-           SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+           field->set_loc_bitpos (offset * bits_per_byte);
          else
            {
              dwarf2_per_objfile *per_objfile = cu->per_objfile;
@@ -14391,12 +15030,18 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
              dlbaton->per_objfile = per_objfile;
              dlbaton->per_cu = cu->per_cu;
 
-             SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+             field->set_loc_dwarf_block (dlbaton);
            }
        }
       else
        dwarf2_complex_location_expr_complaint ();
     }
+  else
+    {
+      attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
+      if (attr != nullptr)
+       field->set_loc_bitpos (attr->constant_value (0));
+    }
 }
 
 /* Add an aggregate field to the field list.  */
@@ -14437,14 +15082,27 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && !die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+         /* Typically, DW_TAG_namelist_item are references to namelist items.
+            If so, follow that reference.  */
+         struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+         struct die_info *item_die = nullptr;
+         struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+           item_die = follow_die_ref (die, attr1, &item_cu);
+         if (item_die != nullptr)
+           die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
       fp->set_type (die_type (die, cu));
 
-      SET_FIELD_BITPOS (*fp, 0);
+      fp->set_loc_bitpos (0);
 
       /* Get bit size of field (zero if none).  */
       attr = dwarf2_attr (die, DW_AT_bit_size, cu);
@@ -14458,7 +15116,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      handle_data_member_location (die, cu, fp);
+      handle_member_location (die, cu, fp);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr != nullptr && attr->form_is_constant ())
        {
@@ -14469,8 +15127,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
                 anonymous object to the MSB of the field.  We don't
                 have to do anything special since we don't need to
                 know the size of the anonymous object.  */
-             SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
-                                     + attr->constant_value (0)));
+             fp->set_loc_bitpos (fp->loc_bitpos () + attr->constant_value (0));
            }
          else
            {
@@ -14499,16 +15156,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
                     bit field.  */
                  anonymous_size = TYPE_LENGTH (fp->type ());
                }
-             SET_FIELD_BITPOS (*fp,
-                               (FIELD_BITPOS (*fp)
-                                + anonymous_size * bits_per_byte
-                                - bit_offset - FIELD_BITSIZE (*fp)));
+             fp->set_loc_bitpos (fp->loc_bitpos ()
+                                 + anonymous_size * bits_per_byte
+                                 - bit_offset - FIELD_BITSIZE (*fp));
            }
        }
-      attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
-      if (attr != NULL)
-       SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
-                               + attr->constant_value (0)));
 
       /* Get name of field.  */
       fieldname = dwarf2_name (die, cu);
@@ -14517,7 +15169,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
       /* The name is already allocated along with this objfile, so we don't
         need to duplicate it for the type.  */
-      fp->name = fieldname;
+      fp->set_name (fieldname);
 
       /* Change accessibility for artificial fields (e.g. virtual table
         pointer or virtual base class pointer) to private.  */
@@ -14562,17 +15214,17 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
       /* The name is already allocated along with this objfile, so we don't
         need to duplicate it for the type.  */
-      SET_FIELD_PHYSNAME (*fp, physname ? physname : "");
+      fp->set_loc_physname (physname ? physname : "");
       fp->set_type (die_type (die, cu));
-      FIELD_NAME (*fp) = fieldname;
+      fp->set_name (fieldname);
     }
   else if (die->tag == DW_TAG_inheritance)
     {
       /* C++ base class field.  */
-      handle_data_member_location (die, cu, fp);
+      handle_member_location (die, cu, fp);
       FIELD_BITSIZE (*fp) = 0;
       fp->set_type (die_type (die, cu));
-      FIELD_NAME (*fp) = fp->type ()->name ();
+      fp->set_name (fp->type ()->name ());
     }
   else
     gdb_assert_not_reached ("missing case in dwarf2_add_field");
@@ -14815,7 +15467,7 @@ add_variant_property (struct field_info *fip, struct type *type,
     offset_map[fip->fields[i].offset] = i;
 
   struct objfile *objfile = cu->per_objfile->objfile;
-  gdb::array_view<variant_part> parts
+  gdb::array_view<const variant_part> parts
     = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
                            fip->variant_parts);
 
@@ -15207,10 +15859,10 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
     return;
 
   /* Check for __pfn and __delta members.  */
-  if (TYPE_FIELD_NAME (type, 0) == NULL
-      || strcmp (TYPE_FIELD_NAME (type, 0), "__pfn") != 0
-      || TYPE_FIELD_NAME (type, 1) == NULL
-      || strcmp (TYPE_FIELD_NAME (type, 1), "__delta") != 0)
+  if (type->field (0).name () == NULL
+      || strcmp (type->field (0).name (), "__pfn") != 0
+      || type->field (1).name () == NULL
+      || strcmp (type->field (1).name (), "__delta") != 0)
     return;
 
   /* Find the type of the method.  */
@@ -15301,10 +15953,10 @@ quirk_ada_thick_pointer_struct (struct die_info *die, struct dwarf2_cu *cu,
     return;
 
   /* Check for P_ARRAY and P_BOUNDS members.  */
-  if (TYPE_FIELD_NAME (type, 0) == NULL
-      || strcmp (TYPE_FIELD_NAME (type, 0), "P_ARRAY") != 0
-      || TYPE_FIELD_NAME (type, 1) == NULL
-      || strcmp (TYPE_FIELD_NAME (type, 1), "P_BOUNDS") != 0)
+  if (type->field (0).name () == NULL
+      || strcmp (type->field (0).name (), "P_ARRAY") != 0
+      || type->field (1).name () == NULL
+      || strcmp (type->field (1).name (), "P_BOUNDS") != 0)
     return;
 
   /* Make sure we're looking at a pointer to an array.  */
@@ -15502,6 +16154,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15704,7 +16360,8 @@ 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_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
         should be a DW_TAG_member that is a declaration, but
@@ -15747,8 +16404,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
     handle_variant (child_die, type, fi, template_args, cu);
 }
 
-/* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+/* Finish creating a structure or union type, including filling in its
+   members and creating a symbol for it. This function also handles Fortran
+   namelist variables, their items or members and creating a symbol for
+   them.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -15817,7 +16476,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                       i >= TYPE_N_BASECLASSES (t);
                       --i)
                    {
-                     const char *fieldname = TYPE_FIELD_NAME (t, i);
+                     const char *fieldname = t->field (i).name ();
 
                      if (is_vtable_name (fieldname, cu))
                        {
@@ -15850,7 +16509,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
                   i >= TYPE_N_BASECLASSES (type);
                   --i)
                {
-                 if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
+                 if (strcmp (type->field (i).name (), "__vfp") == 0)
                    {
                      set_type_vptr_fieldno (type, i);
                      set_type_vptr_basetype (type, type);
@@ -16021,8 +16680,8 @@ update_enumeration_type_from_children (struct die_info *die,
 
       fields.emplace_back ();
       struct field &field = fields.back ();
-      FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
-      SET_FIELD_ENUMVAL (field, value);
+      field.set_name (dwarf2_physname (name, child_die, cu));
+      field.set_loc_enumval (value);
     }
 
   if (!fields.empty ())
@@ -16296,7 +16955,7 @@ recognize_bound_expression (struct die_info *die, enum dwarf_attribute name,
   else
     return false;
 
-  SET_FIELD_BITPOS (*field, 8 * offset);
+  field->set_loc_bitpos (8 * offset);
   if (size != TYPE_LENGTH (field->type ()))
     FIELD_BITSIZE (*field) = 8 * size;
 
@@ -16395,9 +17054,9 @@ quirk_ada_thick_pointer (struct die_info *die, struct dwarf2_cu *cu,
 
       /* Set the name of each field in the bounds.  */
       xsnprintf (name, sizeof (name), "LB%d", i / 2);
-      FIELD_NAME (range_fields[i]) = objfile->intern (name);
+      range_fields[i].set_name (objfile->intern (name));
       xsnprintf (name, sizeof (name), "UB%d", i / 2);
-      FIELD_NAME (range_fields[i + 1]) = objfile->intern (name);
+      range_fields[i + 1].set_name (objfile->intern (name));
     }
 
   struct type *bounds = alloc_type (objfile);
@@ -16411,7 +17070,7 @@ quirk_ada_thick_pointer (struct die_info *die, struct dwarf2_cu *cu,
          bounds->num_fields () * sizeof (struct field));
 
   int last_fieldno = range_fields.size () - 1;
-  int bounds_size = (TYPE_FIELD_BITPOS (bounds, last_fieldno) / 8
+  int bounds_size = (bounds->field (last_fieldno).loc_bitpos () / 8
                     + TYPE_LENGTH (bounds->field (last_fieldno).type ()));
   TYPE_LENGTH (bounds) = align_up (bounds_size, max_align);
 
@@ -16439,12 +17098,12 @@ quirk_ada_thick_pointer (struct die_info *die, struct dwarf2_cu *cu,
   /* The names are chosen to coincide with what the compiler does with
      -fgnat-encodings=all, which the Ada code in gdb already
      understands.  */
-  TYPE_FIELD_NAME (result, 0) = "P_ARRAY";
+  result->field (0).set_name ("P_ARRAY");
   result->field (0).set_type (lookup_pointer_type (type));
 
-  TYPE_FIELD_NAME (result, 1) = "P_BOUNDS";
+  result->field (1).set_name ("P_BOUNDS");
   result->field (1).set_type (lookup_pointer_type (bounds));
-  SET_FIELD_BITPOS (result->field (1), 8 * bounds_offset);
+  result->field (1).set_loc_bitpos (8 * bounds_offset);
 
   result->set_name (type->name ());
   TYPE_LENGTH (result) = (TYPE_LENGTH (result->field (0).type ())
@@ -16518,7 +17177,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   child_die = die->child;
   while (child_die && child_die->tag)
     {
-      if (child_die->tag == DW_TAG_subrange_type)
+      if (child_die->tag == DW_TAG_subrange_type
+         || child_die->tag == DW_TAG_generic_subrange)
        {
          struct type *child_type = read_type_die (child_die, cu);
 
@@ -16752,7 +17412,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
   gdb_assert (ptr - baton->data == baton->size);
 
   SYMBOL_LOCATION_BATON (sym) = baton;
-  SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
+  sym->set_aclass_index (dwarf2_locexpr_index);
 }
 
 /* Create appropriate locally-scoped variables for all the
@@ -16851,7 +17511,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
        }
 
       sym = new_symbol (die, objfile_type (objfile)->builtin_void, cu);
-      SYMBOL_VALUE_COMMON_BLOCK (sym) = common_block;
+      sym->set_value_common_block (common_block);
     }
 }
 
@@ -17310,7 +17970,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
          /* Pass 0 as the default as we know this attribute is constant
             and the default value will not be returned.  */
          LONGEST sz = len->constant_value (0);
-         prop_type = cu->per_objfile->int_type (sz, true);
+         prop_type = objfile_int_type (objfile, sz, true);
        }
       else
        {
@@ -18137,16 +18797,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
        break;
       case DW_ATE_UTF:
        {
-         if (bits == 16)
-           type = builtin_type (arch)->builtin_char16;
-         else if (bits == 32)
-           type = builtin_type (arch)->builtin_char32;
-         else
-           {
-             complaint (_("unsupported DW_ATE_UTF bit size: '%d'"),
-                        bits);
-             type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
-           }
+         type = init_character_type (objfile, bits, 1, name);
          return set_die_type (die, type, cu);
        }
        break;
@@ -18166,7 +18817,9 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
        break;
     }
 
-  if (name && strcmp (name, "char") == 0)
+  if (type->code () == TYPE_CODE_INT
+      && name != nullptr
+      && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
   maybe_set_alignment (cu, die, type);
@@ -18242,7 +18895,22 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
       baton->locexpr.per_cu = cu->per_cu;
       baton->locexpr.per_objfile = per_objfile;
 
-      struct dwarf_block *block = attr->as_block ();
+      struct dwarf_block *block;
+      if (attr->form == DW_FORM_data16)
+       {
+         size_t data_size = 16;
+         block = XOBNEW (obstack, struct dwarf_block);
+         block->size = (data_size
+                        + 2 /* Extra bytes for DW_OP and arg.  */);
+         gdb_byte *data = XOBNEWVEC (obstack, gdb_byte, block->size);
+         data[0] = DW_OP_implicit_value;
+         data[1] = data_size;
+         memcpy (&data[2], attr->as_block ()->data, data_size);
+         block->data = data;
+       }
+      else
+       block = attr->as_block ();
+
       baton->locexpr.size = block->size;
       baton->locexpr.data = block->data;
       switch (attr->name)
@@ -18269,6 +18937,9 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
       if (target_attr == NULL)
        target_attr = dwarf2_attr (target_die, DW_AT_data_member_location,
                                   target_cu);
+      if (target_attr == nullptr)
+       target_attr = dwarf2_attr (target_die, DW_AT_data_bit_offset,
+                                  target_cu);
       if (target_attr == NULL)
        {
          const char *name = var_decl_name (target_die, target_cu);
@@ -18312,11 +18983,11 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
              }
            break;
          case DW_AT_data_member_location:
+         case DW_AT_data_bit_offset:
            {
              LONGEST offset;
 
-             if (!handle_data_member_location (target_die, target_cu,
-                                               &offset))
+             if (!handle_member_location (target_die, target_cu, &offset))
                return 0;
 
              baton = XOBNEW (obstack, struct dwarf2_property_baton);
@@ -18331,42 +19002,34 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
     }
   else if (attr->form_is_constant ())
     prop->set_const_val (attr->constant_value (0));
-  else
+  else if (attr->form_is_section_offset ())
     {
-      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
-                                            dwarf2_name (die, cu));
-      return 0;
+      switch (attr->name)
+       {
+       case DW_AT_string_length:
+         baton = XOBNEW (obstack, struct dwarf2_property_baton);
+         baton->property_type = default_type;
+         fill_in_loclist_baton (cu, &baton->loclist, attr);
+         prop->set_loclist (baton);
+         gdb_assert (prop->baton () != NULL);
+         break;
+       default:
+         goto invalid;
+       }
     }
+  else
+    goto invalid;
 
   return 1;
+
+ invalid:
+  dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
+                                        dwarf2_name (die, cu));
+  return 0;
 }
 
 /* See read.h.  */
 
-struct type *
-dwarf2_per_objfile::int_type (int size_in_bytes, bool unsigned_p) const
-{
-  struct type *int_type;
-
-  /* Helper macro to examine the various builtin types.  */
-#define TRY_TYPE(F)                                                    \
-  int_type = (unsigned_p                                               \
-             ? objfile_type (objfile)->builtin_unsigned_ ## F          \
-             : objfile_type (objfile)->builtin_ ## F);                 \
-  if (int_type != NULL && TYPE_LENGTH (int_type) == size_in_bytes)     \
-    return int_type
-
-  TRY_TYPE (char);
-  TRY_TYPE (short);
-  TRY_TYPE (int);
-  TRY_TYPE (long);
-  TRY_TYPE (long_long);
-
-#undef TRY_TYPE
-
-  gdb_assert_not_reached ("unable to find suitable integer type");
-}
-
 /* Read the DW_AT_type attribute for a sub-range.  If this attribute is not
    present (which is valid) then compute the default type based on the
    compilation units address size.  */
@@ -18688,11 +19351,11 @@ read_die_and_siblings (const struct die_reader_specs *reader,
 
   if (dwarf_die_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Read die from %s@0x%x of %s:\n",
-                         reader->die_section->get_name (),
-                         (unsigned) (info_ptr - reader->die_section->buffer),
-                         bfd_get_filename (reader->abfd));
+      gdb_printf (gdb_stdlog,
+                 "Read die from %s@0x%x of %s:\n",
+                 reader->die_section->get_name (),
+                 (unsigned) (info_ptr - reader->die_section->buffer),
+                 bfd_get_filename (reader->abfd));
       dump_die (die, dwarf_die_debug);
     }
 
@@ -18794,11 +19457,11 @@ read_full_die (const struct die_reader_specs *reader,
 
   if (dwarf_die_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Read die from %s@0x%x of %s:\n",
-                         reader->die_section->get_name (),
-                         (unsigned) (info_ptr - reader->die_section->buffer),
-                         bfd_get_filename (reader->abfd));
+      gdb_printf (gdb_stdlog,
+                 "Read die from %s@0x%x of %s:\n",
+                 reader->die_section->get_name (),
+                 (unsigned) (info_ptr - reader->die_section->buffer),
+                 bfd_get_filename (reader->abfd));
       dump_die (*diep, dwarf_die_debug);
     }
 
@@ -18806,6 +19469,841 @@ read_full_die (const struct die_reader_specs *reader,
 }
 \f
 
+void
+cooked_indexer::check_bounds (cutu_reader *reader)
+{
+  if (reader->cu->per_cu->addresses_seen)
+    return;
+
+  dwarf2_cu *cu = reader->cu;
+
+  CORE_ADDR best_lowpc = 0, best_highpc = 0;
+  /* Possibly set the default values of LOWPC and HIGHPC from
+     `DW_AT_ranges'.  */
+  dwarf2_find_base_address (reader->comp_unit_die, cu);
+  enum pc_bounds_kind cu_bounds_kind
+    = dwarf2_get_pc_bounds (reader->comp_unit_die, &best_lowpc, &best_highpc,
+                           cu, m_index_storage->get_addrmap (), cu->per_cu);
+  if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
+    {
+      struct objfile *objfile = cu->per_objfile->objfile;
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
+      struct gdbarch *gdbarch = objfile->arch ();
+      CORE_ADDR low
+       = (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr)
+          - baseaddr);
+      CORE_ADDR high
+       = (gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr)
+          - baseaddr - 1);
+      /* Store the contiguous range if it is not empty; it can be
+        empty for CUs with no code.  */
+      addrmap_set_empty (m_index_storage->get_addrmap (), low, high,
+                        cu->per_cu);
+
+      cu->per_cu->addresses_seen = true;
+    }
+}
+
+/* Helper function that returns true if TAG can have a linkage
+   name.  */
+
+static bool
+tag_can_have_linkage_name (enum dwarf_tag tag)
+{
+  switch (tag)
+    {
+      /* We include types here because an anonymous C++ type might
+        have a name for linkage purposes.  */
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_variable:
+    case DW_TAG_subprogram:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+cutu_reader *
+cooked_indexer::ensure_cu_exists (cutu_reader *reader,
+                                 dwarf2_per_objfile *per_objfile,
+                                 sect_offset sect_off, bool is_dwz,
+                                 bool for_scanning)
+{
+  /* Lookups for type unit references are always in the CU, and
+     cross-CU references will crash.  */
+  if (reader->cu->per_cu->is_dwz == is_dwz
+      && reader->cu->header.offset_in_cu_p (sect_off))
+    return reader;
+
+  dwarf2_per_cu_data *per_cu
+    = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
+                                       per_objfile->per_bfd);
+
+  /* When scanning, we only want to visit a given CU a single time.
+     Doing this check here avoids self-imports as well.  */
+  if (for_scanning)
+    {
+      bool nope = false;
+      if (!per_cu->scanned.compare_exchange_strong (nope, true))
+       return nullptr;
+    }
+  if (per_cu == m_per_cu)
+    return reader;
+
+  cutu_reader *result = m_index_storage->get_reader (per_cu);
+  if (result == nullptr)
+    {
+      cutu_reader new_reader (per_cu, per_objfile, nullptr, nullptr, false,
+                             m_index_storage->get_abbrev_cache ());
+
+      prepare_one_comp_unit (new_reader.cu, new_reader.comp_unit_die,
+                            language_minimal);
+      std::unique_ptr<cutu_reader> copy
+       (new cutu_reader (std::move (new_reader)));
+      result = m_index_storage->preserve (std::move (copy));
+    }
+
+  if (result->dummy_p || !result->comp_unit_die->has_children)
+    return nullptr;
+
+  if (for_scanning)
+    check_bounds (result);
+
+  return result;
+}
+
+const gdb_byte *
+cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
+                                cutu_reader *reader,
+                                const gdb_byte *watermark_ptr,
+                                const gdb_byte *info_ptr,
+                                const abbrev_info *abbrev,
+                                const char **name,
+                                const char **linkage_name,
+                                cooked_index_flag *flags,
+                                sect_offset *sibling_offset,
+                                const cooked_index_entry **parent_entry,
+                                CORE_ADDR *maybe_defer,
+                                bool for_specification)
+{
+  bool origin_is_dwz = false;
+  bool is_declaration = false;
+  sect_offset origin_offset {};
+
+  gdb::optional<CORE_ADDR> low_pc;
+  gdb::optional<CORE_ADDR> high_pc;
+  bool high_pc_relative = false;
+
+  for (int i = 0; i < abbrev->num_attrs; ++i)
+    {
+      attribute attr;
+      info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
+      if (attr.requires_reprocessing_p ())
+       read_attribute_reprocess (reader, &attr, abbrev->tag);
+
+      /* Store the data if it is of an attribute we want to keep in a
+        partial symbol table.  */
+      switch (attr.name)
+       {
+       case DW_AT_name:
+         switch (abbrev->tag)
+           {
+           case DW_TAG_compile_unit:
+           case DW_TAG_partial_unit:
+           case DW_TAG_type_unit:
+             /* Compilation units have a DW_AT_name that is a filename, not
+                a source language identifier.  */
+             break;
+
+           default:
+             if (*name == nullptr)
+               *name = attr.as_string ();
+             break;
+           }
+         break;
+
+       case DW_AT_linkage_name:
+       case DW_AT_MIPS_linkage_name:
+         /* 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.  */
+         if (*linkage_name == nullptr)
+           *linkage_name = attr.as_string ();
+         break;
+
+       case DW_AT_main_subprogram:
+         if (attr.as_boolean ())
+           *flags |= IS_MAIN;
+         break;
+
+       case DW_AT_declaration:
+         is_declaration = attr.as_boolean ();
+         break;
+
+       case DW_AT_sibling:
+         if (sibling_offset != nullptr)
+           *sibling_offset = attr.get_ref_die_offset ();
+         break;
+
+       case DW_AT_specification:
+       case DW_AT_abstract_origin:
+       case DW_AT_extension:
+         origin_offset = attr.get_ref_die_offset ();
+         origin_is_dwz = attr.form == DW_FORM_GNU_ref_alt;
+         break;
+
+       case DW_AT_external:
+         if (attr.as_boolean ())
+           *flags &= ~IS_STATIC;
+         break;
+
+       case DW_AT_enum_class:
+         if (attr.as_boolean ())
+           *flags |= IS_ENUM_CLASS;
+         break;
+
+       case DW_AT_low_pc:
+         low_pc = attr.as_address ();
+         break;
+
+       case DW_AT_high_pc:
+         high_pc = attr.as_address ();
+         if (reader->cu->header.version >= 4 && attr.form_is_constant ())
+           high_pc_relative = true;
+         break;
+
+       case DW_AT_location:
+         if (!scanning_per_cu->addresses_seen && attr.form_is_block ())
+           {
+             struct dwarf_block *locdesc = attr.as_block ();
+             CORE_ADDR addr = decode_locdesc (locdesc, reader->cu);
+             if (addr != 0
+                 || reader->cu->per_objfile->per_bfd->has_section_at_zero)
+               {
+                 low_pc = addr;
+                 /* For variables, we don't want to try decoding the
+                    type just to find the size -- for gdb's purposes
+                    we only need the address of a variable.  */
+                 high_pc = addr + 1;
+                 high_pc_relative = false;
+               }
+           }
+         break;
+
+       case DW_AT_ranges:
+         if (!scanning_per_cu->addresses_seen)
+           {
+             /* Offset in the .debug_ranges or .debug_rnglist section
+                (depending on DWARF version).  */
+             ULONGEST ranges_offset = attr.as_unsigned ();
+
+             /* See dwarf2_cu::gnu_ranges_base's doc for why we might
+                want to add this value.  */
+             ranges_offset += reader->cu->gnu_ranges_base;
+
+             CORE_ADDR lowpc, highpc;
+             dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, reader->cu,
+                                 m_index_storage->get_addrmap (),
+                                 scanning_per_cu, abbrev->tag);
+           }
+         break;
+       }
+    }
+
+  /* We don't want to examine declarations, but if we found a
+     declaration when handling DW_AT_specification or the like, then
+     that is ok.  Similarly, we allow an external variable without a
+     location; those are resolved via minimal symbols.  */
+  if (is_declaration && !for_specification
+      && (abbrev->tag != DW_TAG_variable
+         || (*flags & IS_STATIC) != 0))
+    {
+      *linkage_name = nullptr;
+      *name = nullptr;
+    }
+  else if ((*name == nullptr
+           || (*linkage_name == nullptr
+               && tag_can_have_linkage_name (abbrev->tag))
+           || (*parent_entry == nullptr && m_language != language_c))
+          && origin_offset != sect_offset (0))
+    {
+      cutu_reader *new_reader
+       = ensure_cu_exists (reader, reader->cu->per_objfile, origin_offset,
+                           origin_is_dwz, false);
+      if (new_reader != nullptr)
+       {
+         const gdb_byte *new_info_ptr = (new_reader->buffer
+                                         + to_underlying (origin_offset));
+
+         if (new_reader->cu == reader->cu
+             && new_info_ptr > watermark_ptr
+             && maybe_defer != nullptr
+             && *parent_entry == nullptr)
+           *maybe_defer = form_addr (origin_offset, origin_is_dwz);
+         else if (*parent_entry == nullptr)
+           {
+             CORE_ADDR lookup = form_addr (origin_offset, origin_is_dwz);
+             *parent_entry
+               = (cooked_index_entry *) addrmap_find (m_die_range_map,
+                                                      lookup);
+           }
+
+         unsigned int bytes_read;
+         const abbrev_info *new_abbrev = peek_die_abbrev (*new_reader,
+                                                          new_info_ptr,
+                                                          &bytes_read);
+         new_info_ptr += bytes_read;
+         scan_attributes (scanning_per_cu, new_reader, new_info_ptr, new_info_ptr,
+                          new_abbrev, name, linkage_name, flags, nullptr,
+                          parent_entry, maybe_defer, true);
+       }
+    }
+
+  if (!for_specification)
+    {
+      if (m_language == language_ada
+         && *linkage_name == nullptr)
+       *linkage_name = *name;
+
+      if (!scanning_per_cu->addresses_seen
+         && low_pc.has_value ()
+         && (reader->cu->per_objfile->per_bfd->has_section_at_zero
+             || *low_pc != 0)
+         && high_pc.has_value ())
+       {
+         if (high_pc_relative)
+           high_pc = *high_pc + *low_pc;
+
+         if (*high_pc > *low_pc)
+           {
+             struct objfile *objfile = reader->cu->per_objfile->objfile;
+             CORE_ADDR baseaddr = objfile->text_section_offset ();
+             struct gdbarch *gdbarch = objfile->arch ();
+             CORE_ADDR lo
+               = (gdbarch_adjust_dwarf2_addr (gdbarch, *low_pc + baseaddr)
+                  - baseaddr);
+             CORE_ADDR hi
+               = (gdbarch_adjust_dwarf2_addr (gdbarch, *high_pc + baseaddr)
+                  - baseaddr);
+             addrmap_set_empty (m_index_storage->get_addrmap (), lo, hi - 1,
+                                scanning_per_cu);
+           }
+       }
+
+      if (abbrev->tag == DW_TAG_module || abbrev->tag == DW_TAG_namespace)
+       *flags &= ~IS_STATIC;
+
+      if (abbrev->tag == DW_TAG_namespace && *name == nullptr)
+       *name = "(anonymous namespace)";
+
+      if (m_language == language_cplus
+         && (abbrev->tag == DW_TAG_class_type
+             || abbrev->tag == DW_TAG_interface_type
+             || abbrev->tag == DW_TAG_structure_type
+             || abbrev->tag == DW_TAG_union_type
+             || abbrev->tag == DW_TAG_enumeration_type
+             || abbrev->tag == DW_TAG_enumerator))
+       *flags &= ~IS_STATIC;
+    }
+
+  return info_ptr;
+}
+
+const gdb_byte *
+cooked_indexer::index_imported_unit (cutu_reader *reader,
+                                    const gdb_byte *info_ptr,
+                                    const abbrev_info *abbrev)
+{
+  sect_offset sect_off {};
+  bool is_dwz = false;
+
+  for (int i = 0; i < abbrev->num_attrs; ++i)
+    {
+      /* Note that we never need to reprocess attributes here.  */
+      attribute attr;
+      info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
+
+      if (attr.name == DW_AT_import)
+       {
+         sect_off = attr.get_ref_die_offset ();
+         is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+                   || reader->cu->per_cu->is_dwz);
+       }
+    }
+
+  /* Did not find DW_AT_import.  */
+  if (sect_off == sect_offset (0))
+    return info_ptr;
+
+  dwarf2_per_objfile *per_objfile = reader->cu->per_objfile;
+  cutu_reader *new_reader = ensure_cu_exists (reader, per_objfile, sect_off,
+                                             is_dwz, true);
+  if (new_reader != nullptr)
+    {
+      index_dies (new_reader, new_reader->info_ptr, nullptr, false);
+
+      reader->cu->add_dependence (new_reader->cu->per_cu);
+    }
+
+  return info_ptr;
+}
+
+const gdb_byte *
+cooked_indexer::recurse (cutu_reader *reader,
+                        const gdb_byte *info_ptr,
+                        const cooked_index_entry *parent_entry,
+                        bool fully)
+{
+  info_ptr = index_dies (reader, info_ptr, parent_entry, fully);
+
+  if (parent_entry != nullptr)
+    {
+      CORE_ADDR start = form_addr (parent_entry->die_offset,
+                                  reader->cu->per_cu->is_dwz);
+      CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer),
+                                reader->cu->per_cu->is_dwz);
+      addrmap_set_empty (m_die_range_map, start, end, (void *) parent_entry);
+    }
+
+  return info_ptr;
+}
+
+const gdb_byte *
+cooked_indexer::index_dies (cutu_reader *reader,
+                           const gdb_byte *info_ptr,
+                           const cooked_index_entry *parent_entry,
+                           bool fully)
+{
+  const gdb_byte *end_ptr = info_ptr + reader->cu->header.get_length ();
+
+  while (info_ptr < end_ptr)
+    {
+      sect_offset this_die = (sect_offset) (info_ptr - reader->buffer);
+      unsigned int bytes_read;
+      const abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr,
+                                                  &bytes_read);
+      info_ptr += bytes_read;
+      if (abbrev == nullptr)
+       break;
+
+      if (abbrev->tag == DW_TAG_imported_unit)
+       {
+         info_ptr = index_imported_unit (reader, info_ptr, abbrev);
+         continue;
+       }
+
+      if (!abbrev->interesting)
+       {
+         info_ptr = skip_one_die (reader, info_ptr, abbrev, !fully);
+         if (fully && abbrev->has_children)
+           info_ptr = index_dies (reader, info_ptr, parent_entry, fully);
+         continue;
+       }
+
+      const char *name = nullptr;
+      const char *linkage_name = nullptr;
+      CORE_ADDR defer = 0;
+      cooked_index_flag flags = IS_STATIC;
+      sect_offset sibling {};
+      const cooked_index_entry *this_parent_entry = parent_entry;
+      info_ptr = scan_attributes (reader->cu->per_cu, reader, info_ptr,
+                                 info_ptr, abbrev, &name, &linkage_name,
+                                 &flags, &sibling, &this_parent_entry,
+                                 &defer, false);
+
+      if (abbrev->tag == DW_TAG_namespace
+         && m_language == language_cplus
+         && strcmp (name, "::") == 0)
+       {
+         /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they
+            generated bogus DW_TAG_namespace DIEs with a name of "::"
+            for the global namespace.  Work around this problem
+            here.  */
+         name = nullptr;
+       }
+
+      const cooked_index_entry *this_entry = nullptr;
+      if (name != nullptr)
+       {
+         if (defer != 0)
+           m_deferred_entries.push_back ({
+               this_die, name, defer, abbrev->tag, flags
+             });
+         else
+           this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
+                                              name, this_parent_entry,
+                                              m_per_cu);
+       }
+
+      if (linkage_name != nullptr)
+       {
+         /* We only want this to be "main" if it has a linkage name
+            but not an ordinary name.  */
+         if (name != nullptr)
+           flags = flags & ~IS_MAIN;
+         m_index_storage->add (this_die, abbrev->tag, flags | IS_LINKAGE,
+                               linkage_name, nullptr, m_per_cu);
+       }
+
+      if (abbrev->has_children)
+       {
+         switch (abbrev->tag)
+           {
+           case DW_TAG_class_type:
+           case DW_TAG_interface_type:
+           case DW_TAG_structure_type:
+           case DW_TAG_union_type:
+             if (m_language != language_c && this_entry != nullptr)
+               {
+                 info_ptr = recurse (reader, info_ptr, this_entry, fully);
+                 continue;
+               }
+             break;
+
+           case DW_TAG_enumeration_type:
+             /* We need to recurse even for an anonymous enumeration.
+                Which scope we record as the parent scope depends on
+                whether we're reading an "enum class".  If so, we use
+                the enum itself as the parent, yielding names like
+                "enum_class::enumerator"; otherwise we inject the
+                names into our own parent scope.  */
+             info_ptr = recurse (reader, info_ptr,
+                                 ((flags & IS_ENUM_CLASS) == 0)
+                                 ? parent_entry
+                                 : this_entry,
+                                 fully);
+             continue;
+
+           case DW_TAG_module:
+             if (this_entry == nullptr)
+               break;
+             /* FALLTHROUGH */
+           case DW_TAG_namespace:
+             /* We don't check THIS_ENTRY for a namespace, to handle
+                the ancient G++ workaround pointed out above.  */
+             info_ptr = recurse (reader, info_ptr, this_entry, fully);
+             continue;
+
+           case DW_TAG_subprogram:
+             if ((m_language == language_fortran
+                  || m_language == language_ada)
+                 && this_entry != nullptr)
+               {
+                 info_ptr = recurse (reader, info_ptr, this_entry, true);
+                 continue;
+               }
+             break;
+           }
+
+         if (sibling != sect_offset (0))
+           {
+             const gdb_byte *sibling_ptr
+               = reader->buffer + to_underlying (sibling);
+
+             if (sibling_ptr < info_ptr)
+               complaint (_("DW_AT_sibling points backwards"));
+             else if (sibling_ptr > reader->buffer_end)
+               reader->die_section->overflow_complaint ();
+             else
+               info_ptr = sibling_ptr;
+           }
+         else
+           info_ptr = skip_children (reader, info_ptr);
+       }
+    }
+
+  return info_ptr;
+}
+
+void
+cooked_indexer::make_index (cutu_reader *reader)
+{
+  check_bounds (reader);
+  find_file_and_directory (reader->comp_unit_die, reader->cu);
+  if (!reader->comp_unit_die->has_children)
+    return;
+  index_dies (reader, reader->info_ptr, nullptr, false);
+
+  for (const auto &entry : m_deferred_entries)
+    {
+      CORE_ADDR key = form_addr (entry.die_offset, m_per_cu->is_dwz);
+      cooked_index_entry *parent
+       = (cooked_index_entry *) addrmap_find (m_die_range_map, key);
+      m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
+                           entry.name, parent, m_per_cu);
+    }
+}
+
+/* An implementation of quick_symbol_functions for the cooked DWARF
+   index.  */
+
+struct cooked_index_functions : public dwarf2_base_index_functions
+{
+  struct compunit_symtab *find_pc_sect_compunit_symtab
+    (struct objfile *objfile, struct bound_minimal_symbol msymbol,
+     CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override;
+
+  struct compunit_symtab *find_compunit_symtab_by_address
+    (struct objfile *objfile, CORE_ADDR address) override;
+
+  void dump (struct objfile *objfile) override
+  {
+    gdb_printf ("Cooked index in use\n");
+  }
+
+  void expand_matching_symbols
+    (struct objfile *,
+     const lookup_name_info &lookup_name,
+     domain_enum domain,
+     int global,
+     symbol_compare_ftype *ordered_compare) override;
+
+  bool expand_symtabs_matching
+    (struct objfile *objfile,
+     gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+     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,
+     block_search_flags search_flags,
+     domain_enum domain,
+     enum search_domain kind) override;
+
+  bool can_lazily_read_symbols () override
+  {
+    return true;
+  }
+
+  void read_partial_symbols (struct objfile *objfile) override
+  {
+    if (dwarf2_has_info (objfile, nullptr))
+      dwarf2_build_psymtabs (objfile);
+  }
+};
+
+struct compunit_symtab *
+cooked_index_functions::find_pc_sect_compunit_symtab
+     (struct objfile *objfile,
+      struct bound_minimal_symbol msymbol,
+      CORE_ADDR pc,
+      struct obj_section *section,
+      int warn_if_readin)
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->per_bfd->cooked_index_table == nullptr)
+    return nullptr;
+
+  CORE_ADDR baseaddr = objfile->text_section_offset ();
+  dwarf2_per_cu_data *per_cu
+    = per_objfile->per_bfd->cooked_index_table->lookup (pc - baseaddr);
+  if (per_cu == nullptr)
+    return nullptr;
+
+  if (warn_if_readin && per_objfile->symtab_set_p (per_cu))
+    warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
+            paddress (objfile->arch (), pc));
+
+  compunit_symtab *result = (recursively_find_pc_sect_compunit_symtab
+                            (dw2_instantiate_symtab (per_cu, per_objfile,
+                                                     false),
+                             pc));
+  gdb_assert (result != nullptr);
+  return result;
+}
+
+struct compunit_symtab *
+cooked_index_functions::find_compunit_symtab_by_address
+     (struct objfile *objfile, CORE_ADDR address)
+{
+  if (objfile->sect_index_data == -1)
+    return nullptr;
+
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->per_bfd->cooked_index_table == nullptr)
+    return nullptr;
+
+  CORE_ADDR baseaddr = objfile->data_section_offset ();
+  dwarf2_per_cu_data *per_cu
+    = per_objfile->per_bfd->cooked_index_table->lookup (address - baseaddr);
+  if (per_cu == nullptr)
+    return nullptr;
+
+  return dw2_instantiate_symtab (per_cu, per_objfile, false);
+}
+
+void
+cooked_index_functions::expand_matching_symbols
+     (struct objfile *objfile,
+      const lookup_name_info &lookup_name,
+      domain_enum domain,
+      int global,
+      symbol_compare_ftype *ordered_compare)
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->per_bfd->cooked_index_table == nullptr)
+    return;
+  const block_search_flags search_flags = (global
+                                          ? SEARCH_GLOBAL_BLOCK
+                                          : SEARCH_STATIC_BLOCK);
+  const language_defn *lang = language_def (language_ada);
+  symbol_name_matcher_ftype *name_match
+    = lang->get_symbol_name_matcher (lookup_name);
+
+  for (const cooked_index_entry *entry
+        : per_objfile->per_bfd->cooked_index_table->all_entries ())
+    {
+      if (entry->parent_entry != nullptr)
+       continue;
+
+      if (!entry->matches (search_flags)
+         || !entry->matches (domain))
+       continue;
+
+      if (name_match (entry->canonical, lookup_name, nullptr))
+       dw2_instantiate_symtab (entry->per_cu, per_objfile, false);
+    }
+}
+
+bool
+cooked_index_functions::expand_symtabs_matching
+     (struct objfile *objfile,
+      gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+      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,
+      block_search_flags search_flags,
+      domain_enum domain,
+      enum search_domain kind)
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->per_bfd->cooked_index_table == nullptr)
+    return true;
+
+  dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
+
+  /* This invariant is documented in quick-functions.h.  */
+  gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
+  if (lookup_name == nullptr)
+    {
+      for (dwarf2_per_cu_data *per_cu
+            : all_comp_units_range (per_objfile->per_bfd))
+       {
+         QUIT;
+
+         if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+                                               file_matcher,
+                                               expansion_notify))
+           return false;
+       }
+      return true;
+    }
+
+  lookup_name_info lookup_name_without_params
+    = lookup_name->make_ignore_params ();
+  bool completing = lookup_name->completion_mode ();
+
+  /* Unique styles of language splitting.  */
+  static const enum language unique_styles[] =
+  {
+    /* No splitting is also a style.  */
+    language_c,
+    /* This includes Rust.  */
+    language_cplus,
+    /* This includes Go.  */
+    language_d,
+    language_ada
+  };
+
+  for (enum language lang : unique_styles)
+    {
+      std::vector<gdb::string_view> name_vec
+       = lookup_name_without_params.split_name (lang);
+
+      for (const cooked_index_entry *entry
+          : per_objfile->per_bfd->cooked_index_table->find (name_vec.back (),
+                                                            completing))
+       {
+         /* No need to consider symbols from expanded CUs.  */
+         if (per_objfile->symtab_set_p (entry->per_cu))
+           continue;
+
+         /* If file-matching was done, we don't need to consider
+            symbols from unmarked CUs.  */
+         if (file_matcher != nullptr && !entry->per_cu->v.quick->mark)
+           continue;
+
+         /* See if the symbol matches the type filter.  */
+         if (!entry->matches (search_flags)
+             || !entry->matches (domain)
+             || !entry->matches (kind))
+           continue;
+
+         /* We've found the base name of the symbol; now walk its
+            parentage chain, ensuring that each component
+            matches.  */
+         bool found = true;
+
+         const cooked_index_entry *parent = entry->parent_entry;
+         for (int i = name_vec.size () - 1; i > 0; --i)
+           {
+             /* If we ran out of entries, or if this segment doesn't
+                match, this did not match.  */
+             if (parent == nullptr
+                 || strncmp (parent->name, name_vec[i - 1].data (),
+                             name_vec[i - 1].length ()) != 0)
+               {
+                 found = false;
+                 break;
+               }
+
+             parent = parent->parent_entry;
+           }
+
+         if (!found)
+           continue;
+
+         /* Might have been looking for "a::b" and found
+            "x::a::b".  */
+         if (symbol_matcher == nullptr)
+           {
+             symbol_name_match_type match_type
+               = lookup_name_without_params.match_type ();
+             if ((match_type == symbol_name_match_type::FULL
+                  || (lang != language_ada
+                      && match_type == symbol_name_match_type::EXPRESSION))
+                 && parent != nullptr)
+               continue;
+           }
+         else
+           {
+             auto_obstack temp_storage;
+             const char *full_name = entry->full_name (&temp_storage);
+             if (!symbol_matcher (full_name))
+               continue;
+           }
+
+         if (!dw2_expand_symtabs_matching_one (entry->per_cu, per_objfile,
+                                               file_matcher,
+                                               expansion_notify))
+           return false;
+       }
+    }
+
+  return true;
+}
+
+/* Return a new cooked_index_functions object.  */
+
+static quick_symbol_functions_up
+make_cooked_index_funcs ()
+{
+  return quick_symbol_functions_up (new cooked_index_functions);
+}
+
+\f
+
 /* Returns nonzero if TAG represents a type that we might generate a partial
    symbol for.  */
 
@@ -18837,6 +20335,7 @@ is_type_tag_for_partial (int tag, enum language lang)
     case DW_TAG_enumeration_type:
     case DW_TAG_structure_type:
     case DW_TAG_subrange_type:
+    case DW_TAG_generic_subrange:
     case DW_TAG_typedef:
     case DW_TAG_union_type:
       return 1;
@@ -18970,6 +20469,7 @@ load_partial_dies (const struct die_reader_specs *reader,
          && ((pdi.tag == DW_TAG_typedef && !pdi.has_children)
              || pdi.tag == DW_TAG_base_type
              || pdi.tag == DW_TAG_array_type
+             || pdi.tag == DW_TAG_generic_subrange
              || pdi.tag == DW_TAG_subrange_type))
        {
          if (building_psymtab && pdi.raw_name != NULL)
@@ -19297,16 +20797,14 @@ partial_die_info::read (const struct die_reader_specs *reader,
          {
            /* Offset in the .debug_ranges or .debug_rnglist section (depending
               on DWARF version).  */
-           ULONGEST ranges_offset = attr.as_unsigned ();
+           ranges_offset = attr.as_unsigned ();
 
            /* See dwarf2_cu::gnu_ranges_base's doc for why we might want to add
               this value.  */
            if (tag != DW_TAG_compile_unit)
              ranges_offset += cu->gnu_ranges_base;
 
-           if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
-                                   nullptr, tag))
-             has_pc_info = 1;
+           has_range_info = 1;
          }
          break;
 
@@ -19415,7 +20913,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
        }
       dwarf2_per_cu_data *per_cu
        = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-                                           per_objfile);
+                                           per_objfile->per_bfd);
 
       cu = per_objfile->get_cu (per_cu);
       if (cu == NULL || cu->partial_dies == NULL)
@@ -19850,7 +21348,7 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
          break;
        }
       default:
-       gdb_assert_not_reached (_("Unexpected DWARF form."));
+       gdb_assert_not_reached ("Unexpected DWARF form.");
     }
 }
 
@@ -20175,6 +21673,18 @@ read_indirect_string (dwarf2_per_objfile *per_objfile, bfd *abfd,
 
 /* See read.h.  */
 
+const char *
+dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
+                                     unsigned int offset_size)
+{
+  bfd *abfd = objfile->obfd;
+  ULONGEST str_offset = read_offset (abfd, buf, offset_size);
+
+  return per_bfd->line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
+}
+
+/* See read.h.  */
+
 const char *
 dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
                                      const struct comp_unit_head *cu_header,
@@ -20624,7 +22134,7 @@ compute_include_file_name (const struct line_header *lh, const file_entry &fe,
 
   gdb::unique_xmalloc_ptr<char> hold_compare;
   if (!IS_ABSOLUTE_PATH (include_name)
-      && (dir_name != NULL || cu_info.comp_dir != NULL))
+      && (dir_name != nullptr || cu_info.get_comp_dir () != nullptr))
     {
       /* Avoid creating a duplicate name for CU_INFO.
         We do this by comparing INCLUDE_NAME and CU_INFO.
@@ -20654,19 +22164,20 @@ compute_include_file_name (const struct line_header *lh, const file_entry &fe,
          include_name = name_holder->get ();
          include_name_to_compare = include_name;
        }
-      if (!IS_ABSOLUTE_PATH (include_name) && cu_info.comp_dir != nullptr)
+      if (!IS_ABSOLUTE_PATH (include_name)
+         && cu_info.get_comp_dir () != nullptr)
        {
-         hold_compare.reset (concat (cu_info.comp_dir, SLASH_STRING,
+         hold_compare.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
                                      include_name, (char *) NULL));
          include_name_to_compare = hold_compare.get ();
        }
     }
 
   gdb::unique_xmalloc_ptr<char> copied_name;
-  const char *cu_filename = cu_info.name;
-  if (!IS_ABSOLUTE_PATH (cu_filename) && cu_info.comp_dir != nullptr)
+  const char *cu_filename = cu_info.get_name ();
+  if (!IS_ABSOLUTE_PATH (cu_filename) && cu_info.get_comp_dir () != nullptr)
     {
-      copied_name.reset (concat (cu_info.comp_dir, SLASH_STRING,
+      copied_name.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
                                 cu_filename, (char *) NULL));
       cu_filename = copied_name.get ();
     }
@@ -20735,7 +22246,7 @@ public:
   /* Handle DW_LNS_negate_stmt.  */
   void handle_negate_stmt ()
   {
-    m_is_stmt = !m_is_stmt;
+    m_flags ^= LEF_IS_STMT;
   }
 
   /* Handle DW_LNS_const_add_pc.  */
@@ -20753,6 +22264,7 @@ public:
   {
     record_line (false);
     m_discriminator = 0;
+    m_flags &= ~LEF_PROLOGUE_END;
   }
 
   /* Handle DW_LNE_end_sequence.  */
@@ -20761,6 +22273,12 @@ public:
     m_currently_recording_lines = true;
   }
 
+  /* Handle DW_LNS_set_prologue_end.  */
+  void handle_set_prologue_end ()
+  {
+    m_flags |= LEF_PROLOGUE_END;
+  }
+
 private:
   /* Advance the line by LINE_DELTA.  */
   void advance_line (int line_delta)
@@ -20794,7 +22312,7 @@ private:
   /* These are initialized in the constructor.  */
 
   CORE_ADDR m_address;
-  bool m_is_stmt;
+  linetable_entry_flags m_flags;
   unsigned int m_discriminator;
 
   /* Additional bits of state we need to track.  */
@@ -20809,9 +22327,9 @@ private:
   CORE_ADDR m_last_address;
 
   /* Set to true when a previous line at the same address (using
-     m_last_address) had m_is_stmt true.  This is reset to false when a
-     line entry at a new address (m_address different to m_last_address) is
-     processed.  */
+     m_last_address) had LEF_IS_STMT set in m_flags.  This is reset to false
+     when a line entry at a new address (m_address different to
+     m_last_address) is processed.  */
   bool m_stmt_at_address = false;
 
   /* When true, record the lines we decode.  */
@@ -20852,6 +22370,7 @@ lnp_state_machine::handle_special_opcode (unsigned char op_code)
   advance_line (line_delta);
   record_line (false);
   m_discriminator = 0;
+  m_flags &= ~LEF_PROLOGUE_END;
 }
 
 void
@@ -20941,21 +22460,22 @@ dwarf_record_line_p (struct dwarf2_cu *cu,
 
 static void
 dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
-                    unsigned int line, CORE_ADDR address, bool is_stmt,
+                    unsigned int line, CORE_ADDR address,
+                    linetable_entry_flags flags,
                     struct dwarf2_cu *cu)
 {
   CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
 
   if (dwarf_line_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Recording line %u, file %s, address %s\n",
-                         line, lbasename (subfile->name),
-                         paddress (gdbarch, address));
+      gdb_printf (gdb_stdlog,
+                 "Recording line %u, file %s, address %s\n",
+                 line, lbasename (subfile->name),
+                 paddress (gdbarch, address));
     }
 
   if (cu != nullptr)
-    cu->get_builder ()->record_line (subfile, line, addr, is_stmt);
+    cu->get_builder ()->record_line (subfile, line, addr, flags);
 }
 
 /* Subroutine of dwarf_decode_lines_1 to simplify it.
@@ -20972,13 +22492,13 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
 
   if (dwarf_line_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Finishing current line, file %s, address %s\n",
-                         lbasename (subfile->name),
-                         paddress (gdbarch, address));
+      gdb_printf (gdb_stdlog,
+                 "Finishing current line, file %s, address %s\n",
+                 lbasename (subfile->name),
+                 paddress (gdbarch, address));
     }
 
-  dwarf_record_line_1 (gdbarch, subfile, 0, address, true, cu);
+  dwarf_record_line_1 (gdbarch, subfile, 0, address, LEF_IS_STMT, cu);
 }
 
 void
@@ -20986,13 +22506,15 @@ lnp_state_machine::record_line (bool end_sequence)
 {
   if (dwarf_line_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Processing actual line %u: file %u,"
-                         " address %s, is_stmt %u, discrim %u%s\n",
-                         m_line, m_file,
-                         paddress (m_gdbarch, m_address),
-                         m_is_stmt, m_discriminator,
-                         (end_sequence ? "\t(end sequence)" : ""));
+      gdb_printf (gdb_stdlog,
+                 "Processing actual line %u: file %u,"
+                 " address %s, is_stmt %u, prologue_end %u, discrim %u%s\n",
+                 m_line, m_file,
+                 paddress (m_gdbarch, m_address),
+                 (m_flags & LEF_IS_STMT) != 0,
+                 (m_flags & LEF_PROLOGUE_END) != 0,
+                 m_discriminator,
+                 (end_sequence ? "\t(end sequence)" : ""));
     }
 
   file_entry *fe = current_file ();
@@ -21026,7 +22548,8 @@ lnp_state_machine::record_line (bool end_sequence)
            = m_last_subfile != m_cu->get_builder ()->get_current_subfile ();
          bool ignore_this_line
           = ((file_changed && !end_sequence && m_last_address == m_address
-              && !m_is_stmt && m_stmt_at_address)
+              && ((m_flags & LEF_IS_STMT) == 0)
+              && m_stmt_at_address)
              || (!end_sequence && m_line == 0));
 
          if ((file_changed && !ignore_this_line) || end_sequence)
@@ -21037,7 +22560,9 @@ lnp_state_machine::record_line (bool end_sequence)
 
          if (!end_sequence && !ignore_this_line)
            {
-             bool is_stmt = producer_is_codewarrior (m_cu) || m_is_stmt;
+             linetable_entry_flags lte_flags = m_flags;
+             if (producer_is_codewarrior (m_cu))
+               lte_flags |= LEF_IS_STMT;
 
              if (dwarf_record_line_p (m_cu, m_line, m_last_line,
                                       m_line_has_non_zero_discriminator,
@@ -21046,7 +22571,7 @@ lnp_state_machine::record_line (bool end_sequence)
                  buildsym_compunit *builder = m_cu->get_builder ();
                  dwarf_record_line_1 (m_gdbarch,
                                       builder->get_current_subfile (),
-                                      m_line, m_address, is_stmt,
+                                      m_line, m_address, lte_flags,
                                       m_currently_recording_lines ? m_cu : nullptr);
                }
              m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
@@ -21055,14 +22580,14 @@ lnp_state_machine::record_line (bool end_sequence)
        }
     }
 
-  /* Track whether we have seen any m_is_stmt true at m_address in case we
+  /* Track whether we have seen any IS_STMT true at m_address in case we
      have multiple line table entries all at m_address.  */
   if (m_last_address != m_address)
     {
       m_stmt_at_address = false;
       m_last_address = m_address;
     }
-  m_stmt_at_address |= m_is_stmt;
+  m_stmt_at_address |= (m_flags & LEF_IS_STMT) != 0;
 }
 
 lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
@@ -21080,7 +22605,9 @@ lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
      and also record it in case it needs it.  This is currently used by MIPS
      code, cf. `mips_adjust_dwarf2_line'.  */
   m_address = gdbarch_adjust_dwarf2_line (arch, 0, 0);
-  m_is_stmt = lh->default_is_stmt;
+  m_flags = 0;
+  if (lh->default_is_stmt)
+    m_flags |= LEF_IS_STMT;
   m_discriminator = 0;
 
   m_last_address = m_address;
@@ -21308,6 +22835,9 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
                state_machine.handle_fixed_advance_pc (addr_adj);
              }
              break;
+           case DW_LNS_set_prologue_end:
+             state_machine.handle_set_prologue_end ();
+             break;
            default:
              {
                /* Unknown standard opcode, ignore it.  */
@@ -21474,7 +23004,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
      variable has been optimized away.  */
   if (attr->form_is_block () && attr->as_block ()->size == 0)
     {
-      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
+      sym->set_aclass_index (LOC_OPTIMIZED_OUT);
       return;
     }
 
@@ -21497,19 +23027,16 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
          unsigned int dummy;
 
          if (block->data[0] == DW_OP_addr)
-           SET_SYMBOL_VALUE_ADDRESS
-             (sym, cu->header.read_address (objfile->obfd,
-                                            block->data + 1,
-                                            &dummy));
+           sym->set_value_address
+             (cu->header.read_address (objfile->obfd, block->data + 1,
+                                       &dummy));
          else
-           SET_SYMBOL_VALUE_ADDRESS
-             (sym, read_addr_index_from_leb128 (cu, block->data + 1,
-                                                &dummy));
-         SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+           sym->set_value_address
+             (read_addr_index_from_leb128 (cu, block->data + 1, &dummy));
+         sym->set_aclass_index (LOC_STATIC);
          fixup_symbol_section (sym, objfile);
-         SET_SYMBOL_VALUE_ADDRESS
-           (sym,
-            SYMBOL_VALUE_ADDRESS (sym)
+         sym->set_value_address
+           (sym->value_address ()
             + objfile->section_offsets[sym->section_index ()]);
          return;
        }
@@ -21583,19 +23110,24 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
          sym->set_linkage_name (linkagename);
        }
 
+      /* Handle DW_AT_artificial.  */
+      attr = dwarf2_attr (die, DW_AT_artificial, cu);
+      if (attr != nullptr)
+       sym->artificial = attr->as_boolean ();
+
       /* Default assumptions.
         Use the passed type or decode it from the die.  */
-      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
+      sym->set_domain (VAR_DOMAIN);
+      sym->set_aclass_index (LOC_OPTIMIZED_OUT);
       if (type != NULL)
-       SYMBOL_TYPE (sym) = type;
+       sym->set_type (type);
       else
-       SYMBOL_TYPE (sym) = die_type (die, cu);
+       sym->set_type (die_type (die, cu));
       attr = dwarf2_attr (die,
                          inlined_func ? DW_AT_call_line : DW_AT_decl_line,
                          cu);
       if (attr != nullptr)
-       SYMBOL_LINE (sym) = attr->constant_value (0);
+       sym->set_line (attr->constant_value (0));
 
       attr = dwarf2_attr (die,
                          inlined_func ? DW_AT_call_file : DW_AT_decl_file,
@@ -21627,19 +23159,19 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
              addr = attr->as_address ();
              addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr);
-             SET_SYMBOL_VALUE_ADDRESS (sym, addr);
-             SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL;
+             sym->set_value_address (addr);
+             sym->set_aclass_index (LOC_LABEL);
            }
          else
-           SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
-         SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
-         SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
+           sym->set_aclass_index (LOC_OPTIMIZED_OUT);
+         sym->set_type (objfile_type (objfile)->builtin_core_addr);
+         sym->set_domain (LABEL_DOMAIN);
          add_symbol_to_list (sym, cu->list_in_scope);
          break;
        case DW_TAG_subprogram:
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
-         SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
+         sym->set_aclass_index (LOC_BLOCK);
          attr2 = dwarf2_attr (die, DW_AT_external, cu);
          if ((attr2 != nullptr && attr2->as_boolean ())
              || cu->per_cu->lang == language_ada
@@ -21661,8 +23193,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
        case DW_TAG_inlined_subroutine:
          /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
             finish_block.  */
-         SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
-         SYMBOL_INLINED (sym) = 1;
+         sym->set_aclass_index (LOC_BLOCK);
+         sym->set_is_inlined (1);
          list_to_add = cu->list_in_scope;
          break;
        case DW_TAG_template_value_param:
@@ -21674,8 +23206,8 @@ 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 (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
-           SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
+         if (sym->type ()->code () == TYPE_CODE_VOID)
+           sym->set_type (objfile_type (objfile)->builtin_int);
 
          attr = dwarf2_attr (die, DW_AT_const_value, cu);
          /* In the case of DW_TAG_member, we should only be called for
@@ -21712,8 +23244,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                  && die->parent->tag == DW_TAG_common_block)
                attr2 = NULL;
 
-             if (SYMBOL_CLASS (sym) == LOC_STATIC
-                 && SYMBOL_VALUE_ADDRESS (sym) == 0
+             if (sym->aclass () == LOC_STATIC
+                 && sym->value_address () == 0
                  && !per_objfile->per_bfd->has_section_at_zero)
                {
                  /* When a static variable is eliminated by the linker,
@@ -21723,7 +23255,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                }
              else if (attr2 != nullptr && attr2->as_boolean ())
                {
-                 if (SYMBOL_CLASS (sym) == LOC_STATIC
+                 if (sym->aclass () == LOC_STATIC
                      && (objfile->flags & OBJF_MAINLINE) == 0
                      && per_objfile->per_bfd->can_copy)
                    {
@@ -21781,12 +23313,12 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
                       ? cu->get_builder ()->get_global_symbols ()
                       : cu->list_in_scope);
 
-                 SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
+                 sym->set_aclass_index (LOC_UNRESOLVED);
                }
              else if (!die_is_declaration (die, cu))
                {
                  /* Use the default LOC_OPTIMIZED_OUT class.  */
-                 gdb_assert (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT);
+                 gdb_assert (sym->aclass () == LOC_OPTIMIZED_OUT);
                  if (!suppress_add)
                    list_to_add = cu->list_in_scope;
                }
@@ -21802,7 +23334,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
            struct context_stack *curr
              = cu->get_builder ()->get_current_context_stack ();
            if (curr != nullptr && curr->name != nullptr)
-             SYMBOL_IS_ARGUMENT (sym) = 1;
+             sym->set_is_argument (1);
            attr = dwarf2_attr (die, DW_AT_location, cu);
            if (attr != nullptr)
              {
@@ -21831,9 +23363,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
        case DW_TAG_union_type:
        case DW_TAG_set_type:
        case DW_TAG_enumeration_type:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-
+       case DW_TAG_namelist:
+         if (die->tag == DW_TAG_namelist)
+           {
+             sym->set_aclass_index (LOC_STATIC);
+             sym->set_domain (VAR_DOMAIN);
+           }
+         else
+           {
+             sym->set_aclass_index (LOC_TYPEDEF);
+             sym->set_domain (STRUCT_DOMAIN);
+           }
          {
            /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
               really ever be static objects: otherwise, if you try
@@ -21862,22 +23402,23 @@ 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 (SYMBOL_TYPE (sym)->name () == 0)
-                     SYMBOL_TYPE (sym)->set_name (sym->search_name ());
+                   if (sym->type ()->name () == 0)
+                     sym->type ()->set_name (sym->search_name ());
                  }
              }
          }
          break;
        case DW_TAG_typedef:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         sym->set_aclass_index (LOC_TYPEDEF);
+         sym->set_domain (VAR_DOMAIN);
          list_to_add = cu->list_in_scope;
          break;
        case DW_TAG_array_type:
        case DW_TAG_base_type:
        case DW_TAG_subrange_type:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+       case DW_TAG_generic_subrange:
+         sym->set_aclass_index (LOC_TYPEDEF);
+         sym->set_domain (VAR_DOMAIN);
          list_to_add = cu->list_in_scope;
          break;
        case DW_TAG_enumerator:
@@ -21899,17 +23440,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
          break;
        case DW_TAG_imported_declaration:
        case DW_TAG_namespace:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+         sym->set_aclass_index (LOC_TYPEDEF);
          list_to_add = cu->get_builder ()->get_global_symbols ();
          break;
        case DW_TAG_module:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-         SYMBOL_DOMAIN (sym) = MODULE_DOMAIN;
+         sym->set_aclass_index (LOC_TYPEDEF);
+         sym->set_domain (MODULE_DOMAIN);
          list_to_add = cu->get_builder ()->get_global_symbols ();
          break;
        case DW_TAG_common_block:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
-         SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
+         sym->set_aclass_index (LOC_COMMON_BLOCK);
+         sym->set_domain (COMMON_BLOCK_DOMAIN);
          add_symbol_to_list (sym, cu->list_in_scope);
          break;
        default:
@@ -22098,7 +23639,7 @@ dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
   const gdb_byte *bytes;
   struct dwarf2_locexpr_baton *baton;
 
-  dwarf2_const_value_attr (attr, SYMBOL_TYPE (sym),
+  dwarf2_const_value_attr (attr, sym->type (),
                           sym->print_name (),
                           &objfile->objfile_obstack, cu,
                           &value, &bytes, &baton);
@@ -22106,17 +23647,17 @@ dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
   if (baton != NULL)
     {
       SYMBOL_LOCATION_BATON (sym) = baton;
-      SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
+      sym->set_aclass_index (dwarf2_locexpr_index);
     }
   else if (bytes != NULL)
-     {
-      SYMBOL_VALUE_BYTES (sym) = bytes;
-      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST_BYTES;
+    {
+      sym->set_value_bytes (bytes);
+      sym->set_aclass_index (LOC_CONST_BYTES);
     }
   else
     {
-      SYMBOL_VALUE (sym) = value;
-      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
+      sym->set_value_longest (value);
+      sym->set_aclass_index (LOC_CONST);
     }
 }
 
@@ -22242,7 +23783,8 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
       struct dwarf2_per_cu_data *per_cu;
       sect_offset sect_off = attr->get_ref_die_offset ();
 
-      per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, per_objfile);
+      per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
+                                                per_objfile->per_bfd);
       this_type = get_die_type_at_offset (sect_off, per_cu, per_objfile);
     }
   else if (attr->form_is_ref ())
@@ -22368,6 +23910,7 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_typedef:
       this_type = read_typedef (die, cu);
       break;
+    case DW_TAG_generic_subrange:
     case DW_TAG_subrange_type:
       this_type = read_subrange_type (die, cu);
       break;
@@ -22769,6 +24312,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22793,6 +24337,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
         structures or unions.  These were of the form "._%d" in GCC 4.1,
         or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
@@ -22866,85 +24411,82 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 {
   unsigned int i;
 
-  print_spaces (indent, f);
-  fprintf_unfiltered (f, "Die: %s (abbrev %d, offset %s)\n",
-                     dwarf_tag_name (die->tag), die->abbrev,
-                     sect_offset_str (die->sect_off));
+  gdb_printf (f, "%*sDie: %s (abbrev %d, offset %s)\n",
+             indent, "",
+             dwarf_tag_name (die->tag), die->abbrev,
+             sect_offset_str (die->sect_off));
 
   if (die->parent != NULL)
-    {
-      print_spaces (indent, f);
-      fprintf_unfiltered (f, "  parent at offset: %s\n",
-                         sect_offset_str (die->parent->sect_off));
-    }
+    gdb_printf (f, "%*s  parent at offset: %s\n",
+               indent, "",
+               sect_offset_str (die->parent->sect_off));
 
-  print_spaces (indent, f);
-  fprintf_unfiltered (f, "  has children: %s\n",
-          dwarf_bool_name (die->child != NULL));
+  gdb_printf (f, "%*s  has children: %s\n",
+             indent, "",
+             dwarf_bool_name (die->child != NULL));
 
-  print_spaces (indent, f);
-  fprintf_unfiltered (f, "  attributes:\n");
+  gdb_printf (f, "%*s  attributes:\n", indent, "");
 
   for (i = 0; i < die->num_attrs; ++i)
     {
-      print_spaces (indent, f);
-      fprintf_unfiltered (f, "    %s (%s) ",
-              dwarf_attr_name (die->attrs[i].name),
-              dwarf_form_name (die->attrs[i].form));
+      gdb_printf (f, "%*s    %s (%s) ",
+                 indent, "",
+                 dwarf_attr_name (die->attrs[i].name),
+                 dwarf_form_name (die->attrs[i].form));
 
       switch (die->attrs[i].form)
        {
        case DW_FORM_addr:
        case DW_FORM_addrx:
        case DW_FORM_GNU_addr_index:
-         fprintf_unfiltered (f, "address: ");
-         fputs_filtered (hex_string (die->attrs[i].as_address ()), f);
+         gdb_printf (f, "address: ");
+         gdb_puts (hex_string (die->attrs[i].as_address ()), f);
          break;
        case DW_FORM_block2:
        case DW_FORM_block4:
        case DW_FORM_block:
        case DW_FORM_block1:
-         fprintf_unfiltered (f, "block: size %s",
-                             pulongest (die->attrs[i].as_block ()->size));
+         gdb_printf (f, "block: size %s",
+                     pulongest (die->attrs[i].as_block ()->size));
          break;
        case DW_FORM_exprloc:
-         fprintf_unfiltered (f, "expression: size %s",
-                             pulongest (die->attrs[i].as_block ()->size));
+         gdb_printf (f, "expression: size %s",
+                     pulongest (die->attrs[i].as_block ()->size));
          break;
        case DW_FORM_data16:
-         fprintf_unfiltered (f, "constant of 16 bytes");
+         gdb_printf (f, "constant of 16 bytes");
          break;
        case DW_FORM_ref_addr:
-         fprintf_unfiltered (f, "ref address: ");
-         fputs_filtered (hex_string (die->attrs[i].as_unsigned ()), f);
+         gdb_printf (f, "ref address: ");
+         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
          break;
        case DW_FORM_GNU_ref_alt:
-         fprintf_unfiltered (f, "alt ref address: ");
-         fputs_filtered (hex_string (die->attrs[i].as_unsigned ()), f);
+         gdb_printf (f, "alt ref address: ");
+         gdb_puts (hex_string (die->attrs[i].as_unsigned ()), f);
          break;
        case DW_FORM_ref1:
        case DW_FORM_ref2:
        case DW_FORM_ref4:
        case DW_FORM_ref8:
        case DW_FORM_ref_udata:
-         fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)",
-                             (long) (die->attrs[i].as_unsigned ()));
+         gdb_printf (f, "constant ref: 0x%lx (adjusted)",
+                     (long) (die->attrs[i].as_unsigned ()));
          break;
        case DW_FORM_data1:
        case DW_FORM_data2:
        case DW_FORM_data4:
        case DW_FORM_data8:
        case DW_FORM_udata:
-         fprintf_unfiltered (f, "constant: %s",
-                             pulongest (die->attrs[i].as_unsigned ()));
+         gdb_printf (f, "constant: %s",
+                     pulongest (die->attrs[i].as_unsigned ()));
          break;
        case DW_FORM_sec_offset:
-         fprintf_unfiltered (f, "section offset: %s",
-                             pulongest (die->attrs[i].as_unsigned ()));
+         gdb_printf (f, "section offset: %s",
+                     pulongest (die->attrs[i].as_unsigned ()));
          break;
        case DW_FORM_ref_sig8:
-         fprintf_unfiltered (f, "signature: %s",
-                             hex_string (die->attrs[i].as_signature ()));
+         gdb_printf (f, "signature: %s",
+                     hex_string (die->attrs[i].as_signature ()));
          break;
        case DW_FORM_string:
        case DW_FORM_strp:
@@ -22952,37 +24494,37 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
        case DW_FORM_strx:
        case DW_FORM_GNU_str_index:
        case DW_FORM_GNU_strp_alt:
-         fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
-                             die->attrs[i].as_string ()
-                             ? die->attrs[i].as_string () : "",
-                             die->attrs[i].canonical_string_p () ? "is" : "not");
+         gdb_printf (f, "string: \"%s\" (%s canonicalized)",
+                     die->attrs[i].as_string ()
+                     ? die->attrs[i].as_string () : "",
+                     die->attrs[i].canonical_string_p () ? "is" : "not");
          break;
        case DW_FORM_flag:
          if (die->attrs[i].as_boolean ())
-           fprintf_unfiltered (f, "flag: TRUE");
+           gdb_printf (f, "flag: TRUE");
          else
-           fprintf_unfiltered (f, "flag: FALSE");
+           gdb_printf (f, "flag: FALSE");
          break;
        case DW_FORM_flag_present:
-         fprintf_unfiltered (f, "flag: TRUE");
+         gdb_printf (f, "flag: TRUE");
          break;
        case DW_FORM_indirect:
          /* The reader will have reduced the indirect form to
             the "base form" so this form should not occur.  */
-         fprintf_unfiltered (f,
-                             "unexpected attribute form: DW_FORM_indirect");
+         gdb_printf (f,
+                     "unexpected attribute form: DW_FORM_indirect");
          break;
        case DW_FORM_sdata:
        case DW_FORM_implicit_const:
-         fprintf_unfiltered (f, "constant: %s",
-                             plongest (die->attrs[i].as_signed ()));
+         gdb_printf (f, "constant: %s",
+                     plongest (die->attrs[i].as_signed ()));
          break;
        default:
-         fprintf_unfiltered (f, "unsupported attribute form: %d.",
-                  die->attrs[i].form);
+         gdb_printf (f, "unsupported attribute form: %d.",
+                     die->attrs[i].form);
          break;
        }
-      fprintf_unfiltered (f, "\n");
+      gdb_printf (f, "\n");
     }
 }
 
@@ -23006,17 +24548,16 @@ dump_die_1 (struct ui_file *f, int level, int max_level, struct die_info *die)
 
   if (die->child != NULL)
     {
-      print_spaces (indent, f);
-      fprintf_unfiltered (f, "  Children:");
+      gdb_printf (f, "%*s  Children:", indent, "");
       if (level + 1 < max_level)
        {
-         fprintf_unfiltered (f, "\n");
+         gdb_printf (f, "\n");
          dump_die_1 (f, level + 1, max_level, die->child);
        }
       else
        {
-         fprintf_unfiltered (f,
-                             " [not printed, max nesting level reached]\n");
+         gdb_printf (f,
+                     " [not printed, max nesting level reached]\n");
        }
     }
 
@@ -23108,7 +24649,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
       struct dwarf2_per_cu_data *per_cu;
 
       per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-                                                per_objfile);
+                                                per_objfile->per_bfd);
 
       dwarf_read_debug_printf_v ("target CU offset: %s, "
                                 "target CU DIEs loaded: %d",
@@ -24095,7 +25636,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 
   struct dwarf2_section_info *str_offsets_section;
   struct dwarf2_section_info *str_section;
-  ULONGEST str_offsets_base;
+  gdb::optional<ULONGEST> str_offsets_base;
 
   if (cu->dwo_unit != nullptr)
     {
@@ -24108,7 +25649,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
     {
       str_offsets_section = &per_objfile->per_bfd->str_offsets;
       str_section = &per_objfile->per_bfd->str;
-      str_offsets_base = *cu->str_offsets_base;
+      str_offsets_base = cu->str_offsets_base;
     }
 
   dwarf_decode_macros (per_objfile, builder, section, lh,
@@ -24212,9 +25753,9 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
        complaint (_("Location list used without "
                     "specifying the CU base address."));
 
-      SYMBOL_ACLASS_INDEX (sym) = (is_block
-                                  ? dwarf2_loclist_block_index
-                                  : dwarf2_loclist_index);
+      sym->set_aclass_index ((is_block
+                             ? dwarf2_loclist_block_index
+                             : dwarf2_loclist_index));
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
@@ -24244,9 +25785,9 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
          baton->size = 0;
        }
 
-      SYMBOL_ACLASS_INDEX (sym) = (is_block
-                                  ? dwarf2_locexpr_block_index
-                                  : dwarf2_locexpr_index);
+      sym->set_aclass_index ((is_block
+                             ? dwarf2_locexpr_block_index
+                             : dwarf2_locexpr_index));
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
@@ -24340,12 +25881,11 @@ dwarf2_find_containing_comp_unit
 static struct dwarf2_per_cu_data *
 dwarf2_find_containing_comp_unit (sect_offset sect_off,
                                  unsigned int offset_in_dwz,
-                                 dwarf2_per_objfile *per_objfile)
+                                 dwarf2_per_bfd *per_bfd)
 {
   int low = dwarf2_find_containing_comp_unit
-    (sect_off, offset_in_dwz, per_objfile->per_bfd->all_comp_units);
-  dwarf2_per_cu_data *this_cu
-    = per_objfile->per_bfd->all_comp_units[low].get ();
+    (sect_off, offset_in_dwz, per_bfd->all_comp_units);
+  dwarf2_per_cu_data *this_cu = per_bfd->all_comp_units[low].get ();
 
   if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
     {
@@ -24353,15 +25893,15 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
        error (_("Dwarf Error: could not find partial DIE containing "
               "offset %s [in module %s]"),
               sect_offset_str (sect_off),
-              bfd_get_filename (per_objfile->objfile->obfd));
+              bfd_get_filename (per_bfd->obfd));
 
-      gdb_assert (per_objfile->per_bfd->all_comp_units[low-1]->sect_off
+      gdb_assert (per_bfd->all_comp_units[low-1]->sect_off
                  <= sect_off);
-      return per_objfile->per_bfd->all_comp_units[low - 1].get ();
+      return per_bfd->all_comp_units[low - 1].get ();
     }
   else
     {
-      if (low == per_objfile->per_bfd->all_comp_units.size () - 1
+      if (low == per_bfd->all_comp_units.size () - 1
          && sect_off >= this_cu->sect_off + this_cu->length)
        error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
       gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
@@ -24654,6 +26194,15 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
        type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
     }
 
+  /* Read DW_AT_rank and set in type.  */
+  attr = dwarf2_attr (die, DW_AT_rank, cu);
+  if (attr != NULL)
+    {
+      struct type *prop_type = cu->addr_sized_int_type (false);
+      if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
+       type->add_dyn_prop (DYN_PROP_RANK, prop);
+    }
+
   /* Read DW_AT_data_location and set in type.  */
   if (!skip_data_location)
     {
@@ -24748,26 +26297,24 @@ static void
 show_check_physname (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Whether to check \"physname\" is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Whether to check \"physname\" is %s.\n"),
+             value);
 }
 
 void _initialize_dwarf2_read ();
 void
 _initialize_dwarf2_read ()
 {
-  add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
+  add_setshow_prefix_cmd ("dwarf", class_maintenance,
+                         _("\
 Set DWARF specific variables.\n\
 Configure DWARF variables such as the cache size."),
-                       &set_dwarf_cmdlist,
-                       0/*allow-unknown*/, &maintenance_set_cmdlist);
-
-  add_show_prefix_cmd ("dwarf", class_maintenance, _("\
+                         _("\
 Show DWARF specific variables.\n\
 Show DWARF variables such as the cache size."),
-                      &show_dwarf_cmdlist,
-                      0/*allow-unknown*/, &maintenance_show_cmdlist);
+                         &set_dwarf_cmdlist, &show_dwarf_cmdlist,
+                         &maintenance_set_cmdlist, &maintenance_show_cmdlist);
 
   add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
                            &dwarf_max_cache_age, _("\