gdb/fortran: Don't include module symbols when searching for types
[deliverable/binutils-gdb.git] / gdb / symtab.c
index b32eca18faf7e7ba08ebb60d783fe070fb24bc13..88e34de05be4ff70838bc79cfb236ab37a1edb11 100644 (file)
@@ -41,6 +41,7 @@
 #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 "parser-defs.h"
 #include "completer.h"
 #include "progspace-and-thread.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/gdb_optional.h"
 #include "filename-seen-cache.h"
 #include "arch-utils.h"
 #include <algorithm>
-#include "common/pathstuff.h"
+#include "gdbsupport/pathstuff.h"
 
 /* Forward declarations for local functions.  */
 
@@ -91,32 +92,33 @@ struct block_symbol lookup_local_symbol (const char *name,
                                         enum language language);
 
 static struct block_symbol
-  lookup_symbol_in_objfile (struct objfile *objfile, int block_index,
+  lookup_symbol_in_objfile (struct objfile *objfile,
+                           enum block_enum block_index,
                            const char *name, const domain_enum domain);
 
-/* See symtab.h.  */
-const struct block_symbol null_block_symbol = { NULL, NULL };
-
-/* Program space key for finding name and language of "main".  */
-
-static const struct program_space_data *main_progspace_key;
-
 /* Type of the data stored on the program space.  */
 
 struct main_info
 {
+  main_info () = default;
+
+  ~main_info ()
+  {
+    xfree (name_of_main);
+  }
+
   /* Name of "main".  */
 
-  char *name_of_main;
+  char *name_of_main = nullptr;
 
   /* Language of "main".  */
 
-  enum language language_of_main;
+  enum language language_of_main = language_unknown;
 };
 
-/* Program space key for finding its symbol cache.  */
+/* Program space key for finding name and language of "main".  */
 
-static const struct program_space_data *symbol_cache_key;
+static const program_space_key<main_info> main_progspace_key;
 
 /* The default symbol cache size.
    There is no extra cpu cost for large N (except when flushing the cache,
@@ -209,10 +211,22 @@ struct block_symbol_cache
 
 struct symbol_cache
 {
-  struct block_symbol_cache *global_symbols;
-  struct block_symbol_cache *static_symbols;
+  symbol_cache () = default;
+
+  ~symbol_cache ()
+  {
+    xfree (global_symbols);
+    xfree (static_symbols);
+  }
+
+  struct block_symbol_cache *global_symbols = nullptr;
+  struct block_symbol_cache *static_symbols = nullptr;
 };
 
+/* Program space key for finding its symbol cache.  */
+
+static const program_space_key<symbol_cache> symbol_cache_key;
+
 /* When non-zero, print debugging messages related to symtab creation.  */
 unsigned int symtab_create_debug = 0;
 
@@ -311,6 +325,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
@@ -473,7 +512,7 @@ iterate_over_symtabs (const char *name,
       gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
     }
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (iterate_over_some_symtabs (name, real_path.get (),
                                     objfile->compunit_symtabs, NULL,
@@ -484,7 +523,7 @@ iterate_over_symtabs (const char *name,
   /* Same search rules as above apply here, but now we look thru the
      psymtabs.  */
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (objfile->sf
          && objfile->sf->qf->map_symtabs_matching_filename (objfile,
@@ -675,6 +714,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,16 +747,16 @@ 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.reset (htab_create_alloc
     (256, hash_demangled_name_entry, eq_demangled_name_entry,
-     NULL, xcalloc, xfree);
+     NULL, xcalloc, xfree));
 }
 
 /* Try to determine the demangled name for a symbol, based on the
@@ -772,13 +812,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 +840,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')
     {
@@ -816,14 +855,9 @@ symbol_set_names (struct general_symbol_info *gsymbol,
   else
     linkage_name_copy = linkage_name;
 
-  /* Set the symbol language.  */
-  char *demangled_name_ptr
-    = symbol_find_demangled_name (gsymbol, linkage_name_copy);
-  gdb::unique_xmalloc_ptr<char> demangled_name (demangled_name_ptr);
-
   entry.mangled = linkage_name_copy;
   slot = ((struct demangled_name_entry **)
-         htab_find_slot (per_bfd->demangled_names_hash,
+         htab_find_slot (per_bfd->demangled_names_hash.get (),
                          &entry, INSERT));
 
   /* If this name is not in the hash table, add it.  */
@@ -833,6 +867,9 @@ symbol_set_names (struct general_symbol_info *gsymbol,
       || (gsymbol->language == language_go
          && (*slot)->demangled[0] == '\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
@@ -869,12 +906,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.get());
+       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')
@@ -971,7 +1012,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)
@@ -1011,7 +1051,8 @@ matching_obj_sections (struct obj_section *obj_first,
 
   /* Otherwise check that they are in corresponding objfiles.  */
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  struct objfile *obj = NULL;
+  for (objfile *objfile : current_program_space->objfiles ())
     if (objfile->obfd == first->owner)
       {
        obj = objfile;
@@ -1040,15 +1081,10 @@ expand_symtab_containing_pc (CORE_ADDR pc, struct obj_section *section)
      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;
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       struct compunit_symtab *cust = NULL;
 
@@ -1202,57 +1238,23 @@ resize_symbol_cache (struct symbol_cache *cache, unsigned int new_size)
     }
 }
 
-/* Make a symbol cache of size SIZE.  */
-
-static struct symbol_cache *
-make_symbol_cache (unsigned int size)
-{
-  struct symbol_cache *cache;
-
-  cache = XCNEW (struct symbol_cache);
-  resize_symbol_cache (cache, symbol_cache_size);
-  return cache;
-}
-
-/* Free the space used by CACHE.  */
-
-static void
-free_symbol_cache (struct symbol_cache *cache)
-{
-  xfree (cache->global_symbols);
-  xfree (cache->static_symbols);
-  xfree (cache);
-}
-
 /* Return the symbol cache of PSPACE.
    Create one if it doesn't exist yet.  */
 
 static struct symbol_cache *
 get_symbol_cache (struct program_space *pspace)
 {
-  struct symbol_cache *cache
-    = (struct symbol_cache *) program_space_data (pspace, symbol_cache_key);
+  struct symbol_cache *cache = symbol_cache_key.get (pspace);
 
   if (cache == NULL)
     {
-      cache = make_symbol_cache (symbol_cache_size);
-      set_program_space_data (pspace, symbol_cache_key, cache);
+      cache = symbol_cache_key.emplace (pspace);
+      resize_symbol_cache (cache, symbol_cache_size);
     }
 
   return cache;
 }
 
-/* Delete the symbol cache of PSPACE.
-   Called when PSPACE is destroyed.  */
-
-static void
-symbol_cache_cleanup (struct program_space *pspace, void *data)
-{
-  struct symbol_cache *cache = (struct symbol_cache *) data;
-
-  free_symbol_cache (cache);
-}
-
 /* Set the size of the symbol cache in all program spaces.  */
 
 static void
@@ -1262,8 +1264,7 @@ set_symbol_cache_size (unsigned int new_size)
 
   ALL_PSPACES (pspace)
     {
-      struct symbol_cache *cache
-       = (struct symbol_cache *) program_space_data (pspace, symbol_cache_key);
+      struct symbol_cache *cache = symbol_cache_key.get (pspace);
 
       /* The pspace could have been created but not have a cache yet.  */
       if (cache != NULL)
@@ -1296,13 +1297,12 @@ set_symbol_cache_size_handler (const char *args, int from_tty,
    The result is the symbol if found, SYMBOL_LOOKUP_FAILED if a previous lookup
    failed (and thus this one will too), or NULL if the symbol is not present
    in the cache.
-   If the symbol is not present in the cache, then *BSC_PTR and *SLOT_PTR are
-   set to the cache and slot of the symbol to save the result of a full lookup
-   attempt.  */
+   *BSC_PTR and *SLOT_PTR are set to the cache and slot of the symbol, which
+   can be used to save the result of a full lookup attempt.  */
 
 static struct block_symbol
 symbol_cache_lookup (struct symbol_cache *cache,
-                    struct objfile *objfile_context, int block,
+                    struct objfile *objfile_context, enum block_enum block,
                     const char *name, domain_enum domain,
                     struct block_symbol_cache **bsc_ptr,
                     struct symbol_cache_slot **slot_ptr)
@@ -1319,12 +1319,15 @@ symbol_cache_lookup (struct symbol_cache *cache,
     {
       *bsc_ptr = NULL;
       *slot_ptr = NULL;
-      return (struct block_symbol) {NULL, NULL};
+      return {};
     }
 
   hash = hash_symbol_entry (objfile_context, name, domain);
   slot = bsc->symbols + hash % bsc->size;
 
+  *bsc_ptr = bsc;
+  *slot_ptr = slot;
+
   if (eq_symbol_entry (slot, objfile_context, name, domain))
     {
       if (symbol_lookup_debug)
@@ -1342,9 +1345,6 @@ symbol_cache_lookup (struct symbol_cache *cache,
 
   /* Symbol is not present in the cache.  */
 
-  *bsc_ptr = bsc;
-  *slot_ptr = slot;
-
   if (symbol_lookup_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -1353,7 +1353,7 @@ symbol_cache_lookup (struct symbol_cache *cache,
                          name, domain_name (domain));
     }
   ++bsc->misses;
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* Clear out SLOT.  */
@@ -1419,8 +1419,7 @@ symbol_cache_mark_not_found (struct block_symbol_cache *bsc,
 static void
 symbol_cache_flush (struct program_space *pspace)
 {
-  struct symbol_cache *cache
-    = (struct symbol_cache *) program_space_data (pspace, symbol_cache_key);
+  struct symbol_cache *cache = symbol_cache_key.get (pspace);
   int pass;
 
   if (cache == NULL)
@@ -1534,8 +1533,7 @@ maintenance_print_symbol_cache (const char *args, int from_tty)
                       : "(no object file)");
 
       /* If the cache hasn't been created yet, avoid creating one.  */
-      cache
-       = (struct symbol_cache *) program_space_data (pspace, symbol_cache_key);
+      cache = symbol_cache_key.get (pspace);
       if (cache == NULL)
        printf_filtered ("  <empty>\n");
       else
@@ -1606,8 +1604,7 @@ maintenance_print_symbol_cache_statistics (const char *args, int from_tty)
                       : "(no object file)");
 
       /* If the cache hasn't been created yet, avoid creating one.  */
-      cache
-       = (struct symbol_cache *) program_space_data (pspace, symbol_cache_key);
+      cache = symbol_cache_key.get (pspace);
       if (cache == NULL)
        printf_filtered ("  empty, no stats available\n");
       else
@@ -1918,7 +1915,7 @@ lookup_language_this (const struct language_defn *lang,
                      const struct block *block)
 {
   if (lang->la_name_of_this == NULL || block == NULL)
-    return (struct block_symbol) {NULL, NULL};
+    return {};
 
   if (symbol_lookup_debug > 1)
     {
@@ -1955,7 +1952,7 @@ lookup_language_this (const struct language_defn *lang,
 
   if (symbol_lookup_debug > 1)
     fprintf_unfiltered (gdb_stdlog, " = NULL\n");
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* Given TYPE, a structure/union,
@@ -2082,7 +2079,7 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
                  fprintf_unfiltered (gdb_stdlog,
                                      "lookup_symbol_aux (...) = NULL\n");
                }
-             return (struct block_symbol) {NULL, NULL};
+             return {};
            }
        }
     }
@@ -2132,7 +2129,7 @@ lookup_local_symbol (const char *name,
   /* Check if either no block is specified or it's a global block.  */
 
   if (static_block == NULL)
-    return (struct block_symbol) {NULL, NULL};
+    return {};
 
   while (block != static_block)
     {
@@ -2157,7 +2154,7 @@ lookup_local_symbol (const char *name,
 
   /* We've reached the end of the function without finding a result.  */
 
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* See symtab.h.  */
@@ -2170,9 +2167,9 @@ lookup_objfile_from_block (const struct block *block)
 
   block = block_global_block (block);
   /* Look through all blockvectors.  */
-  for (objfile *obj : all_objfiles (current_program_space))
+  for (objfile *obj : current_program_space->objfiles ())
     {
-      for (compunit_symtab *cust : objfile_compunits (obj))
+      for (compunit_symtab *cust : obj->compunits ())
        if (block == BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
                                        GLOBAL_BLOCK))
          {
@@ -2226,23 +2223,22 @@ lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
 
 struct block_symbol
 lookup_global_symbol_from_objfile (struct objfile *main_objfile,
+                                  enum block_enum block_index,
                                   const char *name,
                                   const domain_enum domain)
 {
-  struct objfile *objfile;
+  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
 
-  for (objfile = main_objfile;
-       objfile;
-       objfile = objfile_separate_debug_iterate (main_objfile, objfile))
+  for (objfile *objfile : main_objfile->separate_debug_objfiles ())
     {
       struct block_symbol result
-        = lookup_symbol_in_objfile (objfile, GLOBAL_BLOCK, name, domain);
+        = lookup_symbol_in_objfile (objfile, block_index, name, domain);
 
-      if (result.symbol != NULL)
+      if (result.symbol != nullptr)
        return result;
     }
 
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* Check to see if the symbol is defined in one of the OBJFILE's
@@ -2251,8 +2247,9 @@ lookup_global_symbol_from_objfile (struct objfile *main_objfile,
    static symbols.  */
 
 static struct block_symbol
-lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
-                                 const char *name, const domain_enum domain)
+lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
+                                 enum block_enum block_index, const char *name,
+                                 const domain_enum domain)
 {
   gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
 
@@ -2266,7 +2263,7 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
                          name, domain_name (domain));
     }
 
-  for (compunit_symtab *cust : objfile_compunits (objfile))
+  for (compunit_symtab *cust : objfile->compunits ())
     {
       const struct blockvector *bv;
       const struct block *block;
@@ -2292,7 +2289,7 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
 
   if (symbol_lookup_debug > 1)
     fprintf_unfiltered (gdb_stdlog, " = NULL\n");
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* Wrapper around lookup_symbol_in_objfile_symtabs for search_symbols.
@@ -2302,7 +2299,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,
@@ -2310,7 +2307,7 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
                                            domain_enum domain)
 {
   enum language lang = current_language->la_language;
-  struct objfile *main_objfile, *cur_objfile;
+  struct objfile *main_objfile;
 
   demangle_result_storage storage;
   const char *modified_name = demangle_for_lookup (linkage_name, lang, storage);
@@ -2320,9 +2317,7 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
   else
     main_objfile = objfile;
 
-  for (cur_objfile = main_objfile;
-       cur_objfile;
-       cur_objfile = objfile_separate_debug_iterate (main_objfile, cur_objfile))
+  for (::objfile *cur_objfile : main_objfile->separate_debug_objfiles ())
     {
       struct block_symbol result;
 
@@ -2335,14 +2330,14 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
        return result;
     }
 
-  return (struct block_symbol) {NULL, NULL};
+  return {};
 }
 
 /* A helper function that throws an exception when a symbol was found
    in a psymtab but not in a symtab.  */
 
 static void ATTRIBUTE_NORETURN
-error_in_psymtab_expansion (int block_index, const char *name,
+error_in_psymtab_expansion (enum block_enum block_index, const char *name,
                            struct compunit_symtab *cust)
 {
   error (_("\
@@ -2359,8 +2354,9 @@ Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
    the "quick" symbol table functions.  */
 
 static struct block_symbol
-lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index,
-                            const char *name, const domain_enum domain)
+lookup_symbol_via_quick_fns (struct objfile *objfile,
+                            enum block_enum block_index, const char *name,
+                            const domain_enum domain)
 {
   struct compunit_symtab *cust;
   const struct blockvector *bv;
@@ -2368,7 +2364,7 @@ lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index,
   struct block_symbol result;
 
   if (!objfile->sf)
-    return (struct block_symbol) {NULL, NULL};
+    return {};
 
   if (symbol_lookup_debug > 1)
     {
@@ -2388,7 +2384,7 @@ lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index,
          fprintf_unfiltered (gdb_stdlog,
                              "lookup_symbol_via_quick_fns (...) = NULL\n");
        }
-      return (struct block_symbol) {NULL, NULL};
+      return {};
     }
 
   bv = COMPUNIT_BLOCKVECTOR (cust);
@@ -2492,7 +2488,7 @@ lookup_symbol_in_static_block (const char *name,
   struct symbol *sym;
 
   if (static_block == NULL)
-    return (struct block_symbol) {NULL, NULL};
+    return {};
 
   if (symbol_lookup_debug)
     {
@@ -2525,11 +2521,13 @@ lookup_symbol_in_static_block (const char *name,
    BLOCK_INDEX is one of GLOBAL_BLOCK or STATIC_BLOCK.  */
 
 static struct block_symbol
-lookup_symbol_in_objfile (struct objfile *objfile, int block_index,
+lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
                          const char *name, const domain_enum domain)
 {
   struct block_symbol result;
 
+  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
+
   if (symbol_lookup_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -2568,47 +2566,9 @@ lookup_symbol_in_objfile (struct objfile *objfile, int block_index,
   return result;
 }
 
-/* See symtab.h.  */
-
-struct block_symbol
-lookup_static_symbol (const char *name, const domain_enum domain)
-{
-  struct symbol_cache *cache = get_symbol_cache (current_program_space);
-  struct block_symbol result;
-  struct block_symbol_cache *bsc;
-  struct symbol_cache_slot *slot;
-
-  /* Lookup in STATIC_BLOCK is not current-objfile-dependent, so just pass
-     NULL for OBJFILE_CONTEXT.  */
-  result = symbol_cache_lookup (cache, NULL, STATIC_BLOCK, name, domain,
-                               &bsc, &slot);
-  if (result.symbol != NULL)
-    {
-      if (SYMBOL_LOOKUP_FAILED_P (result))
-       return (struct block_symbol) {NULL, NULL};
-      return result;
-    }
-
-  for (objfile *objfile : all_objfiles (current_program_space))
-    {
-      result = lookup_symbol_in_objfile (objfile, STATIC_BLOCK, name, domain);
-      if (result.symbol != NULL)
-       {
-         /* Still pass NULL for OBJFILE_CONTEXT here.  */
-         symbol_cache_mark_found (bsc, slot, NULL, result.symbol,
-                                  result.block);
-         return result;
-       }
-    }
-
-  /* Still pass NULL for OBJFILE_CONTEXT here.  */
-  symbol_cache_mark_not_found (bsc, slot, NULL, name, domain);
-  return (struct block_symbol) {NULL, NULL};
-}
-
 /* Private data to be used with lookup_symbol_global_iterator_cb.  */
 
-struct global_sym_lookup_data
+struct global_or_static_sym_lookup_data
 {
   /* The name of the symbol we are searching for.  */
   const char *name;
@@ -2616,27 +2576,30 @@ struct global_sym_lookup_data
   /* The domain to use for our search.  */
   domain_enum domain;
 
+  /* The block index in which to search.  */
+  enum block_enum block_index;
+
   /* The field where the callback should store the symbol if found.
      It should be initialized to {NULL, NULL} before the search is started.  */
   struct block_symbol result;
 };
 
 /* A callback function for gdbarch_iterate_over_objfiles_in_search_order.
-   It searches by name for a symbol in the GLOBAL_BLOCK of the given
-   OBJFILE.  The arguments for the search are passed via CB_DATA,
-   which in reality is a pointer to struct global_sym_lookup_data.  */
+   It searches by name for a symbol in the block given by BLOCK_INDEX of the
+   given OBJFILE.  The arguments for the search are passed via CB_DATA, which
+   in reality is a pointer to struct global_or_static_sym_lookup_data.  */
 
 static int
-lookup_symbol_global_iterator_cb (struct objfile *objfile,
-                                 void *cb_data)
+lookup_symbol_global_or_static_iterator_cb (struct objfile *objfile,
+                                           void *cb_data)
 {
-  struct global_sym_lookup_data *data =
-    (struct global_sym_lookup_data *) cb_data;
+  struct global_or_static_sym_lookup_data *data =
+    (struct global_or_static_sym_lookup_data *) cb_data;
 
   gdb_assert (data->result.symbol == NULL
              && data->result.block == NULL);
 
-  data->result = lookup_symbol_in_objfile (objfile, GLOBAL_BLOCK,
+  data->result = lookup_symbol_in_objfile (objfile, data->block_index,
                                           data->name, data->domain);
 
   /* If we found a match, tell the iterator to stop.  Otherwise,
@@ -2644,30 +2607,33 @@ lookup_symbol_global_iterator_cb (struct objfile *objfile,
   return (data->result.symbol != NULL);
 }
 
-/* See symtab.h.  */
+/* This function contains the common code of lookup_{global,static}_symbol.
+   OBJFILE is only used if BLOCK_INDEX is GLOBAL_SCOPE, in which case it is
+   the objfile to start the lookup in.  */
 
-struct block_symbol
-lookup_global_symbol (const char *name,
-                     const struct block *block,
-                     const domain_enum domain)
+static struct block_symbol
+lookup_global_or_static_symbol (const char *name,
+                               enum block_enum block_index,
+                               struct objfile *objfile,
+                               const domain_enum domain)
 {
   struct symbol_cache *cache = get_symbol_cache (current_program_space);
   struct block_symbol result;
-  struct objfile *objfile;
-  struct global_sym_lookup_data lookup_data;
+  struct global_or_static_sym_lookup_data lookup_data;
   struct block_symbol_cache *bsc;
   struct symbol_cache_slot *slot;
 
-  objfile = lookup_objfile_from_block (block);
+  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
+  gdb_assert (objfile == nullptr || block_index == GLOBAL_BLOCK);
 
   /* First see if we can find the symbol in the cache.
      This works because we use the current objfile to qualify the lookup.  */
-  result = symbol_cache_lookup (cache, objfile, GLOBAL_BLOCK, name, domain,
+  result = symbol_cache_lookup (cache, objfile, block_index, name, domain,
                                &bsc, &slot);
   if (result.symbol != NULL)
     {
       if (SYMBOL_LOOKUP_FAILED_P (result))
-       return (struct block_symbol) {NULL, NULL};
+       return {};
       return result;
     }
 
@@ -2680,10 +2646,11 @@ lookup_global_symbol (const char *name,
     {
       memset (&lookup_data, 0, sizeof (lookup_data));
       lookup_data.name = 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 (),
-        lookup_symbol_global_iterator_cb, &lookup_data, objfile);
+        lookup_symbol_global_or_static_iterator_cb, &lookup_data, objfile);
       result = lookup_data.result;
     }
 
@@ -2695,6 +2662,25 @@ lookup_global_symbol (const char *name,
   return result;
 }
 
+/* See symtab.h.  */
+
+struct block_symbol
+lookup_static_symbol (const char *name, const domain_enum domain)
+{
+  return lookup_global_or_static_symbol (name, STATIC_BLOCK, nullptr, domain);
+}
+
+/* See symtab.h.  */
+
+struct block_symbol
+lookup_global_symbol (const char *name,
+                     const struct block *block,
+                     const domain_enum domain)
+{
+  struct objfile *objfile = lookup_objfile_from_block (block);
+  return lookup_global_or_static_symbol (name, GLOBAL_BLOCK, objfile, domain);
+}
+
 int
 symbol_matches_domain (enum language symbol_language,
                       domain_enum symbol_domain,
@@ -2727,12 +2713,13 @@ lookup_transparent_type (const char *name)
    "quick" symbol table functions.  */
 
 static struct type *
-basic_lookup_transparent_type_quick (struct objfile *objfile, int block_index,
+basic_lookup_transparent_type_quick (struct objfile *objfile,
+                                    enum block_enum block_index,
                                     const char *name)
 {
   struct compunit_symtab *cust;
   const struct blockvector *bv;
-  struct block *block;
+  const struct block *block;
   struct symbol *sym;
 
   if (!objfile->sf)
@@ -2757,14 +2744,15 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int block_index,
    BLOCK_INDEX is either GLOBAL_BLOCK or STATIC_BLOCK.  */
 
 static struct type *
-basic_lookup_transparent_type_1 (struct objfile *objfile, int block_index,
+basic_lookup_transparent_type_1 (struct objfile *objfile,
+                                enum block_enum block_index,
                                 const char *name)
 {
   const struct blockvector *bv;
   const struct block *block;
   const struct symbol *sym;
 
-  for (compunit_symtab *cust : objfile_compunits (objfile))
+  for (compunit_symtab *cust : objfile->compunits ())
     {
       bv = COMPUNIT_BLOCKVECTOR (cust);
       block = BLOCKVECTOR_BLOCK (bv, block_index);
@@ -2796,14 +2784,14 @@ 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.  */
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK, name);
       if (t)
        return t;
     }
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK, name);
       if (t)
@@ -2817,14 +2805,14 @@ 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.  */
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK, name);
       if (t)
        return t;
     }
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK, name);
       if (t)
@@ -2880,12 +2868,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
@@ -2903,11 +2886,11 @@ 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.  */
 
-  for (objfile *obj_file : all_objfiles (current_program_space))
+  for (objfile *obj_file : current_program_space->objfiles ())
     {
-      for (compunit_symtab *cust : objfile_compunits (obj_file))
+      for (compunit_symtab *cust : obj_file->compunits ())
        {
-         struct block *b;
+         const struct block *b;
          const struct blockvector *bv;
 
          bv = COMPUNIT_BLOCKVECTOR (cust);
@@ -2965,7 +2948,7 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
 
   /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs).  */
 
-  for (objfile *objf : all_objfiles (current_program_space))
+  for (objfile *objf : current_program_space->objfiles ())
     {
       struct compunit_symtab *result;
 
@@ -2997,7 +2980,7 @@ find_pc_compunit_symtab (CORE_ADDR pc)
 struct symbol *
 find_symbol_at_address (CORE_ADDR address)
 {
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (objfile->sf == NULL
          || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
@@ -3011,7 +2994,7 @@ find_symbol_at_address (CORE_ADDR address)
 
          for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
            {
-             struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+             const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
              struct block_iterator iter;
              struct symbol *sym;
 
@@ -3352,44 +3335,49 @@ find_line_symtab (struct symtab *sym_tab, int line,
       else
        best = 0;
 
-      for (objfile *objfile : all_objfiles (current_program_space))
+      for (objfile *objfile : current_program_space->objfiles ())
        {
          if (objfile->sf)
            objfile->sf->qf->expand_symtabs_with_fullname
              (objfile, symtab_to_fullname (sym_tab));
        }
 
-      struct objfile *objfile;
-      ALL_FILETABS (objfile, cu, s)
-      {
-       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;
-             }
-         }
-      }
+      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)
@@ -3682,8 +3670,10 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
 
 /* Adjust SAL to the first instruction past the function prologue.
    If the PC was explicitly specified, the SAL is not changed.
-   If the line number was explicitly specified, at most the SAL's PC
-   is updated.  If SAL is already past the prologue, then do nothing.  */
+   If the line number was explicitly specified then the SAL can still be
+   updated, unless the language for SAL is assembler, in which case the SAL
+   will be left unchanged.
+   If SAL is already past the prologue, then do nothing.  */
 
 void
 skip_prologue_sal (struct symtab_and_line *sal)
@@ -3702,6 +3692,15 @@ skip_prologue_sal (struct symtab_and_line *sal)
   if (sal->explicit_pc)
     return;
 
+  /* In assembly code, if the user asks for a specific line then we should
+     not adjust the SAL.  The user already has instruction level
+     visibility in this case, so selecting a line other than one requested
+     is likely to be the wrong choice.  */
+  if (sal->symtab != nullptr
+      && sal->explicit_line
+      && SYMTAB_LANGUAGE (sal->symtab) == language_asm)
+    return;
+
   scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   switch_to_program_space_and_thread (sal->pspace);
@@ -3821,12 +3820,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
 
   sal->pc = pc;
   sal->section = section;
-
-  /* Unless the explicit_line flag was set, update the SAL line
-     and symtab to correspond to the modified PC location.  */
-  if (sal->explicit_line)
-    return;
-
   sal->symtab = start_sal.symtab;
   sal->line = start_sal.line;
   sal->end = start_sal.end;
@@ -4123,10 +4116,28 @@ operator_chars (const char *p, const char **end)
 }
 \f
 
+/* What part to match in a file name.  */
+
+struct filename_partial_match_opts
+{
+  /* Only match the directory name part.   */
+  int dirname = false;
+
+  /* Only match the basename part.  */
+  int basename = false;
+};
+
 /* Data structure to maintain printing state for output_source_filename.  */
 
 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;
+
+
   /* Cache of what we've seen so far.  */
   struct filename_seen_cache *filename_seen_cache;
 
@@ -4158,13 +4169,33 @@ output_source_filename (const char *name,
       return;
     }
 
-  /* No; print it and reset *FIRST.  */
+  /* Does it match data->regexp?  */
+  if (data->c_regexp.has_value ())
+    {
+      const char *to_match;
+      std::string dirname;
+
+      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 (data->c_regexp->exec (to_match, 0, NULL, 0) != 0)
+       return;
+    }
+
+  /* Print it and reset *FIRST.  */
   if (! data->first)
     printf_filtered (", ");
   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.  */
@@ -4177,10 +4208,75 @@ output_partial_symbol_filename (const char *filename, const char *fullname,
                          (struct output_source_filename_data *) data);
 }
 
+using isrc_flag_option_def
+  = gdb::option::flag_option_def<filename_partial_match_opts>;
+
+static const gdb::option::option_def info_sources_option_defs[] = {
+
+  isrc_flag_option_def {
+    "dirname",
+    [] (filename_partial_match_opts *opts) { return &opts->dirname; },
+    N_("Show only the files having a dirname matching REGEXP."),
+  },
+
+  isrc_flag_option_def {
+    "basename",
+    [] (filename_partial_match_opts *opts) { return &opts->basename; },
+    N_("Show only the files having a basename matching REGEXP."),
+  },
+
+};
+
+/* Create an option_def_group for the "info sources" options, with
+   ISRC_OPTS as context.  */
+
+static inline gdb::option::option_def_group
+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
-info_sources_command (const char *ignore, int from_tty)
+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
+info_sources_command_completer (cmd_list_element *ignore,
+                               completion_tracker &tracker,
+                               const char *text, const char *word)
+{
+  const auto group = make_info_sources_options_def_group (nullptr);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
+}
+
+static void
+info_sources_command (const char *args, int from_tty)
 {
-  struct objfile *objfile;
   struct output_source_filename_data data;
 
   if (!have_full_symbols () && !have_partial_symbols ())
@@ -4190,21 +4286,54 @@ info_sources_command (const char *ignore, int from_tty)
 
   filename_seen_cache filenames_seen;
 
-  data.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);
 
-  printf_filtered ("Source files for which symbols have been read in:\n\n");
+  if (args != NULL && *args != '\000')
+    data.regexp = args;
 
+  data.filename_seen_cache = &filenames_seen;
   data.first = 1;
-  ALL_FILETABS (objfile, cu, s)
-  {
-    const char *fullname = symtab_to_fullname (s);
 
-    output_source_filename (fullname, &data);
-  }
+  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'."));
+
+  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"));
+    }
+
+  print_info_sources_header
+    (_("Source files for which symbols have been read in:\n"), &data);
+
+  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);
+           }
+       }
+    }
   printf_filtered ("\n\n");
 
-  printf_filtered ("Source files for which symbols "
-                  "will be read in on demand:\n\n");
+  print_info_sources_header
+    (_("Source files for which symbols will be read in on demand:\n"), &data);
 
   filenames_seen.clear ();
   data.first = 1;
@@ -4324,27 +4453,31 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
 
    Within each file the results are sorted locally; each symtab's global and
    static blocks are separately alphabetized.
-   Duplicate entries are removed.  */
+   Duplicate entries are removed.
+
+   When EXCLUDE_MINSYMS is false then matching minsyms are also returned,
+   otherwise they are excluded.  */
 
 std::vector<symbol_search>
 search_symbols (const char *regexp, enum search_domain kind,
                const char *t_regexp,
-               int nfiles, const char *files[])
+               int nfiles, const char *files[],
+               bool exclude_minsyms)
 {
   const struct blockvector *bv;
-  struct block *b;
+  const struct block *b;
   int i = 0;
   struct block_iterator iter;
   struct symbol *sym;
   int found_misc = 0;
   static const enum minimal_symbol_type types[]
-    = {mst_data, mst_text, mst_abs};
+    = {mst_data, mst_text, mst_unknown};
   static const enum minimal_symbol_type types2[]
-    = {mst_bss, mst_file_text, mst_abs};
+    = {mst_bss, mst_file_text, mst_unknown};
   static const enum minimal_symbol_type types3[]
-    = {mst_file_data, mst_solib_trampoline, mst_abs};
+    = {mst_file_data, mst_solib_trampoline, mst_unknown};
   static const enum minimal_symbol_type types4[]
-    = {mst_file_bss, mst_text_gnu_ifunc, mst_abs};
+    = {mst_file_bss, mst_text_gnu_ifunc, mst_unknown};
   enum minimal_symbol_type ourtype;
   enum minimal_symbol_type ourtype2;
   enum minimal_symbol_type ourtype3;
@@ -4444,9 +4577,9 @@ search_symbols (const char *regexp, enum search_domain kind,
 
   if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN))
     {
-      for (objfile *objfile : all_objfiles (current_program_space))
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+         for (minimal_symbol *msymbol : objfile->msymbols ())
            {
              QUIT;
 
@@ -4481,9 +4614,9 @@ search_symbols (const char *regexp, enum search_domain kind,
        }
     }
 
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
-      for (compunit_symtab *cust : objfile_compunits (objfile))
+      for (compunit_symtab *cust : objfile->compunits ())
        {
          bv = COMPUNIT_BLOCKVECTOR (cust);
          for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
@@ -4526,7 +4659,8 @@ search_symbols (const char *regexp, enum search_domain kind,
                                      || treg_matches_sym_type_name (*treg,
                                                                     sym)))
                              || (kind == TYPES_DOMAIN
-                                 && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
+                                 && SYMBOL_CLASS (sym) == LOC_TYPEDEF
+                                 && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN))))
                    {
                      /* match */
                      result.emplace_back (i, sym);
@@ -4545,11 +4679,12 @@ search_symbols (const char *regexp, enum search_domain kind,
      as we assume that a minimal symbol does not have a type.  */
 
   if ((found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
+      && !exclude_minsyms
       && !treg.has_value ())
     {
-      for (objfile *objfile : all_objfiles (current_program_space))
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+         for (minimal_symbol *msymbol : objfile->msymbols ())
            {
              QUIT;
 
@@ -4611,7 +4746,7 @@ print_symbol_info (enum search_domain kind,
       if (filename_cmp (last, s_filename) != 0)
        {
          fputs_filtered ("\nFile ", gdb_stdout);
-         fputs_filtered (s_filename, gdb_stdout);
+         fputs_styled (s_filename, file_name_style.style (), gdb_stdout);
          fputs_filtered (":\n", gdb_stdout);
        }
 
@@ -4627,7 +4762,23 @@ print_symbol_info (enum search_domain kind,
   /* Typedef that is not a C++ class.  */
   if (kind == TYPES_DOMAIN
       && SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
-    typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
+    {
+      /* FIXME: For C (and C++) we end up with a difference in output here
+        between how a typedef is printed, and non-typedefs are printed.
+        The TYPEDEF_PRINT code places a ";" at the end in an attempt to
+        appear C-like, while TYPE_PRINT doesn't.
+
+        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)
+       typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
+      else
+       {
+         type_print (SYMBOL_TYPE (sym), "", gdb_stdout, -1);
+         printf_filtered ("\n");
+       }
+    }
   /* variable, func, or typedef-that-is-c++-class.  */
   else if (kind < TYPES_DOMAIN
           || (kind == TYPES_DOMAIN
@@ -4658,8 +4809,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
@@ -4668,7 +4826,7 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
    matches.  */
 
 static void
-symtab_symbol_info (bool quiet,
+symtab_symbol_info (bool quiet, bool exclude_minsyms,
                    const char *regexp, enum search_domain kind,
                    const char *t_regexp, int from_tty)
 {
@@ -4679,9 +4837,13 @@ symtab_symbol_info (bool quiet,
 
   gdb_assert (kind <= TYPES_DOMAIN);
 
+  if (regexp != nullptr && *regexp == '\0')
+    regexp = nullptr;
+
   /* Must make sure that if we're interrupted, symbols gets freed.  */
   std::vector<symbol_search> symbols = search_symbols (regexp, kind,
-                                                      t_regexp, 0, NULL);
+                                                      t_regexp, 0, NULL,
+                                                      exclude_minsyms);
 
   if (!quiet)
     {
@@ -4690,7 +4852,7 @@ symtab_symbol_info (bool quiet,
          if (t_regexp != NULL)
            printf_filtered
              (_("All %ss matching regular expression \"%s\""
-                " with type matching regulation expression \"%s\":\n"),
+                " with type matching regular expression \"%s\":\n"),
               classnames[kind], regexp, t_regexp);
          else
            printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
@@ -4701,7 +4863,7 @@ symtab_symbol_info (bool quiet,
          if (t_regexp != NULL)
            printf_filtered
              (_("All defined %ss"
-                " with type matching regulation expression \"%s\" :\n"),
+                " with type matching regular expression \"%s\" :\n"),
               classnames[kind], t_regexp);
          else
            printf_filtered (_("All defined %ss:\n"), classnames[kind]);
@@ -4734,54 +4896,162 @@ symtab_symbol_info (bool quiet,
     }
 }
 
-static void
-info_variables_command (const char *args, int from_tty)
+/* Structure to hold the values of the options used by the 'info variables'
+   and 'info functions' commands.  These correspond to the -q, -t, and -n
+   options.  */
+
+struct info_print_options
 {
-  std::string regexp;
-  std::string t_regexp;
-  bool quiet = false;
+  int quiet = false;
+  int exclude_minsyms = false;
+  char *type_regexp = nullptr;
+
+  ~info_print_options ()
+  {
+    xfree (type_regexp);
+  }
+};
+
+/* 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> {
+    "q",
+    [] (info_print_options *opt) { return &opt->quiet; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::boolean_option_def<info_print_options> {
+    "n",
+    [] (info_print_options *opt) { return &opt->exclude_minsyms; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  },
+
+  gdb::option::string_option_def<info_print_options> {
+    "t",
+    [] (info_print_options *opt) { return &opt->type_regexp; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  }
+};
+
+/* Returns the option group used by 'info variables' and 'info
+   functions'.  */
+
+static gdb::option::option_def_group
+make_info_print_options_def_group (info_print_options *opts)
+{
+  return {{info_print_options_defs}, opts};
+}
+
+/* Command completer for 'info variables' and 'info functions'.  */
 
-  while (args != NULL
-        && extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
-    ;
+static void
+info_print_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);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
 
-  if (args != NULL)
-    report_unrecognized_option_error ("info variables", args);
+  const char *word = advance_to_expression_complete_word_point (tracker, text);
+  symbol_completer (ignore, tracker, text, word);
+}
 
-  symtab_symbol_info (quiet,
-                     regexp.empty () ? NULL : regexp.c_str (),
-                     VARIABLES_DOMAIN,
-                     t_regexp.empty () ? NULL : t_regexp.c_str (),
-                     from_tty);
+/* Implement the 'info variables' command.  */
+
+static void
+info_variables_command (const char *args, int from_tty)
+{
+  info_print_options opts;
+  auto grp = make_info_print_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+
+  symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args, VARIABLES_DOMAIN,
+                     opts.type_regexp, from_tty);
 }
 
+/* Implement the 'info functions' command.  */
 
 static void
 info_functions_command (const char *args, int from_tty)
 {
-  std::string regexp;
-  std::string t_regexp;
-  bool quiet = false;
+  info_print_options opts;
+  auto grp = make_info_print_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
 
-  while (args != NULL
-        && extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
-    ;
+  symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args,
+                     FUNCTIONS_DOMAIN, opts.type_regexp, from_tty);
+}
+
+/* Holds the -q option for the 'info types' command.  */
+
+struct info_types_options
+{
+  int quiet = false;
+};
+
+/* The options used by the 'info types' command.  */
+
+static const gdb::option::option_def info_types_options_defs[] = {
+  gdb::option::boolean_option_def<info_types_options> {
+    "q",
+    [] (info_types_options *opt) { return &opt->quiet; },
+    nullptr, /* show_cmd_cb */
+    nullptr /* set_doc */
+  }
+};
 
-  if (args != NULL)
-    report_unrecognized_option_error ("info functions", args);
+/* Returns the option group used by 'info types'.  */
 
-  symtab_symbol_info (quiet,
-                     regexp.empty () ? NULL : regexp.c_str (),
-                     FUNCTIONS_DOMAIN,
-                     t_regexp.empty () ? NULL : t_regexp.c_str (),
-                     from_tty);
+static gdb::option::option_def_group
+make_info_types_options_def_group (info_types_options *opts)
+{
+  return {{info_types_options_defs}, opts};
 }
 
+/* Implement the 'info types' command.  */
 
 static void
-info_types_command (const char *regexp, int from_tty)
+info_types_command (const char *args, int from_tty)
 {
-  symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty);
+  info_types_options opts;
+
+  auto grp = make_info_types_options_def_group (&opts);
+  gdb::option::process_options
+    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
+  if (args != nullptr && *args == '\0')
+    args = nullptr;
+  symtab_symbol_info (opts.quiet, false, args, TYPES_DOMAIN, NULL, from_tty);
+}
+
+/* Command completer for 'info types' command.  */
+
+static void
+info_types_command_completer (struct cmd_list_element *ignore,
+                             completion_tracker &tracker,
+                             const char *text, const char * /* word */)
+{
+  const auto group
+    = make_info_types_options_def_group (nullptr);
+  if (gdb::option::complete_options
+      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
+    return;
+
+  const char *word = advance_to_expression_complete_word_point (tracker, text);
+  symbol_completer (ignore, tracker, text, word);
 }
 
 /* Breakpoint all functions matching regular expression.  */
@@ -4825,7 +5095,8 @@ rbreak_command (const char *regexp, int from_tty)
   std::vector<symbol_search> symbols = search_symbols (regexp,
                                                       FUNCTIONS_DOMAIN,
                                                       NULL,
-                                                      nfiles, files);
+                                                      nfiles, files,
+                                                      false);
 
   scoped_rbreak_breakpoints finalize;
   for (const symbol_search &p : symbols)
@@ -5263,9 +5534,9 @@ default_collect_symbol_completion_matches_break_on
 
   if (code == TYPE_CODE_UNDEF)
     {
-      for (objfile *objfile : all_objfiles (current_program_space))
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+         for (minimal_symbol *msymbol : objfile->msymbols ())
            {
              QUIT;
 
@@ -5282,9 +5553,9 @@ default_collect_symbol_completion_matches_break_on
     }
 
   /* Add completions for all currently loaded symbol tables.  */
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
-      for (compunit_symtab *cust : objfile_compunits (objfile))
+      for (compunit_symtab *cust : objfile->compunits ())
        add_symtab_completions (cust, tracker, mode, lookup_name,
                                sym_text, word, code);
     }
@@ -5581,7 +5852,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 objfile *objfile;
   size_t text_len = strlen (text);
   completion_list list;
   const char *base_name;
@@ -5592,28 +5862,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)
+      for (compunit_symtab *cu : objfile->compunits ())
        {
-         /* 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);
+         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);
+               }
+           }
        }
     }
 
@@ -5637,9 +5913,7 @@ make_source_files_completion_list (const char *text, const char *word)
 static struct main_info *
 get_main_info (void)
 {
-  struct main_info *info
-    = (struct main_info *) program_space_data (current_program_space,
-                                              main_progspace_key);
+  struct main_info *info = main_progspace_key.get (current_program_space);
 
   if (info == NULL)
     {
@@ -5649,28 +5923,12 @@ get_main_info (void)
         gdb returned "main" as the name even if no function named
         "main" was defined the program; and this approach lets us
         keep compatibility.  */
-      info = XCNEW (struct main_info);
-      info->language_of_main = language_unknown;
-      set_program_space_data (current_program_space, main_progspace_key,
-                             info);
+      info = main_progspace_key.emplace (current_program_space);
     }
 
   return info;
 }
 
-/* A cleanup to destroy a struct main_info when a progspace is
-   destroyed.  */
-
-static void
-main_info_cleanup (struct program_space *pspace, void *data)
-{
-  struct main_info *info = (struct main_info *) data;
-
-  if (info != NULL)
-    xfree (info->name_of_main);
-  xfree (info);
-}
-
 static void
 set_main_name (const char *name, enum language lang)
 {
@@ -5703,7 +5961,7 @@ 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.  */
-  for (objfile *objfile : all_objfiles (current_program_space))
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (objfile->per_bfd->name_of_main != NULL)
        {
@@ -5762,8 +6020,10 @@ find_main_name (void)
   set_main_name ("main", language_unknown);
 }
 
-char *
-main_name (void)
+/* See symtab.h.  */
+
+const char *
+main_name ()
 {
   struct main_info *info = get_main_info ();
 
@@ -6018,48 +6278,60 @@ symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
 void
 _initialize_symtab (void)
 {
-  initialize_ordinary_address_classes ();
+  cmd_list_element *c;
 
-  main_progspace_key
-    = register_program_space_data_with_cleanup (NULL, main_info_cleanup);
-
-  symbol_cache_key
-    = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup);
+  initialize_ordinary_address_classes ();
 
-  add_info ("variables", info_variables_command,
-           info_print_args_help (_("\
+  c = 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\
+Usage: info variables [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
-                                 _("global and static variables")));
+                                     _("global and static variables"),
+                                     true));
+  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
   if (dbx_commands)
-    add_com ("whereis", class_info, info_variables_command,
-            info_print_args_help (_("\
+    {
+      c = 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\
+Usage: whereis [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
 Prints the global and static variables.\n"),
-                                  _("global and static variables")));
+                                        _("global and static variables"),
+                                        true));
+      set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+    }
 
-  add_info ("functions", info_functions_command,
-           info_print_args_help (_("\
+  c = add_info ("functions", info_functions_command,
+               info_print_args_help (_("\
 All function names or those matching REGEXPs.\n\
-Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
+Usage: info functions [-q] [-n] [-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).
-     2.  It doesn't print right, e.g. with
-     typedef struct foo *FOO
-     type_print prints "FOO" when we want to make it (in this situation)
-     print "struct foo *".
-     I also think "ptype" or "whatis" is more likely to be useful (but if
-     there is much disagreement "info types" can be fixed).  */
-  add_info ("types", info_types_command,
-           _("All type names, or those matching REGEXP."));
-
-  add_info ("sources", info_sources_command,
-           _("Source files in the program."));
+                                     _("functions"),
+                                     true));
+  set_cmd_completer_handle_brkchars (c, info_print_command_completer);
+
+  c = add_info ("types", info_types_command, _("\
+All type names, or those matching REGEXP.\n\
+Usage: info types [-q] [REGEXP]\n\
+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);
+
+  static std::string info_sources_help
+    = gdb::option::build_help (_("\
+All source files in the program or those matching REGEXP.\n\
+Usage: info sources [OPTION]... [REGEXP]\n\
+By default, REGEXP is used to match anywhere in the filename.\n\
+\n\
+Options:\n\
+%OPTIONS%"),
+                              info_sources_opts);
+
+  c = add_info ("sources", info_sources_command, info_sources_help.c_str ());
+  set_cmd_completer_handle_brkchars (c, info_sources_command_completer);
 
   add_com ("rbreak", class_breakpoint, rbreak_command,
           _("Set a breakpoint for all functions matching REGEXP."));
@@ -6067,8 +6339,7 @@ Prints the functions.\n"),
   add_setshow_enum_cmd ("multiple-symbols", no_class,
                         multiple_symbols_modes, &multiple_symbols_mode,
                         _("\
-Set the debugger behavior when more than one symbol are possible matches\n\
-in an expression."), _("\
+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);
This page took 0.050423 seconds and 4 git commands to generate.