Automatic date update in version.in
[external/binutils.git] / gdb / symtab.c
index 146dc2e..774f209 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table lookup for the GNU debugger, GDB.
 
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "p-lang.h"
 #include "addrmap.h"
 #include "cli/cli-utils.h"
+#include "cli/cli-style.h"
 #include "fnmatch.h"
 #include "hashtab.h"
+#include "typeprint.h"
 
 #include "gdb_obstack.h"
 #include "block.h"
@@ -54,7 +56,7 @@
 #include <ctype.h>
 #include "cp-abi.h"
 #include "cp-support.h"
-#include "observer.h"
+#include "observable.h"
 #include "solist.h"
 #include "macrotab.h"
 #include "macroscope.h"
@@ -66,6 +68,7 @@
 #include "filename-seen-cache.h"
 #include "arch-utils.h"
 #include <algorithm>
+#include "common/pathstuff.h"
 
 /* Forward declarations for local functions.  */
 
@@ -309,6 +312,31 @@ compunit_language (const struct compunit_symtab *cust)
   return SYMTAB_LANGUAGE (symtab);
 }
 
+/* See symtab.h.  */
+
+bool
+minimal_symbol::data_p () const
+{
+  return type == mst_data
+    || type == mst_bss
+    || type == mst_abs
+    || type == mst_file_data
+    || type == mst_file_bss;
+}
+
+/* See symtab.h.  */
+
+bool
+minimal_symbol::text_p () const
+{
+  return type == mst_text
+    || type == mst_text_gnu_ifunc
+    || type == mst_data_gnu_ifunc
+    || type == mst_slot_got_plt
+    || type == mst_solib_trampoline
+    || type == mst_file_text;
+}
+
 /* See whether FILENAME matches SEARCH_NAME using the rule that we
    advertise to the user.  (The manual's description of linespecs
    describes what we advertise).  Returns true if they match, false
@@ -403,12 +431,11 @@ iterate_over_some_symtabs (const char *name,
                           gdb::function_view<bool (symtab *)> callback)
 {
   struct compunit_symtab *cust;
-  struct symtab *s;
   const char* base_name = lbasename (name);
 
   for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
     {
-      ALL_COMPUNIT_FILETABS (cust, s)
+      for (symtab *s : compunit_filetabs (cust))
        {
          if (compare_filenames_for_search (s->filename, name))
            {
@@ -462,7 +489,6 @@ void
 iterate_over_symtabs (const char *name,
                      gdb::function_view<bool (symtab *)> callback)
 {
-  struct objfile *objfile;
   gdb::unique_xmalloc_ptr<char> real_path;
 
   /* Here we are interested in canonicalizing an absolute path, not
@@ -473,7 +499,7 @@ iterate_over_symtabs (const char *name,
       gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
     }
 
-  ALL_OBJFILES (objfile)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (iterate_over_some_symtabs (name, real_path.get (),
                                     objfile->compunit_symtabs, NULL,
@@ -484,7 +510,7 @@ iterate_over_symtabs (const char *name,
   /* Same search rules as above apply here, but now we look thru the
      psymtabs.  */
 
-  ALL_OBJFILES (objfile)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (objfile->sf
          && objfile->sf->qf->map_symtabs_matching_filename (objfile,
@@ -527,7 +553,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_no_tag (type);
+  const char *newname = TYPE_NAME (type);
 
   /* Does the form of physname indicate that it is the full mangled name
      of a constructor (not just the args)?  */
@@ -675,6 +701,7 @@ symbol_set_language (struct general_symbol_info *gsymbol,
 struct demangled_name_entry
 {
   const char *mangled;
+  ENUM_BITFIELD(language) language : LANGUAGE_BITS;
   char demangled[1];
 };
 
@@ -707,14 +734,14 @@ eq_demangled_name_entry (const void *a, const void *b)
    name.  The entry is hashed via just the mangled name.  */
 
 static void
-create_demangled_names_hash (struct objfile *objfile)
+create_demangled_names_hash (struct objfile_per_bfd_storage *per_bfd)
 {
   /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
      The hash table code will round this up to the next prime number.
      Choosing a much larger table size wastes memory, and saves only about
      1% in symbol reading.  */
 
-  objfile->per_bfd->demangled_names_hash = htab_create_alloc
+  per_bfd->demangled_names_hash = htab_create_alloc
     (256, hash_demangled_name_entry, eq_demangled_name_entry,
      NULL, xcalloc, xfree);
 }
@@ -772,13 +799,12 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
 void
 symbol_set_names (struct general_symbol_info *gsymbol,
                  const char *linkage_name, int len, int copy_name,
-                 struct objfile *objfile)
+                 struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
   /* A 0-terminated copy of the linkage name.  */
   const char *linkage_name_copy;
   struct demangled_name_entry entry;
-  struct objfile_per_bfd_storage *per_bfd = objfile->per_bfd;
 
   if (gsymbol->language == language_ada)
     {
@@ -801,7 +827,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
     }
 
   if (per_bfd->demangled_names_hash == NULL)
-    create_demangled_names_hash (objfile);
+    create_demangled_names_hash (per_bfd);
 
   if (linkage_name[len] != '\0')
     {
@@ -828,9 +854,10 @@ symbol_set_names (struct general_symbol_info *gsymbol,
       || (gsymbol->language == language_go
          && (*slot)->demangled[0] == '\0'))
     {
-      char *demangled_name = symbol_find_demangled_name (gsymbol,
-                                                        linkage_name_copy);
-      int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+      char *demangled_name_ptr
+       = symbol_find_demangled_name (gsymbol, linkage_name_copy);
+      gdb::unique_xmalloc_ptr<char> demangled_name (demangled_name_ptr);
+      int demangled_len = demangled_name ? strlen (demangled_name.get ()) : 0;
 
       /* Suppose we have demangled_name==NULL, copy_name==0, and
         linkage_name_copy==linkage_name.  In this case, we already have the
@@ -866,15 +893,16 @@ symbol_set_names (struct general_symbol_info *gsymbol,
          strcpy (mangled_ptr, linkage_name_copy);
          (*slot)->mangled = mangled_ptr;
        }
+      (*slot)->language = gsymbol->language;
 
       if (demangled_name != NULL)
-       {
-         strcpy ((*slot)->demangled, demangled_name);
-         xfree (demangled_name);
-       }
+       strcpy ((*slot)->demangled, demangled_name.get ());
       else
        (*slot)->demangled[0] = '\0';
     }
+  else if (gsymbol->language == language_unknown
+          || gsymbol->language == language_auto)
+    gsymbol->language = (*slot)->language;
 
   gsymbol->name = (*slot)->mangled;
   if ((*slot)->demangled[0] != '\0')
@@ -955,8 +983,7 @@ symbol_matches_search_name (const struct general_symbol_info *gsymbol,
                            const lookup_name_info &name)
 {
   symbol_name_matcher_ftype *name_match
-    = language_get_symbol_name_matcher (language_def (gsymbol->language),
-                                       name);
+    = get_symbol_name_matcher (language_def (gsymbol->language), name);
   return name_match (symbol_search_name (gsymbol), name, NULL);
 }
 
@@ -972,7 +999,6 @@ matching_obj_sections (struct obj_section *obj_first,
 {
   asection *first = obj_first? obj_first->the_bfd_section : NULL;
   asection *second = obj_second? obj_second->the_bfd_section : NULL;
-  struct objfile *obj;
 
   /* If they're the same section, then they match.  */
   if (first == second)
@@ -1012,9 +1038,13 @@ matching_obj_sections (struct obj_section *obj_first,
 
   /* Otherwise check that they are in corresponding objfiles.  */
 
-  ALL_OBJFILES (obj)
-    if (obj->obfd == first->owner)
-      break;
+  struct objfile *obj = NULL;
+  for (objfile *objfile : current_program_space->objfiles ())
+    if (objfile->obfd == first->owner)
+      {
+       obj = objfile;
+       break;
+      }
   gdb_assert (obj != NULL);
 
   if (obj->separate_debug_objfile != NULL
@@ -1032,31 +1062,25 @@ matching_obj_sections (struct obj_section *obj_first,
 void
 expand_symtab_containing_pc (CORE_ADDR pc, struct obj_section *section)
 {
-  struct objfile *objfile;
   struct bound_minimal_symbol msymbol;
 
   /* If we know that this is not a text address, return failure.  This is
      necessary because we loop based on texthigh and textlow, which do
      not include the data ranges.  */
   msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
-  if (msymbol.minsym
-      && (MSYMBOL_TYPE (msymbol.minsym) == mst_data
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_bss
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_abs
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_file_data
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_file_bss))
+  if (msymbol.minsym && msymbol.minsym->data_p ())
     return;
 
-  ALL_OBJFILES (objfile)
-  {
-    struct compunit_symtab *cust = NULL;
+  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);
-    if (cust)
-      return;
-  }
+      if (objfile->sf)
+       cust = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile, msymbol,
+                                                             pc, section, 0);
+      if (cust)
+       return;
+    }
 }
 \f
 /* Hash function for the symbol cache.  */
@@ -1746,7 +1770,7 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
       addr = SYMBOL_VALUE_ADDRESS (sym);
       break;
     case LOC_BLOCK:
-      addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      addr = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
       break;
 
     default:
@@ -2141,12 +2165,12 @@ lookup_local_symbol (const char *name,
 
       if (language == language_cplus || language == language_fortran)
         {
-          struct block_symbol sym
+          struct block_symbol blocksym
            = cp_lookup_symbol_imports_or_template (scope, name, block,
                                                    domain);
 
-          if (sym.symbol != NULL)
-            return sym;
+          if (blocksym.symbol != NULL)
+            return blocksym;
         }
 
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
@@ -2164,23 +2188,23 @@ lookup_local_symbol (const char *name,
 struct objfile *
 lookup_objfile_from_block (const struct block *block)
 {
-  struct objfile *obj;
-  struct compunit_symtab *cust;
-
   if (block == NULL)
     return NULL;
 
   block = block_global_block (block);
   /* Look through all blockvectors.  */
-  ALL_COMPUNITS (obj, cust)
-    if (block == BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
-                                   GLOBAL_BLOCK))
-      {
-       if (obj->separate_debug_objfile_backlink)
-         obj = obj->separate_debug_objfile_backlink;
+  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 obj;
+         }
+    }
 
   return NULL;
 }
@@ -2253,8 +2277,6 @@ static struct block_symbol
 lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
                                  const char *name, const domain_enum domain)
 {
-  struct compunit_symtab *cust;
-
   gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
 
   if (symbol_lookup_debug > 1)
@@ -2267,7 +2289,7 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
                          name, domain_name (domain));
     }
 
-  ALL_OBJFILE_COMPUNITS (objfile, cust)
+  for (compunit_symtab *cust : objfile->compunits ())
     {
       const struct blockvector *bv;
       const struct block *block;
@@ -2303,7 +2325,7 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
    Normally we only look in OBJFILE, and not any separate debug objfiles
    because the outer loop will cause them to be searched too.  This case is
    different.  Here we're called from search_symbols where it will only
-   call us for the the objfile that contains a matching minsym.  */
+   call us for the objfile that contains a matching minsym.  */
 
 static struct block_symbol
 lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
@@ -2575,7 +2597,6 @@ struct block_symbol
 lookup_static_symbol (const char *name, const domain_enum domain)
 {
   struct symbol_cache *cache = get_symbol_cache (current_program_space);
-  struct objfile *objfile;
   struct block_symbol result;
   struct block_symbol_cache *bsc;
   struct symbol_cache_slot *slot;
@@ -2591,7 +2612,7 @@ lookup_static_symbol (const char *name, const domain_enum domain)
       return result;
     }
 
-  ALL_OBJFILES (objfile)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       result = lookup_symbol_in_objfile (objfile, STATIC_BLOCK, name, domain);
       if (result.symbol != NULL)
@@ -2762,12 +2783,11 @@ static struct type *
 basic_lookup_transparent_type_1 (struct objfile *objfile, int block_index,
                                 const char *name)
 {
-  const struct compunit_symtab *cust;
   const struct blockvector *bv;
   const struct block *block;
   const struct symbol *sym;
 
-  ALL_OBJFILE_COMPUNITS (objfile, cust)
+  for (compunit_symtab *cust : objfile->compunits ())
     {
       bv = COMPUNIT_BLOCKVECTOR (cust);
       block = BLOCKVECTOR_BLOCK (bv, block_index);
@@ -2792,7 +2812,6 @@ basic_lookup_transparent_type_1 (struct objfile *objfile, int block_index,
 struct type *
 basic_lookup_transparent_type (const char *name)
 {
-  struct objfile *objfile;
   struct type *t;
 
   /* Now search all the global symbols.  Do the symtab's first, then
@@ -2800,19 +2819,19 @@ basic_lookup_transparent_type (const char *name)
      of the desired name as a global, then do psymtab-to-symtab
      conversion on the fly and return the found symbol.  */
 
-  ALL_OBJFILES (objfile)
-  {
-    t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK, name);
-    if (t)
-      return t;
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK, name);
+      if (t)
+       return t;
+    }
 
-  ALL_OBJFILES (objfile)
-  {
-    t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK, name);
-    if (t)
-      return t;
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK, name);
+      if (t)
+       return t;
+    }
 
   /* Now search the static file-level symbols.
      Not strictly correct, but more useful than an error.
@@ -2821,19 +2840,19 @@ basic_lookup_transparent_type (const char *name)
      of the desired name as a file-level static, then do psymtab-to-symtab
      conversion on the fly and return the found symbol.  */
 
-  ALL_OBJFILES (objfile)
-  {
-    t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK, name);
-    if (t)
-      return t;
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK, name);
+      if (t)
+       return t;
+    }
 
-  ALL_OBJFILES (objfile)
-  {
-    t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK, name);
-    if (t)
-      return t;
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK, name);
+      if (t)
+       return t;
+    }
 
   return (struct type *) 0;
 }
@@ -2860,7 +2879,9 @@ iterate_over_symbols (const struct block *block,
       if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
                                 SYMBOL_DOMAIN (sym), domain))
        {
-         if (!callback (sym))
+         struct block_symbol block_sym = {sym, block};
+
+         if (!callback (&block_sym))
            return;
        }
     }
@@ -2872,9 +2893,7 @@ iterate_over_symbols (const struct block *block,
 struct compunit_symtab *
 find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
 {
-  struct compunit_symtab *cust;
   struct compunit_symtab *best_cust = NULL;
-  struct objfile *objfile;
   CORE_ADDR distance = 0;
   struct bound_minimal_symbol msymbol;
 
@@ -2884,12 +2903,7 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
      we call find_pc_sect_psymtab which has a similar restriction based
      on the partial_symtab's texthigh and textlow.  */
   msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
-  if (msymbol.minsym
-      && (MSYMBOL_TYPE (msymbol.minsym) == mst_data
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_bss
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_abs
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_file_data
-         || MSYMBOL_TYPE (msymbol.minsym) == mst_file_bss))
+  if (msymbol.minsym && msymbol.minsym->data_p ())
     return NULL;
 
   /* Search all symtabs for the one whose file contains our address, and which
@@ -2907,76 +2921,81 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
      It also happens for objfiles that have their functions reordered.
      For these, the symtab we are looking for is not necessarily read in.  */
 
-  ALL_COMPUNITS (objfile, cust)
-  {
-    struct block *b;
-    const struct blockvector *bv;
-
-    bv = COMPUNIT_BLOCKVECTOR (cust);
-    b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+  for (objfile *obj_file : current_program_space->objfiles ())
+    {
+      for (compunit_symtab *cust : obj_file->compunits ())
+       {
+         struct block *b;
+         const struct blockvector *bv;
 
-    if (BLOCK_START (b) <= pc
-       && BLOCK_END (b) > pc
-       && (distance == 0
-           || BLOCK_END (b) - BLOCK_START (b) < distance))
-      {
-       /* 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 ((objfile->flags & OBJF_REORDERED) && objfile->sf)
-         {
-           struct compunit_symtab *result;
-
-           result
-             = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
-                                                              msymbol,
-                                                              pc, section,
-                                                              0);
-           if (result != NULL)
-             return result;
-         }
-       if (section != 0)
-         {
-           struct block_iterator iter;
-           struct symbol *sym = NULL;
+         bv = COMPUNIT_BLOCKVECTOR (cust);
+         b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
 
-           ALL_BLOCK_SYMBOLS (b, iter, sym)
-             {
-               fixup_symbol_section (sym, objfile);
-               if (matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, sym),
-                                          section))
-                 break;
-             }
-           if (sym == NULL)
-             continue;         /* No symbol in this symtab matches
-                                  section.  */
-         }
-       distance = BLOCK_END (b) - BLOCK_START (b);
-       best_cust = cust;
-      }
-  }
+         if (BLOCK_START (b) <= pc
+             && BLOCK_END (b) > pc
+             && (distance == 0
+                 || BLOCK_END (b) - BLOCK_START (b) < distance))
+           {
+             /* 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;
+
+                 ALL_BLOCK_SYMBOLS (b, iter, sym)
+                   {
+                     fixup_symbol_section (sym, obj_file);
+                     if (matching_obj_sections (SYMBOL_OBJ_SECTION (obj_file,
+                                                                    sym),
+                                                section))
+                       break;
+                   }
+                 if (sym == NULL)
+                   continue;           /* No symbol in this symtab matches
+                                          section.  */
+               }
+             distance = BLOCK_END (b) - BLOCK_START (b);
+             best_cust = cust;
+           }
+       }
+    }
 
   if (best_cust != NULL)
     return best_cust;
 
   /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs).  */
 
-  ALL_OBJFILES (objfile)
-  {
-    struct compunit_symtab *result;
-
-    if (!objfile->sf)
-      continue;
-    result = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
-                                                           msymbol,
-                                                           pc, section,
-                                                           1);
-    if (result != NULL)
-      return result;
-  }
+  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);
+      if (result != NULL)
+       return result;
+    }
 
   return NULL;
 }
@@ -2996,35 +3015,33 @@ find_pc_compunit_symtab (CORE_ADDR pc)
 struct symbol *
 find_symbol_at_address (CORE_ADDR address)
 {
-  struct objfile *objfile;
-
-  ALL_OBJFILES (objfile)
-  {
-    if (objfile->sf == NULL
-       || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
-      continue;
-
-    struct compunit_symtab *symtab
-      = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address);
-    if (symtab != NULL)
-      {
-       const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      if (objfile->sf == NULL
+         || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
+       continue;
 
-       for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
-         {
-           struct block *b = BLOCKVECTOR_BLOCK (bv, i);
-           struct block_iterator iter;
-           struct symbol *sym;
+      struct compunit_symtab *symtab
+       = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address);
+      if (symtab != NULL)
+       {
+         const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
 
-           ALL_BLOCK_SYMBOLS (b, iter, sym)
+         for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
            {
-             if (SYMBOL_CLASS (sym) == LOC_STATIC
-                 && SYMBOL_VALUE_ADDRESS (sym) == address)
-               return sym;
+             struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+             struct block_iterator iter;
+             struct symbol *sym;
+
+             ALL_BLOCK_SYMBOLS (b, iter, sym)
+               {
+                 if (SYMBOL_CLASS (sym) == LOC_STATIC
+                     && SYMBOL_VALUE_ADDRESS (sym) == address)
+                   return sym;
+               }
            }
-         }
-      }
-  }
+       }
+    }
 
   return NULL;
 }
@@ -3046,16 +3063,12 @@ find_symbol_at_address (CORE_ADDR address)
    find the one whose first PC is closer than that of the next line in this
    symtab.  */
 
-/* If it's worth the effort, we could be using a binary search.  */
-
 struct symtab_and_line
 find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 {
   struct compunit_symtab *cust;
-  struct symtab *iter_s;
   struct linetable *l;
   int len;
-  int i;
   struct linetable_entry *item;
   const struct blockvector *bv;
   struct bound_minimal_symbol msymbol;
@@ -3190,7 +3203,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
      They all have the same apriori range, that we found was right;
      but they have different line tables.  */
 
-  ALL_COMPUNIT_FILETABS (cust, iter_s)
+  for (symtab *iter_s : compunit_filetabs (cust))
     {
       /* Find the best line in this symtab.  */
       l = SYMTAB_LINETABLE (iter_s);
@@ -3214,15 +3227,17 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       if (item->pc > pc && (!alt || item->pc < alt->pc))
        alt = item;
 
-      for (i = 0; i < len; i++, item++)
-       {
-         /* Leave prev pointing to the linetable entry for the last line
-            that started at or before PC.  */
-         if (item->pc > pc)
-           break;
+      auto pc_compare = [](const CORE_ADDR & comp_pc,
+                          const struct linetable_entry & lhs)->bool
+      {
+       return comp_pc < lhs.pc;
+      };
 
-         prev = item;
-       }
+      struct linetable_entry *first = item;
+      struct linetable_entry *last = item + len;
+      item = std::upper_bound (first, last, pc, pc_compare);
+      if (item != first)
+       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
@@ -3245,10 +3260,10 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
        }
 
       /* If another line (denoted by ITEM) is in the linetable and its
-         PC is after BEST's PC, but before the current BEST_END, then
+        PC is after BEST's PC, but before the current BEST_END, then
         use ITEM's PC as the new best_end.  */
-      if (best && i < len && item->pc > best->pc
-          && (best_end == 0 || best_end > item->pc))
+      if (best && item < last && item->pc > best->pc
+         && (best_end == 0 || best_end > item->pc))
        best_end = item->pc;
     }
 
@@ -3320,7 +3335,7 @@ find_pc_line_symtab (CORE_ADDR pc)
    If not found, return NULL.  */
 
 struct symtab *
-find_line_symtab (struct symtab *symtab, int line,
+find_line_symtab (struct symtab *sym_tab, int line,
                  int *index, int *exact_match)
 {
   int exact = 0;  /* Initialized here to avoid a compiler warning.  */
@@ -3333,8 +3348,8 @@ find_line_symtab (struct symtab *symtab, int line,
   struct symtab *best_symtab;
 
   /* First try looking it up in the given symtab.  */
-  best_linetable = SYMTAB_LINETABLE (symtab);
-  best_symtab = symtab;
+  best_linetable = SYMTAB_LINETABLE (sym_tab);
+  best_symtab = sym_tab;
   best_index = find_line_common (best_linetable, line, &exact, 0);
   if (best_index < 0 || !exact)
     {
@@ -3350,52 +3365,54 @@ find_line_symtab (struct symtab *symtab, int line,
          BEST_INDEX and BEST_LINETABLE identify the item for it.  */
       int best;
 
-      struct objfile *objfile;
-      struct compunit_symtab *cu;
-      struct symtab *s;
-
       if (best_index >= 0)
        best = best_linetable->item[best_index].line;
       else
        best = 0;
 
-      ALL_OBJFILES (objfile)
-      {
-       if (objfile->sf)
-         objfile->sf->qf->expand_symtabs_with_fullname (objfile,
-                                                  symtab_to_fullname (symtab));
-      }
-
-      ALL_FILETABS (objfile, cu, s)
-      {
-       struct linetable *l;
-       int ind;
+      for (objfile *objfile : current_program_space->objfiles ())
+       {
+         if (objfile->sf)
+           objfile->sf->qf->expand_symtabs_with_fullname
+             (objfile, symtab_to_fullname (sym_tab));
+       }
 
-       if (FILENAME_CMP (symtab->filename, s->filename) != 0)
-         continue;
-       if (FILENAME_CMP (symtab_to_fullname (symtab),
-                         symtab_to_fullname (s)) != 0)
-         continue;     
-       l = SYMTAB_LINETABLE (s);
-       ind = find_line_common (l, line, &exact, 0);
-       if (ind >= 0)
-         {
-           if (exact)
-             {
-               best_index = ind;
-               best_linetable = l;
-               best_symtab = s;
-               goto done;
-             }
-           if (best == 0 || l->item[ind].line < best)
-             {
-               best = l->item[ind].line;
-               best_index = ind;
-               best_linetable = l;
-               best_symtab = s;
-             }
-         }
-      }
+      for (objfile *objfile : current_program_space->objfiles ())
+       {
+         for (compunit_symtab *cu : objfile->compunits ())
+           {
+             for (symtab *s : compunit_filetabs (cu))
+               {
+                 struct linetable *l;
+                 int ind;
+
+                 if (FILENAME_CMP (sym_tab->filename, s->filename) != 0)
+                   continue;
+                 if (FILENAME_CMP (symtab_to_fullname (sym_tab),
+                                   symtab_to_fullname (s)) != 0)
+                   continue;   
+                 l = SYMTAB_LINETABLE (s);
+                 ind = find_line_common (l, line, &exact, 0);
+                 if (ind >= 0)
+                   {
+                     if (exact)
+                       {
+                         best_index = ind;
+                         best_linetable = l;
+                         best_symtab = s;
+                         goto done;
+                       }
+                     if (best == 0 || l->item[ind].line < best)
+                       {
+                         best = l->item[ind].line;
+                         best_index = ind;
+                         best_linetable = l;
+                         best_symtab = s;
+                       }
+                   }
+               }
+           }
+       }
     }
 done:
   if (best_index < 0)
@@ -3575,46 +3592,37 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
   return sal.symtab != 0;
 }
 
-/* Given a function symbol SYM, find the symtab and line for the start
-   of the function.
-   If the argument FUNFIRSTLINE is nonzero, we want the first line
-   of real code inside the function.
-   This function should return SALs matching those from minsym_found,
-   otherwise false multiple-locations breakpoints could be placed.  */
+/* Helper for find_function_start_sal.  Does most of the work, except
+   setting the sal's symbol.  */
 
-struct symtab_and_line
-find_function_start_sal (struct symbol *sym, int funfirstline)
+static symtab_and_line
+find_function_start_sal_1 (CORE_ADDR func_addr, obj_section *section,
+                          bool funfirstline)
 {
-  fixup_symbol_section (sym, NULL);
-
-  obj_section *section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
-  symtab_and_line sal
-    = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), section, 0);
-  sal.symbol = sym;
+  symtab_and_line sal = find_pc_sect_line (func_addr, section, 0);
 
   if (funfirstline && sal.symtab != NULL
       && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
          || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
     {
-      struct gdbarch *gdbarch = symbol_arch (sym);
+      struct gdbarch *gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
 
-      sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      sal.pc = func_addr;
       if (gdbarch_skip_entrypoint_p (gdbarch))
        sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
       return sal;
     }
 
   /* We always should have a line for the function start address.
-     If we don't, something is odd.  Create a plain SAL refering
+     If we don't, something is odd.  Create a plain SAL referring
      just the PC and hope that skip_prologue_sal (if requested)
      can find a line number for after the prologue.  */
-  if (sal.pc < BLOCK_START (SYMBOL_BLOCK_VALUE (sym)))
+  if (sal.pc < func_addr)
     {
       sal = {};
       sal.pspace = current_program_space;
-      sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      sal.pc = func_addr;
       sal.section = section;
-      sal.symbol = sym;
     }
 
   if (funfirstline)
@@ -3623,6 +3631,38 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
   return sal;
 }
 
+/* See symtab.h.  */
+
+symtab_and_line
+find_function_start_sal (CORE_ADDR func_addr, obj_section *section,
+                        bool funfirstline)
+{
+  symtab_and_line sal
+    = find_function_start_sal_1 (func_addr, section, funfirstline);
+
+  /* find_function_start_sal_1 does a linetable search, so it finds
+     the symtab and linenumber, but not a symbol.  Fill in the
+     function symbol too.  */
+  sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section);
+
+  return sal;
+}
+
+/* See symtab.h.  */
+
+symtab_and_line
+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),
+                                funfirstline);
+  sal.symbol = sym;
+  return sal;
+}
+
+
 /* Given a function start address FUNC_ADDR and SYMTAB, find the first
    address for that function that has an entry in SYMTAB's line info
    table.  If such an entry cannot be found, return FUNC_ADDR
@@ -3695,7 +3735,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
       fixup_symbol_section (sym, NULL);
 
       objfile = symbol_objfile (sym);
-      pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      pc = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
       section = SYMBOL_OBJ_SECTION (objfile, sym);
       name = SYMBOL_LINKAGE_NAME (sym);
     }
@@ -3756,7 +3796,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
       /* Check if gdbarch_skip_prologue left us in mid-line, and the next
         line is still part of the same function.  */
       if (skip && start_sal.pc != pc
-         && (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
+         && (sym ? (BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
                     && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
              : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym
                 == lookup_minimal_symbol_by_pc_section (pc, section).minsym)))
@@ -3960,7 +4000,7 @@ find_function_alias_target (bound_minimal_symbol msymbol)
   symbol *sym = find_pc_function (func_addr);
   if (sym != NULL
       && SYMBOL_CLASS (sym) == LOC_BLOCK
-      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == func_addr)
+      && BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) == func_addr)
     return sym;
 
   return NULL;
@@ -4147,7 +4187,7 @@ output_source_filename (const char *name,
   data->first = 0;
 
   wrap_here ("");
-  fputs_filtered (name, gdb_stdout);
+  fputs_styled (name, file_name_style.style (), gdb_stdout);
 }
 
 /* A callback for map_partial_symbol_filenames.  */
@@ -4163,9 +4203,6 @@ output_partial_symbol_filename (const char *filename, const char *fullname,
 static void
 info_sources_command (const char *ignore, int from_tty)
 {
-  struct compunit_symtab *cu;
-  struct symtab *s;
-  struct objfile *objfile;
   struct output_source_filename_data data;
 
   if (!have_full_symbols () && !have_partial_symbols ())
@@ -4180,12 +4217,18 @@ info_sources_command (const char *ignore, int from_tty)
   printf_filtered ("Source files for which symbols have been read in:\n\n");
 
   data.first = 1;
-  ALL_FILETABS (objfile, cu, s)
-  {
-    const char *fullname = symtab_to_fullname (s);
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      for (compunit_symtab *cu : objfile->compunits ())
+       {
+         for (symtab *s : compunit_filetabs (cu))
+           {
+             const char *fullname = symtab_to_fullname (s);
 
-    output_source_filename (fullname, &data);
-  }
+             output_source_filename (fullname, &data);
+           }
+       }
+    }
   printf_filtered ("\n\n");
 
   printf_filtered ("Source files for which symbols "
@@ -4242,6 +4285,49 @@ symbol_search::compare_search_syms (const symbol_search &sym_a,
                 SYMBOL_PRINT_NAME (sym_b.symbol));
 }
 
+/* Returns true if the type_name of symbol_type of SYM matches TREG.
+   If SYM has no symbol_type or symbol_name, returns false.  */
+
+bool
+treg_matches_sym_type_name (const compiled_regex &treg,
+                           const struct symbol *sym)
+{
+  struct type *sym_type;
+  std::string printed_sym_type_name;
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "treg_matches_sym_type_name\n     sym %s\n",
+                         SYMBOL_NATURAL_NAME (sym));
+    }
+
+  sym_type = SYMBOL_TYPE (sym);
+  if (sym_type == NULL)
+    return false;
+
+  {
+    scoped_switch_to_sym_language_if_auto l (sym);
+
+    printed_sym_type_name = type_to_string (sym_type);
+  }
+
+
+  if (symbol_lookup_debug > 1)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "     sym_type_name %s\n",
+                         printed_sym_type_name.c_str ());
+    }
+
+
+  if (printed_sym_type_name.empty ())
+    return false;
+
+  return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0;
+}
+
+
 /* Sort the symbols in RESULT and remove duplicates.  */
 
 static void
@@ -4257,7 +4343,9 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
    Only symbols of KIND are searched:
    VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
-                      and constants (enums)
+                      and constants (enums).
+                     if T_REGEXP is not NULL, only returns var that have
+                     a type matching regular expression T_REGEXP.
    FUNCTIONS_DOMAIN - search all functions
    TYPES_DOMAIN     - search all type names
    ALL_DOMAIN       - an internal error for this function
@@ -4268,16 +4356,14 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
 std::vector<symbol_search>
 search_symbols (const char *regexp, enum search_domain kind,
+               const char *t_regexp,
                int nfiles, const char *files[])
 {
-  struct compunit_symtab *cust;
   const struct blockvector *bv;
   struct block *b;
   int i = 0;
   struct block_iterator iter;
   struct symbol *sym;
-  struct objfile *objfile;
-  struct minimal_symbol *msymbol;
   int found_misc = 0;
   static const enum minimal_symbol_type types[]
     = {mst_data, mst_text, mst_abs};
@@ -4293,6 +4379,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   enum minimal_symbol_type ourtype4;
   std::vector<symbol_search> result;
   gdb::optional<compiled_regex> preg;
+  gdb::optional<compiled_regex> treg;
 
   gdb_assert (kind <= TYPES_DOMAIN);
 
@@ -4342,6 +4429,13 @@ search_symbols (const char *regexp, enum search_domain kind,
       preg.emplace (regexp, cflags, _("Invalid regexp"));
     }
 
+  if (t_regexp != NULL)
+    {
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+                               ? REG_ICASE : 0);
+      treg.emplace (t_regexp, cflags, _("Invalid regexp"));
+    }
+
   /* Search through the partial symtabs *first* for all symbols
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below.  */
@@ -4353,8 +4447,9 @@ search_symbols (const char *regexp, enum search_domain kind,
                           lookup_name_info::match_any (),
                           [&] (const char *symname)
                           {
-                            return (!preg || preg->exec (symname,
-                                                         0, NULL, 0) == 0);
+                            return (!preg.has_value ()
+                                    || preg->exec (symname,
+                                                   0, NULL, 0) == 0);
                           },
                           NULL,
                           kind);
@@ -4377,122 +4472,147 @@ search_symbols (const char *regexp, enum search_domain kind,
 
   if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN))
     {
-      ALL_MSYMBOLS (objfile, msymbol)
-      {
-        QUIT;
+      for (objfile *objfile : current_program_space->objfiles ())
+       {
+         for (minimal_symbol *msymbol : objfile->msymbols ())
+           {
+             QUIT;
 
-       if (msymbol->created_by_gdb)
-         continue;
+             if (msymbol->created_by_gdb)
+               continue;
 
-       if (MSYMBOL_TYPE (msymbol) == ourtype
-           || MSYMBOL_TYPE (msymbol) == ourtype2
-           || MSYMBOL_TYPE (msymbol) == ourtype3
-           || MSYMBOL_TYPE (msymbol) == ourtype4)
-         {
-           if (!preg
-               || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
-                              NULL, 0) == 0)
-             {
-               /* Note: An important side-effect of these lookup functions
-                  is to expand the symbol table if msymbol is found, for the
-                  benefit of the next loop on ALL_COMPUNITS.  */
-               if (kind == FUNCTIONS_DOMAIN
-                   ? (find_pc_compunit_symtab
-                      (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL)
-                   : (lookup_symbol_in_objfile_from_linkage_name
-                      (objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
-                      .symbol == NULL))
-                 found_misc = 1;
-             }
-         }
-      }
+             if (MSYMBOL_TYPE (msymbol) == ourtype
+                 || MSYMBOL_TYPE (msymbol) == ourtype2
+                 || MSYMBOL_TYPE (msymbol) == ourtype3
+                 || MSYMBOL_TYPE (msymbol) == ourtype4)
+               {
+                 if (!preg.has_value ()
+                     || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+                                    NULL, 0) == 0)
+                   {
+                     /* Note: An important side-effect of these
+                        lookup functions is to expand the symbol
+                        table if msymbol is found, for the benefit of
+                        the next loop on compunits.  */
+                     if (kind == FUNCTIONS_DOMAIN
+                         ? (find_pc_compunit_symtab
+                            (MSYMBOL_VALUE_ADDRESS (objfile, msymbol))
+                            == NULL)
+                         : (lookup_symbol_in_objfile_from_linkage_name
+                            (objfile, MSYMBOL_LINKAGE_NAME (msymbol),
+                             VAR_DOMAIN)
+                            .symbol == NULL))
+                       found_misc = 1;
+                   }
+               }
+           }
+       }
     }
 
-  ALL_COMPUNITS (objfile, cust)
-  {
-    bv = COMPUNIT_BLOCKVECTOR (cust);
-    for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
-      {
-       b = BLOCKVECTOR_BLOCK (bv, i);
-       ALL_BLOCK_SYMBOLS (b, iter, sym)
-         {
-           struct symtab *real_symtab = symbol_symtab (sym);
-
-           QUIT;
-
-           /* Check first sole REAL_SYMTAB->FILENAME.  It does not need to be
-              a substring of symtab_to_fullname as it may contain "./" etc.  */
-           if ((file_matches (real_symtab->filename, files, nfiles, 0)
-                || ((basenames_may_differ
-                     || file_matches (lbasename (real_symtab->filename),
-                                      files, nfiles, 1))
-                    && file_matches (symtab_to_fullname (real_symtab),
-                                     files, nfiles, 0)))
-               && ((!preg
-                    || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
-                                   NULL, 0) == 0)
-                   && ((kind == VARIABLES_DOMAIN
-                        && SYMBOL_CLASS (sym) != LOC_TYPEDEF
-                        && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
-                        && SYMBOL_CLASS (sym) != LOC_BLOCK
-                        /* LOC_CONST can be used for more than just enums,
-                           e.g., c++ static const members.
-                           We only want to skip enums here.  */
-                        && !(SYMBOL_CLASS (sym) == LOC_CONST
-                             && (TYPE_CODE (SYMBOL_TYPE (sym))
-                                 == TYPE_CODE_ENUM)))
-                       || (kind == FUNCTIONS_DOMAIN 
-                           && SYMBOL_CLASS (sym) == LOC_BLOCK)
-                       || (kind == TYPES_DOMAIN
-                           && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
-             {
-               /* match */
-               result.emplace_back (i, sym);
-             }
-         }
-      }
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      for (compunit_symtab *cust : objfile->compunits ())
+       {
+         bv = COMPUNIT_BLOCKVECTOR (cust);
+         for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+           {
+             b = BLOCKVECTOR_BLOCK (bv, i);
+             ALL_BLOCK_SYMBOLS (b, iter, sym)
+               {
+                 struct symtab *real_symtab = symbol_symtab (sym);
+
+                 QUIT;
+
+                 /* Check first sole REAL_SYMTAB->FILENAME.  It does
+                    not need to be a substring of symtab_to_fullname as
+                    it may contain "./" etc.  */
+                 if ((file_matches (real_symtab->filename, files, nfiles, 0)
+                      || ((basenames_may_differ
+                           || file_matches (lbasename (real_symtab->filename),
+                                            files, nfiles, 1))
+                          && file_matches (symtab_to_fullname (real_symtab),
+                                           files, nfiles, 0)))
+                     && ((!preg.has_value ()
+                          || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+                                         NULL, 0) == 0)
+                         && ((kind == VARIABLES_DOMAIN
+                              && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+                              && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
+                              && SYMBOL_CLASS (sym) != LOC_BLOCK
+                              /* LOC_CONST can be used for more than
+                                 just enums, e.g., c++ static const
+                                 members.  We only want to skip enums
+                                 here.  */
+                              && !(SYMBOL_CLASS (sym) == LOC_CONST
+                                   && (TYPE_CODE (SYMBOL_TYPE (sym))
+                                       == TYPE_CODE_ENUM))
+                              && (!treg.has_value ()
+                                  || treg_matches_sym_type_name (*treg, sym)))
+                             || (kind == FUNCTIONS_DOMAIN
+                                 && SYMBOL_CLASS (sym) == LOC_BLOCK
+                                 && (!treg.has_value ()
+                                     || treg_matches_sym_type_name (*treg,
+                                                                    sym)))
+                             || (kind == TYPES_DOMAIN
+                                 && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
+                   {
+                     /* match */
+                     result.emplace_back (i, sym);
+                   }
+               }
+           }
+       }
+    }
 
   if (!result.empty ())
     sort_search_symbols_remove_dups (&result);
 
   /* If there are no eyes, avoid all contact.  I mean, if there are
-     no debug symbols, then add matching minsyms.  */
+     no debug symbols, then add matching minsyms.  But if the user wants
+     to see symbols matching a type regexp, then never give a minimal symbol,
+     as we assume that a minimal symbol does not have a type.  */
 
-  if (found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
+  if ((found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
+      && !treg.has_value ())
     {
-      ALL_MSYMBOLS (objfile, msymbol)
-      {
-        QUIT;
+      for (objfile *objfile : current_program_space->objfiles ())
+       {
+         for (minimal_symbol *msymbol : objfile->msymbols ())
+           {
+             QUIT;
 
-       if (msymbol->created_by_gdb)
-         continue;
+             if (msymbol->created_by_gdb)
+               continue;
 
-       if (MSYMBOL_TYPE (msymbol) == ourtype
-           || MSYMBOL_TYPE (msymbol) == ourtype2
-           || MSYMBOL_TYPE (msymbol) == ourtype3
-           || MSYMBOL_TYPE (msymbol) == ourtype4)
-         {
-           if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+             if (MSYMBOL_TYPE (msymbol) == ourtype
+                 || MSYMBOL_TYPE (msymbol) == ourtype2
+                 || MSYMBOL_TYPE (msymbol) == ourtype3
+                 || MSYMBOL_TYPE (msymbol) == ourtype4)
+               {
+                 if (!preg.has_value ()
+                     || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
                                     NULL, 0) == 0)
-             {
-               /* For functions we can do a quick check of whether the
-                  symbol might be found via find_pc_symtab.  */
-               if (kind != FUNCTIONS_DOMAIN
-                   || (find_pc_compunit_symtab
-                       (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL))
-                 {
-                   if (lookup_symbol_in_objfile_from_linkage_name
-                       (objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
-                       .symbol == NULL)
-                     {
-                       /* match */
-                       result.emplace_back (i, msymbol, objfile);
-                     }
-                 }
-             }
-         }
-      }
+                   {
+                     /* For functions we can do a quick check of whether the
+                        symbol might be found via find_pc_symtab.  */
+                     if (kind != FUNCTIONS_DOMAIN
+                         || (find_pc_compunit_symtab
+                             (MSYMBOL_VALUE_ADDRESS (objfile, msymbol))
+                             == NULL))
+                       {
+                         if (lookup_symbol_in_objfile_from_linkage_name
+                             (objfile, MSYMBOL_LINKAGE_NAME (msymbol),
+                              VAR_DOMAIN)
+                             .symbol == NULL)
+                           {
+                             /* match */
+                             result.emplace_back (i, msymbol, objfile);
+                           }
+                       }
+                   }
+               }
+           }
+       }
     }
 
   return result;
@@ -4500,21 +4620,33 @@ search_symbols (const char *regexp, enum search_domain kind,
 
 /* Helper function for symtab_symbol_info, this function uses
    the data returned from search_symbols() to print information
-   regarding the match to gdb_stdout.  */
+   regarding the match to gdb_stdout.  If LAST is not NULL,
+   print file and line number information for the symbol as
+   well.  Skip printing the filename if it matches LAST.  */
 
 static void
 print_symbol_info (enum search_domain kind,
                   struct symbol *sym,
                   int block, const char *last)
 {
+  scoped_switch_to_sym_language_if_auto l (sym);
   struct symtab *s = symbol_symtab (sym);
-  const char *s_filename = symtab_to_filename_for_display (s);
 
-  if (last == NULL || filename_cmp (last, s_filename) != 0)
+  if (last != NULL)
     {
-      fputs_filtered ("\nFile ", gdb_stdout);
-      fputs_filtered (s_filename, gdb_stdout);
-      fputs_filtered (":\n", gdb_stdout);
+      const char *s_filename = symtab_to_filename_for_display (s);
+
+      if (filename_cmp (last, s_filename) != 0)
+       {
+         fputs_filtered ("\nFile ", gdb_stdout);
+         fputs_styled (s_filename, file_name_style.style (), gdb_stdout);
+         fputs_filtered (":\n", gdb_stdout);
+       }
+
+      if (SYMBOL_LINE (sym) != 0)
+       printf_filtered ("%d:\t", SYMBOL_LINE (sym));
+      else
+       puts_filtered ("\t");
     }
 
   if (kind != TYPES_DOMAIN && block == STATIC_BLOCK)
@@ -4554,8 +4686,15 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
   else
     tmp = hex_string_custom (BMSYMBOL_VALUE_ADDRESS (msymbol),
                             16);
-  printf_filtered ("%s  %s\n",
-                  tmp, MSYMBOL_PRINT_NAME (msymbol.minsym));
+  fputs_styled (tmp, address_style.style (), gdb_stdout);
+  fputs_filtered ("  ", gdb_stdout);
+  if (msymbol.minsym->text_p ())
+    fputs_styled (MSYMBOL_PRINT_NAME (msymbol.minsym),
+                 function_name_style.style (),
+                 gdb_stdout);
+  else
+    fputs_filtered (MSYMBOL_PRINT_NAME (msymbol.minsym), gdb_stdout);
+  fputs_filtered ("\n", gdb_stdout);
 }
 
 /* This is the guts of the commands "info functions", "info types", and
@@ -4564,23 +4703,45 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
    matches.  */
 
 static void
-symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
+symtab_symbol_info (bool quiet,
+                   const char *regexp, enum search_domain kind,
+                   const char *t_regexp, int from_tty)
 {
   static const char * const classnames[] =
     {"variable", "function", "type"};
-  const char *last_filename = NULL;
+  const char *last_filename = "";
   int first = 1;
 
   gdb_assert (kind <= TYPES_DOMAIN);
 
   /* Must make sure that if we're interrupted, symbols gets freed.  */
-  std::vector<symbol_search> symbols = search_symbols (regexp, kind, 0, NULL);
+  std::vector<symbol_search> symbols = search_symbols (regexp, kind,
+                                                      t_regexp, 0, NULL);
 
-  if (regexp != NULL)
-    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
-                    classnames[kind], regexp);
-  else
-    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+  if (!quiet)
+    {
+      if (regexp != NULL)
+       {
+         if (t_regexp != NULL)
+           printf_filtered
+             (_("All %ss matching regular expression \"%s\""
+                " with type matching regular expression \"%s\":\n"),
+              classnames[kind], regexp, t_regexp);
+         else
+           printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
+                            classnames[kind], regexp);
+       }
+      else
+       {
+         if (t_regexp != NULL)
+           printf_filtered
+             (_("All defined %ss"
+                " with type matching regular expression \"%s\" :\n"),
+              classnames[kind], t_regexp);
+         else
+           printf_filtered (_("All defined %ss:\n"), classnames[kind]);
+       }
+    }
 
   for (const symbol_search &p : symbols)
     {
@@ -4590,7 +4751,8 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
        {
          if (first)
            {
-             printf_filtered (_("\nNon-debugging symbols:\n"));
+             if (!quiet)
+               printf_filtered (_("\nNon-debugging symbols:\n"));
              first = 0;
            }
          print_msymbol_info (p.msymbol);
@@ -4608,22 +4770,53 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
 }
 
 static void
-info_variables_command (const char *regexp, int from_tty)
+info_variables_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet = false;
+
+  while (args != NULL
+        && extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
+    ;
+
+  if (args != NULL)
+    report_unrecognized_option_error ("info variables", args);
+
+  symtab_symbol_info (quiet,
+                     regexp.empty () ? NULL : regexp.c_str (),
+                     VARIABLES_DOMAIN,
+                     t_regexp.empty () ? NULL : t_regexp.c_str (),
+                     from_tty);
 }
 
+
 static void
-info_functions_command (const char *regexp, int from_tty)
+info_functions_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty);
+  std::string regexp;
+  std::string t_regexp;
+  bool quiet = false;
+
+  while (args != NULL
+        && extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
+    ;
+
+  if (args != NULL)
+    report_unrecognized_option_error ("info functions", args);
+
+  symtab_symbol_info (quiet,
+                     regexp.empty () ? NULL : regexp.c_str (),
+                     FUNCTIONS_DOMAIN,
+                     t_regexp.empty () ? NULL : t_regexp.c_str (),
+                     from_tty);
 }
 
 
 static void
 info_types_command (const char *regexp, int from_tty)
 {
-  symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty);
+  symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty);
 }
 
 /* Breakpoint all functions matching regular expression.  */
@@ -4666,6 +4859,7 @@ rbreak_command (const char *regexp, int from_tty)
 
   std::vector<symbol_search> symbols = search_symbols (regexp,
                                                       FUNCTIONS_DOMAIN,
+                                                      NULL,
                                                       nfiles, files);
 
   scoped_rbreak_breakpoints finalize;
@@ -4679,10 +4873,7 @@ rbreak_command (const char *regexp, int from_tty)
          string = string_printf ("%s:'%s'", fullname,
                                  SYMBOL_LINKAGE_NAME (p.symbol));
          break_command (&string[0], from_tty);
-         print_symbol_info (FUNCTIONS_DOMAIN,
-                            p.symbol,
-                            p.block,
-                            symtab_to_filename_for_display (symtab));
+         print_symbol_info (FUNCTIONS_DOMAIN, p.symbol, p.block, NULL);
        }
       else
        {
@@ -4704,24 +4895,10 @@ compare_symbol_name (const char *symbol_name, language symbol_language,
                     const lookup_name_info &lookup_name,
                     completion_match_result &match_res)
 {
-  const language_defn *lang;
-
-  /* If we're completing for an expression and the symbol doesn't have
-     an explicit language set, fallback to the current language.  Ada
-     minimal symbols won't have their language set to Ada, for
-     example, and if we compared using the default/C-like matcher,
-     then when completing e.g., symbols in a package named "pck", we'd
-     match internal Ada symbols like "pckS", which are invalid in an
-     Ada expression, unless you wrap them in '<' '>' to request a
-     verbatim match.  */
-  if (symbol_language == language_auto
-      && lookup_name.match_type () == symbol_name_match_type::EXPRESSION)
-    lang = current_language;
-  else
-    lang = language_def (symbol_language);
+  const language_defn *lang = language_def (symbol_language);
 
   symbol_name_matcher_ftype *name_match
-    = language_get_symbol_name_matcher (lang, lookup_name);
+    = get_symbol_name_matcher (lang, lookup_name);
 
   return name_match (symbol_name, lookup_name, &match_res);
 }
@@ -4959,6 +5136,50 @@ symbol_is_function_or_method (minimal_symbol *msymbol)
     }
 }
 
+/* See symtab.h.  */
+
+bound_minimal_symbol
+find_gnu_ifunc (const symbol *sym)
+{
+  if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+    return {};
+
+  lookup_name_info lookup_name (SYMBOL_SEARCH_NAME (sym),
+                               symbol_name_match_type::SEARCH_NAME);
+  struct objfile *objfile = symbol_objfile (sym);
+
+  CORE_ADDR address = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
+  minimal_symbol *ifunc = NULL;
+
+  iterate_over_minimal_symbols (objfile, lookup_name,
+                               [&] (minimal_symbol *minsym)
+    {
+      if (MSYMBOL_TYPE (minsym) == mst_text_gnu_ifunc
+         || MSYMBOL_TYPE (minsym) == mst_data_gnu_ifunc)
+       {
+         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 ());
+           }
+         if (msym_addr == address)
+           {
+             ifunc = minsym;
+             return true;
+           }
+       }
+      return false;
+    });
+
+  if (ifunc != NULL)
+    return {ifunc, objfile};
+  return {};
+}
+
 /* Add matching symbols from SYMTAB to the current completion list.  */
 
 static void
@@ -5008,9 +5229,6 @@ default_collect_symbol_completion_matches_break_on
      won't be that many.  */
 
   struct symbol *sym;
-  struct compunit_symtab *cust;
-  struct minimal_symbol *msymbol;
-  struct objfile *objfile;
   const struct block *b;
   const struct block *surrounding_static_block, *surrounding_global_block;
   struct block_iterator iter;
@@ -5080,25 +5298,31 @@ default_collect_symbol_completion_matches_break_on
 
   if (code == TYPE_CODE_UNDEF)
     {
-      ALL_MSYMBOLS (objfile, msymbol)
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         QUIT;
+         for (minimal_symbol *msymbol : objfile->msymbols ())
+           {
+             QUIT;
 
-         if (completion_skip_symbol (mode, msymbol))
-           continue;
+             if (completion_skip_symbol (mode, msymbol))
+               continue;
 
-         completion_list_add_msymbol (tracker, msymbol, lookup_name,
-                                      sym_text, word);
+             completion_list_add_msymbol (tracker, msymbol, lookup_name,
+                                          sym_text, word);
 
-         completion_list_objc_symbol (tracker, msymbol, lookup_name,
-                                      sym_text, word);
+             completion_list_objc_symbol (tracker, msymbol, lookup_name,
+                                          sym_text, word);
+           }
        }
     }
 
   /* Add completions for all currently loaded symbol tables.  */
-  ALL_COMPUNITS (objfile, cust)
-    add_symtab_completions (cust, tracker, mode, lookup_name,
-                           sym_text, word, code);
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      for (compunit_symtab *cust : objfile->compunits ())
+       add_symtab_completions (cust, tracker, mode, lookup_name,
+                               sym_text, word, code);
+    }
 
   /* Look through the partial symtabs for all symbols which begin by
      matching SYM_TEXT.  Expand all CUs that you find to the list.  */
@@ -5169,7 +5393,7 @@ default_collect_symbol_completion_matches_break_on
   if (current_language->la_macro_expansion == macro_expansion_c
       && code == TYPE_CODE_UNDEF)
     {
-      struct macro_scope *scope;
+      gdb::unique_xmalloc_ptr<struct macro_scope> scope;
 
       /* This adds a macro's name to the current completion list.  */
       auto add_macro_name = [&] (const char *macro_name,
@@ -5190,11 +5414,8 @@ default_collect_symbol_completion_matches_break_on
         completion time.  */
       scope = default_macro_scope ();
       if (scope)
-       {
-         macro_for_each_in_scope (scope->file, scope->line,
-                                  add_macro_name);
-         xfree (scope);
-       }
+       macro_for_each_in_scope (scope->file, scope->line,
+                                add_macro_name);
 
       /* User-defined macros are always visible.  */
       macro_for_each (macro_user_macros, add_macro_name);
@@ -5395,9 +5616,6 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
 completion_list
 make_source_files_completion_list (const char *text, const char *word)
 {
-  struct compunit_symtab *cu;
-  struct symtab *s;
-  struct objfile *objfile;
   size_t text_len = strlen (text);
   completion_list list;
   const char *base_name;
@@ -5408,28 +5626,34 @@ make_source_files_completion_list (const char *text, const char *word)
 
   filename_seen_cache filenames_seen;
 
-  ALL_FILETABS (objfile, cu, s)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
-      if (not_interesting_fname (s->filename))
-       continue;
-      if (!filenames_seen.seen (s->filename)
-         && filename_ncmp (s->filename, text, text_len) == 0)
-       {
-         /* This file matches for a completion; add it to the current
-            list of matches.  */
-         add_filename_to_list (s->filename, text, word, &list);
-       }
-      else
+      for (compunit_symtab *cu : objfile->compunits ())
        {
-         /* NOTE: We allow the user to type a base name when the
-            debug info records leading directories, but not the other
-            way around.  This is what subroutines of breakpoint
-            command do when they parse file names.  */
-         base_name = lbasename (s->filename);
-         if (base_name != s->filename
-             && !filenames_seen.seen (base_name)
-             && filename_ncmp (base_name, text, text_len) == 0)
-           add_filename_to_list (base_name, text, word, &list);
+         for (symtab *s : compunit_filetabs (cu))
+           {
+             if (not_interesting_fname (s->filename))
+               continue;
+             if (!filenames_seen.seen (s->filename)
+                 && filename_ncmp (s->filename, text, text_len) == 0)
+               {
+                 /* This file matches for a completion; add it to the current
+                    list of matches.  */
+                 add_filename_to_list (s->filename, text, word, &list);
+               }
+             else
+               {
+                 /* NOTE: We allow the user to type a base name when the
+                    debug info records leading directories, but not the other
+                    way around.  This is what subroutines of breakpoint
+                    command do when they parse file names.  */
+                 base_name = lbasename (s->filename);
+                 if (base_name != s->filename
+                     && !filenames_seen.seen (base_name)
+                     && filename_ncmp (base_name, text, text_len) == 0)
+                   add_filename_to_list (base_name, text, word, &list);
+               }
+           }
        }
     }
 
@@ -5512,7 +5736,6 @@ static void
 find_main_name (void)
 {
   const char *new_main_name;
-  struct objfile *objfile;
 
   /* First check the objfiles to see whether a debuginfo reader has
      picked up the appropriate main name.  Historically the main name
@@ -5520,15 +5743,15 @@ find_main_name (void)
      relies on the order of objfile creation -- which still isn't
      guaranteed to get the correct answer, but is just probably more
      accurate.  */
-  ALL_OBJFILES (objfile)
-  {
-    if (objfile->per_bfd->name_of_main != NULL)
-      {
-       set_main_name (objfile->per_bfd->name_of_main,
-                      objfile->per_bfd->language_of_main);
-       return;
-      }
-  }
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      if (objfile->per_bfd->name_of_main != NULL)
+       {
+         set_main_name (objfile->per_bfd->name_of_main,
+                        objfile->per_bfd->language_of_main);
+         return;
+       }
+    }
 
   /* Try to see if the main procedure is in Ada.  */
   /* FIXME: brobecker/2005-03-07: Another way of doing this would
@@ -5843,14 +6066,26 @@ _initialize_symtab (void)
   symbol_cache_key
     = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup);
 
-  add_info ("variables", info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
+  add_info ("variables", info_variables_command,
+           info_print_args_help (_("\
+All global and static variable names or those matching REGEXPs.\n\
+Usage: info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"),
+                                 _("global and static variables")));
   if (dbx_commands)
-    add_com ("whereis", class_info, info_variables_command, _("\
-All global and static variable names, or those matching REGEXP."));
+    add_com ("whereis", class_info, info_variables_command,
+            info_print_args_help (_("\
+All global and static variable names, or those matching REGEXPs.\n\
+Usage: whereis [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the global and static variables.\n"),
+                                  _("global and static variables")));
 
   add_info ("functions", info_functions_command,
-           _("All function names, or those matching REGEXP."));
+           info_print_args_help (_("\
+All function names or those matching REGEXPs.\n\
+Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Prints the functions.\n"),
+                                 _("functions")));
 
   /* FIXME:  This command has at least the following problems:
      1.  It prints builtin types (in a very strange and confusing fashion).
@@ -5934,7 +6169,7 @@ If zero then the symbol cache is disabled."),
           _("Flush the symbol cache for each program space."),
           &maintenancelist);
 
-  observer_attach_executable_changed (symtab_observer_executable_changed);
-  observer_attach_new_objfile (symtab_new_objfile_observer);
-  observer_attach_free_objfile (symtab_free_objfile_observer);
+  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);
 }