gdb/mi: handle no condition argument case for -break-condition
[deliverable/binutils-gdb.git] / gdb / symtab.c
index d54ff1444317eb33be5da9d0e437e87c33b4248b..fa3f42207ecd763bcd5cefc41132c125398fe117 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table lookup for the GNU debugger, GDB.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -42,6 +42,7 @@
 #include "addrmap.h"
 #include "cli/cli-utils.h"
 #include "cli/cli-style.h"
+#include "cli/cli-cmds.h"
 #include "fnmatch.h"
 #include "hashtab.h"
 #include "typeprint.h"
@@ -554,11 +555,8 @@ iterate_over_symtabs (const char *name,
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
-      if (objfile->sf
-         && objfile->sf->qf->map_symtabs_matching_filename (objfile,
-                                                            name,
-                                                            real_path.get (),
-                                                            callback))
+      if (objfile->map_symtabs_matching_filename (name, real_path.get (),
+                                                 callback))
        return;
     }
 }
@@ -595,7 +593,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   struct fn_field *method = &f[signature_id];
   const char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
   const char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
-  const char *newname = TYPE_NAME (type);
+  const char *newname = type->name ();
 
   /* Does the form of physname indicate that it is the full mangled name
      of a constructor (not just the args)?  */
@@ -637,7 +635,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   else if (physname[0] == 't' || physname[0] == 'Q')
     {
       /* The physname for template and qualified methods already includes
-         the class name.  */
+        the class name.  */
       xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
       newname = NULL;
       len = 0;
@@ -667,44 +665,27 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   return (mangled_name);
 }
 
-/* Set the demangled name of GSYMBOL to NAME.  NAME must be already
-   correctly allocated.  */
+/* See symtab.h.  */
 
 void
-symbol_set_demangled_name (struct general_symbol_info *gsymbol,
-                           const char *name,
-                           struct obstack *obstack)
+general_symbol_info::set_demangled_name (const char *name,
+                                        struct obstack *obstack)
 {
-  if (gsymbol->language == language_ada)
+  if (language () == language_ada)
     {
       if (name == NULL)
        {
-         gsymbol->ada_mangled = 0;
-         gsymbol->language_specific.obstack = obstack;
+         ada_mangled = 0;
+         language_specific.obstack = obstack;
        }
       else
        {
-         gsymbol->ada_mangled = 1;
-         gsymbol->language_specific.demangled_name = name;
+         ada_mangled = 1;
+         language_specific.demangled_name = name;
        }
     }
   else
-    gsymbol->language_specific.demangled_name = name;
-}
-
-/* Return the demangled name of GSYMBOL.  */
-
-const char *
-symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
-{
-  if (gsymbol->language == language_ada)
-    {
-      if (!gsymbol->ada_mangled)
-       return NULL;
-      /* Fall through.  */
-    }
-
-  return gsymbol->language_specific.demangled_name;
+    language_specific.demangled_name = name;
 }
 
 \f
@@ -712,28 +693,26 @@ symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
    depending upon the language for the symbol.  */
 
 void
-symbol_set_language (struct general_symbol_info *gsymbol,
-                     enum language language,
-                    struct obstack *obstack)
+general_symbol_info::set_language (enum language language,
+                                  struct obstack *obstack)
 {
-  gsymbol->language = language;
-  if (gsymbol->language == language_cplus
-      || gsymbol->language == language_d
-      || gsymbol->language == language_go
-      || gsymbol->language == language_objc
-      || gsymbol->language == language_fortran)
+  m_language = language;
+  if (language == language_cplus
+      || language == language_d
+      || language == language_go
+      || language == language_objc
+      || language == language_fortran)
     {
-      symbol_set_demangled_name (gsymbol, NULL, obstack);
+      set_demangled_name (NULL, obstack);
     }
-  else if (gsymbol->language == language_ada)
+  else if (language == language_ada)
     {
-      gdb_assert (gsymbol->ada_mangled == 0);
-      gsymbol->language_specific.obstack = obstack;
+      gdb_assert (ada_mangled == 0);
+      language_specific.obstack = obstack;
     }
   else
     {
-      memset (&gsymbol->language_specific, 0,
-             sizeof (gsymbol->language_specific));
+      memset (&language_specific, 0, sizeof (language_specific));
     }
 }
 
@@ -819,14 +798,14 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
   char *demangled = NULL;
   int i;
 
-  if (gsymbol->language == language_unknown)
-    gsymbol->language = language_auto;
+  if (gsymbol->language () == language_unknown)
+    gsymbol->m_language = language_auto;
 
-  if (gsymbol->language != language_auto)
+  if (gsymbol->language () != language_auto)
     {
-      const struct language_defn *lang = language_def (gsymbol->language);
+      const struct language_defn *lang = language_def (gsymbol->language ());
 
-      language_sniff_from_mangled_name (lang, mangled, &demangled);
+      lang->sniff_from_mangled_name (mangled, &demangled);
       return demangled;
     }
 
@@ -835,9 +814,9 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
       enum language l = (enum language) i;
       const struct language_defn *lang = language_def (l);
 
-      if (language_sniff_from_mangled_name (lang, mangled, &demangled))
+      if (lang->sniff_from_mangled_name (mangled, &demangled))
        {
-         gsymbol->language = l;
+         gsymbol->m_language = l;
          return demangled;
        }
     }
@@ -857,29 +836,24 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
    so the pointer can be discarded after calling this function.  */
 
 void
-symbol_set_names (struct general_symbol_info *gsymbol,
-                 gdb::string_view linkage_name, bool copy_name,
-                 struct objfile_per_bfd_storage *per_bfd,
-                 gdb::optional<hashval_t> hash)
+general_symbol_info::compute_and_set_names (gdb::string_view linkage_name,
+                                           bool copy_name,
+                                           objfile_per_bfd_storage *per_bfd,
+                                           gdb::optional<hashval_t> hash)
 {
   struct demangled_name_entry **slot;
 
-  if (gsymbol->language == language_ada)
+  if (language () == language_ada)
     {
       /* In Ada, we do the symbol lookups using the mangled name, so
-         we can save some space by not storing the demangled name.  */
+        we can save some space by not storing the demangled name.  */
       if (!copy_name)
-       gsymbol->name = linkage_name.data ();
+       m_name = linkage_name.data ();
       else
-       {
-         char *name = (char *) obstack_alloc (&per_bfd->storage_obstack,
-                                              linkage_name.length () + 1);
-
-         memcpy (name, linkage_name.data (), linkage_name.length ());
-         name[linkage_name.length ()] = '\0';
-         gsymbol->name = name;
-       }
-      symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
+       m_name = obstack_strndup (&per_bfd->storage_obstack,
+                                 linkage_name.data (),
+                                 linkage_name.length ());
+      set_demangled_name (NULL, &per_bfd->storage_obstack);
 
       return;
     }
@@ -891,18 +865,28 @@ symbol_set_names (struct general_symbol_info *gsymbol,
   if (!hash.has_value ())
     hash = hash_demangled_name_entry (&entry);
   slot = ((struct demangled_name_entry **)
-          htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
+         htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
                                    &entry, *hash, INSERT));
 
+  /* The const_cast is safe because the only reason it is already
+     initialized is if we purposefully set it from a background
+     thread to avoid doing the work here.  However, it is still
+     allocated from the heap and needs to be freed by us, just
+     like if we called symbol_find_demangled_name here.  If this is
+     nullptr, we call symbol_find_demangled_name below, but we put
+     this smart pointer here to be sure that we don't leak this name.  */
+  gdb::unique_xmalloc_ptr<char> demangled_name
+    (const_cast<char *> (language_specific.demangled_name));
+
   /* If this name is not in the hash table, add it.  */
   if (*slot == NULL
       /* A C version of the symbol may have already snuck into the table.
         This happens to, e.g., main.init (__go_init_main).  Cope.  */
-      || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
+      || (language () == language_go && (*slot)->demangled == nullptr))
     {
       /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
-         to true if the string might not be nullterminated.  We have to make
-         this copy because demangling needs a nullterminated string.  */
+        to true if the string might not be nullterminated.  We have to make
+        this copy because demangling needs a nullterminated string.  */
       gdb::string_view linkage_name_copy;
       if (copy_name)
        {
@@ -916,15 +900,9 @@ symbol_set_names (struct general_symbol_info *gsymbol,
       else
        linkage_name_copy = linkage_name;
 
-      /* The const_cast is safe because the only reason it is already
-         initialized is if we purposefully set it from a background
-         thread to avoid doing the work here.  However, it is still
-         allocated from the heap and needs to be freed by us, just
-         like if we called symbol_find_demangled_name here.  */
-      gdb::unique_xmalloc_ptr<char> demangled_name
-       (gsymbol->language_specific.demangled_name
-        ? const_cast<char *> (gsymbol->language_specific.demangled_name)
-        : symbol_find_demangled_name (gsymbol, linkage_name_copy.data ()));
+      if (demangled_name.get () == nullptr)
+        demangled_name.reset
+          (symbol_find_demangled_name (this, linkage_name_copy.data ()));
 
       /* Suppose we have demangled_name==NULL, copy_name==0, and
         linkage_name_copy==linkage_name.  In this case, we already have the
@@ -959,18 +937,13 @@ symbol_set_names (struct general_symbol_info *gsymbol,
            (gdb::string_view (mangled_ptr, linkage_name.length ()));
        }
       (*slot)->demangled = std::move (demangled_name);
-      (*slot)->language = gsymbol->language;
+      (*slot)->language = language ();
     }
-  else if (gsymbol->language == language_unknown
-          || gsymbol->language == language_auto)
-    gsymbol->language = (*slot)->language;
+  else if (language () == language_unknown || language () == language_auto)
+    m_language = (*slot)->language;
 
-  gsymbol->name = (*slot)->mangled.data ();
-  if ((*slot)->demangled != nullptr)
-    symbol_set_demangled_name (gsymbol, (*slot)->demangled.get (),
-                              &per_bfd->storage_obstack);
-  else
-    symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
+  m_name = (*slot)->mangled.data ();
+  set_demangled_name ((*slot)->demangled.get (), &per_bfd->storage_obstack);
 }
 
 /* See symtab.h.  */
@@ -978,22 +951,23 @@ symbol_set_names (struct general_symbol_info *gsymbol,
 const char *
 general_symbol_info::natural_name () const
 {
-  switch (language)
+  switch (language ())
     {
     case language_cplus:
     case language_d:
     case language_go:
     case language_objc:
     case language_fortran:
-      if (symbol_get_demangled_name (this) != NULL)
-       return symbol_get_demangled_name (this);
+    case language_rust:
+      if (language_specific.demangled_name != nullptr)
+       return language_specific.demangled_name;
       break;
     case language_ada:
       return ada_decode_symbol (this);
     default:
       break;
     }
-  return name;
+  return linkage_name ();
 }
 
 /* See symtab.h.  */
@@ -1003,14 +977,15 @@ general_symbol_info::demangled_name () const
 {
   const char *dem_name = NULL;
 
-  switch (language)
+  switch (language ())
     {
     case language_cplus:
     case language_d:
     case language_go:
     case language_objc:
     case language_fortran:
-      dem_name = symbol_get_demangled_name (this);
+    case language_rust:
+      dem_name = language_specific.demangled_name;
       break;
     case language_ada:
       dem_name = ada_decode_symbol (this);
@@ -1026,20 +1001,30 @@ general_symbol_info::demangled_name () const
 const char *
 general_symbol_info::search_name () const
 {
-  if (language == language_ada)
-    return name;
+  if (language () == language_ada)
+    return linkage_name ();
   else
     return natural_name ();
 }
 
 /* See symtab.h.  */
 
+struct obj_section *
+general_symbol_info::obj_section (const struct objfile *objfile) const
+{
+  if (section_index () >= 0)
+    return &objfile->sections[section_index ()];
+  return nullptr;
+}
+
+/* See symtab.h.  */
+
 bool
 symbol_matches_search_name (const struct general_symbol_info *gsymbol,
                            const lookup_name_info &name)
 {
   symbol_name_matcher_ftype *name_match
-    = get_symbol_name_matcher (language_def (gsymbol->language), name);
+    = language_def (gsymbol->language ())->get_symbol_name_matcher (name);
   return name_match (gsymbol->search_name (), name, NULL);
 }
 
@@ -1126,11 +1111,8 @@ expand_symtab_containing_pc (CORE_ADDR pc, struct obj_section *section)
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
-      struct compunit_symtab *cust = NULL;
-
-      if (objfile->sf)
-       cust = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile, msymbol,
-                                                             pc, section, 0);
+      struct compunit_symtab *cust
+       = objfile->find_pc_sect_compunit_symtab (msymbol, pc, section, 0);
       if (cust)
        return;
     }
@@ -1219,8 +1201,7 @@ eq_symbol_entry (const struct symbol_cache_slot *slot,
          if (!SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
            return 0;
 
-         if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-                                     slot_domain, domain))
+         if (!symbol_matches_domain (sym->language (), slot_domain, domain))
            return 0;
        }
     }
@@ -1300,9 +1281,7 @@ get_symbol_cache (struct program_space *pspace)
 static void
 set_symbol_cache_size (unsigned int new_size)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache = symbol_cache_key.get (pspace);
 
@@ -1550,9 +1529,7 @@ symbol_cache_dump (const struct symbol_cache *cache)
 static void
 maintenance_print_symbol_cache (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache;
 
@@ -1576,9 +1553,7 @@ maintenance_print_symbol_cache (const char *args, int from_tty)
 static void
 maintenance_flush_symbol_cache (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       symbol_cache_flush (pspace);
     }
@@ -1621,9 +1596,7 @@ symbol_cache_stats (struct symbol_cache *cache)
 static void
 maintenance_print_symbol_cache_statistics (const char *args, int from_tty)
 {
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
+  for (struct program_space *pspace : program_spaces)
     {
       struct symbol_cache *cache;
 
@@ -1636,7 +1609,7 @@ maintenance_print_symbol_cache_statistics (const char *args, int from_tty)
       /* If the cache hasn't been created yet, avoid creating one.  */
       cache = symbol_cache_key.get (pspace);
       if (cache == NULL)
-       printf_filtered ("  empty, no stats available\n");
+       printf_filtered ("  empty, no stats available\n");
       else
        symbol_cache_stats (cache);
     }
@@ -1673,9 +1646,10 @@ fixup_section (struct general_symbol_info *ginfo,
      e.g. on PowerPC64, where the minimal symbol for a function will
      point to the function descriptor, while the debug symbol will
      point to the actual function code.  */
-  msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
+  msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->linkage_name (),
+                                          objfile);
   if (msym)
-    ginfo->section = MSYMBOL_SECTION (msym);
+    ginfo->set_section_index (msym->section_index ());
   else
     {
       /* Static, function-local variables do appear in the linker
@@ -1690,11 +1664,10 @@ fixup_section (struct general_symbol_info *ginfo,
 
         So, instead, search the section table when lookup by name has
         failed.  The ``addr'' and ``endaddr'' fields may have already
-        been relocated.  If so, the relocation offset (i.e. the
-        ANOFFSET value) needs to be subtracted from these values when
-        performing the comparison.  We unconditionally subtract it,
-        because, when no relocation has been performed, the ANOFFSET
-        value will simply be zero.
+        been relocated.  If so, the relocation offset needs to be
+        subtracted from these values when performing the comparison.
+        We unconditionally subtract it, because, when no relocation
+        has been performed, the value will simply be zero.
 
         The address of the symbol whose section we're fixing up HAS
         NOT BEEN adjusted (relocated) yet.  It can't have been since
@@ -1720,15 +1693,14 @@ fixup_section (struct general_symbol_info *ginfo,
       ALL_OBJFILE_OSECTIONS (objfile, s)
        {
          int idx = s - objfile->sections;
-         CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+         CORE_ADDR offset = objfile->section_offsets[idx];
 
          if (fallback == -1)
            fallback = idx;
 
-         if (obj_section_addr (s) - offset <= addr
-             && addr < obj_section_endaddr (s) - offset)
+         if (s->addr () - offset <= addr && addr < s->endaddr () - offset)
            {
-             ginfo->section = idx;
+             ginfo->set_section_index (idx);
              return;
            }
        }
@@ -1737,9 +1709,9 @@ fixup_section (struct general_symbol_info *ginfo,
         section.  If there is no allocated section, then it hardly
         matters what we pick, so just pick zero.  */
       if (fallback == -1)
-       ginfo->section = 0;
+       ginfo->set_section_index (0);
       else
-       ginfo->section = fallback;
+       ginfo->set_section_index (fallback);
     }
 }
 
@@ -1761,7 +1733,7 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
   if (objfile == NULL)
     objfile = symbol_objfile (sym);
 
-  if (SYMBOL_OBJ_SECTION (objfile, sym))
+  if (sym->obj_section (objfile) != nullptr)
     return sym;
 
   /* We should have an objfile by now.  */
@@ -1798,7 +1770,7 @@ demangle_for_lookup_info::demangle_for_lookup_info
   if (lookup_name.ignore_parameters () && lang == language_cplus)
     {
       gdb::unique_xmalloc_ptr<char> without_params
-       = cp_remove_params_if_any (lookup_name.name ().c_str (),
+       = cp_remove_params_if_any (lookup_name.c_str (),
                                   lookup_name.completion_mode ());
 
       if (without_params != NULL)
@@ -1811,9 +1783,9 @@ demangle_for_lookup_info::demangle_for_lookup_info
     }
 
   if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
-    m_demangled_name = lookup_name.name ();
+    m_demangled_name = lookup_name.c_str ();
   else
-    m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
+    m_demangled_name = demangle_for_lookup (lookup_name.c_str (),
                                            lang, storage);
 }
 
@@ -1824,7 +1796,7 @@ lookup_name_info::match_any ()
 {
   /* Lookup any symbol that "" would complete.  I.e., this matches all
      symbol names.  */
-  static const lookup_name_info lookup_name ({}, symbol_name_match_type::FULL,
+  static const lookup_name_info lookup_name ("", symbol_name_match_type::FULL,
                                             true);
 
   return lookup_name;
@@ -1862,9 +1834,9 @@ demangle_for_lookup (const char *name, enum language lang,
 
       /* If we were given a non-mangled name, canonicalize it
         according to the language (so far only for C++).  */
-      std::string canon = cp_canonicalize_string (name);
-      if (!canon.empty ())
-       return storage.swap_string (canon);
+      gdb::unique_xmalloc_ptr<char> canon = cp_canonicalize_string (name);
+      if (canon != nullptr)
+       return storage.set_malloc_ptr (std::move (canon));
     }
   else if (lang == language_d)
     {
@@ -1874,7 +1846,8 @@ demangle_for_lookup (const char *name, enum language lang,
     }
   else if (lang == language_go)
     {
-      char *demangled_name = go_demangle (name, 0);
+      char *demangled_name
+       = language_def (language_go)->demangle_symbol (name, 0);
       if (demangled_name != NULL)
        return storage.set_malloc_ptr (demangled_name);
     }
@@ -1887,7 +1860,7 @@ demangle_for_lookup (const char *name, enum language lang,
 unsigned int
 search_name_hash (enum language language, const char *search_name)
 {
-  return language_def (language)->la_search_name_hash (search_name);
+  return language_def (language)->search_name_hash (search_name);
 }
 
 /* See symtab.h.
@@ -1944,16 +1917,16 @@ struct block_symbol
 lookup_language_this (const struct language_defn *lang,
                      const struct block *block)
 {
-  if (lang->la_name_of_this == NULL || block == NULL)
+  if (lang->name_of_this () == NULL || block == NULL)
     return {};
 
   if (symbol_lookup_debug > 1)
     {
-      struct objfile *objfile = lookup_objfile_from_block (block);
+      struct objfile *objfile = block_objfile (block);
 
       fprintf_unfiltered (gdb_stdlog,
                          "lookup_language_this (%s, %s (objfile %s))",
-                         lang->la_name, host_address_to_string (block),
+                         lang->name (), host_address_to_string (block),
                          objfile_debug_name (objfile));
     }
 
@@ -1961,7 +1934,7 @@ lookup_language_this (const struct language_defn *lang,
     {
       struct symbol *sym;
 
-      sym = block_lookup_symbol (block, lang->la_name_of_this,
+      sym = block_lookup_symbol (block, lang->name_of_this (),
                                 symbol_name_match_type::SEARCH_NAME,
                                 VAR_DOMAIN);
       if (sym != NULL)
@@ -1998,14 +1971,14 @@ check_field (struct type *type, const char *name,
   /* The type may be a stub.  */
   type = check_typedef (type);
 
-  for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+  for (i = type->num_fields () - 1; i >= TYPE_N_BASECLASSES (type); i--)
     {
       const char *t_field_name = TYPE_FIELD_NAME (type, i);
 
       if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
        {
          is_a_field_of_this->type = type;
-         is_a_field_of_this->field = &TYPE_FIELD (type, i);
+         is_a_field_of_this->field = &type->field (i);
          return 1;
        }
     }
@@ -2044,7 +2017,8 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
 
   if (symbol_lookup_debug)
     {
-      struct objfile *objfile = lookup_objfile_from_block (block);
+      struct objfile *objfile = (block == nullptr
+                                ? nullptr : block_objfile (block));
 
       fprintf_unfiltered (gdb_stdlog,
                          "lookup_symbol_aux (%s, %s (objfile %s), %s, %s)\n",
@@ -2094,13 +2068,13 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
          /* I'm not really sure that type of this can ever
             be typedefed; just be safe.  */
          t = check_typedef (t);
-         if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
+         if (t->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
            t = TYPE_TARGET_TYPE (t);
 
-         if (TYPE_CODE (t) != TYPE_CODE_STRUCT
-             && TYPE_CODE (t) != TYPE_CODE_UNION)
+         if (t->code () != TYPE_CODE_STRUCT
+             && t->code () != TYPE_CODE_UNION)
            error (_("Internal error: `%s' is not an aggregate"),
-                  langdef->la_name_of_this);
+                  langdef->name_of_this ());
 
          if (check_field (t, name, is_a_field_of_this))
            {
@@ -2117,7 +2091,7 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
   /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
 
-  result = langdef->la_lookup_symbol_nonlocal (langdef, name, block, domain);
+  result = langdef->lookup_symbol_nonlocal (name, block, domain);
   if (result.symbol != NULL)
     {
       if (symbol_lookup_debug)
@@ -2168,14 +2142,14 @@ lookup_local_symbol (const char *name,
        return (struct block_symbol) {sym, block};
 
       if (language == language_cplus || language == language_fortran)
-        {
-          struct block_symbol blocksym
+       {
+         struct block_symbol blocksym
            = cp_lookup_symbol_imports_or_template (scope, name, block,
                                                    domain);
 
-          if (blocksym.symbol != NULL)
-            return blocksym;
-        }
+         if (blocksym.symbol != NULL)
+           return blocksym;
+       }
 
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
        break;
@@ -2189,32 +2163,6 @@ lookup_local_symbol (const char *name,
 
 /* See symtab.h.  */
 
-struct objfile *
-lookup_objfile_from_block (const struct block *block)
-{
-  if (block == NULL)
-    return NULL;
-
-  block = block_global_block (block);
-  /* Look through all blockvectors.  */
-  for (objfile *obj : current_program_space->objfiles ())
-    {
-      for (compunit_symtab *cust : obj->compunits ())
-       if (block == BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
-                                       GLOBAL_BLOCK))
-         {
-           if (obj->separate_debug_objfile_backlink)
-             obj = obj->separate_debug_objfile_backlink;
-
-           return obj;
-         }
-    }
-
-  return NULL;
-}
-
-/* See symtab.h.  */
-
 struct symbol *
 lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
                        const struct block *block,
@@ -2224,7 +2172,8 @@ lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
 
   if (symbol_lookup_debug > 1)
     {
-      struct objfile *objfile = lookup_objfile_from_block (block);
+      struct objfile *objfile = (block == nullptr
+                                ? nullptr : block_objfile (block));
 
       fprintf_unfiltered (gdb_stdlog,
                          "lookup_symbol_in_block (%s, %s (objfile %s), %s)",
@@ -2262,7 +2211,7 @@ lookup_global_symbol_from_objfile (struct objfile *main_objfile,
   for (objfile *objfile : main_objfile->separate_debug_objfiles ())
     {
       struct block_symbol result
-        = lookup_symbol_in_objfile (objfile, block_index, name, domain);
+       = lookup_symbol_in_objfile (objfile, block_index, name, domain);
 
       if (result.symbol != nullptr)
        return result;
@@ -2293,6 +2242,8 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
                          name, domain_name (domain));
     }
 
+  struct block_symbol other;
+  other.symbol = NULL;
   for (compunit_symtab *cust : objfile->compunits ())
     {
       const struct blockvector *bv;
@@ -2303,18 +2254,36 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
       block = BLOCKVECTOR_BLOCK (bv, block_index);
       result.symbol = block_lookup_symbol_primary (block, name, domain);
       result.block = block;
-      if (result.symbol != NULL)
+      if (result.symbol == NULL)
+       continue;
+      if (best_symbol (result.symbol, domain))
        {
-         if (symbol_lookup_debug > 1)
+         other = result;
+         break;
+       }
+      if (symbol_matches_domain (result.symbol->language (),
+                                SYMBOL_DOMAIN (result.symbol), domain))
+       {
+         struct symbol *better
+           = better_symbol (other.symbol, result.symbol, domain);
+         if (better != other.symbol)
            {
-             fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n",
-                                 host_address_to_string (result.symbol),
-                                 host_address_to_string (block));
+             other.symbol = better;
+             other.block = block;
            }
-         result.symbol = fixup_symbol_section (result.symbol, objfile);
-         return result;
+       }
+    }
 
+  if (other.symbol != NULL)
+    {
+      if (symbol_lookup_debug > 1)
+       {
+         fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n",
+                             host_address_to_string (other.symbol),
+                             host_address_to_string (other.block));
        }
+      other.symbol = fixup_symbol_section (other.symbol, objfile);
+      return other;
     }
 
   if (symbol_lookup_debug > 1)
@@ -2393,9 +2362,6 @@ lookup_symbol_via_quick_fns (struct objfile *objfile,
   const struct block *block;
   struct block_symbol result;
 
-  if (!objfile->sf)
-    return {};
-
   if (symbol_lookup_debug > 1)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -2406,7 +2372,7 @@ lookup_symbol_via_quick_fns (struct objfile *objfile,
                          name, domain_name (domain));
     }
 
-  cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
+  cust = objfile->lookup_symbol (block_index, name, domain);
   if (cust == NULL)
     {
       if (symbol_lookup_debug > 1)
@@ -2437,13 +2403,12 @@ lookup_symbol_via_quick_fns (struct objfile *objfile,
   return result;
 }
 
-/* See symtab.h.  */
+/* See language.h.  */
 
 struct block_symbol
-basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
-                             const char *name,
-                             const struct block *block,
-                             const domain_enum domain)
+language_defn::lookup_symbol_nonlocal (const char *name,
+                                      const struct block *block,
+                                      const domain_enum domain) const
 {
   struct block_symbol result;
 
@@ -2469,7 +2434,7 @@ basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
        gdbarch = target_gdbarch ();
       else
        gdbarch = block_gdbarch (block);
-      result.symbol = language_lookup_primitive_type_as_symbol (langdef,
+      result.symbol = language_lookup_primitive_type_as_symbol (this,
                                                                gdbarch, name);
       result.block = NULL;
       if (result.symbol != NULL)
@@ -2494,7 +2459,8 @@ lookup_symbol_in_static_block (const char *name,
 
   if (symbol_lookup_debug)
     {
-      struct objfile *objfile = lookup_objfile_from_block (static_block);
+      struct objfile *objfile = (block == nullptr
+                                ? nullptr : block_objfile (block));
 
       fprintf_unfiltered (gdb_stdlog,
                          "lookup_symbol_in_static_block (%s, %s (objfile %s),"
@@ -2568,6 +2534,23 @@ lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
   return result;
 }
 
+/* Find the language for partial symbol with NAME.  */
+
+static enum language
+find_quick_global_symbol_language (const char *name, const domain_enum domain)
+{
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      bool symbol_found_p;
+      enum language lang
+       = objfile->lookup_global_symbol_language (name, domain, &symbol_found_p);
+      if (symbol_found_p)
+       return lang;
+    }
+
+  return language_unknown;
+}
+
 /* Private data to be used with lookup_symbol_global_iterator_cb.  */
 
 struct global_or_static_sym_lookup_data
@@ -2647,7 +2630,7 @@ lookup_global_or_static_symbol (const char *name,
       lookup_data.block_index = block_index;
       lookup_data.domain = domain;
       gdbarch_iterate_over_objfiles_in_search_order
-       (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch (),
+       (objfile != NULL ? objfile->arch () : target_gdbarch (),
         lookup_symbol_global_or_static_iterator_cb, &lookup_data, objfile);
       result = lookup_data.result;
     }
@@ -2679,17 +2662,30 @@ lookup_global_symbol (const char *name,
      global block first.  This yields "more expected" behavior, and is
      needed to support 'FILENAME'::VARIABLE lookups.  */
   const struct block *global_block = block_global_block (block);
+  symbol *sym = NULL;
   if (global_block != nullptr)
     {
-      symbol *sym = lookup_symbol_in_block (name,
-                                           symbol_name_match_type::FULL,
-                                           global_block, domain);
-      if (sym != nullptr)
+      sym = lookup_symbol_in_block (name,
+                                   symbol_name_match_type::FULL,
+                                   global_block, domain);
+      if (sym != NULL && best_symbol (sym, domain))
        return { sym, global_block };
     }
 
-  struct objfile *objfile = lookup_objfile_from_block (block);
-  return lookup_global_or_static_symbol (name, GLOBAL_BLOCK, objfile, domain);
+  struct objfile *objfile = nullptr;
+  if (block != nullptr)
+    {
+      objfile = block_objfile (block);
+      if (objfile->separate_debug_objfile_backlink != nullptr)
+       objfile = objfile->separate_debug_objfile_backlink;
+    }
+
+  block_symbol bs
+    = lookup_global_or_static_symbol (name, GLOBAL_BLOCK, objfile, domain);
+  if (better_symbol (sym, bs.symbol, domain) == sym)
+    return { sym, global_block };
+  else
+    return bs;
 }
 
 bool
@@ -2717,7 +2713,7 @@ symbol_matches_domain (enum language symbol_language,
 struct type *
 lookup_transparent_type (const char *name)
 {
-  return current_language->la_lookup_transparent_type (name);
+  return current_language->lookup_transparent_type (name);
 }
 
 /* A helper for basic_lookup_transparent_type that interfaces with the
@@ -2733,10 +2729,7 @@ basic_lookup_transparent_type_quick (struct objfile *objfile,
   const struct block *block;
   struct symbol *sym;
 
-  if (!objfile->sf)
-    return NULL;
-  cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
-                                        STRUCT_DOMAIN);
+  cust = objfile->lookup_symbol (block_index, name, STRUCT_DOMAIN);
   if (cust == NULL)
     return NULL;
 
@@ -2846,8 +2839,7 @@ iterate_over_symbols (const struct block *block,
 
   ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
     {
-      if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-                                SYMBOL_DOMAIN (sym), domain))
+      if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
        {
          struct block_symbol block_sym = {sym, block};
 
@@ -2880,7 +2872,7 @@ struct compunit_symtab *
 find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
 {
   struct compunit_symtab *best_cust = NULL;
-  CORE_ADDR distance = 0;
+  CORE_ADDR best_cust_range = 0;
   struct bound_minimal_symbol msymbol;
 
   /* If we know that this is not a text address, return failure.  This is
@@ -2911,56 +2903,74 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
     {
       for (compunit_symtab *cust : obj_file->compunits ())
        {
-         const struct block *b;
-         const struct blockvector *bv;
+         const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
+         const struct block *global_block
+           = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         CORE_ADDR start = BLOCK_START (global_block);
+         CORE_ADDR end = BLOCK_END (global_block);
+         bool in_range_p = start <= pc && pc < end;
+         if (!in_range_p)
+           continue;
+
+         if (BLOCKVECTOR_MAP (bv))
+           {
+             if (addrmap_find (BLOCKVECTOR_MAP (bv), pc) == nullptr)
+               continue;
 
-         bv = COMPUNIT_BLOCKVECTOR (cust);
-         b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+             return cust;
+           }
 
-         if (BLOCK_START (b) <= pc
-             && BLOCK_END (b) > pc
-             && (distance == 0
-                 || BLOCK_END (b) - BLOCK_START (b) < distance))
+         CORE_ADDR range = end - start;
+         if (best_cust != nullptr
+             && range >= best_cust_range)
+           /* Cust doesn't have a smaller range than best_cust, skip it.  */
+           continue;
+       
+         /* For an objfile that has its functions reordered,
+            find_pc_psymtab will find the proper partial symbol table
+            and we simply return its corresponding symtab.  */
+         /* In order to better support objfiles that contain both
+            stabs and coff debugging info, we continue on if a psymtab
+            can't be found.  */
+         if ((obj_file->flags & OBJF_REORDERED) != 0)
            {
-             /* For an objfile that has its functions reordered,
-                find_pc_psymtab will find the proper partial symbol table
-                and we simply return its corresponding symtab.  */
-             /* In order to better support objfiles that contain both
-                stabs and coff debugging info, we continue on if a psymtab
-                can't be found.  */
-             if ((obj_file->flags & OBJF_REORDERED) && obj_file->sf)
-               {
-                 struct compunit_symtab *result;
-
-                 result
-                   = obj_file->sf->qf->find_pc_sect_compunit_symtab (obj_file,
-                                                                     msymbol,
-                                                                     pc,
-                                                                     section,
-                                                                     0);
-                 if (result != NULL)
-                   return result;
-               }
-             if (section != 0)
-               {
-                 struct block_iterator iter;
-                 struct symbol *sym = NULL;
+             struct compunit_symtab *result;
+
+             result
+               = obj_file->find_pc_sect_compunit_symtab (msymbol,
+                                                         pc,
+                                                         section,
+                                                         0);
+             if (result != NULL)
+               return result;
+           }
+
+         if (section != 0)
+           {
+             struct symbol *sym = NULL;
+             struct block_iterator iter;
 
+             for (int b_index = GLOBAL_BLOCK;
+                  b_index <= STATIC_BLOCK && sym == NULL;
+                  ++b_index)
+               {
+                 const struct block *b = BLOCKVECTOR_BLOCK (bv, b_index);
                  ALL_BLOCK_SYMBOLS (b, iter, sym)
                    {
                      fixup_symbol_section (sym, obj_file);
-                     if (matching_obj_sections (SYMBOL_OBJ_SECTION (obj_file,
-                                                                    sym),
+                     if (matching_obj_sections (sym->obj_section (obj_file),
                                                 section))
                        break;
                    }
-                 if (sym == NULL)
-                   continue;           /* No symbol in this symtab matches
-                                          section.  */
                }
-             distance = BLOCK_END (b) - BLOCK_START (b);
-             best_cust = cust;
+             if (sym == NULL)
+               continue;               /* No symbol in this symtab matches
+                                          section.  */
            }
+
+         /* Cust is best found sofar, save it.  */
+         best_cust = cust;
+         best_cust_range = range;
        }
     }
 
@@ -2971,14 +2981,8 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
 
   for (objfile *objf : current_program_space->objfiles ())
     {
-      struct compunit_symtab *result;
-
-      if (!objf->sf)
-       continue;
-      result = objf->sf->qf->find_pc_sect_compunit_symtab (objf,
-                                                          msymbol,
-                                                          pc, section,
-                                                          1);
+      struct compunit_symtab *result
+       = objf->find_pc_sect_compunit_symtab (msymbol, pc, section, 1);
       if (result != NULL)
        return result;
     }
@@ -3001,30 +3005,50 @@ find_pc_compunit_symtab (CORE_ADDR pc)
 struct symbol *
 find_symbol_at_address (CORE_ADDR address)
 {
-  for (objfile *objfile : current_program_space->objfiles ())
+  /* A helper function to search a given symtab for a symbol matching
+     ADDR.  */
+  auto search_symtab = [] (compunit_symtab *symtab, CORE_ADDR addr) -> symbol *
     {
-      if (objfile->sf == NULL
-         || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
-       continue;
+      const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
 
-      struct compunit_symtab *symtab
-       = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address);
-      if (symtab != NULL)
+      for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
        {
-         const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
+         const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+         struct block_iterator iter;
+         struct symbol *sym;
 
-         for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
+         ALL_BLOCK_SYMBOLS (b, iter, sym)
            {
-             const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
-             struct block_iterator iter;
-             struct symbol *sym;
+             if (SYMBOL_CLASS (sym) == LOC_STATIC
+                 && SYMBOL_VALUE_ADDRESS (sym) == addr)
+               return sym;
+           }
+       }
+      return nullptr;
+    };
 
-             ALL_BLOCK_SYMBOLS (b, iter, sym)
-               {
-                 if (SYMBOL_CLASS (sym) == LOC_STATIC
-                     && SYMBOL_VALUE_ADDRESS (sym) == address)
-                   return sym;
-               }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      /* If this objfile was read with -readnow, then we need to
+        search the symtabs directly.  */
+      if ((objfile->flags & OBJF_READNOW) != 0)
+       {
+         for (compunit_symtab *symtab : objfile->compunits ())
+           {
+             struct symbol *sym = search_symtab (symtab, address);
+             if (sym != nullptr)
+               return sym;
+           }
+       }
+      else
+       {
+         struct compunit_symtab *symtab
+           = objfile->find_compunit_symtab_by_address (address);
+         if (symtab != NULL)
+           {
+             struct symbol *sym = search_symtab (symtab, address);
+             if (sym != nullptr)
+               return sym;
            }
        }
     }
@@ -3167,7 +3191,17 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
          ;
        /* fall through */
        else
-         return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
+         {
+           /* Detect an obvious case of infinite recursion.  If this
+              should occur, we'd like to know about it, so error out,
+              fatally.  */
+           if (BMSYMBOL_VALUE_ADDRESS (mfunsym) == pc)
+             internal_error (__FILE__, __LINE__,
+               _("Infinite recursion detected in find_pc_sect_line;"
+                 "please file a bug report"));
+
+           return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
+         }
       }
 
   symtab_and_line val;
@@ -3209,7 +3243,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       item = l->item;          /* Get first line info.  */
 
       /* Is this file's first line closer than the first lines of other files?
-         If so, record this file, and its first line, as best alternate.  */
+        If so, record this file, and its first line, as best alternate.  */
       if (item->pc > pc && (!alt || item->pc < alt->pc))
        alt = item;
 
@@ -3226,20 +3260,37 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
        prev = item - 1;                /* Found a matching item.  */
 
       /* At this point, prev points at the line whose start addr is <= pc, and
-         item points at the next line.  If we ran off the end of the linetable
-         (pc >= start of the last line), then prev == item.  If pc < start of
-         the first line, prev will not be set.  */
+        item points at the next line.  If we ran off the end of the linetable
+        (pc >= start of the last line), then prev == item.  If pc < start of
+        the first line, prev will not be set.  */
 
       /* Is this file's best line closer than the best in the other files?
-         If so, record this file, and its best line, as best so far.  Don't
-         save prev if it represents the end of a function (i.e. line number
-         0) instead of a real line.  */
+        If so, record this file, and its best line, as best so far.  Don't
+        save prev if it represents the end of a function (i.e. line number
+        0) instead of a real line.  */
 
       if (prev && prev->line && (!best || prev->pc > best->pc))
        {
          best = prev;
          best_symtab = iter_s;
 
+         /* If during the binary search we land on a non-statement entry,
+            scan backward through entries at the same address to see if
+            there is an entry marked as is-statement.  In theory this
+            duplication should have been removed from the line table
+            during construction, this is just a double check.  If the line
+            table has had the duplication removed then this should be
+            pretty cheap.  */
+         if (!best->is_stmt)
+           {
+             struct linetable_entry *tmp = best;
+             while (tmp > first && (tmp - 1)->pc == tmp->pc
+                    && (tmp - 1)->line != 0 && !tmp->is_stmt)
+               --tmp;
+             if (tmp->is_stmt)
+               best = tmp;
+           }
+
          /* Discard BEST_END if it's before the PC of the current BEST.  */
          if (best_end <= best->pc)
            best_end = 0;
@@ -3270,6 +3321,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
     }
   else
     {
+      val.is_stmt = best->is_stmt;
       val.symtab = best_symtab;
       val.line = best->line;
       val.pc = best->pc;
@@ -3292,9 +3344,18 @@ find_pc_line (CORE_ADDR pc, int notcurrent)
   struct obj_section *section;
 
   section = find_pc_overlay (pc);
-  if (pc_in_unmapped_range (pc, section))
-    pc = overlay_mapped_address (pc, section);
-  return find_pc_sect_line (pc, section, notcurrent);
+  if (!pc_in_unmapped_range (pc, section))
+    return find_pc_sect_line (pc, section, notcurrent);
+
+  /* If the original PC was an unmapped address then we translate this to a
+     mapped address in order to lookup the sal.  However, as the user
+     passed us an unmapped address it makes more sense to return a result
+     that has the pc and end fields translated to unmapped addresses.  */
+  pc = overlay_mapped_address (pc, section);
+  symtab_and_line sal = find_pc_sect_line (pc, section, notcurrent);
+  sal.pc = overlay_unmapped_address (sal.pc, section);
+  sal.end = overlay_unmapped_address (sal.end, section);
+  return sal;
 }
 
 /* See symtab.h.  */
@@ -3340,15 +3401,15 @@ find_line_symtab (struct symtab *sym_tab, int line,
   if (best_index < 0 || !exact)
     {
       /* Didn't find an exact match.  So we better keep looking for
-         another symtab with the same name.  In the case of xcoff,
-         multiple csects for one source file (produced by IBM's FORTRAN
-         compiler) produce multiple symtabs (this is unavoidable
-         assuming csects can be at arbitrary places in memory and that
-         the GLOBAL_BLOCK of a symtab has a begin and end address).  */
+        another symtab with the same name.  In the case of xcoff,
+        multiple csects for one source file (produced by IBM's FORTRAN
+        compiler) produce multiple symtabs (this is unavoidable
+        assuming csects can be at arbitrary places in memory and that
+        the GLOBAL_BLOCK of a symtab has a begin and end address).  */
 
       /* BEST is the smallest linenumber > LINE so far seen,
-         or 0 if none has been seen so far.
-         BEST_INDEX and BEST_LINETABLE identify the item for it.  */
+        or 0 if none has been seen so far.
+        BEST_INDEX and BEST_LINETABLE identify the item for it.  */
       int best;
 
       if (best_index >= 0)
@@ -3357,11 +3418,7 @@ find_line_symtab (struct symtab *sym_tab, int line,
        best = 0;
 
       for (objfile *objfile : current_program_space->objfiles ())
-       {
-         if (objfile->sf)
-           objfile->sf->qf->expand_symtabs_with_fullname
-             (objfile, symtab_to_fullname (sym_tab));
-       }
+       objfile->expand_symtabs_with_fullname (symtab_to_fullname (sym_tab));
 
       for (objfile *objfile : current_program_space->objfiles ())
        {
@@ -3438,7 +3495,8 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
        {
          struct linetable_entry *item = &SYMTAB_LINETABLE (symtab)->item[idx];
 
-         if (*best_item == NULL || item->line < (*best_item)->line)
+         if (*best_item == NULL
+             || (item->line < (*best_item)->line && item->is_stmt))
            *best_item = item;
 
          break;
@@ -3549,6 +3607,10 @@ find_line_common (struct linetable *l, int lineno,
     {
       struct linetable_entry *item = &(l->item[i]);
 
+      /* Ignore non-statements.  */
+      if (!item->is_stmt)
+       continue;
+
       if (item->line == lineno)
        {
          /* Return the first (lowest address) entry which matches.  */
@@ -3591,7 +3653,7 @@ find_function_start_sal_1 (CORE_ADDR func_addr, obj_section *section,
       && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
          || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
     {
-      struct gdbarch *gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
+      struct gdbarch *gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
 
       sal.pc = func_addr;
       if (gdbarch_skip_entrypoint_p (gdbarch))
@@ -3642,7 +3704,7 @@ find_function_start_sal (symbol *sym, bool funfirstline)
   fixup_symbol_section (sym, NULL);
   symtab_and_line sal
     = find_function_start_sal_1 (BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)),
-                                SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym),
+                                sym->obj_section (symbol_objfile (sym)),
                                 funfirstline);
   sal.symbol = sym;
   return sal;
@@ -3733,24 +3795,24 @@ skip_prologue_sal (struct symtab_and_line *sal)
 
       objfile = symbol_objfile (sym);
       pc = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
-      section = SYMBOL_OBJ_SECTION (objfile, sym);
+      section = sym->obj_section (objfile);
       name = sym->linkage_name ();
     }
   else
     {
       struct bound_minimal_symbol msymbol
-        = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
+       = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
 
       if (msymbol.minsym == NULL)
        return;
 
       objfile = msymbol.objfile;
       pc = BMSYMBOL_VALUE_ADDRESS (msymbol);
-      section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
+      section = msymbol.minsym->obj_section (objfile);
       name = msymbol.minsym->linkage_name ();
     }
 
-  gdbarch = get_objfile_arch (objfile);
+  gdbarch = objfile->arch ();
 
   /* Process the prologue in two passes.  In the first pass try to skip the
      prologue (SKIP is true) and verify there is a real need for it (indicated
@@ -3780,7 +3842,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
       /* Skip "first line" of function (which is actually its prologue).  */
       pc += gdbarch_deprecated_function_start_offset (gdbarch);
       if (gdbarch_skip_entrypoint_p (gdbarch))
-        pc = gdbarch_skip_entrypoint (gdbarch, pc);
+       pc = gdbarch_skip_entrypoint (gdbarch, pc);
       if (skip)
        pc = gdbarch_skip_prologue_noexcept (gdbarch, pc);
 
@@ -4137,42 +4199,131 @@ operator_chars (const char *p, const char **end)
 }
 \f
 
-/* What part to match in a file name.  */
+/* See class declaration.  */
 
-struct filename_partial_match_opts
+info_sources_filter::info_sources_filter (match_on match_type,
+                                          const char *regexp)
+  : m_match_type (match_type),
+    m_regexp (regexp)
 {
-  /* Only match the directory name part.   */
-  bool dirname = false;
+  /* Setup the compiled regular expression M_C_REGEXP based on M_REGEXP.  */
+  if (m_regexp != nullptr && *m_regexp != '\0')
+    {
+      gdb_assert (m_regexp != nullptr);
 
-  /* Only match the basename part.  */
-  bool basename = false;
-};
+      int cflags = REG_NOSUB;
+#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
+      cflags |= REG_ICASE;
+#endif
+      m_c_regexp.emplace (m_regexp, cflags, _("Invalid regexp"));
+    }
+}
 
-/* Data structure to maintain printing state for output_source_filename.  */
+/* See class declaration.  */
+
+bool
+info_sources_filter::matches (const char *fullname) const
+{
+  /* Does it match regexp?  */
+  if (m_c_regexp.has_value ())
+    {
+      const char *to_match;
+      std::string dirname;
+
+      switch (m_match_type)
+        {
+        case match_on::DIRNAME:
+          dirname = ldirname (fullname);
+          to_match = dirname.c_str ();
+          break;
+        case match_on::BASENAME:
+          to_match = lbasename (fullname);
+          break;
+        case match_on::FULLNAME:
+          to_match = fullname;
+          break;
+       default:
+         gdb_assert_not_reached ("bad m_match_type");
+        }
+
+      if (m_c_regexp->exec (to_match, 0, NULL, 0) != 0)
+        return false;
+    }
+
+  return true;
+}
+
+/* Data structure to maintain the state used for printing the results of
+   the 'info sources' command.  */
 
 struct output_source_filename_data
 {
-  /* Output only filenames matching REGEXP.  */
-  std::string regexp;
-  gdb::optional<compiled_regex> c_regexp;
-  /* Possibly only match a part of the filename.  */
-  filename_partial_match_opts partial_match;
+  /* Create an object for displaying the results of the 'info sources'
+     command to UIOUT.  FILTER must remain valid and unchanged for the
+     lifetime of this object as this object retains a reference to FILTER.  */
+  output_source_filename_data (struct ui_out *uiout,
+                              const info_sources_filter &filter)
+    : m_filter (filter),
+      m_uiout (uiout)
+  { /* Nothing.  */ }
 
+  DISABLE_COPY_AND_ASSIGN (output_source_filename_data);
 
-  /* Cache of what we've seen so far.  */
-  struct filename_seen_cache *filename_seen_cache;
+  /* Reset enough state of this object so we can match against a new set of
+     files.  The existing regular expression is retained though.  */
+  void reset_output ()
+  {
+    m_first = true;
+    m_filename_seen_cache.clear ();
+  }
+
+  /* Worker for sources_info, outputs the file name formatted for either
+     cli or mi (based on the current_uiout).  In cli mode displays
+     FULLNAME with a comma separating this name from any previously
+     printed name (line breaks are added at the comma).  In MI mode
+     outputs a tuple containing DISP_NAME (the files display name),
+     FULLNAME, and EXPANDED_P (true when this file is from a fully
+     expanded symtab, otherwise false).  */
+  void output (const char *disp_name, const char *fullname, bool expanded_p);
+
+  /* An overload suitable for use as a callback to
+     quick_symbol_functions::map_symbol_filenames.  */
+  void operator() (const char *filename, const char *fullname)
+  {
+    /* The false here indicates that this file is from an unexpanded
+       symtab.  */
+    output (filename, fullname, false);
+  }
+
+  /* Return true if at least one filename has been printed (after a call to
+     output) since either this object was created, or the last call to
+     reset_output.  */
+  bool printed_filename_p () const
+  {
+    return !m_first;
+  }
+
+private:
 
   /* Flag of whether we're printing the first one.  */
-  int first;
+  bool m_first = true;
+
+  /* Cache of what we've seen so far.  */
+  filename_seen_cache m_filename_seen_cache;
+
+  /* How source filename should be filtered.  */
+  const info_sources_filter &m_filter;
+
+  /* The object to which output is sent.  */
+  struct ui_out *m_uiout;
 };
 
-/* Slave routine for sources_info.  Force line breaks at ,'s.
-   NAME is the name to print.
-   DATA contains the state for printing and watching for duplicates.  */
+/* See comment in class declaration above.  */
 
-static void
-output_source_filename (const char *name,
-                       struct output_source_filename_data *data)
+void
+output_source_filename_data::output (const char *disp_name,
+                                    const char *fullname,
+                                    bool expanded_p)
 {
   /* Since a single source file can result in several partial symbol
      tables, we need to avoid printing it more than once.  Note: if
@@ -4183,51 +4334,51 @@ output_source_filename (const char *name,
      situation.  I'm not sure whether this can also happen for
      symtabs; it doesn't hurt to check.  */
 
-  /* Was NAME already seen?  */
-  if (data->filename_seen_cache->seen (name))
-    {
-      /* Yes; don't print it again.  */
-      return;
-    }
-
-  /* Does it match data->regexp?  */
-  if (data->c_regexp.has_value ())
-    {
-      const char *to_match;
-      std::string dirname;
+  /* Was NAME already seen?  If so, then don't print it again.  */
+  if (m_filename_seen_cache.seen (fullname))
+    return;
 
-      if (data->partial_match.dirname)
-       {
-         dirname = ldirname (name);
-         to_match = dirname.c_str ();
-       }
-      else if (data->partial_match.basename)
-       to_match = lbasename (name);
-      else
-       to_match = name;
+  /* If the filter rejects this file then don't print it.  */
+  if (!m_filter.matches (fullname))
+    return;
 
-      if (data->c_regexp->exec (to_match, 0, NULL, 0) != 0)
-       return;
-    }
+  ui_out_emit_tuple ui_emitter (m_uiout, nullptr);
 
   /* Print it and reset *FIRST.  */
-  if (! data->first)
-    printf_filtered (", ");
-  data->first = 0;
+  if (!m_first)
+    m_uiout->text (", ");
+  m_first = false;
 
   wrap_here ("");
-  fputs_styled (name, file_name_style.style (), gdb_stdout);
+  if (m_uiout->is_mi_like_p ())
+    {
+      m_uiout->field_string ("file", disp_name, file_name_style.style ());
+      if (fullname != nullptr)
+       m_uiout->field_string ("fullname", fullname,
+                              file_name_style.style ());
+      m_uiout->field_string ("debug-fully-read",
+                            (expanded_p ? "true" : "false"));
+    }
+  else
+    {
+      if (fullname == nullptr)
+       fullname = disp_name;
+      m_uiout->field_string ("fullname", fullname,
+                            file_name_style.style ());
+    }
 }
 
-/* A callback for map_partial_symbol_filenames.  */
+/* For the 'info sources' command, what part of the file names should we be
+   matching the user supplied regular expression against?  */
 
-static void
-output_partial_symbol_filename (const char *filename, const char *fullname,
-                               void *data)
+struct filename_partial_match_opts
 {
-  output_source_filename (fullname ? fullname : filename,
-                         (struct output_source_filename_data *) data);
-}
+  /* Only match the directory name part.   */
+  bool dirname = false;
+
+  /* Only match the basename part.  */
+  bool basename = false;
+};
 
 using isrc_flag_option_def
   = gdb::option::flag_option_def<filename_partial_match_opts>;
@@ -4257,31 +4408,6 @@ make_info_sources_options_def_group (filename_partial_match_opts *isrc_opts)
   return {{info_sources_option_defs}, isrc_opts};
 }
 
-/* Prints the header message for the source files that will be printed
-   with the matching info present in DATA.  SYMBOL_MSG is a message
-   that tells what will or has been done with the symbols of the
-   matching source files.  */
-
-static void
-print_info_sources_header (const char *symbol_msg,
-                          const struct output_source_filename_data *data)
-{
-  puts_filtered (symbol_msg);
-  if (!data->regexp.empty ())
-    {
-      if (data->partial_match.dirname)
-       printf_filtered (_("(dirname matching regular expression \"%s\")"),
-                        data->regexp.c_str ());
-      else if (data->partial_match.basename)
-       printf_filtered (_("(basename matching regular expression \"%s\")"),
-                        data->regexp.c_str ());
-      else
-       printf_filtered (_("(filename matching regular expression \"%s\")"),
-                        data->regexp.c_str ());
-    }
-  puts_filtered ("\n");
-}
-
 /* Completer for "info sources".  */
 
 static void
@@ -4295,72 +4421,116 @@ info_sources_command_completer (cmd_list_element *ignore,
     return;
 }
 
-static void
-info_sources_command (const char *args, int from_tty)
-{
-  struct output_source_filename_data data;
-
-  if (!have_full_symbols () && !have_partial_symbols ())
-    {
-      error (_("No symbol table is loaded.  Use the \"file\" command."));
-    }
-
-  filename_seen_cache filenames_seen;
-
-  auto group = make_info_sources_options_def_group (&data.partial_match);
-
-  gdb::option::process_options
-    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
-
-  if (args != NULL && *args != '\000')
-    data.regexp = args;
-
-  data.filename_seen_cache = &filenames_seen;
-  data.first = 1;
+/* See symtab.h.  */
 
-  if (data.partial_match.dirname && data.partial_match.basename)
-    error (_("You cannot give both -basename and -dirname to 'info sources'."));
-  if ((data.partial_match.dirname || data.partial_match.basename)
-      && data.regexp.empty ())
-     error (_("Missing REGEXP for 'info sources'."));
+void
+info_sources_worker (struct ui_out *uiout,
+                    bool group_by_objfile,
+                    const info_sources_filter &filter)
+{
+  output_source_filename_data data (uiout, filter);
 
-  if (data.regexp.empty ())
-    data.c_regexp.reset ();
-  else
-    {
-      int cflags = REG_NOSUB;
-#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
-      cflags |= REG_ICASE;
-#endif
-      data.c_regexp.emplace (data.regexp.c_str (), cflags,
-                            _("Invalid regexp"));
-    }
+  ui_out_emit_list results_emitter (uiout, "files");
+  gdb::optional<ui_out_emit_tuple> output_tuple;
+  gdb::optional<ui_out_emit_list> sources_list;
 
-  print_info_sources_header
-    (_("Source files for which symbols have been read in:\n"), &data);
+  gdb_assert (group_by_objfile || uiout->is_mi_like_p ());
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
+      if (group_by_objfile)
+       {
+         output_tuple.emplace (uiout, nullptr);
+         uiout->field_string ("filename", objfile_name (objfile));
+         uiout->text (":\n");
+         bool debug_fully_readin = !objfile->has_unexpanded_symtabs ();
+         if (uiout->is_mi_like_p ())
+           {
+             const char *debug_info_state;
+             if (objfile_has_symbols (objfile))
+               {
+                 if (debug_fully_readin)
+                   debug_info_state = "fully-read";
+                 else
+                   debug_info_state = "partially-read";
+               }
+             else
+               debug_info_state = "none";
+             current_uiout->field_string ("debug-info", debug_info_state);
+           }
+         else
+           {
+             if (!debug_fully_readin)
+               uiout->text ("(Full debug information has not yet been read "
+                            "for this file.)\n");
+             if (!objfile_has_symbols (objfile))
+               uiout->text ("(Objfile has no debug information.)\n");
+             uiout->text ("\n");
+           }
+         sources_list.emplace (uiout, "sources");
+       }
+
       for (compunit_symtab *cu : objfile->compunits ())
        {
          for (symtab *s : compunit_filetabs (cu))
            {
+             const char *file = symtab_to_filename_for_display (s);
              const char *fullname = symtab_to_fullname (s);
-
-             output_source_filename (fullname, &data);
+             data.output (file, fullname, true);
            }
        }
+
+      if (group_by_objfile)
+       {
+         objfile->map_symbol_filenames (data, true /* need_fullname */);
+         if (data.printed_filename_p ())
+           uiout->text ("\n\n");
+         data.reset_output ();
+         sources_list.reset ();
+         output_tuple.reset ();
+       }
     }
-  printf_filtered ("\n\n");
 
-  print_info_sources_header
-    (_("Source files for which symbols will be read in on demand:\n"), &data);
+  if (!group_by_objfile)
+    {
+      data.reset_output ();
+      map_symbol_filenames (data, true /*need_fullname*/);
+    }
+}
+
+/* Implement the 'info sources' command.  */
+
+static void
+info_sources_command (const char *args, int from_tty)
+{
+  if (!have_full_symbols () && !have_partial_symbols ())
+    error (_("No symbol table is loaded.  Use the \"file\" command."));
+
+  filename_partial_match_opts match_opts;
+  auto group = make_info_sources_options_def_group (&match_opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
+
+  if (match_opts.dirname && match_opts.basename)
+    error (_("You cannot give both -basename and -dirname to 'info sources'."));
+
+  const char *regex = nullptr;
+  if (args != NULL && *args != '\000')
+    regex = args;
+
+  if ((match_opts.dirname || match_opts.basename) && regex == nullptr)
+    error (_("Missing REGEXP for 'info sources'."));
+
+  info_sources_filter::match_on match_type;
+  if (match_opts.dirname)
+    match_type = info_sources_filter::match_on::DIRNAME;
+  else if (match_opts.basename)
+    match_type = info_sources_filter::match_on::BASENAME;
+  else
+    match_type = info_sources_filter::match_on::FULLNAME;
 
-  filenames_seen.clear ();
-  data.first = 1;
-  map_symbol_filenames (output_partial_symbol_filename, &data,
-                       1 /*need_fullname*/);
-  printf_filtered ("\n");
+  info_sources_filter filter (match_type, regex);
+  info_sources_worker (current_uiout, true, filter);
 }
 
 /* Compare FILE against all the entries of FILENAMES.  If BASENAMES is
@@ -4477,21 +4647,21 @@ global_symbol_searcher::expand_symtabs
   enum search_domain kind = m_kind;
   bool found_msymbol = false;
 
-  if (objfile->sf)
-    objfile->sf->qf->expand_symtabs_matching
-      (objfile,
-       [&] (const char *filename, bool basenames)
-       {
-        return file_matches (filename, filenames, basenames);
-       },
-       lookup_name_info::match_any (),
-       [&] (const char *symname)
-       {
-        return (!preg.has_value ()
-                || preg->exec (symname, 0, NULL, 0) == 0);
-       },
-       NULL,
-       kind);
+  objfile->expand_symtabs_matching
+    ([&] (const char *filename, bool basenames)
+     {
+       return file_matches (filename, filenames, basenames);
+     },
+     &lookup_name_info::match_any (),
+     [&] (const char *symname)
+     {
+       return (!preg.has_value ()
+              || preg->exec (symname, 0, NULL, 0) == 0);
+     },
+     NULL,
+     SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
+     UNDEF_DOMAIN,
+     kind);
 
   /* Here, we search through the minimal symbol tables for functions and
      variables that match, and force their symbols to be read.  This is in
@@ -4547,12 +4717,12 @@ global_symbol_searcher::expand_symtabs
 
 /* See symtab.h.  */
 
-void
+bool
 global_symbol_searcher::add_matching_symbols
        (objfile *objfile,
         const gdb::optional<compiled_regex> &preg,
         const gdb::optional<compiled_regex> &treg,
-        std::vector<symbol_search> *results) const
+        std::set<symbol_search> *result_set) const
 {
   enum search_domain kind = m_kind;
 
@@ -4594,7 +4764,7 @@ global_symbol_searcher::add_matching_symbols
                              members.  We only want to skip enums
                              here.  */
                           && !(SYMBOL_CLASS (sym) == LOC_CONST
-                               && (TYPE_CODE (SYMBOL_TYPE (sym))
+                               && (SYMBOL_TYPE (sym)->code ()
                                    == TYPE_CODE_ENUM))
                           && (!treg.has_value ()
                               || treg_matches_sym_type_name (*treg, sym)))
@@ -4610,17 +4780,26 @@ global_symbol_searcher::add_matching_symbols
                              && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN
                              && SYMBOL_LINE (sym) != 0))))
                {
-                 /* Matching msymbol, add it to the results list.  */
-                 results->emplace_back (block, sym);
+                 if (result_set->size () < m_max_search_results)
+                   {
+                     /* Match, insert if not already in the results.  */
+                     symbol_search ss (block, sym);
+                     if (result_set->find (ss) == result_set->end ())
+                       result_set->insert (ss);
+                   }
+                 else
+                   return false;
                }
            }
        }
     }
+
+  return true;
 }
 
 /* See symtab.h.  */
 
-void
+bool
 global_symbol_searcher::add_matching_msymbols
        (objfile *objfile, const gdb::optional<compiled_regex> &preg,
         std::vector<symbol_search> *results) const
@@ -4652,22 +4831,17 @@ global_symbol_searcher::add_matching_msymbols
                       VAR_DOMAIN).symbol == NULL)
                    {
                      /* Matching msymbol, add it to the results list.  */
-                     results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+                     if (results->size () < m_max_search_results)
+                       results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+                     else
+                       return false;
                    }
                }
            }
        }
     }
-}
-
-/* Sort the symbols in RESULT and remove duplicates.  */
 
-static void
-sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
-{
-  std::sort (result->begin (), result->end ());
-  result->erase (std::unique (result->begin (), result->end ()),
-                result->end ());
+  return true;
 }
 
 /* See symtab.h.  */
@@ -4685,16 +4859,16 @@ global_symbol_searcher::search () const
       const char *symbol_name_regexp = m_symbol_name_regexp;
 
       /* Make sure spacing is right for C++ operators.
-         This is just a courtesy to make the matching less sensitive
-         to how many spaces the user leaves between 'operator'
-         and <TYPENAME> or <OPERATOR>.  */
+        This is just a courtesy to make the matching less sensitive
+        to how many spaces the user leaves between 'operator'
+        and <TYPENAME> or <OPERATOR>.  */
       const char *opend;
       const char *opname = operator_chars (symbol_name_regexp, &opend);
 
       if (*opname)
        {
          int fix = -1;         /* -1 means ok; otherwise number of
-                                    spaces needed.  */
+                                   spaces needed.  */
 
          if (isalpha (*opname) || *opname == '_' || *opname == '$')
            {
@@ -4733,20 +4907,24 @@ global_symbol_searcher::search () const
     }
 
   bool found_msymbol = false;
-  std::vector<symbol_search> result;
+  std::set<symbol_search> result_set;
   for (objfile *objfile : current_program_space->objfiles ())
     {
       /* Expand symtabs within objfile that possibly contain matching
         symbols.  */
       found_msymbol |= expand_symtabs (objfile, preg);
 
-      /* Find matching symbols within OBJFILE and add them in to the RESULT
-        vector.  */
-      add_matching_symbols (objfile, preg, treg, &result);
+      /* Find matching symbols within OBJFILE and add them in to the
+        RESULT_SET set.  Use a set here so that we can easily detect
+        duplicates as we go, and can therefore track how many unique
+        matches we have found so far.  */
+      if (!add_matching_symbols (objfile, preg, treg, &result_set))
+       break;
     }
 
-  if (!result.empty ())
-    sort_search_symbols_remove_dups (&result);
+  /* Convert the result set into a sorted result list, as std::set is
+     defined to be sorted then no explicit call to std::sort is needed.  */
+  std::vector<symbol_search> result (result_set.begin (), result_set.end ());
 
   /* If there are no debug symbols, then add matching minsyms.  But if the
      user wants to see symbols matching a type regexp, then never give a
@@ -4758,7 +4936,8 @@ global_symbol_searcher::search () const
     {
       gdb_assert (m_kind == VARIABLES_DOMAIN || m_kind == FUNCTIONS_DOMAIN);
       for (objfile *objfile : current_program_space->objfiles ())
-       add_matching_msymbols (objfile, preg, &result);
+       if (!add_matching_msymbols (objfile, preg, &result))
+         break;
     }
 
   return result;
@@ -4791,7 +4970,7 @@ symbol_to_info_string (struct symbol *sym, int block,
         For the struct printing case below, things are worse, we force
         printing of the ";" in this function, which is going to be wrong
         for languages that don't require a ";" between statements.  */
-      if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_TYPEDEF)
+      if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_TYPEDEF)
        typedef_print (SYMBOL_TYPE (sym), sym, &tmp_stream);
       else
        type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1);
@@ -4863,7 +5042,7 @@ print_symbol_info (enum search_domain kind,
 static void
 print_msymbol_info (struct bound_minimal_symbol msymbol)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
+  struct gdbarch *gdbarch = msymbol.objfile->arch ();
   char *tmp;
 
   if (gdbarch_addr_bit (gdbarch) <= 32)
@@ -4963,13 +5142,13 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms,
    and 'info functions' commands.  These correspond to the -q, -t, and -n
    options.  */
 
-struct info_print_options
+struct info_vars_funcs_options
 {
   bool quiet = false;
   bool exclude_minsyms = false;
   char *type_regexp = nullptr;
 
-  ~info_print_options ()
+  ~info_vars_funcs_options ()
   {
     xfree (type_regexp);
   }
@@ -4978,24 +5157,25 @@ struct info_print_options
 /* The options used by the 'info variables' and 'info functions'
    commands.  */
 
-static const gdb::option::option_def info_print_options_defs[] = {
-  gdb::option::boolean_option_def<info_print_options> {
+static const gdb::option::option_def info_vars_funcs_options_defs[] = {
+  gdb::option::boolean_option_def<info_vars_funcs_options> {
     "q",
-    [] (info_print_options *opt) { return &opt->quiet; },
+    [] (info_vars_funcs_options *opt) { return &opt->quiet; },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   },
 
-  gdb::option::boolean_option_def<info_print_options> {
+  gdb::option::boolean_option_def<info_vars_funcs_options> {
     "n",
-    [] (info_print_options *opt) { return &opt->exclude_minsyms; },
+    [] (info_vars_funcs_options *opt) { return &opt->exclude_minsyms; },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   },
 
-  gdb::option::string_option_def<info_print_options> {
+  gdb::option::string_option_def<info_vars_funcs_options> {
     "t",
-    [] (info_print_options *opt) { return &opt->type_regexp; },
+    [] (info_vars_funcs_options *opt) { return &opt->type_regexp;
+  },
     nullptr, /* show_cmd_cb */
     nullptr /* set_doc */
   }
@@ -5005,20 +5185,20 @@ static const gdb::option::option_def info_print_options_defs[] = {
    functions'.  */
 
 static gdb::option::option_def_group
-make_info_print_options_def_group (info_print_options *opts)
+make_info_vars_funcs_options_def_group (info_vars_funcs_options *opts)
 {
-  return {{info_print_options_defs}, opts};
+  return {{info_vars_funcs_options_defs}, opts};
 }
 
 /* Command completer for 'info variables' and 'info functions'.  */
 
 static void
-info_print_command_completer (struct cmd_list_element *ignore,
-                             completion_tracker &tracker,
-                             const char *text, const char * /* word */)
+info_vars_funcs_command_completer (struct cmd_list_element *ignore,
+                                  completion_tracker &tracker,
+                                  const char *text, const char * /* word */)
 {
   const auto group
-    = make_info_print_options_def_group (nullptr);
+    = make_info_vars_funcs_options_def_group (nullptr);
   if (gdb::option::complete_options
       (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
     return;
@@ -5032,8 +5212,8 @@ info_print_command_completer (struct cmd_list_element *ignore,
 static void
 info_variables_command (const char *args, int from_tty)
 {
-  info_print_options opts;
-  auto grp = make_info_print_options_def_group (&opts);
+  info_vars_funcs_options opts;
+  auto grp = make_info_vars_funcs_options_def_group (&opts);
   gdb::option::process_options
     (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
   if (args != nullptr && *args == '\0')
@@ -5048,8 +5228,9 @@ info_variables_command (const char *args, int from_tty)
 static void
 info_functions_command (const char *args, int from_tty)
 {
-  info_print_options opts;
-  auto grp = make_info_print_options_def_group (&opts);
+  info_vars_funcs_options opts;
+
+  auto grp = make_info_vars_funcs_options_def_group (&opts);
   gdb::option::process_options
     (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
   if (args != nullptr && *args == '\0')
@@ -5143,6 +5324,11 @@ rbreak_command (const char *regexp, int from_tty)
     {
       const char *colon = strchr (regexp, ':');
 
+      /* Ignore the colon if it is part of a Windows drive.  */
+      if (HAS_DRIVE_SPEC (regexp)
+         && (regexp[2] == '/' || regexp[2] == '\\'))
+       colon = strchr (STRIP_DRIVE_SPEC (regexp), ':');
+
       if (colon && *(colon + 1) != ':')
        {
          int colon_index;
@@ -5200,14 +5386,14 @@ compare_symbol_name (const char *symbol_name, language symbol_language,
   const language_defn *lang = language_def (symbol_language);
 
   symbol_name_matcher_ftype *name_match
-    = get_symbol_name_matcher (lang, lookup_name);
+    = lang->get_symbol_name_matcher (lookup_name);
 
   return name_match (symbol_name, lookup_name, &match_res);
 }
 
 /*  See symtab.h.  */
 
-void
+bool
 completion_list_add_name (completion_tracker &tracker,
                          language symbol_language,
                          const char *symname,
@@ -5219,7 +5405,7 @@ completion_list_add_name (completion_tracker &tracker,
 
   /* Clip symbols that cannot match.  */
   if (!compare_symbol_name (symname, symbol_language, lookup_name, match_res))
-    return;
+    return false;
 
   /* Refresh SYMNAME from the match string.  It's potentially
      different depending on language.  (E.g., on Ada, the match may be
@@ -5243,6 +5429,8 @@ completion_list_add_name (completion_tracker &tracker,
     tracker.add_completion (std::move (completion),
                            &match_res.match_for_lcd, text, word);
   }
+
+  return true;
 }
 
 /* completion_list_add_name wrapper for struct symbol.  */
@@ -5253,9 +5441,31 @@ completion_list_add_symbol (completion_tracker &tracker,
                            const lookup_name_info &lookup_name,
                            const char *text, const char *word)
 {
-  completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym),
-                           sym->natural_name (),
-                           lookup_name, text, word);
+  if (!completion_list_add_name (tracker, sym->language (),
+                                sym->natural_name (),
+                                lookup_name, text, word))
+    return;
+
+  /* C++ function symbols include the parameters within both the msymbol
+     name and the symbol name.  The problem is that the msymbol name will
+     describe the parameters in the most basic way, with typedefs stripped
+     out, while the symbol name will represent the types as they appear in
+     the program.  This means we will see duplicate entries in the
+     completion tracker.  The following converts the symbol name back to
+     the msymbol name and removes the msymbol name from the completion
+     tracker.  */
+  if (sym->language () == language_cplus
+      && SYMBOL_DOMAIN (sym) == VAR_DOMAIN
+      && SYMBOL_CLASS (sym) == LOC_BLOCK)
+    {
+      /* The call to canonicalize returns the empty string if the input
+        string is already in canonical form, thanks to this we don't
+        remove the symbol we just added above.  */
+      gdb::unique_xmalloc_ptr<char> str
+       = cp_canonicalize_string_no_typedefs (sym->natural_name ());
+      if (str != nullptr)
+       tracker.remove_completion (str.get ());
+    }
 }
 
 /* completion_list_add_name wrapper for struct minimal_symbol.  */
@@ -5266,7 +5476,7 @@ completion_list_add_msymbol (completion_tracker &tracker,
                             const lookup_name_info &lookup_name,
                             const char *text, const char *word)
 {
-  completion_list_add_name (tracker, MSYMBOL_LANGUAGE (sym),
+  completion_list_add_name (tracker, sym->language (),
                            sym->natural_name (),
                            lookup_name, text, word);
 }
@@ -5394,13 +5604,13 @@ completion_list_add_fields (completion_tracker &tracker,
   if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
     {
       struct type *t = SYMBOL_TYPE (sym);
-      enum type_code c = TYPE_CODE (t);
+      enum type_code c = t->code ();
       int j;
 
       if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
-       for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+       for (j = TYPE_N_BASECLASSES (t); j < t->num_fields (); j++)
          if (TYPE_FIELD_NAME (t, j))
-           completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym),
+           completion_list_add_name (tracker, sym->language (),
                                      TYPE_FIELD_NAME (t, j),
                                      lookup_name, text, word);
     }
@@ -5411,7 +5621,7 @@ completion_list_add_fields (completion_tracker &tracker,
 bool
 symbol_is_function_or_method (symbol *sym)
 {
-  switch (TYPE_CODE (SYMBOL_TYPE (sym)))
+  switch (SYMBOL_TYPE (sym)->code ())
     {
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
@@ -5462,11 +5672,9 @@ find_gnu_ifunc (const symbol *sym)
          CORE_ADDR msym_addr = MSYMBOL_VALUE_ADDRESS (objfile, minsym);
          if (MSYMBOL_TYPE (minsym) == mst_data_gnu_ifunc)
            {
-             struct gdbarch *gdbarch = get_objfile_arch (objfile);
-             msym_addr
-               = gdbarch_convert_from_func_ptr_addr (gdbarch,
-                                                     msym_addr,
-                                                     current_top_target ());
+             struct gdbarch *gdbarch = objfile->arch ();
+             msym_addr = gdbarch_convert_from_func_ptr_addr
+               (gdbarch, msym_addr, current_inferior ()->top_target ());
            }
          if (msym_addr == address)
            {
@@ -5511,7 +5719,7 @@ add_symtab_completions (struct compunit_symtab *cust,
 
          if (code == TYPE_CODE_UNDEF
              || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
-                 && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
+                 && SYMBOL_TYPE (sym)->code () == code))
            completion_list_add_symbol (tracker, sym,
                                        lookup_name,
                                        text, word);
@@ -5541,55 +5749,55 @@ default_collect_symbol_completion_matches_break_on
   if (mode == complete_symbol_mode::LINESPEC)
     sym_text = text;
   else
-  {
-    const char *p;
-    char quote_found;
-    const char *quote_pos = NULL;
+    {
+      const char *p;
+      char quote_found;
+      const char *quote_pos = NULL;
 
-    /* First see if this is a quoted string.  */
-    quote_found = '\0';
-    for (p = text; *p != '\0'; ++p)
-      {
-       if (quote_found != '\0')
-         {
-           if (*p == quote_found)
-             /* Found close quote.  */
-             quote_found = '\0';
-           else if (*p == '\\' && p[1] == quote_found)
-             /* A backslash followed by the quote character
-                doesn't end the string.  */
-             ++p;
-         }
-       else if (*p == '\'' || *p == '"')
-         {
-           quote_found = *p;
-           quote_pos = p;
-         }
-      }
-    if (quote_found == '\'')
-      /* A string within single quotes can be a symbol, so complete on it.  */
-      sym_text = quote_pos + 1;
-    else if (quote_found == '"')
-      /* A double-quoted string is never a symbol, nor does it make sense
-         to complete it any other way.  */
-      {
-       return;
-      }
-    else
-      {
-       /* It is not a quoted string.  Break it based on the characters
-          which are in symbols.  */
-       while (p > text)
-         {
-           if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
-               || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
-             --p;
-           else
-             break;
-         }
-       sym_text = p;
-      }
-  }
+      /* First see if this is a quoted string.  */
+      quote_found = '\0';
+      for (p = text; *p != '\0'; ++p)
+       {
+         if (quote_found != '\0')
+           {
+             if (*p == quote_found)
+               /* Found close quote.  */
+               quote_found = '\0';
+             else if (*p == '\\' && p[1] == quote_found)
+               /* A backslash followed by the quote character
+                  doesn't end the string.  */
+               ++p;
+           }
+         else if (*p == '\'' || *p == '"')
+           {
+             quote_found = *p;
+             quote_pos = p;
+           }
+       }
+      if (quote_found == '\'')
+       /* A string within single quotes can be a symbol, so complete on it.  */
+       sym_text = quote_pos + 1;
+      else if (quote_found == '"')
+       /* A double-quoted string is never a symbol, nor does it make sense
+          to complete it any other way.  */
+       {
+         return;
+       }
+      else
+       {
+         /* It is not a quoted string.  Break it based on the characters
+            which are in symbols.  */
+         while (p > text)
+           {
+             if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
+                 || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
+               --p;
+             else
+               break;
+           }
+         sym_text = p;
+       }
+    }
 
   lookup_name_info lookup_name (sym_text, name_match_type, true);
 
@@ -5636,7 +5844,9 @@ default_collect_symbol_completion_matches_break_on
                               add_symtab_completions (symtab,
                                                       tracker, mode, lookup_name,
                                                       sym_text, word, code);
+                              return true;
                             },
+                          SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
                           ALL_DOMAIN);
 
   /* Search upwards from currently selected frame (so that we can
@@ -5662,7 +5872,7 @@ default_collect_symbol_completion_matches_break_on
                                            sym_text, word);
              }
            else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
-                    && TYPE_CODE (SYMBOL_TYPE (sym)) == code)
+                    && SYMBOL_TYPE (sym)->code () == code)
              completion_list_add_symbol (tracker, sym, lookup_name,
                                          sym_text, word);
          }
@@ -5692,7 +5902,7 @@ default_collect_symbol_completion_matches_break_on
 
   /* Skip macros if we are completing a struct tag -- arguable but
      usually what is expected.  */
-  if (current_language->la_macro_expansion == macro_expansion_c
+  if (current_language->macro_expansion () == macro_expansion_c
       && code == TYPE_CODE_UNDEF)
     {
       gdb::unique_xmalloc_ptr<struct macro_scope> scope;
@@ -5724,19 +5934,6 @@ default_collect_symbol_completion_matches_break_on
     }
 }
 
-void
-default_collect_symbol_completion_matches (completion_tracker &tracker,
-                                          complete_symbol_mode mode,
-                                          symbol_name_match_type name_match_type,
-                                          const char *text, const char *word,
-                                          enum type_code code)
-{
-  return default_collect_symbol_completion_matches_break_on (tracker, mode,
-                                                            name_match_type,
-                                                            text, word, "",
-                                                            code);
-}
-
 /* Collect all symbols (regardless of class) which begin by matching
    TEXT.  */
 
@@ -5746,10 +5943,10 @@ collect_symbol_completion_matches (completion_tracker &tracker,
                                   symbol_name_match_type name_match_type,
                                   const char *text, const char *word)
 {
-  current_language->la_collect_symbol_completion_matches (tracker, mode,
-                                                         name_match_type,
-                                                         text, word,
-                                                         TYPE_CODE_UNDEF);
+  current_language->collect_symbol_completion_matches (tracker, mode,
+                                                      name_match_type,
+                                                      text, word,
+                                                      TYPE_CODE_UNDEF);
 }
 
 /* Like collect_symbol_completion_matches, but only collect
@@ -5766,9 +5963,9 @@ collect_symbol_completion_matches_type (completion_tracker &tracker,
   gdb_assert (code == TYPE_CODE_UNION
              || code == TYPE_CODE_STRUCT
              || code == TYPE_CODE_ENUM);
-  current_language->la_collect_symbol_completion_matches (tracker, mode,
-                                                         name_match_type,
-                                                         text, word, code);
+  current_language->collect_symbol_completion_matches (tracker, mode,
+                                                      name_match_type,
+                                                      text, word, code);
 }
 
 /* Like collect_symbol_completion_matches, but collects a list of
@@ -5789,46 +5986,46 @@ collect_file_symbol_completion_matches (completion_tracker &tracker,
   if (mode == complete_symbol_mode::LINESPEC)
     sym_text = text;
   else
-  {
-    const char *p;
-    char quote_found;
-    const char *quote_pos = NULL;
+    {
+      const char *p;
+      char quote_found;
+      const char *quote_pos = NULL;
 
-    /* First see if this is a quoted string.  */
-    quote_found = '\0';
-    for (p = text; *p != '\0'; ++p)
-      {
-       if (quote_found != '\0')
-         {
-           if (*p == quote_found)
-             /* Found close quote.  */
-             quote_found = '\0';
-           else if (*p == '\\' && p[1] == quote_found)
-             /* A backslash followed by the quote character
-                doesn't end the string.  */
-             ++p;
-         }
-       else if (*p == '\'' || *p == '"')
-         {
-           quote_found = *p;
-           quote_pos = p;
-         }
-      }
-    if (quote_found == '\'')
-      /* A string within single quotes can be a symbol, so complete on it.  */
-      sym_text = quote_pos + 1;
-    else if (quote_found == '"')
-      /* A double-quoted string is never a symbol, nor does it make sense
-         to complete it any other way.  */
-      {
-       return;
-      }
-    else
-      {
-       /* Not a quoted string.  */
-       sym_text = language_search_unquoted_string (text, p);
-      }
-  }
+      /* First see if this is a quoted string.  */
+      quote_found = '\0';
+      for (p = text; *p != '\0'; ++p)
+       {
+         if (quote_found != '\0')
+           {
+             if (*p == quote_found)
+               /* Found close quote.  */
+               quote_found = '\0';
+             else if (*p == '\\' && p[1] == quote_found)
+               /* A backslash followed by the quote character
+                  doesn't end the string.  */
+               ++p;
+           }
+         else if (*p == '\'' || *p == '"')
+           {
+             quote_found = *p;
+             quote_pos = p;
+           }
+       }
+      if (quote_found == '\'')
+       /* A string within single quotes can be a symbol, so complete on it.  */
+       sym_text = quote_pos + 1;
+      else if (quote_found == '"')
+       /* A double-quoted string is never a symbol, nor does it make sense
+          to complete it any other way.  */
+       {
+         return;
+       }
+      else
+       {
+         /* Not a quoted string.  */
+         sym_text = language_search_unquoted_string (text, p);
+       }
+    }
 
   lookup_name_info lookup_name (sym_text, name_match_type, true);
 
@@ -5871,7 +6068,7 @@ not_interesting_fname (const char *fname)
   return 0;
 }
 
-/* An object of this type is passed as the user_data argument to
+/* An object of this type is passed as the callback argument to
    map_partial_symbol_filenames.  */
 struct add_partial_filename_data
 {
@@ -5880,34 +6077,33 @@ struct add_partial_filename_data
   const char *word;
   int text_len;
   completion_list *list;
+
+  void operator() (const char *filename, const char *fullname);
 };
 
 /* A callback for map_partial_symbol_filenames.  */
 
-static void
-maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
-                                  void *user_data)
+void
+add_partial_filename_data::operator() (const char *filename,
+                                      const char *fullname)
 {
-  struct add_partial_filename_data *data
-    = (struct add_partial_filename_data *) user_data;
-
   if (not_interesting_fname (filename))
     return;
-  if (!data->filename_seen_cache->seen (filename)
-      && filename_ncmp (filename, data->text, data->text_len) == 0)
+  if (!filename_seen_cache->seen (filename)
+      && filename_ncmp (filename, text, text_len) == 0)
     {
       /* This file matches for a completion; add it to the
         current list of matches.  */
-      add_filename_to_list (filename, data->text, data->word, data->list);
+      add_filename_to_list (filename, text, word, list);
     }
   else
     {
       const char *base_name = lbasename (filename);
 
       if (base_name != filename
-         && !data->filename_seen_cache->seen (base_name)
-         && filename_ncmp (base_name, data->text, data->text_len) == 0)
-       add_filename_to_list (base_name, data->text, data->word, data->list);
+         && !filename_seen_cache->seen (base_name)
+         && filename_ncmp (base_name, text, text_len) == 0)
+       add_filename_to_list (base_name, text, word, list);
     }
 }
 
@@ -5964,8 +6160,7 @@ make_source_files_completion_list (const char *text, const char *word)
   datum.word = word;
   datum.text_len = text_len;
   datum.list = &list;
-  map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
-                       0 /*need_fullname*/);
+  map_symbol_filenames (datum, false /*need_fullname*/);
 
   return list;
 }
@@ -6083,6 +6278,16 @@ find_main_name (void)
 
   /* The languages above didn't identify the name of the main procedure.
      Fallback to "main".  */
+
+  /* Try to find language for main in psymtabs.  */
+  enum language lang
+    = find_quick_global_symbol_language ("main", VAR_DOMAIN);
+  if (lang != language_unknown)
+    {
+      set_main_name ("main", lang);
+      return;
+    }
+
   set_main_name ("main", language_unknown);
 }
 
@@ -6255,42 +6460,6 @@ initialize_ordinary_address_classes (void)
 
 \f
 
-/* Initialize the symbol SYM, and mark it as being owned by an objfile.  */
-
-void
-initialize_objfile_symbol (struct symbol *sym)
-{
-  SYMBOL_OBJFILE_OWNED (sym) = 1;
-  SYMBOL_SECTION (sym) = -1;
-}
-
-/* Allocate and initialize a new 'struct symbol' on OBJFILE's
-   obstack.  */
-
-struct symbol *
-allocate_symbol (struct objfile *objfile)
-{
-  struct symbol *result = new (&objfile->objfile_obstack) symbol ();
-
-  initialize_objfile_symbol (result);
-
-  return result;
-}
-
-/* Allocate and initialize a new 'struct template_symbol' on OBJFILE's
-   obstack.  */
-
-struct template_symbol *
-allocate_template_symbol (struct objfile *objfile)
-{
-  struct template_symbol *result;
-
-  result = new (&objfile->objfile_obstack) template_symbol ();
-  initialize_objfile_symbol (result);
-
-  return result;
-}
-
 /* See symtab.h.  */
 
 struct objfile *
@@ -6307,7 +6476,7 @@ symbol_arch (const struct symbol *symbol)
 {
   if (!SYMBOL_OBJFILE_OWNED (symbol))
     return symbol->owner.arch;
-  return get_objfile_arch (SYMTAB_OBJFILE (symbol->owner.symtab));
+  return SYMTAB_OBJFILE (symbol->owner.symtab)->arch ();
 }
 
 /* See symtab.h.  */
@@ -6340,6 +6509,9 @@ get_symbol_address (const struct symbol *sym)
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
+      if (objfile->separate_debug_objfile_backlink != nullptr)
+       continue;
+
       bound_minimal_symbol minsym
        = lookup_minimal_symbol_linkage (linkage_name, objfile);
       if (minsym.minsym != nullptr)
@@ -6360,7 +6532,8 @@ get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
 
   for (objfile *objfile : current_program_space->objfiles ())
     {
-      if ((objfile->flags & OBJF_MAINLINE) != 0)
+      if (objfile->separate_debug_objfile_backlink == nullptr
+         && (objfile->flags & OBJF_MAINLINE) != 0)
        {
          bound_minimal_symbol found
            = lookup_minimal_symbol_linkage (linkage_name, objfile);
@@ -6369,7 +6542,7 @@ get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
        }
     }
   return (minsym->value.address
-         + ANOFFSET (objf->section_offsets, minsym->section));
+         + objf->section_offsets[minsym->section_index ()]);
 }
 
 \f
@@ -6378,15 +6551,6 @@ get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
 
 static struct cmd_list_element *info_module_cmdlist = NULL;
 
-/* Implement the 'info module' command, just displays some help text for
-   the available sub-commands.  */
-
-static void
-info_module_command (const char *args, int from_tty)
-{
-  help_list (info_module_cmdlist, "info module ", class_info, gdb_stdout);
-}
-
 /* See symtab.h.  */
 
 std::vector<module_symbol_search>
@@ -6682,8 +6846,9 @@ info_module_var_func_command_completer (struct cmd_list_element *ignore,
 
 \f
 
+void _initialize_symtab ();
 void
-_initialize_symtab (void)
+_initialize_symtab ()
 {
   cmd_list_element *c;
 
@@ -6696,7 +6861,7 @@ Usage: info variables [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
                                      _("global and static variables"),
                                      true));
-  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
   if (dbx_commands)
     {
       c = add_com ("whereis", class_info, info_variables_command,
@@ -6706,7 +6871,7 @@ Usage: whereis [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
                                         _("global and static variables"),
                                         true));
-      set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+      set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
     }
 
   c = add_info ("functions", info_functions_command,
@@ -6716,7 +6881,7 @@ Usage: info functions [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the functions.\n"),
                                      _("functions"),
                                      true));
-  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);
 
   c = add_info ("types", info_types_command, _("\
 All type names, or those matching REGEXP.\n\
@@ -6725,7 +6890,8 @@ Print information about all types matching REGEXP, or all types if no\n\
 REGEXP is given.  The optional flag -q disables printing of headers."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
-  const auto info_sources_opts = make_info_sources_options_def_group (nullptr);
+  const auto info_sources_opts
+    = make_info_sources_options_def_group (nullptr);
 
   static std::string info_sources_help
     = gdb::option::build_help (_("\
@@ -6744,10 +6910,9 @@ Options:\n\
                _("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
-  add_prefix_cmd ("module", class_info, info_module_command, _("\
+  add_basic_prefix_cmd ("module", class_info, _("\
 Print information about modules."),
-                 &info_module_cmdlist, "info module ",
-                 0, &infolist);
+                       &info_module_cmdlist, 0, &infolist);
 
   c = add_cmd ("functions", class_info, info_module_functions_command, _("\
 Display functions arranged by modules.\n\
@@ -6787,12 +6952,12 @@ The -q flag suppresses printing some header information."),
           _("Set a breakpoint for all functions matching REGEXP."));
 
   add_setshow_enum_cmd ("multiple-symbols", no_class,
-                        multiple_symbols_modes, &multiple_symbols_mode,
-                        _("\
+                       multiple_symbols_modes, &multiple_symbols_mode,
+                       _("\
 Set how the debugger handles ambiguities in expressions."), _("\
 Show how the debugger handles ambiguities in expressions."), _("\
 Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
-                        NULL, NULL, &setlist, &showlist);
+                       NULL, NULL, &setlist, &showlist);
 
   add_setshow_boolean_cmd ("basenames-may-differ", class_obscure,
                           &basenames_may_differ, _("\
@@ -6845,12 +7010,17 @@ If zero then the symbol cache is disabled."),
           _("Print symbol cache statistics for each program space."),
           &maintenanceprintlist);
 
-  add_cmd ("flush-symbol-cache", class_maintenance,
-          maintenance_flush_symbol_cache,
-          _("Flush the symbol cache for each program space."),
-          &maintenancelist);
-
-  gdb::observers::executable_changed.attach (symtab_observer_executable_changed);
-  gdb::observers::new_objfile.attach (symtab_new_objfile_observer);
-  gdb::observers::free_objfile.attach (symtab_free_objfile_observer);
+  cmd_list_element *maintenance_flush_symbol_cache_cmd
+    = add_cmd ("symbol-cache", class_maintenance,
+              maintenance_flush_symbol_cache,
+              _("Flush the symbol cache for each program space."),
+              &maintenanceflushlist);
+  c = add_alias_cmd ("flush-symbol-cache", maintenance_flush_symbol_cache_cmd,
+                    class_maintenance, 0, &maintenancelist);
+  deprecate_cmd (c, "maintenancelist flush symbol-cache");
+
+  gdb::observers::executable_changed.attach (symtab_observer_executable_changed,
+                                            "symtab");
+  gdb::observers::new_objfile.attach (symtab_new_objfile_observer, "symtab");
+  gdb::observers::free_objfile.attach (symtab_free_objfile_observer, "symtab");
 }
This page took 0.082153 seconds and 4 git commands to generate.