Use a member function to set a symbol's language
[deliverable/binutils-gdb.git] / gdb / symtab.h
index c6f26e772d2d61daf4a6bcf72ac4af1cec0e414d..e18cd65a3539eb2d3a65812f5844bcbad14e628b 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table definitions for GDB.
 
 /* Symbol table definitions for GDB.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #if !defined (SYMTAB_H)
 #define SYMTAB_H 1
 
 #if !defined (SYMTAB_H)
 #define SYMTAB_H 1
 
-#include "vec.h"
-#include "gdb_vecs.h"
+#include <array>
+#include <vector>
+#include <string>
+#include <set>
+#include "gdbsupport/gdb_vecs.h"
 #include "gdbtypes.h"
 #include "gdbtypes.h"
+#include "gdb_obstack.h"
+#include "gdb_regex.h"
+#include "gdbsupport/enum-flags.h"
+#include "gdbsupport/function-view.h"
+#include "gdbsupport/gdb_optional.h"
+#include "gdbsupport/gdb_string_view.h"
+#include "gdbsupport/next-iterator.h"
+#include "completer.h"
+#include "gdb-demangle.h"
 
 /* Opaque declarations.  */
 struct ui_file;
 
 /* Opaque declarations.  */
 struct ui_file;
@@ -36,10 +48,288 @@ struct axs_value;
 struct agent_expr;
 struct program_space;
 struct language_defn;
 struct agent_expr;
 struct program_space;
 struct language_defn;
-struct probe;
 struct common_block;
 struct obj_section;
 struct cmd_list_element;
 struct common_block;
 struct obj_section;
 struct cmd_list_element;
+class probe;
+struct lookup_name_info;
+
+/* How to match a lookup name against a symbol search name.  */
+enum class symbol_name_match_type
+{
+  /* Wild matching.  Matches unqualified symbol names in all
+     namespace/module/packages, etc.  */
+  WILD,
+
+  /* Full matching.  The lookup name indicates a fully-qualified name,
+     and only matches symbol search names in the specified
+     namespace/module/package.  */
+  FULL,
+
+  /* Search name matching.  This is like FULL, but the search name did
+     not come from the user; instead it is already a search name
+     retrieved from a search_name () call.
+     For Ada, this avoids re-encoding an already-encoded search name
+     (which would potentially incorrectly lowercase letters in the
+     linkage/search name that should remain uppercase).  For C++, it
+     avoids trying to demangle a name we already know is
+     demangled.  */
+  SEARCH_NAME,
+
+  /* Expression matching.  The same as FULL matching in most
+     languages.  The same as WILD matching in Ada.  */
+  EXPRESSION,
+};
+
+/* Hash the given symbol search name according to LANGUAGE's
+   rules.  */
+extern unsigned int search_name_hash (enum language language,
+                                     const char *search_name);
+
+/* Ada-specific bits of a lookup_name_info object.  This is lazily
+   constructed on demand.  */
+
+class ada_lookup_name_info final
+{
+ public:
+  /* Construct.  */
+  explicit ada_lookup_name_info (const lookup_name_info &lookup_name);
+
+  /* Compare SYMBOL_SEARCH_NAME with our lookup name, using MATCH_TYPE
+     as name match type.  Returns true if there's a match, false
+     otherwise.  If non-NULL, store the matching results in MATCH.  */
+  bool matches (const char *symbol_search_name,
+               symbol_name_match_type match_type,
+               completion_match_result *comp_match_res) const;
+
+  /* The Ada-encoded lookup name.  */
+  const std::string &lookup_name () const
+  { return m_encoded_name; }
+
+  /* Return true if we're supposed to be doing a wild match look
+     up.  */
+  bool wild_match_p () const
+  { return m_wild_match_p; }
+
+  /* Return true if we're looking up a name inside package
+     Standard.  */
+  bool standard_p () const
+  { return m_standard_p; }
+
+  /* Return true if doing a verbatim match.  */
+  bool verbatim_p () const
+  { return m_verbatim_p; }
+
+private:
+  /* The Ada-encoded lookup name.  */
+  std::string m_encoded_name;
+
+  /* Whether the user-provided lookup name was Ada encoded.  If so,
+     then return encoded names in the 'matches' method's 'completion
+     match result' output.  */
+  bool m_encoded_p : 1;
+
+  /* True if really doing wild matching.  Even if the user requests
+     wild matching, some cases require full matching.  */
+  bool m_wild_match_p : 1;
+
+  /* True if doing a verbatim match.  This is true if the decoded
+     version of the symbol name is wrapped in '<'/'>'.  This is an
+     escape hatch users can use to look up symbols the Ada encoding
+     does not understand.  */
+  bool m_verbatim_p : 1;
+
+   /* True if the user specified a symbol name that is inside package
+      Standard.  Symbol names inside package Standard are handled
+      specially.  We always do a non-wild match of the symbol name
+      without the "standard__" prefix, and only search static and
+      global symbols.  This was primarily introduced in order to allow
+      the user to specifically access the standard exceptions using,
+      for instance, Standard.Constraint_Error when Constraint_Error is
+      ambiguous (due to the user defining its own Constraint_Error
+      entity inside its program).  */
+  bool m_standard_p : 1;
+};
+
+/* Language-specific bits of a lookup_name_info object, for languages
+   that do name searching using demangled names (C++/D/Go).  This is
+   lazily constructed on demand.  */
+
+struct demangle_for_lookup_info final
+{
+public:
+  demangle_for_lookup_info (const lookup_name_info &lookup_name,
+                           language lang);
+
+  /* The demangled lookup name.  */
+  const std::string &lookup_name () const
+  { return m_demangled_name; }
+
+private:
+  /* The demangled lookup name.  */
+  std::string m_demangled_name;
+};
+
+/* Object that aggregates all information related to a symbol lookup
+   name.  I.e., the name that is matched against the symbol's search
+   name.  Caches per-language information so that it doesn't require
+   recomputing it for every symbol comparison, like for example the
+   Ada encoded name and the symbol's name hash for a given language.
+   The object is conceptually immutable once constructed, and thus has
+   no setters.  This is to prevent some code path from tweaking some
+   property of the lookup name for some local reason and accidentally
+   altering the results of any continuing search(es).
+   lookup_name_info objects are generally passed around as a const
+   reference to reinforce that.  (They're not passed around by value
+   because they're not small.)  */
+class lookup_name_info final
+{
+ public:
+  /* Create a new object.  */
+  lookup_name_info (std::string name,
+                   symbol_name_match_type match_type,
+                   bool completion_mode = false,
+                   bool ignore_parameters = false)
+    : m_match_type (match_type),
+      m_completion_mode (completion_mode),
+      m_ignore_parameters (ignore_parameters),
+      m_name (std::move (name))
+  {}
+
+  /* Getters.  See description of each corresponding field.  */
+  symbol_name_match_type match_type () const { return m_match_type; }
+  bool completion_mode () const { return m_completion_mode; }
+  const std::string &name () const { return m_name; }
+  const bool ignore_parameters () const { return m_ignore_parameters; }
+
+  /* Return a version of this lookup name that is usable with
+     comparisons against symbols have no parameter info, such as
+     psymbols and GDB index symbols.  */
+  lookup_name_info make_ignore_params () const
+  {
+    return lookup_name_info (m_name, m_match_type, m_completion_mode,
+                            true /* ignore params */);
+  }
+
+  /* Get the search name hash for searches in language LANG.  */
+  unsigned int search_name_hash (language lang) const
+  {
+    /* Only compute each language's hash once.  */
+    if (!m_demangled_hashes_p[lang])
+      {
+       m_demangled_hashes[lang]
+         = ::search_name_hash (lang, language_lookup_name (lang).c_str ());
+       m_demangled_hashes_p[lang] = true;
+      }
+    return m_demangled_hashes[lang];
+  }
+
+  /* Get the search name for searches in language LANG.  */
+  const std::string &language_lookup_name (language lang) const
+  {
+    switch (lang)
+      {
+      case language_ada:
+       return ada ().lookup_name ();
+      case language_cplus:
+       return cplus ().lookup_name ();
+      case language_d:
+       return d ().lookup_name ();
+      case language_go:
+       return go ().lookup_name ();
+      default:
+       return m_name;
+      }
+  }
+
+  /* Get the Ada-specific lookup info.  */
+  const ada_lookup_name_info &ada () const
+  {
+    maybe_init (m_ada);
+    return *m_ada;
+  }
+
+  /* Get the C++-specific lookup info.  */
+  const demangle_for_lookup_info &cplus () const
+  {
+    maybe_init (m_cplus, language_cplus);
+    return *m_cplus;
+  }
+
+  /* Get the D-specific lookup info.  */
+  const demangle_for_lookup_info &d () const
+  {
+    maybe_init (m_d, language_d);
+    return *m_d;
+  }
+
+  /* Get the Go-specific lookup info.  */
+  const demangle_for_lookup_info &go () const
+  {
+    maybe_init (m_go, language_go);
+    return *m_go;
+  }
+
+  /* Get a reference to a lookup_name_info object that matches any
+     symbol name.  */
+  static const lookup_name_info &match_any ();
+
+private:
+  /* Initialize FIELD, if not initialized yet.  */
+  template<typename Field, typename... Args>
+  void maybe_init (Field &field, Args&&... args) const
+  {
+    if (!field)
+      field.emplace (*this, std::forward<Args> (args)...);
+  }
+
+  /* The lookup info as passed to the ctor.  */
+  symbol_name_match_type m_match_type;
+  bool m_completion_mode;
+  bool m_ignore_parameters;
+  std::string m_name;
+
+  /* Language-specific info.  These fields are filled lazily the first
+     time a lookup is done in the corresponding language.  They're
+     mutable because lookup_name_info objects are typically passed
+     around by const reference (see intro), and they're conceptually
+     "cache" that can always be reconstructed from the non-mutable
+     fields.  */
+  mutable gdb::optional<ada_lookup_name_info> m_ada;
+  mutable gdb::optional<demangle_for_lookup_info> m_cplus;
+  mutable gdb::optional<demangle_for_lookup_info> m_d;
+  mutable gdb::optional<demangle_for_lookup_info> m_go;
+
+  /* The demangled hashes.  Stored in an array with one entry for each
+     possible language.  The second array records whether we've
+     already computed the each language's hash.  (These are separate
+     arrays instead of a single array of optional<unsigned> to avoid
+     alignment padding).  */
+  mutable std::array<unsigned int, nr_languages> m_demangled_hashes;
+  mutable std::array<bool, nr_languages> m_demangled_hashes_p {};
+};
+
+/* Comparison function for completion symbol lookup.
+
+   Returns true if the symbol name matches against LOOKUP_NAME.
+
+   SYMBOL_SEARCH_NAME should be a symbol's "search" name.
+
+   On success and if non-NULL, COMP_MATCH_RES->match is set to point
+   to the symbol name as should be presented to the user as a
+   completion match list element.  In most languages, this is the same
+   as the symbol's search name, but in some, like Ada, the display
+   name is dynamically computed within the comparison routine.
+
+   Also, on success and if non-NULL, COMP_MATCH_RES->match_for_lcd
+   points the part of SYMBOL_SEARCH_NAME that was considered to match
+   LOOKUP_NAME.  E.g., in C++, in linespec/wild mode, if the symbol is
+   "foo::function()" and LOOKUP_NAME is "function(", MATCH_FOR_LCD
+   points to "function()" inside SYMBOL_SEARCH_NAME.  */
+typedef bool (symbol_name_matcher_ftype)
+  (const char *symbol_search_name,
+   const lookup_name_info &lookup_name,
+   completion_match_result *comp_match_res);
 
 /* Some of the structures in this file are space critical.
    The space-critical structures are:
 
 /* Some of the structures in this file are space critical.
    The space-critical structures are:
@@ -91,6 +381,57 @@ struct cmd_list_element;
 
 struct general_symbol_info
 {
 
 struct general_symbol_info
 {
+  /* Short version as to when to use which name accessor:
+     Use natural_name () to refer to the name of the symbol in the original
+     source code.  Use linkage_name () if you want to know what the linker
+     thinks the symbol's name is.  Use print_name () for output.  Use
+     demangled_name () if you specifically need to know whether natural_name ()
+     and linkage_name () are different.  */
+
+  const char *linkage_name () const
+  { return name; }
+
+  /* Return SYMBOL's "natural" name, i.e. the name that it was called in
+     the original source code.  In languages like C++ where symbols may
+     be mangled for ease of manipulation by the linker, this is the
+     demangled name.  */
+  const char *natural_name () const;
+
+  /* Returns a version of the name of a symbol that is
+     suitable for output.  In C++ this is the "demangled" form of the
+     name if demangle is on and the "mangled" form of the name if
+     demangle is off.  In other languages this is just the symbol name.
+     The result should never be NULL.  Don't use this for internal
+     purposes (e.g. storing in a hashtable): it's only suitable for output.  */
+  const char *print_name () const
+  { return demangle ? natural_name () : linkage_name (); }
+
+  /* Return the demangled name for a symbol based on the language for
+     that symbol.  If no demangled name exists, return NULL.  */
+  const char *demangled_name () const;
+
+  /* Returns the name to be used when sorting and searching symbols.
+     In C++, we search for the demangled form of a name,
+     and so sort symbols accordingly.  In Ada, however, we search by mangled
+     name.  If there is no distinct demangled name, then this
+     returns the same value (same pointer) as linkage_name ().  */
+  const char *search_name () const;
+
+  /* Set just the linkage name of a symbol; do not try to demangle
+     it.  Used for constructs which do not have a mangled name,
+     e.g. struct tags.  Unlike SYMBOL_SET_NAMES, linkage_name must
+     be terminated and either already on the objfile's obstack or
+     permanently allocated.  */
+  void set_linkage_name (const char *linkage_name)
+  { name = linkage_name; }
+
+  enum language language () const
+  { return m_language; }
+
+  /* Initializes the language dependent portion of a symbol
+     depending upon the language for the symbol.  */
+  void set_language (enum language language, struct obstack *obstack);
+
   /* Name of the symbol.  This is a required field.  Storage for the
      name is allocated on the objfile_obstack for the associated
      objfile.  For languages like C++ that make a distinction between
   /* Name of the symbol.  This is a required field.  Storage for the
      name is allocated on the objfile_obstack for the associated
      objfile.  For languages like C++ that make a distinction between
@@ -136,12 +477,8 @@ struct general_symbol_info
     struct obstack *obstack;
 
     /* This is used by languages which wish to store a demangled name.
     struct obstack *obstack;
 
     /* This is used by languages which wish to store a demangled name.
-       currently used by Ada, C++, Java, and Objective C.  */
-    struct mangled_lang
-    {
-      const char *demangled_name;
-    }
-    mangled_lang;
+       currently used by Ada, C++, and Objective C.  */
+    const char *demangled_name;
   }
   language_specific;
 
   }
   language_specific;
 
@@ -149,9 +486,9 @@ struct general_symbol_info
      This is used to select one of the fields from the language specific
      union above.  */
 
      This is used to select one of the fields from the language specific
      union above.  */
 
-  ENUM_BITFIELD(language) language : LANGUAGE_BITS;
+  ENUM_BITFIELD(language) m_language : LANGUAGE_BITS;
 
 
-  /* This is only used by Ada.  If set, then the 'mangled_lang' field
+  /* This is only used by Ada.  If set, then the 'demangled_name' field
      of language_specific is valid.  Otherwise, the 'obstack' field is
      valid.  */
   unsigned int ada_mangled : 1;
      of language_specific is valid.  Otherwise, the 'obstack' field is
      valid.  */
   unsigned int ada_mangled : 1;
@@ -172,111 +509,68 @@ extern const char *symbol_get_demangled_name
 
 extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
 
 
 extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
 
-/* Note that all the following SYMBOL_* macros are used with the
-   SYMBOL argument being either a partial symbol or
-   a full symbol.  Both types have a ginfo field.  In particular
-   the SYMBOL_SET_LANGUAGE, SYMBOL_DEMANGLED_NAME, etc.
-   macros cannot be entirely substituted by
-   functions, unless the callers are changed to pass in the ginfo
-   field only, instead of the SYMBOL parameter.  */
-
-#define SYMBOL_VALUE(symbol)           (symbol)->ginfo.value.ivalue
-#define SYMBOL_VALUE_ADDRESS(symbol)   (symbol)->ginfo.value.address
-#define SYMBOL_VALUE_BYTES(symbol)     (symbol)->ginfo.value.bytes
-#define SYMBOL_VALUE_COMMON_BLOCK(symbol) (symbol)->ginfo.value.common_block
-#define SYMBOL_BLOCK_VALUE(symbol)     (symbol)->ginfo.value.block
-#define SYMBOL_VALUE_CHAIN(symbol)     (symbol)->ginfo.value.chain
-#define SYMBOL_LANGUAGE(symbol)                (symbol)->ginfo.language
-#define SYMBOL_SECTION(symbol)         (symbol)->ginfo.section
+/* Return the address of SYM.  The MAYBE_COPIED flag must be set on
+   SYM.  If SYM appears in the main program's minimal symbols, then
+   that minsym's address is returned; otherwise, SYM's address is
+   returned.  This should generally only be used via the
+   SYMBOL_VALUE_ADDRESS macro.  */
+
+extern CORE_ADDR get_symbol_address (const struct symbol *sym);
+
+/* Note that these macros only work with symbol, not partial_symbol.  */
+
+#define SYMBOL_VALUE(symbol)           (symbol)->value.ivalue
+#define SYMBOL_VALUE_ADDRESS(symbol)                         \
+  (((symbol)->maybe_copied) ? get_symbol_address (symbol)     \
+   : ((symbol)->value.address))
+#define SET_SYMBOL_VALUE_ADDRESS(symbol, new_value)    \
+  ((symbol)->value.address = (new_value))
+#define SYMBOL_VALUE_BYTES(symbol)     (symbol)->value.bytes
+#define SYMBOL_VALUE_COMMON_BLOCK(symbol) (symbol)->value.common_block
+#define SYMBOL_BLOCK_VALUE(symbol)     (symbol)->value.block
+#define SYMBOL_VALUE_CHAIN(symbol)     (symbol)->value.chain
+#define SYMBOL_SECTION(symbol)         (symbol)->section
 #define SYMBOL_OBJ_SECTION(objfile, symbol)                    \
 #define SYMBOL_OBJ_SECTION(objfile, symbol)                    \
-  (((symbol)->ginfo.section >= 0)                              \
-   ? (&(((objfile)->sections)[(symbol)->ginfo.section]))       \
+  (((symbol)->section >= 0)                            \
+   ? (&(((objfile)->sections)[(symbol)->section]))     \
    : NULL)
 
    : NULL)
 
-/* Initializes the language dependent portion of a symbol
-   depending upon the language for the symbol.  */
-#define SYMBOL_SET_LANGUAGE(symbol,language,obstack)   \
-  (symbol_set_language (&(symbol)->ginfo, (language), (obstack)))
-extern void symbol_set_language (struct general_symbol_info *symbol,
-                                 enum language language,
-                                struct obstack *obstack);
-
-/* Set just the linkage name of a symbol; do not try to demangle
-   it.  Used for constructs which do not have a mangled name,
-   e.g. struct tags.  Unlike SYMBOL_SET_NAMES, linkage_name must
-   be terminated and either already on the objfile's obstack or
-   permanently allocated.  */
-#define SYMBOL_SET_LINKAGE_NAME(symbol,linkage_name) \
-  (symbol)->ginfo.name = (linkage_name)
+/* Try to determine the demangled name for a symbol, based on the
+   language of that symbol.  If the language is set to language_auto,
+   it will attempt to find any demangling algorithm that works and
+   then set the language appropriately.  The returned name is allocated
+   by the demangler and should be xfree'd.  */
+
+extern char *symbol_find_demangled_name (struct general_symbol_info *gsymbol,
+                                        const char *mangled);
 
 /* Set the linkage and natural names of a symbol, by demangling
 
 /* Set the linkage and natural names of a symbol, by demangling
-   the linkage name.  */
-#define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)    \
-  symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, objfile)
+   the linkage name.  If linkage_name may not be nullterminated,
+   copy_name must be set to true.  */
+#define SYMBOL_SET_NAMES(symbol,linkage_name,copy_name,objfile)        \
+  symbol_set_names ((symbol), linkage_name, copy_name, \
+                   (objfile)->per_bfd)
 extern void symbol_set_names (struct general_symbol_info *symbol,
 extern void symbol_set_names (struct general_symbol_info *symbol,
-                             const char *linkage_name, int len, int copy_name,
-                             struct objfile *objfile);
-
-/* Now come lots of name accessor macros.  Short version as to when to
-   use which: Use SYMBOL_NATURAL_NAME to refer to the name of the
-   symbol in the original source code.  Use SYMBOL_LINKAGE_NAME if you
-   want to know what the linker thinks the symbol's name is.  Use
-   SYMBOL_PRINT_NAME for output.  Use SYMBOL_DEMANGLED_NAME if you
-   specifically need to know whether SYMBOL_NATURAL_NAME and
-   SYMBOL_LINKAGE_NAME are different.  */
-
-/* Return SYMBOL's "natural" name, i.e. the name that it was called in
-   the original source code.  In languages like C++ where symbols may
-   be mangled for ease of manipulation by the linker, this is the
-   demangled name.  */
-
-#define SYMBOL_NATURAL_NAME(symbol) \
-  (symbol_natural_name (&(symbol)->ginfo))
-extern const char *symbol_natural_name
-  (const struct general_symbol_info *symbol);
-
-/* Return SYMBOL's name from the point of view of the linker.  In
-   languages like C++ where symbols may be mangled for ease of
-   manipulation by the linker, this is the mangled name; otherwise,
-   it's the same as SYMBOL_NATURAL_NAME.  */
-
-#define SYMBOL_LINKAGE_NAME(symbol)    (symbol)->ginfo.name
-
-/* Return the demangled name for a symbol based on the language for
-   that symbol.  If no demangled name exists, return NULL.  */
-#define SYMBOL_DEMANGLED_NAME(symbol) \
-  (symbol_demangled_name (&(symbol)->ginfo))
-extern const char *symbol_demangled_name
-  (const struct general_symbol_info *symbol);
-
-/* Macro that returns a version of the name of a symbol that is
-   suitable for output.  In C++ this is the "demangled" form of the
-   name if demangle is on and the "mangled" form of the name if
-   demangle is off.  In other languages this is just the symbol name.
-   The result should never be NULL.  Don't use this for internal
-   purposes (e.g. storing in a hashtable): it's only suitable for output.
-
-   N.B. symbol may be anything with a ginfo member,
-   e.g., struct symbol or struct minimal_symbol.  */
-
-#define SYMBOL_PRINT_NAME(symbol)                                      \
-  (demangle ? SYMBOL_NATURAL_NAME (symbol) : SYMBOL_LINKAGE_NAME (symbol))
-extern int demangle;
-
-/* Macro that returns the name to be used when sorting and searching symbols.
-   In  C++ and Java, we search for the demangled form of a name,
-   and so sort symbols accordingly.  In Ada, however, we search by mangled
-   name.  If there is no distinct demangled name, then SYMBOL_SEARCH_NAME
-   returns the same value (same pointer) as SYMBOL_LINKAGE_NAME.  */
-#define SYMBOL_SEARCH_NAME(symbol)                                      \
-   (symbol_search_name (&(symbol)->ginfo))
-extern const char *symbol_search_name (const struct general_symbol_info *);
-
-/* Return non-zero if NAME matches the "search" name of SYMBOL.
-   Whitespace and trailing parentheses are ignored.
-   See strcmp_iw for details about its behavior.  */
-#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name)                       \
-  (strcmp_iw (SYMBOL_SEARCH_NAME (symbol), (name)) == 0)
+                             gdb::string_view linkage_name, bool copy_name,
+                             struct objfile_per_bfd_storage *per_bfd,
+                             gdb::optional<hashval_t> hash
+                               = gdb::optional<hashval_t> ());
+
+/* Return true if NAME matches the "search" name of SYMBOL, according
+   to the symbol's language.  */
+#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name)                       \
+  symbol_matches_search_name ((symbol), (name))
+
+/* Helper for SYMBOL_MATCHES_SEARCH_NAME that works with both symbols
+   and psymbols.  */
+extern bool symbol_matches_search_name
+  (const struct general_symbol_info *gsymbol,
+   const lookup_name_info &name);
+
+/* Compute the hash of the given symbol search name of a symbol of
+   language LANGUAGE.  */
+extern unsigned int search_name_hash (enum language language,
+                                     const char *search_name);
 
 /* Classification types for a minimal symbol.  These should be taken as
    "advisory only", since if gdb can't easily figure out a
 
 /* Classification types for a minimal symbol.  These should be taken as
    "advisory only", since if gdb can't easily figure out a
@@ -290,8 +584,26 @@ enum minimal_symbol_type
 {
   mst_unknown = 0,             /* Unknown type, the default */
   mst_text,                    /* Generally executable instructions */
 {
   mst_unknown = 0,             /* Unknown type, the default */
   mst_text,                    /* Generally executable instructions */
-  mst_text_gnu_ifunc,          /* Executable code returning address
+
+  /* A GNU ifunc symbol, in the .text section.  GDB uses to know
+     whether the user is setting a breakpoint on a GNU ifunc function,
+     and thus GDB needs to actually set the breakpoint on the target
+     function.  It is also used to know whether the program stepped
+     into an ifunc resolver -- the resolver may get a separate
+     symbol/alias under a different name, but it'll have the same
+     address as the ifunc symbol.  */
+  mst_text_gnu_ifunc,           /* Executable code returning address
+                                  of executable code */
+
+  /* A GNU ifunc function descriptor symbol, in a data section
+     (typically ".opd").  Seen on architectures that use function
+     descriptors, like PPC64/ELFv1.  In this case, this symbol's value
+     is the address of the descriptor.  There'll be a corresponding
+     mst_text_gnu_ifunc synthetic symbol for the text/entry
+     address.  */
+  mst_data_gnu_ifunc,          /* Executable code returning address
                                   of executable code */
                                   of executable code */
+
   mst_slot_got_plt,            /* GOT entries for .plt sections */
   mst_data,                    /* Generally initialized data */
   mst_bss,                     /* Generally uninitialized data */
   mst_slot_got_plt,            /* GOT entries for .plt sections */
   mst_data,                    /* Generally initialized data */
   mst_bss,                     /* Generally uninitialized data */
@@ -330,16 +642,8 @@ gdb_static_assert (nr_minsym_types <= (1 << MINSYM_TYPE_BITS));
    between names and addresses, and vice versa.  They are also sometimes
    used to figure out what full symbol table entries need to be read in.  */
 
    between names and addresses, and vice versa.  They are also sometimes
    used to figure out what full symbol table entries need to be read in.  */
 
-struct minimal_symbol
+struct minimal_symbol : public general_symbol_info
 {
 {
-
-  /* The general symbol info required for all types of symbols.
-
-     The SYMBOL_VALUE_ADDRESS contains the address that this symbol
-     corresponds to.  */
-
-  struct general_symbol_info mginfo;
-
   /* Size of this symbol.  dbx_end_psymtab in dbxread.c uses this
      information to calculate the end of the partial symtab based on the
      address of the last symbol plus the size of the last symbol.  */
   /* Size of this symbol.  dbx_end_psymtab in dbxread.c uses this
      information to calculate the end of the partial symtab based on the
      address of the last symbol plus the size of the last symbol.  */
@@ -366,6 +670,18 @@ struct minimal_symbol
      the object file format may not carry that piece of information.  */
   unsigned int has_size : 1;
 
      the object file format may not carry that piece of information.  */
   unsigned int has_size : 1;
 
+  /* For data symbols only, if this is set, then the symbol might be
+     subject to copy relocation.  In this case, a minimal symbol
+     matching the symbol's linkage name is first looked for in the
+     main objfile.  If found, then that address is used; otherwise the
+     address in this symbol is used.  */
+
+  unsigned maybe_copied : 1;
+
+  /* Non-zero if this symbol ever had its demangled name set (even if
+     it was set to NULL).  */
+  unsigned int name_set : 1;
+
   /* Minimal symbols with the same hash key are kept on a linked
      list.  This is the link.  */
 
   /* Minimal symbols with the same hash key are kept on a linked
      list.  This is the link.  */
 
@@ -375,8 +691,25 @@ struct minimal_symbol
      the `next' pointer for the demangled hash table.  */
 
   struct minimal_symbol *demangled_hash_next;
      the `next' pointer for the demangled hash table.  */
 
   struct minimal_symbol *demangled_hash_next;
+
+  /* True if this symbol is of some data type.  */
+
+  bool data_p () const;
+
+  /* True if MSYMBOL is of some text type.  */
+
+  bool text_p () const;
 };
 
 };
 
+/* Return the address of MINSYM, which comes from OBJF.  The
+   MAYBE_COPIED flag must be set on MINSYM.  If MINSYM appears in the
+   main program's minimal symbols, then that minsym's address is
+   returned; otherwise, MINSYM's address is returned.  This should
+   generally only be used via the MSYMBOL_VALUE_ADDRESS macro.  */
+
+extern CORE_ADDR get_msymbol_address (struct objfile *objf,
+                                     const struct minimal_symbol *minsym);
+
 #define MSYMBOL_TARGET_FLAG_1(msymbol)  (msymbol)->target_flag_1
 #define MSYMBOL_TARGET_FLAG_2(msymbol)  (msymbol)->target_flag_2
 #define MSYMBOL_SIZE(msymbol)          ((msymbol)->size + 0)
 #define MSYMBOL_TARGET_FLAG_1(msymbol)  (msymbol)->target_flag_1
 #define MSYMBOL_TARGET_FLAG_2(msymbol)  (msymbol)->target_flag_2
 #define MSYMBOL_SIZE(msymbol)          ((msymbol)->size + 0)
@@ -389,45 +722,29 @@ struct minimal_symbol
 #define MSYMBOL_HAS_SIZE(msymbol)      ((msymbol)->has_size + 0)
 #define MSYMBOL_TYPE(msymbol)          (msymbol)->type
 
 #define MSYMBOL_HAS_SIZE(msymbol)      ((msymbol)->has_size + 0)
 #define MSYMBOL_TYPE(msymbol)          (msymbol)->type
 
-#define MSYMBOL_VALUE(symbol)          (symbol)->mginfo.value.ivalue
+#define MSYMBOL_VALUE(symbol)          (symbol)->value.ivalue
 /* The unrelocated address of the minimal symbol.  */
 /* The unrelocated address of the minimal symbol.  */
-#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->mginfo.value.address + 0)
+#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->value.address + 0)
 /* The relocated address of the minimal symbol, using the section
    offsets from OBJFILE.  */
 #define MSYMBOL_VALUE_ADDRESS(objfile, symbol)                         \
 /* The relocated address of the minimal symbol, using the section
    offsets from OBJFILE.  */
 #define MSYMBOL_VALUE_ADDRESS(objfile, symbol)                         \
-  ((symbol)->mginfo.value.address                                      \
-   + ANOFFSET ((objfile)->section_offsets, ((symbol)->mginfo.section)))
+  (((symbol)->maybe_copied) ? get_msymbol_address (objfile, symbol)    \
+   : ((symbol)->value.address                                          \
+      + ANOFFSET ((objfile)->section_offsets, ((symbol)->section))))
 /* For a bound minsym, we can easily compute the address directly.  */
 #define BMSYMBOL_VALUE_ADDRESS(symbol) \
   MSYMBOL_VALUE_ADDRESS ((symbol).objfile, (symbol).minsym)
 #define SET_MSYMBOL_VALUE_ADDRESS(symbol, new_value)   \
 /* For a bound minsym, we can easily compute the address directly.  */
 #define BMSYMBOL_VALUE_ADDRESS(symbol) \
   MSYMBOL_VALUE_ADDRESS ((symbol).objfile, (symbol).minsym)
 #define SET_MSYMBOL_VALUE_ADDRESS(symbol, new_value)   \
-  ((symbol)->mginfo.value.address = (new_value))
-#define MSYMBOL_VALUE_BYTES(symbol)    (symbol)->mginfo.value.bytes
-#define MSYMBOL_BLOCK_VALUE(symbol)    (symbol)->mginfo.value.block
-#define MSYMBOL_VALUE_CHAIN(symbol)    (symbol)->mginfo.value.chain
-#define MSYMBOL_LANGUAGE(symbol)       (symbol)->mginfo.language
-#define MSYMBOL_SECTION(symbol)                (symbol)->mginfo.section
+  ((symbol)->value.address = (new_value))
+#define MSYMBOL_VALUE_BYTES(symbol)    (symbol)->value.bytes
+#define MSYMBOL_BLOCK_VALUE(symbol)    (symbol)->value.block
+#define MSYMBOL_VALUE_CHAIN(symbol)    (symbol)->value.chain
+#define MSYMBOL_SECTION(symbol)                (symbol)->section
 #define MSYMBOL_OBJ_SECTION(objfile, symbol)                   \
 #define MSYMBOL_OBJ_SECTION(objfile, symbol)                   \
-  (((symbol)->mginfo.section >= 0)                             \
-   ? (&(((objfile)->sections)[(symbol)->mginfo.section]))      \
+  (((symbol)->section >= 0)                            \
+   ? (&(((objfile)->sections)[(symbol)->section]))     \
    : NULL)
 
    : NULL)
 
-#define MSYMBOL_NATURAL_NAME(symbol) \
-  (symbol_natural_name (&(symbol)->mginfo))
-#define MSYMBOL_LINKAGE_NAME(symbol)   (symbol)->mginfo.name
-#define MSYMBOL_PRINT_NAME(symbol)                                     \
-  (demangle ? MSYMBOL_NATURAL_NAME (symbol) : MSYMBOL_LINKAGE_NAME (symbol))
-#define MSYMBOL_DEMANGLED_NAME(symbol) \
-  (symbol_demangled_name (&(symbol)->mginfo))
-#define MSYMBOL_SET_LANGUAGE(symbol,language,obstack)  \
-  (symbol_set_language (&(symbol)->mginfo, (language), (obstack)))
-#define MSYMBOL_SEARCH_NAME(symbol)                                     \
-   (symbol_search_name (&(symbol)->mginfo))
-#define MSYMBOL_MATCHES_SEARCH_NAME(symbol, name)                      \
-  (strcmp_iw (MSYMBOL_SEARCH_NAME (symbol), (name)) == 0)
-#define MSYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)   \
-  symbol_set_names (&(symbol)->mginfo, linkage_name, len, copy_name, objfile)
-
 #include "minsyms.h"
 
 \f
 #include "minsyms.h"
 
 \f
@@ -479,7 +796,7 @@ gdb_static_assert (NR_DOMAINS <= (1 << SYMBOL_DOMAIN_BITS));
 
 extern const char *domain_name (domain_enum);
 
 
 extern const char *domain_name (domain_enum);
 
-/* Searching domains, used for `search_symbols'.  Element numbers are
+/* Searching domains, used when searching for symbols.  Element numbers are
    hardcoded in GDB, check all enum uses before changing it.  */
 
 enum search_domain
    hardcoded in GDB, check all enum uses before changing it.  */
 
 enum search_domain
@@ -494,8 +811,11 @@ enum search_domain
   /* All defined types */
   TYPES_DOMAIN = 2,
 
   /* All defined types */
   TYPES_DOMAIN = 2,
 
+  /* All modules.  */
+  MODULES_DOMAIN = 3,
+
   /* Any type.  */
   /* Any type.  */
-  ALL_DOMAIN = 3
+  ALL_DOMAIN = 4
 };
 
 extern const char *search_domain_name (enum search_domain);
 };
 
 extern const char *search_domain_name (enum search_domain);
@@ -584,7 +904,13 @@ enum address_class
      not find it in the full symbol table.  But a reference to an external
      symbol in a local block shadowing other definition requires full symbol
      without possibly having its address available for LOC_STATIC.  Testcase
      not find it in the full symbol table.  But a reference to an external
      symbol in a local block shadowing other definition requires full symbol
      without possibly having its address available for LOC_STATIC.  Testcase
-     is provided as `gdb.dwarf2/dw2-unresolved.exp'.  */
+     is provided as `gdb.dwarf2/dw2-unresolved.exp'.
+
+     This is also used for thread local storage (TLS) variables.  In this case,
+     the address of the TLS variable must be determined when the variable is
+     referenced, from the MSYMBOL_VALUE_RAW_ADDRESS, which is the offset
+     of the TLS variable in the thread local storage of the shared
+     library/object.  */
 
   LOC_UNRESOLVED,
 
 
   LOC_UNRESOLVED,
 
@@ -626,7 +952,8 @@ struct symbol_computed_ops
      frame FRAME.  If the variable has been optimized out, return
      zero.
 
      frame FRAME.  If the variable has been optimized out, return
      zero.
 
-     Iff `read_needs_frame (SYMBOL)' is zero, then FRAME may be zero.  */
+     Iff `read_needs_frame (SYMBOL)' is not SYMBOL_NEEDS_FRAME, then
+     FRAME may be zero.  */
 
   struct value *(*read_variable) (struct symbol * symbol,
                                  struct frame_info * frame);
 
   struct value *(*read_variable) (struct symbol * symbol,
                                  struct frame_info * frame);
@@ -637,8 +964,11 @@ struct symbol_computed_ops
   struct value *(*read_variable_at_entry) (struct symbol *symbol,
                                           struct frame_info *frame);
 
   struct value *(*read_variable_at_entry) (struct symbol *symbol,
                                           struct frame_info *frame);
 
-  /* Return non-zero if we need a frame to find the value of the SYMBOL.  */
-  int (*read_needs_frame) (struct symbol * symbol);
+  /* Find the "symbol_needs_kind" value for the given symbol.  This
+     value determines whether reading the symbol needs memory (e.g., a
+     global variable), just registers (a thread-local), or a frame (a
+     local variable).  */
+  enum symbol_needs_kind (*get_symbol_read_needs) (struct symbol * symbol);
 
   /* Write to STREAM a natural-language description of the location of
      SYMBOL, in the context of ADDR.  */
 
   /* Write to STREAM a natural-language description of the location of
      SYMBOL, in the context of ADDR.  */
@@ -655,8 +985,8 @@ struct symbol_computed_ops
      the caller will generate the right code in the process of
      treating this as an lvalue or rvalue.  */
 
      the caller will generate the right code in the process of
      treating this as an lvalue or rvalue.  */
 
-  void (*tracepoint_var_ref) (struct symbol *symbol, struct gdbarch *gdbarch,
-                             struct agent_expr *ax, struct axs_value *value);
+  void (*tracepoint_var_ref) (struct symbol *symbol, struct agent_expr *ax,
+                             struct axs_value *value);
 
   /* Generate C code to compute the location of SYMBOL.  The C code is
      emitted to STREAM.  GDBARCH is the current architecture and PC is
 
   /* Generate C code to compute the location of SYMBOL.  The C code is
      emitted to STREAM.  GDBARCH is the current architecture and PC is
@@ -667,7 +997,7 @@ struct symbol_computed_ops
      The generated C code must assign the location to a local
      variable; this variable's name is RESULT_NAME.  */
 
      The generated C code must assign the location to a local
      variable; this variable's name is RESULT_NAME.  */
 
-  void (*generate_c_location) (struct symbol *symbol, struct ui_file *stream,
+  void (*generate_c_location) (struct symbol *symbol, string_file *stream,
                               struct gdbarch *gdbarch,
                               unsigned char *registers_used,
                               CORE_ADDR pc, const char *result_name);
                               struct gdbarch *gdbarch,
                               unsigned char *registers_used,
                               CORE_ADDR pc, const char *result_name);
@@ -699,7 +1029,7 @@ struct symbol_block_ops
      register, the CFA as defined by DWARF unwinding information, ...
 
      So this specific method is supposed to compute the frame base address such
      register, the CFA as defined by DWARF unwinding information, ...
 
      So this specific method is supposed to compute the frame base address such
-     as for nested fuctions, the static link computes the same address.  For
+     as for nested functions, the static link computes the same address.  For
      instance, considering DWARF debugging information, the static link is
      computed with DW_AT_static_link and this method must be used to compute
      the corresponding DW_AT_frame_base attribute.  */
      instance, considering DWARF debugging information, the static link is
      computed with DW_AT_static_link and this method must be used to compute
      the corresponding DW_AT_frame_base attribute.  */
@@ -731,18 +1061,51 @@ struct symbol_impl
   const struct symbol_register_ops *ops_register;
 };
 
   const struct symbol_register_ops *ops_register;
 };
 
-/* This structure is space critical.  See space comments at the top.  */
+/* struct symbol has some subclasses.  This enum is used to
+   differentiate between them.  */
 
 
-struct symbol
+enum symbol_subclass_kind
 {
 {
+  /* Plain struct symbol.  */
+  SYMBOL_NONE,
 
 
-  /* The general symbol info required for all types of symbols.  */
+  /* struct template_symbol.  */
+  SYMBOL_TEMPLATE,
 
 
-  struct general_symbol_info ginfo;
+  /* struct rust_vtable_symbol.  */
+  SYMBOL_RUST_VTABLE
+};
+
+/* This structure is space critical.  See space comments at the top.  */
+
+struct symbol : public general_symbol_info, public allocate_on_obstack
+{
+  symbol ()
+    /* Class-initialization of bitfields is only allowed in C++20.  */
+    : domain (UNDEF_DOMAIN),
+      aclass_index (0),
+      is_objfile_owned (0),
+      is_argument (0),
+      is_inlined (0),
+      maybe_copied (0),
+      subclass (SYMBOL_NONE)
+    {
+      /* We can't use an initializer list for members of a base class, and
+         general_symbol_info needs to stay a POD type.  */
+      name = nullptr;
+      value.ivalue = 0;
+      language_specific.obstack = nullptr;
+      m_language = language_unknown;
+      ada_mangled = 0;
+      section = 0;
+      /* GCC 4.8.5 (on CentOS 7) does not correctly compile class-
+         initialization of unions, so we initialize it manually here.  */
+      owner.symtab = nullptr;
+    }
 
   /* Data type of value */
 
 
   /* Data type of value */
 
-  struct type *type;
+  struct type *type = nullptr;
 
   /* The owner of this symbol.
      Which one to use is defined by symbol.is_objfile_owned.  */
 
   /* The owner of this symbol.
      Which one to use is defined by symbol.is_objfile_owned.  */
@@ -769,7 +1132,7 @@ struct symbol
   unsigned int aclass_index : SYMBOL_ACLASS_BITS;
 
   /* If non-zero then symbol is objfile-owned, use owner.symtab.
   unsigned int aclass_index : SYMBOL_ACLASS_BITS;
 
   /* If non-zero then symbol is objfile-owned, use owner.symtab.
-     Otherwise symbol is arch-owned, use owner.arch.  */
+       Otherwise symbol is arch-owned, use owner.arch.  */
 
   unsigned int is_objfile_owned : 1;
 
 
   unsigned int is_objfile_owned : 1;
 
@@ -780,9 +1143,17 @@ struct symbol
   /* Whether this is an inlined function (class LOC_BLOCK only).  */
   unsigned is_inlined : 1;
 
   /* Whether this is an inlined function (class LOC_BLOCK only).  */
   unsigned is_inlined : 1;
 
-  /* True if this is a C++ function symbol with template arguments.
-     In this case the symbol is really a "struct template_symbol".  */
-  unsigned is_cplus_template_function : 1;
+  /* For LOC_STATIC only, if this is set, then the symbol might be
+     subject to copy relocation.  In this case, a minimal symbol
+     matching the symbol's linkage name is first looked for in the
+     main objfile.  If found, then that address is used; otherwise the
+     address in this symbol is used.  */
+
+  unsigned maybe_copied : 1;
+
+  /* The concrete type of this symbol.  */
+
+  ENUM_BITFIELD (symbol_subclass_kind) subclass : 2;
 
   /* Line number of this symbol's definition, except for inlined
      functions.  For an inlined function (class LOC_BLOCK and
 
   /* Line number of this symbol's definition, except for inlined
      functions.  For an inlined function (class LOC_BLOCK and
@@ -795,24 +1166,23 @@ struct symbol
      to debug files longer than 64K lines?  What about machine
      generated programs?  */
 
      to debug files longer than 64K lines?  What about machine
      generated programs?  */
 
-  unsigned short line;
+  unsigned short line = 0;
 
   /* An arbitrary data pointer, allowing symbol readers to record
      additional information on a per-symbol basis.  Note that this data
      must be allocated using the same obstack as the symbol itself.  */
 
   /* An arbitrary data pointer, allowing symbol readers to record
      additional information on a per-symbol basis.  Note that this data
      must be allocated using the same obstack as the symbol itself.  */
-  /* So far it is only used by LOC_COMPUTED to
-     find the location information.  For a LOC_BLOCK symbol
-     for a function in a compilation unit compiled with DWARF 2
-     information, this is information used internally by the DWARF 2
-     code --- specifically, the location expression for the frame
+  /* So far it is only used by:
+     LOC_COMPUTED: to find the location information
+     LOC_BLOCK (DWARF2 function): information used internally by the
+     DWARF 2 code --- specifically, the location expression for the frame
      base for this function.  */
   /* FIXME drow/2003-02-21: For the LOC_BLOCK case, it might be better
      to add a magic symbol to the block containing this information,
      or to have a generic debug info annotation slot for symbols.  */
 
      base for this function.  */
   /* FIXME drow/2003-02-21: For the LOC_BLOCK case, it might be better
      to add a magic symbol to the block containing this information,
      or to have a generic debug info annotation slot for symbols.  */
 
-  void *aux_value;
+  void *aux_value = nullptr;
 
 
-  struct symbol *hash_next;
+  struct symbol *hash_next = nullptr;
 };
 
 /* Several lookup functions return both a symbol and the block in which the
 };
 
 /* Several lookup functions return both a symbol and the block in which the
@@ -841,7 +1211,7 @@ extern const struct symbol_impl *symbol_impls;
 #define SYMBOL_IS_ARGUMENT(symbol)     (symbol)->is_argument
 #define SYMBOL_INLINED(symbol)         (symbol)->is_inlined
 #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
 #define SYMBOL_IS_ARGUMENT(symbol)     (symbol)->is_argument
 #define SYMBOL_INLINED(symbol)         (symbol)->is_inlined
 #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
-  (symbol)->is_cplus_template_function
+  (((symbol)->subclass) == SYMBOL_TEMPLATE)
 #define SYMBOL_TYPE(symbol)            (symbol)->type
 #define SYMBOL_LINE(symbol)            (symbol)->line
 #define SYMBOL_COMPUTED_OPS(symbol)    (SYMBOL_IMPL (symbol).ops_computed)
 #define SYMBOL_TYPE(symbol)            (symbol)->type
 #define SYMBOL_LINE(symbol)            (symbol)->line
 #define SYMBOL_COMPUTED_OPS(symbol)    (SYMBOL_IMPL (symbol).ops_computed)
@@ -881,22 +1251,26 @@ extern struct symtab *symbol_symtab (const struct symbol *symbol);
 extern void symbol_set_symtab (struct symbol *symbol, struct symtab *symtab);
 
 /* An instance of this type is used to represent a C++ template
 extern void symbol_set_symtab (struct symbol *symbol, struct symtab *symtab);
 
 /* An instance of this type is used to represent a C++ template
-   function.  It includes a "struct symbol" as a kind of base class;
-   users downcast to "struct template_symbol *" when needed.  A symbol
-   is really of this type iff SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION is
-   true.  */
+   function.  A symbol is really of this type iff
+   SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION is true.  */
 
 
-struct template_symbol
+struct template_symbol : public symbol
 {
 {
-  /* The base class.  */
-  struct symbol base;
-
   /* The number of template arguments.  */
   /* The number of template arguments.  */
-  int n_template_arguments;
+  int n_template_arguments = 0;
 
   /* The template arguments.  This is an array with
      N_TEMPLATE_ARGUMENTS elements.  */
 
   /* The template arguments.  This is an array with
      N_TEMPLATE_ARGUMENTS elements.  */
-  struct symbol **template_arguments;
+  struct symbol **template_arguments = nullptr;
+};
+
+/* A symbol that represents a Rust virtual table object.  */
+
+struct rust_vtable_symbol : public symbol
+{
+  /* The concrete type for which this vtable was created; that is, in
+     "impl Trait for Type", this is "Type".  */
+  struct type *concrete_type = nullptr;
 };
 
 \f
 };
 
 \f
@@ -988,16 +1362,6 @@ struct symtab
 
   const char *filename;
 
 
   const char *filename;
 
-  /* Total number of lines found in source file.  */
-
-  int nlines;
-
-  /* line_charpos[N] is the position of the (N-1)th line of the
-     source file.  "position" means something we can lseek() to; it
-     is not guaranteed to be useful any other way.  */
-
-  int *line_charpos;
-
   /* Language of this source file.  */
 
   enum language language;
   /* Language of this source file.  */
 
   enum language language;
@@ -1019,9 +1383,6 @@ struct symtab
 #define SYMTAB_DIRNAME(symtab) \
   COMPUNIT_DIRNAME (SYMTAB_COMPUNIT (symtab))
 
 #define SYMTAB_DIRNAME(symtab) \
   COMPUNIT_DIRNAME (SYMTAB_COMPUNIT (symtab))
 
-typedef struct symtab *symtab_ptr;
-DEF_VEC_P (symtab_ptr);
-
 /* Compunit symtabs contain the actual "symbol table", aka blockvector, as well
    as the list of all source files (what gdb has historically associated with
    the term "symtab").
 /* Compunit symtabs contain the actual "symbol table", aka blockvector, as well
    as the list of all source files (what gdb has historically associated with
    the term "symtab").
@@ -1149,10 +1510,16 @@ struct compunit_symtab
 #define COMPUNIT_CALL_SITE_HTAB(cust) ((cust)->call_site_htab)
 #define COMPUNIT_MACRO_TABLE(cust) ((cust)->macro_table)
 
 #define COMPUNIT_CALL_SITE_HTAB(cust) ((cust)->call_site_htab)
 #define COMPUNIT_MACRO_TABLE(cust) ((cust)->macro_table)
 
-/* Iterate over all file tables (struct symtab) within a compunit.  */
+/* A range adapter to allowing iterating over all the file tables
+   within a compunit.  */
 
 
-#define ALL_COMPUNIT_FILETABS(cu, s) \
-  for ((s) = (cu) -> filetabs; (s) != NULL; (s) = (s) -> next)
+struct compunit_filetabs : public next_adapter<struct symtab>
+{
+  compunit_filetabs (struct compunit_symtab *cu)
+    : next_adapter<struct symtab> (cu->filetabs)
+  {
+  }
+};
 
 /* Return the primary symtab of CUST.  */
 
 
 /* Return the primary symtab of CUST.  */
 
@@ -1163,9 +1530,6 @@ extern struct symtab *
 
 extern enum language compunit_language (const struct compunit_symtab *cust);
 
 
 extern enum language compunit_language (const struct compunit_symtab *cust);
 
-typedef struct compunit_symtab *compunit_symtab_ptr;
-DEF_VEC_P (compunit_symtab_ptr);
-
 \f
 
 /* The virtual function table is now an array of structures which have the
 \f
 
 /* The virtual function table is now an array of structures which have the
@@ -1195,9 +1559,9 @@ extern const char multiple_symbols_cancel[];
 
 const char *multiple_symbols_select_mode (void);
 
 
 const char *multiple_symbols_select_mode (void);
 
-int symbol_matches_domain (enum language symbol_language, 
-                          domain_enum symbol_domain,
-                          domain_enum domain);
+bool symbol_matches_domain (enum language symbol_language,
+                           domain_enum symbol_domain,
+                           domain_enum domain);
 
 /* lookup a symbol table by source file name.  */
 
 
 /* lookup a symbol table by source file name.  */
 
@@ -1248,6 +1612,19 @@ extern struct block_symbol lookup_symbol (const char *,
                                          const domain_enum,
                                          struct field_of_this_result *);
 
                                          const domain_enum,
                                          struct field_of_this_result *);
 
+/* Find the definition for a specified symbol search name in domain
+   DOMAIN, visible from lexical block BLOCK if non-NULL or from
+   global/static blocks if BLOCK is NULL.  The passed-in search name
+   should not come from the user; instead it should already be a
+   search name as retrieved from a search_name () call.  See definition of
+   symbol_name_match_type::SEARCH_NAME.  Returns the struct symbol
+   pointer, or NULL if no symbol is found.  The symbol's section is
+   fixed up if necessary.  */
+
+extern struct block_symbol lookup_symbol_search_name (const char *search_name,
+                                                     const struct block *block,
+                                                     domain_enum domain);
+
 /* A default version of lookup_symbol_nonlocal for use by languages
    that can't think of anything better to do.
    This implements the C lookup rules.  */
 /* A default version of lookup_symbol_nonlocal for use by languages
    that can't think of anything better to do.
    This implements the C lookup rules.  */
@@ -1297,6 +1674,7 @@ extern struct block_symbol
 
 extern struct symbol *
   lookup_symbol_in_block (const char *name,
 
 extern struct symbol *
   lookup_symbol_in_block (const char *name,
+                         symbol_name_match_type match_type,
                          const struct block *block,
                          const domain_enum domain);
 
                          const struct block *block,
                          const domain_enum domain);
 
@@ -1317,23 +1695,99 @@ extern struct type *lookup_enum (const char *, const struct block *);
 
 /* from blockframe.c: */
 
 
 /* from blockframe.c: */
 
-/* lookup the function symbol corresponding to the address.  */
+/* lookup the function symbol corresponding to the address.  The
+   return value will not be an inlined function; the containing
+   function will be returned instead.  */
 
 extern struct symbol *find_pc_function (CORE_ADDR);
 
 
 extern struct symbol *find_pc_function (CORE_ADDR);
 
-/* lookup the function corresponding to the address and section.  */
+/* lookup the function corresponding to the address and section.  The
+   return value will not be an inlined function; the containing
+   function will be returned instead.  */
 
 extern struct symbol *find_pc_sect_function (CORE_ADDR, struct obj_section *);
 
 
 extern struct symbol *find_pc_sect_function (CORE_ADDR, struct obj_section *);
 
-extern int find_pc_partial_function_gnu_ifunc (CORE_ADDR pc, const char **name,
+/* lookup the function symbol corresponding to the address and
+   section.  The return value will be the closest enclosing function,
+   which might be an inline function.  */
+
+extern struct symbol *find_pc_sect_containing_function
+  (CORE_ADDR pc, struct obj_section *section);
+
+/* Find the symbol at the given address.  Returns NULL if no symbol
+   found.  Only exact matches for ADDRESS are considered.  */
+
+extern struct symbol *find_symbol_at_address (CORE_ADDR);
+
+/* Finds the "function" (text symbol) that is smaller than PC but
+   greatest of all of the potential text symbols in SECTION.  Sets
+   *NAME and/or *ADDRESS conditionally if that pointer is non-null.
+   If ENDADDR is non-null, then set *ENDADDR to be the end of the
+   function (exclusive).  If the optional parameter BLOCK is non-null,
+   then set *BLOCK to the address of the block corresponding to the
+   function symbol, if such a symbol could be found during the lookup;
+   nullptr is used as a return value for *BLOCK if no block is found. 
+   This function either succeeds or fails (not halfway succeeds).  If
+   it succeeds, it sets *NAME, *ADDRESS, and *ENDADDR to real
+   information and returns true.  If it fails, it sets *NAME, *ADDRESS
+   and *ENDADDR to zero and returns false.
+   
+   If the function in question occupies non-contiguous ranges,
+   *ADDRESS and *ENDADDR are (subject to the conditions noted above) set
+   to the start and end of the range in which PC is found.  Thus
+   *ADDRESS <= PC < *ENDADDR with no intervening gaps (in which ranges
+   from other functions might be found).
+   
+   This property allows find_pc_partial_function to be used (as it had
+   been prior to the introduction of non-contiguous range support) by
+   various tdep files for finding a start address and limit address
+   for prologue analysis.  This still isn't ideal, however, because we
+   probably shouldn't be doing prologue analysis (in which
+   instructions are scanned to determine frame size and stack layout)
+   for any range that doesn't contain the entry pc.  Moreover, a good
+   argument can be made that prologue analysis ought to be performed
+   starting from the entry pc even when PC is within some other range.
+   This might suggest that *ADDRESS and *ENDADDR ought to be set to the
+   limits of the entry pc range, but that will cause the 
+   *ADDRESS <= PC < *ENDADDR condition to be violated; many of the
+   callers of find_pc_partial_function expect this condition to hold. 
+
+   Callers which require the start and/or end addresses for the range
+   containing the entry pc should instead call
+   find_function_entry_range_from_pc.  */
+
+extern bool find_pc_partial_function (CORE_ADDR pc, const char **name,
+                                     CORE_ADDR *address, CORE_ADDR *endaddr,
+                                     const struct block **block = nullptr);
+
+/* Like find_pc_partial_function, above, but *ADDRESS and *ENDADDR are
+   set to start and end addresses of the range containing the entry pc.
+
+   Note that it is not necessarily the case that (for non-NULL ADDRESS
+   and ENDADDR arguments) the *ADDRESS <= PC < *ENDADDR condition will
+   hold.
+
+   See comment for find_pc_partial_function, above, for further
+   explanation.  */
+
+extern bool find_function_entry_range_from_pc (CORE_ADDR pc,
+                                              const char **name,
                                               CORE_ADDR *address,
                                               CORE_ADDR *address,
-                                              CORE_ADDR *endaddr,
-                                              int *is_gnu_ifunc_p);
+                                              CORE_ADDR *endaddr);
+
+/* Return the type of a function with its first instruction exactly at
+   the PC address.  Return NULL otherwise.  */
 
 
-/* lookup function from address, return name, start addr and end addr.  */
+extern struct type *find_function_type (CORE_ADDR pc);
 
 
-extern int find_pc_partial_function (CORE_ADDR, const char **, CORE_ADDR *,
-                                    CORE_ADDR *);
+/* See if we can figure out the function's actual type from the type
+   that the resolver returns.  RESOLVER_FUNADDR is the address of the
+   ifunc resolver.  */
+
+extern struct type *find_gnu_ifunc_target_type (CORE_ADDR resolver_funaddr);
+
+/* Find the GNU ifunc minimal symbol that matches SYM.  */
+extern bound_minimal_symbol find_gnu_ifunc (const symbol *sym);
 
 extern void clear_pc_function_cache (void);
 
 
 extern void clear_pc_function_cache (void);
 
@@ -1350,7 +1804,7 @@ extern struct compunit_symtab *find_pc_compunit_symtab (CORE_ADDR);
 extern struct compunit_symtab *
   find_pc_sect_compunit_symtab (CORE_ADDR, struct obj_section *);
 
 extern struct compunit_symtab *
   find_pc_sect_compunit_symtab (CORE_ADDR, struct obj_section *);
 
-extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
+extern bool find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
 
 extern void reread_symbols (void);
 
 
 extern void reread_symbols (void);
 
@@ -1372,7 +1826,7 @@ extern struct type *basic_lookup_transparent_type (const char *);
 #define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
 #endif
 
 #define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
 #endif
 
-extern int in_gnu_ifunc_stub (CORE_ADDR pc);
+extern bool in_gnu_ifunc_stub (CORE_ADDR pc);
 
 /* Functions for resolving STT_GNU_IFUNC symbols which are implemented only
    for ELF symbol files.  */
 
 /* Functions for resolving STT_GNU_IFUNC symbols which are implemented only
    for ELF symbol files.  */
@@ -1383,7 +1837,7 @@ struct gnu_ifunc_fns
   CORE_ADDR (*gnu_ifunc_resolve_addr) (struct gdbarch *gdbarch, CORE_ADDR pc);
 
   /* See elf_gnu_ifunc_resolve_name for its real implementation.  */
   CORE_ADDR (*gnu_ifunc_resolve_addr) (struct gdbarch *gdbarch, CORE_ADDR pc);
 
   /* See elf_gnu_ifunc_resolve_name for its real implementation.  */
-  int (*gnu_ifunc_resolve_name) (const char *function_name,
+  bool (*gnu_ifunc_resolve_name) (const char *function_name,
                                 CORE_ADDR *function_address_p);
 
   /* See elf_gnu_ifunc_resolver_stop for its real implementation.  */
                                 CORE_ADDR *function_address_p);
 
   /* See elf_gnu_ifunc_resolver_stop for its real implementation.  */
@@ -1406,34 +1860,29 @@ extern CORE_ADDR find_solib_trampoline_target (struct frame_info *, CORE_ADDR);
 struct symtab_and_line
 {
   /* The program space of this sal.  */
 struct symtab_and_line
 {
   /* The program space of this sal.  */
-  struct program_space *pspace;
+  struct program_space *pspace = NULL;
 
 
-  struct symtab *symtab;
-  struct obj_section *section;
+  struct symtab *symtab = NULL;
+  struct symbol *symbol = NULL;
+  struct obj_section *section = NULL;
+  struct minimal_symbol *msymbol = NULL;
   /* Line number.  Line numbers start at 1 and proceed through symtab->nlines.
      0 is never a valid line number; it is used to indicate that line number
      information is not available.  */
   /* Line number.  Line numbers start at 1 and proceed through symtab->nlines.
      0 is never a valid line number; it is used to indicate that line number
      information is not available.  */
-  int line;
+  int line = 0;
 
 
-  CORE_ADDR pc;
-  CORE_ADDR end;
-  int explicit_pc;
-  int explicit_line;
+  CORE_ADDR pc = 0;
+  CORE_ADDR end = 0;
+  bool explicit_pc = false;
+  bool explicit_line = false;
 
   /* The probe associated with this symtab_and_line.  */
 
   /* The probe associated with this symtab_and_line.  */
-  struct probe *probe;
+  probe *prob = NULL;
   /* If PROBE is not NULL, then this is the objfile in which the probe
      originated.  */
   /* If PROBE is not NULL, then this is the objfile in which the probe
      originated.  */
-  struct objfile *objfile;
+  struct objfile *objfile = NULL;
 };
 
 };
 
-extern void init_sal (struct symtab_and_line *sal);
-
-struct symtabs_and_lines
-{
-  struct symtab_and_line *sals;
-  int nelts;
-};
 \f
 
 /* Given a pc value, return line number it is in.  Second arg nonzero means
 \f
 
 /* Given a pc value, return line number it is in.  Second arg nonzero means
@@ -1452,10 +1901,10 @@ extern struct symtab *find_pc_line_symtab (CORE_ADDR);
 
 /* Given a symtab and line number, return the pc there.  */
 
 
 /* Given a symtab and line number, return the pc there.  */
 
-extern int find_line_pc (struct symtab *, int, CORE_ADDR *);
+extern bool find_line_pc (struct symtab *, int, CORE_ADDR *);
 
 
-extern int find_line_pc_range (struct symtab_and_line, CORE_ADDR *,
-                              CORE_ADDR *);
+extern bool find_line_pc_range (struct symtab_and_line, CORE_ADDR *,
+                               CORE_ADDR *);
 
 extern void resolve_sal_pc (struct symtab_and_line *);
 
 
 extern void resolve_sal_pc (struct symtab_and_line *);
 
@@ -1463,57 +1912,85 @@ extern void resolve_sal_pc (struct symtab_and_line *);
 
 extern void clear_solib (void);
 
 
 extern void clear_solib (void);
 
-/* source.c */
+/* The reason we're calling into a completion match list collector
+   function.  */
+enum class complete_symbol_mode
+  {
+    /* Completing an expression.  */
+    EXPRESSION,
 
 
-extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
+    /* Completing a linespec.  */
+    LINESPEC,
+  };
 
 
-/* Flags passed as 4th argument to print_source_lines.  */
+extern void default_collect_symbol_completion_matches_break_on
+  (completion_tracker &tracker,
+   complete_symbol_mode mode,
+   symbol_name_match_type name_match_type,
+   const char *text, const char *word, const char *break_on,
+   enum type_code code);
+extern void default_collect_symbol_completion_matches
+  (completion_tracker &tracker,
+   complete_symbol_mode,
+   symbol_name_match_type name_match_type,
+   const char *,
+   const char *,
+   enum type_code);
+extern void collect_symbol_completion_matches
+  (completion_tracker &tracker,
+   complete_symbol_mode mode,
+   symbol_name_match_type name_match_type,
+   const char *, const char *);
+extern void collect_symbol_completion_matches_type (completion_tracker &tracker,
+                                                   const char *, const char *,
+                                                   enum type_code);
 
 
-enum print_source_lines_flags
-  {
-    /* Do not print an error message.  */
-    PRINT_SOURCE_LINES_NOERROR = (1 << 0),
+extern void collect_file_symbol_completion_matches
+  (completion_tracker &tracker,
+   complete_symbol_mode,
+   symbol_name_match_type name_match_type,
+   const char *, const char *, const char *);
 
 
-    /* Print the filename in front of the source lines.  */
-    PRINT_SOURCE_LINES_FILENAME = (1 << 1)
-  };
+extern completion_list
+  make_source_files_completion_list (const char *, const char *);
 
 
-extern void print_source_lines (struct symtab *, int, int,
-                               enum print_source_lines_flags);
+/* Return whether SYM is a function/method, as opposed to a data symbol.  */
 
 
-extern void forget_cached_source_info_for_objfile (struct objfile *);
-extern void forget_cached_source_info (void);
+extern bool symbol_is_function_or_method (symbol *sym);
 
 
-extern void select_source_symtab (struct symtab *);
+/* Return whether MSYMBOL is a function/method, as opposed to a data
+   symbol */
 
 
-extern VEC (char_ptr) *default_make_symbol_completion_list_break_on
-  (const char *text, const char *word, const char *break_on,
-   enum type_code code);
-extern VEC (char_ptr) *default_make_symbol_completion_list (const char *,
-                                                           const char *,
-                                                           enum type_code);
-extern VEC (char_ptr) *make_symbol_completion_list (const char *, const char *);
-extern VEC (char_ptr) *make_symbol_completion_type (const char *, const char *,
-                                                   enum type_code);
-extern VEC (char_ptr) *make_symbol_completion_list_fn (struct cmd_list_element *,
-                                                      const char *,
-                                                      const char *);
+extern bool symbol_is_function_or_method (minimal_symbol *msymbol);
 
 
-extern VEC (char_ptr) *make_file_symbol_completion_list (const char *,
-                                                        const char *,
-                                                        const char *);
+/* Return whether SYM should be skipped in completion mode MODE.  In
+   linespec mode, we're only interested in functions/methods.  */
 
 
-extern VEC (char_ptr) *make_source_files_completion_list (const char *,
-                                                         const char *);
+template<typename Symbol>
+static bool
+completion_skip_symbol (complete_symbol_mode mode, Symbol *sym)
+{
+  return (mode == complete_symbol_mode::LINESPEC
+         && !symbol_is_function_or_method (sym));
+}
 
 /* symtab.c */
 
 
 /* symtab.c */
 
-int matching_obj_sections (struct obj_section *, struct obj_section *);
+bool matching_obj_sections (struct obj_section *, struct obj_section *);
 
 
-extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
+extern struct symtab *find_line_symtab (struct symtab *, int, int *, bool *);
 
 
-extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
-                                                      int);
+/* Given a function symbol SYM, find the symtab and line for the start
+   of the function.  If FUNFIRSTLINE is true, we want the first line
+   of real code inside the function.  */
+extern symtab_and_line find_function_start_sal (symbol *sym, bool
+                                               funfirstline);
+
+/* Same, but start with a function address/section instead of a
+   symbol.  */
+extern symtab_and_line find_function_start_sal (CORE_ADDR func_addr,
+                                               obj_section *section,
+                                               bool funfirstline);
 
 extern void skip_prologue_sal (struct symtab_and_line *);
 
 
 extern void skip_prologue_sal (struct symtab_and_line *);
 
@@ -1525,14 +2002,46 @@ extern CORE_ADDR skip_prologue_using_sal (struct gdbarch *gdbarch,
 extern struct symbol *fixup_symbol_section (struct symbol *,
                                            struct objfile *);
 
 extern struct symbol *fixup_symbol_section (struct symbol *,
                                            struct objfile *);
 
+/* If MSYMBOL is an text symbol, look for a function debug symbol with
+   the same address.  Returns NULL if not found.  This is necessary in
+   case a function is an alias to some other function, because debug
+   information is only emitted for the alias target function's
+   definition, not for the alias.  */
+extern symbol *find_function_alias_target (bound_minimal_symbol msymbol);
+
 /* Symbol searching */
 /* Symbol searching */
-/* Note: struct symbol_search, search_symbols, et.al. are declared here,
-   instead of making them local to symtab.c, for gdbtk's sake.  */
 
 
-/* When using search_symbols, a list of the following structs is returned.
-   Callers must free the search list using free_search_symbols!  */
+/* When using the symbol_searcher struct to search for symbols, a vector of
+   the following structs is returned.  */
 struct symbol_search
 {
 struct symbol_search
 {
+  symbol_search (int block_, struct symbol *symbol_)
+    : block (block_),
+      symbol (symbol_)
+  {
+    msymbol.minsym = nullptr;
+    msymbol.objfile = nullptr;
+  }
+
+  symbol_search (int block_, struct minimal_symbol *minsym,
+                struct objfile *objfile)
+    : block (block_),
+      symbol (nullptr)
+  {
+    msymbol.minsym = minsym;
+    msymbol.objfile = objfile;
+  }
+
+  bool operator< (const symbol_search &other) const
+  {
+    return compare_search_syms (*this, other) < 0;
+  }
+
+  bool operator== (const symbol_search &other) const
+  {
+    return compare_search_syms (*this, other) == 0;
+  }
+
   /* The block in which the match was found.  Could be, for example,
      STATIC_BLOCK or GLOBAL_BLOCK.  */
   int block;
   /* The block in which the match was found.  Could be, for example,
      STATIC_BLOCK or GLOBAL_BLOCK.  */
   int block;
@@ -1546,36 +2055,162 @@ struct symbol_search
      which only minimal_symbols exist.  */
   struct bound_minimal_symbol msymbol;
 
      which only minimal_symbols exist.  */
   struct bound_minimal_symbol msymbol;
 
-  /* A link to the next match, or NULL for the end.  */
-  struct symbol_search *next;
+private:
+
+  static int compare_search_syms (const symbol_search &sym_a,
+                                 const symbol_search &sym_b);
 };
 
 };
 
-extern void search_symbols (const char *, enum search_domain, int,
-                           const char **, struct symbol_search **);
-extern void free_search_symbols (struct symbol_search *);
-extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search
-                                                        **);
-
-/* The name of the ``main'' function.
-   FIXME: cagney/2001-03-20: Can't make main_name() const since some
-   of the calling code currently assumes that the string isn't
-   const.  */
-extern /*const */ char *main_name (void);
+/* In order to search for global symbols of a particular kind matching
+   particular regular expressions, create an instance of this structure and
+   call the SEARCH member function.  */
+class global_symbol_searcher
+{
+public:
+
+  /* Constructor.  */
+  global_symbol_searcher (enum search_domain kind,
+                         const char *symbol_name_regexp)
+    : m_kind (kind),
+      m_symbol_name_regexp (symbol_name_regexp)
+  {
+    /* The symbol searching is designed to only find one kind of thing.  */
+    gdb_assert (m_kind != ALL_DOMAIN);
+  }
+
+  /* Set the optional regexp that matches against the symbol type.  */
+  void set_symbol_type_regexp (const char *regexp)
+  {
+    m_symbol_type_regexp = regexp;
+  }
+
+  /* Set the flag to exclude minsyms from the search results.  */
+  void set_exclude_minsyms (bool exclude_minsyms)
+  {
+    m_exclude_minsyms = exclude_minsyms;
+  }
+
+  /* Set the maximum number of search results to be returned.  */
+  void set_max_search_results (size_t max_search_results)
+  {
+    m_max_search_results = max_search_results;
+  }
+
+  /* Search the symbols from all objfiles in the current program space
+     looking for matches as defined by the current state of this object.
+
+     Within each file the results are sorted locally; each symtab's global
+     and static blocks are separately alphabetized.  Duplicate entries are
+     removed.  */
+  std::vector<symbol_search> search () const;
+
+  /* The set of source files to search in for matching symbols.  This is
+     currently public so that it can be populated after this object has
+     been constructed.  */
+  std::vector<const char *> filenames;
+
+private:
+  /* The kind of symbols are we searching for.
+     VARIABLES_DOMAIN - Search all symbols, excluding functions, type
+                        names, and constants (enums).
+     FUNCTIONS_DOMAIN - Search all functions..
+     TYPES_DOMAIN     - Search all type names.
+     MODULES_DOMAIN   - Search all Fortran modules.
+     ALL_DOMAIN       - Not valid for this function.  */
+  enum search_domain m_kind;
+
+  /* Regular expression to match against the symbol name.  */
+  const char *m_symbol_name_regexp = nullptr;
+
+  /* Regular expression to match against the symbol type.  */
+  const char *m_symbol_type_regexp = nullptr;
+
+  /* When this flag is false then minsyms that match M_SYMBOL_REGEXP will
+     be included in the results, otherwise they are excluded.  */
+  bool m_exclude_minsyms = false;
+
+  /* Maximum number of search results.  We currently impose a hard limit
+     of SIZE_MAX, there is no "unlimited".  */
+  size_t m_max_search_results = SIZE_MAX;
+
+  /* Expand symtabs in OBJFILE that match PREG, are of type M_KIND.  Return
+     true if any msymbols were seen that we should later consider adding to
+     the results list.  */
+  bool expand_symtabs (objfile *objfile,
+                      const gdb::optional<compiled_regex> &preg) const;
+
+  /* Add symbols from symtabs in OBJFILE that match PREG, and TREG, and are
+     of type M_KIND, to the results set RESULTS_SET.  Return false if we
+     stop adding results early due to having already found too many results
+     (based on M_MAX_SEARCH_RESULTS limit), otherwise return true.
+     Returning true does not indicate that any results were added, just
+     that we didn't _not_ add a result due to reaching MAX_SEARCH_RESULTS.  */
+  bool add_matching_symbols (objfile *objfile,
+                            const gdb::optional<compiled_regex> &preg,
+                            const gdb::optional<compiled_regex> &treg,
+                            std::set<symbol_search> *result_set) const;
+
+  /* Add msymbols from OBJFILE that match PREG and M_KIND, to the results
+     vector RESULTS.  Return false if we stop adding results early due to
+     having already found too many results (based on max search results
+     limit M_MAX_SEARCH_RESULTS), otherwise return true.  Returning true
+     does not indicate that any results were added, just that we didn't
+     _not_ add a result due to reaching MAX_SEARCH_RESULTS.  */
+  bool add_matching_msymbols (objfile *objfile,
+                             const gdb::optional<compiled_regex> &preg,
+                             std::vector<symbol_search> *results) const;
+
+  /* Return true if MSYMBOL is of type KIND.  */
+  static bool is_suitable_msymbol (const enum search_domain kind,
+                                  const minimal_symbol *msymbol);
+};
+
+/* When searching for Fortran symbols within modules (functions/variables)
+   we return a vector of this type.  The first item in the pair is the
+   module symbol, and the second item is the symbol for the function or
+   variable we found.  */
+typedef std::pair<symbol_search, symbol_search> module_symbol_search;
+
+/* Searches the symbols to find function and variables symbols (depending
+   on KIND) within Fortran modules.  The MODULE_REGEXP matches against the
+   name of the module, REGEXP matches against the name of the symbol within
+   the module, and TYPE_REGEXP matches against the type of the symbol
+   within the module.  */
+extern std::vector<module_symbol_search> search_module_symbols
+       (const char *module_regexp, const char *regexp,
+        const char *type_regexp, search_domain kind);
+
+/* Convert a global or static symbol SYM (based on BLOCK, which should be
+   either GLOBAL_BLOCK or STATIC_BLOCK) into a string for use in 'info'
+   type commands (e.g. 'info variables', 'info functions', etc).  KIND is
+   the type of symbol that was searched for which gave us SYM.  */
+
+extern std::string symbol_to_info_string (struct symbol *sym, int block,
+                                         enum search_domain kind);
+
+extern bool treg_matches_sym_type_name (const compiled_regex &treg,
+                                       const struct symbol *sym);
+
+/* The name of the ``main'' function.  */
+extern const char *main_name ();
 extern enum language main_language (void);
 
 extern enum language main_language (void);
 
-/* Lookup symbol NAME from DOMAIN in MAIN_OBJFILE's global blocks.
+/* Lookup symbol NAME from DOMAIN in MAIN_OBJFILE's global or static blocks,
+   as specified by BLOCK_INDEX.
    This searches MAIN_OBJFILE as well as any associated separate debug info
    objfiles of MAIN_OBJFILE.
    This searches MAIN_OBJFILE as well as any associated separate debug info
    objfiles of MAIN_OBJFILE.
+   BLOCK_INDEX can be GLOBAL_BLOCK or STATIC_BLOCK.
    Upon success fixes up the symbol's section if necessary.  */
 
 extern struct block_symbol
   lookup_global_symbol_from_objfile (struct objfile *main_objfile,
    Upon success fixes up the symbol's section if necessary.  */
 
 extern struct block_symbol
   lookup_global_symbol_from_objfile (struct objfile *main_objfile,
+                                    enum block_enum block_index,
                                     const char *name,
                                     const domain_enum domain);
 
 /* Return 1 if the supplied producer string matches the ARM RealView
    compiler (armcc).  */
                                     const char *name,
                                     const domain_enum domain);
 
 /* Return 1 if the supplied producer string matches the ARM RealView
    compiler (armcc).  */
-int producer_is_realview (const char *producer);
+bool producer_is_realview (const char *producer);
 
 void fixup_section (struct general_symbol_info *ginfo,
                    CORE_ADDR addr, struct objfile *objfile);
 
 void fixup_section (struct general_symbol_info *ginfo,
                    CORE_ADDR addr, struct objfile *objfile);
@@ -1588,45 +2223,95 @@ extern unsigned int symtab_create_debug;
 
 extern unsigned int symbol_lookup_debug;
 
 
 extern unsigned int symbol_lookup_debug;
 
-extern int basenames_may_differ;
+extern bool basenames_may_differ;
+
+bool compare_filenames_for_search (const char *filename,
+                                  const char *search_name);
 
 
-int compare_filenames_for_search (const char *filename,
-                                 const char *search_name);
+bool compare_glob_filenames_for_search (const char *filename,
+                                       const char *search_name);
 
 
-int iterate_over_some_symtabs (const char *name,
-                              const char *real_path,
-                              int (*callback) (struct symtab *symtab,
-                                               void *data),
-                              void *data,
-                              struct compunit_symtab *first,
-                              struct compunit_symtab *after_last);
+bool iterate_over_some_symtabs (const char *name,
+                               const char *real_path,
+                               struct compunit_symtab *first,
+                               struct compunit_symtab *after_last,
+                               gdb::function_view<bool (symtab *)> callback);
 
 void iterate_over_symtabs (const char *name,
 
 void iterate_over_symtabs (const char *name,
-                          int (*callback) (struct symtab *symtab,
-                                           void *data),
-                          void *data);
+                          gdb::function_view<bool (symtab *)> callback);
+
 
 
-DEF_VEC_I (CORE_ADDR);
+std::vector<CORE_ADDR> find_pcs_for_symtab_line
+    (struct symtab *symtab, int line, struct linetable_entry **best_entry);
 
 
-VEC (CORE_ADDR) *find_pcs_for_symtab_line (struct symtab *symtab, int line,
-                                          struct linetable_entry **best_entry);
+/* Prototype for callbacks for LA_ITERATE_OVER_SYMBOLS.  The callback
+   is called once per matching symbol SYM.  The callback should return
+   true to indicate that LA_ITERATE_OVER_SYMBOLS should continue
+   iterating, or false to indicate that the iteration should end.  */
 
 
-/* Callback for LA_ITERATE_OVER_SYMBOLS.  The callback will be called
-   once per matching symbol SYM, with DATA being the argument of the
-   same name that was passed to LA_ITERATE_OVER_SYMBOLS.  The callback
-   should return nonzero to indicate that LA_ITERATE_OVER_SYMBOLS
-   should continue iterating, or zero to indicate that the iteration
-   should end.  */
+typedef bool (symbol_found_callback_ftype) (struct block_symbol *bsym);
 
 
-typedef int (symbol_found_callback_ftype) (struct symbol *sym, void *data);
+/* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK.
 
 
-void iterate_over_symbols (const struct block *block, const char *name,
+   For each symbol that matches, CALLBACK is called.  The symbol is
+   passed to the callback.
+
+   If CALLBACK returns false, the iteration ends and this function
+   returns false.  Otherwise, the search continues, and the function
+   eventually returns true.  */
+
+bool iterate_over_symbols (const struct block *block,
+                          const lookup_name_info &name,
                           const domain_enum domain,
                           const domain_enum domain,
-                          symbol_found_callback_ftype *callback,
-                          void *data);
+                          gdb::function_view<symbol_found_callback_ftype> callback);
+
+/* Like iterate_over_symbols, but if all calls to CALLBACK return
+   true, then calls CALLBACK one additional time with a block_symbol
+   that has a valid block but a NULL symbol.  */
+
+bool iterate_over_symbols_terminated
+  (const struct block *block,
+   const lookup_name_info &name,
+   const domain_enum domain,
+   gdb::function_view<symbol_found_callback_ftype> callback);
+
+/* Storage type used by demangle_for_lookup.  demangle_for_lookup
+   either returns a const char * pointer that points to either of the
+   fields of this type, or a pointer to the input NAME.  This is done
+   this way because the underlying functions that demangle_for_lookup
+   calls either return a std::string (e.g., cp_canonicalize_string) or
+   a malloc'ed buffer (libiberty's demangled), and we want to avoid
+   unnecessary reallocation/string copying.  */
+class demangle_result_storage
+{
+public:
+
+  /* Swap the std::string storage with STR, and return a pointer to
+     the beginning of the new string.  */
+  const char *swap_string (std::string &str)
+  {
+    std::swap (m_string, str);
+    return m_string.c_str ();
+  }
+
+  /* Set the malloc storage to now point at PTR.  Any previous malloc
+     storage is released.  */
+  const char *set_malloc_ptr (char *ptr)
+  {
+    m_malloc.reset (ptr);
+    return ptr;
+  }
+
+private:
 
 
-struct cleanup *demangle_for_lookup (const char *name, enum language lang,
-                                    const char **result_name);
+  /* The storage.  */
+  std::string m_string;
+  gdb::unique_xmalloc_ptr<char> m_malloc;
+};
+
+const char *
+  demangle_for_lookup (const char *name, enum language lang,
+                      demangle_result_storage &storage);
 
 struct symbol *allocate_symbol (struct objfile *);
 
 
 struct symbol *allocate_symbol (struct objfile *);
 
@@ -1634,4 +2319,57 @@ void initialize_objfile_symbol (struct symbol *);
 
 struct template_symbol *allocate_template_symbol (struct objfile *);
 
 
 struct template_symbol *allocate_template_symbol (struct objfile *);
 
+/* Test to see if the symbol of language SYMBOL_LANGUAGE specified by
+   SYMNAME (which is already demangled for C++ symbols) matches
+   SYM_TEXT in the first SYM_TEXT_LEN characters.  If so, add it to
+   the current completion list.  */
+void completion_list_add_name (completion_tracker &tracker,
+                              language symbol_language,
+                              const char *symname,
+                              const lookup_name_info &lookup_name,
+                              const char *text, const char *word);
+
+/* A simple symbol searching class.  */
+
+class symbol_searcher
+{
+public:
+  /* Returns the symbols found for the search.  */
+  const std::vector<block_symbol> &
+  matching_symbols () const
+  {
+    return m_symbols;
+  }
+
+  /* Returns the minimal symbols found for the search.  */
+  const std::vector<bound_minimal_symbol> &
+  matching_msymbols () const
+  {
+    return m_minimal_symbols;
+  }
+
+  /* Search for all symbols named NAME in LANGUAGE with DOMAIN, restricting
+     search to FILE_SYMTABS and SEARCH_PSPACE, both of which may be NULL
+     to search all symtabs and program spaces.  */
+  void find_all_symbols (const std::string &name,
+                        const struct language_defn *language,
+                        enum search_domain search_domain,
+                        std::vector<symtab *> *search_symtabs,
+                        struct program_space *search_pspace);
+
+  /* Reset this object to perform another search.  */
+  void reset ()
+  {
+    m_symbols.clear ();
+    m_minimal_symbols.clear ();
+  }
+
+private:
+  /* Matching debug symbols.  */
+  std::vector<block_symbol>  m_symbols;
+
+  /* Matching non-debug symbols.  */
+  std::vector<bound_minimal_symbol> m_minimal_symbols;
+};
+
 #endif /* !defined(SYMTAB_H) */
 #endif /* !defined(SYMTAB_H) */
This page took 0.064914 seconds and 4 git commands to generate.