+2020-04-01  Tom Tromey  <tromey@adacore.com>
+
+       * symtab.h (class lookup_name_info) <lookup_name_info>: Change
+       "name" parameter to rvalue reference.  Initialize m_name_holder.
+       <lookup_name_info>: New overloads.
+       <name>: Return gdb::string_view.
+       <c_str>: New method.
+       <make_ignore_params>: Update.
+       <search_name_hash>: Update.
+       <language_lookup_name>: Return const char *.
+       <m_name>: Change type.
+       * symtab.c (demangle_for_lookup_info::demangle_for_lookup_info)
+       (demangle_for_lookup_info::demangle_for_lookup_info): Update.
+       (lookup_name_info::match_any): Update.
+       * psymtab.c (match_partial_symbol, lookup_partial_symbol):
+       Update.
+       * minsyms.c (linkage_name_str): Update.
+       * language.c (default_symbol_name_matcher): Update.
+       * dwarf2/read.c (mapped_index_base::find_name_components_bounds):
+       Update.
+       * ada-lang.c (ada_fold_name): Change parameter to string_view.
+       (ada_lookup_name_info::ada_lookup_name_info): Update.
+       (literal_symbol_name_matcher): Update.
+
 2020-04-01  Tom Tromey  <tromey@adacore.com>
 
        * psymtab.c (psymtab_search_name): Remove function.
 
    to next call.  */
 
 static char *
-ada_fold_name (const char *name)
+ada_fold_name (gdb::string_view name)
 {
   static char *fold_buffer = NULL;
   static size_t fold_buffer_size = 0;
 
-  int len = strlen (name);
+  int len = name.size ();
   GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
 
   if (name[0] == '\'')
     {
-      strncpy (fold_buffer, name + 1, len - 2);
+      strncpy (fold_buffer, name.data () + 1, len - 2);
       fold_buffer[len - 2] = '\000';
     }
   else
   if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
     {
       const char *name = ada_lookup_name (lookup_name);
-      lookup_name_info name1 (std::string ("<_ada_") + name + '>',
-                             symbol_name_match_type::FULL);
+      std::string bracket_name = std::string ("<_ada_") + name + '>';
+      lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
 
       for (objfile *objfile : current_program_space->objfiles ())
         {
 
 ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
 {
-  const std::string &user_name = lookup_name.name ();
+  gdb::string_view user_name = lookup_name.name ();
 
   if (user_name[0] == '<')
     {
       if (user_name.back () == '>')
-       m_encoded_name = user_name.substr (1, user_name.size () - 2);
+       m_encoded_name
+         = user_name.substr (1, user_name.size () - 2).to_string ();
       else
-       m_encoded_name = user_name.substr (1, user_name.size () - 1);
+       m_encoded_name
+         = user_name.substr (1, user_name.size () - 1).to_string ();
       m_encoded_p = true;
       m_verbatim_p = true;
       m_wild_match_p = false;
     {
       m_verbatim_p = false;
 
-      m_encoded_p = user_name.find ("__") != std::string::npos;
+      m_encoded_p = user_name.find ("__") != gdb::string_view::npos;
 
       if (!m_encoded_p)
        {
-         const char *folded = ada_fold_name (user_name.c_str ());
+         const char *folded = ada_fold_name (user_name);
          const char *encoded = ada_encode_1 (folded, false);
          if (encoded != NULL)
            m_encoded_name = encoded;
          else
-           m_encoded_name = user_name;
+           m_encoded_name = user_name.to_string ();
        }
       else
-       m_encoded_name = user_name;
+       m_encoded_name = user_name.to_string ();
 
       /* Handle the 'package Standard' special case.  See description
         of m_standard_p.  */
                             const lookup_name_info &lookup_name,
                             completion_match_result *comp_match_res)
 {
-  const std::string &name = lookup_name.name ();
+  gdb::string_view name_view = lookup_name.name ();
 
-  int cmp = (lookup_name.completion_mode ()
-            ? strncmp (symbol_search_name, name.c_str (), name.size ())
-            : strcmp (symbol_search_name, name.c_str ()));
-  if (cmp == 0)
+  if (lookup_name.completion_mode ()
+      ? (strncmp (symbol_search_name, name_view.data (),
+                 name_view.size ()) == 0)
+      : symbol_search_name == name_view)
     {
       if (comp_match_res != NULL)
        comp_match_res->set_match (symbol_search_name);
 
     = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
 
   const char *lang_name
-    = lookup_name_without_params.language_lookup_name (lang).c_str ();
+    = lookup_name_without_params.language_lookup_name (lang);
 
   /* Comparison function object for lower_bound that matches against a
      given symbol name.  */
 
                             const lookup_name_info &lookup_name,
                             completion_match_result *comp_match_res)
 {
-  const std::string &name = lookup_name.name ();
+  gdb::string_view name = lookup_name.name ();
   completion_match_for_lcd *match_for_lcd
     = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
   strncmp_iw_mode mode = (lookup_name.completion_mode ()
                          ? strncmp_iw_mode::NORMAL
                          : strncmp_iw_mode::MATCH_PARAMS);
 
-  if (strncmp_iw_with_mode (symbol_search_name, name.c_str (), name.size (),
+  if (strncmp_iw_with_mode (symbol_search_name, name.data (), name.size (),
                            mode, language_minimal, match_for_lcd) == 0)
     {
       if (comp_match_res != NULL)
 
   if (current_language->la_language == language_ada)
     return lookup_name.ada ().lookup_name ().c_str ();
 
-  return lookup_name.name ().c_str ();
+  return lookup_name.c_str ();
 }
 
 /* See minsyms.h.  */
 
          gdb_assert (center < top);
 
          enum language lang = (*center)->ginfo.language ();
-         const char *lang_ln
-           = name.language_lookup_name (lang).c_str ();
+         const char *lang_ln = name.language_lookup_name (lang);
 
          if (ordered_compare ((*center)->ginfo.search_name (),
                               lang_ln) >= 0)
            internal_error (__FILE__, __LINE__,
                            _("failed internal consistency check"));
          if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
-                                lookup_name.name ().c_str ()) >= 0)
+                                lookup_name.c_str ()) >= 0)
            {
              top = center;
            }
 
   if (lookup_name.ignore_parameters () && lang == language_cplus)
     {
       gdb::unique_xmalloc_ptr<char> without_params
-       = cp_remove_params_if_any (lookup_name.name ().c_str (),
+       = cp_remove_params_if_any (lookup_name.c_str (),
                                   lookup_name.completion_mode ());
 
       if (without_params != NULL)
     }
 
   if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
-    m_demangled_name = lookup_name.name ();
+    m_demangled_name = lookup_name.c_str ();
   else
-    m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
+    m_demangled_name = demangle_for_lookup (lookup_name.c_str (),
                                            lang, storage);
 }
 
 {
   /* Lookup any symbol that "" would complete.  I.e., this matches all
      symbol names.  */
-  static const lookup_name_info lookup_name ({}, symbol_name_match_type::FULL,
+  static const lookup_name_info lookup_name ("", symbol_name_match_type::FULL,
                                             true);
 
   return lookup_name;
 
 class lookup_name_info final
 {
  public:
-  /* Create a new object.  */
-  lookup_name_info (std::string name,
+  /* We delete this overload so that the callers are required to
+     explicitly handle the lifetime of the name.  */
+  lookup_name_info (std::string &&name,
+                   symbol_name_match_type match_type,
+                   bool completion_mode = false,
+                   bool ignore_parameters = false) = delete;
+
+  /* This overload requires that NAME have a lifetime at least as long
+     as the lifetime of this object.  */
+  lookup_name_info (const 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 (name)
+  {}
+
+  /* This overload requires that NAME have a lifetime at least as long
+     as the lifetime of this object.  */
+  lookup_name_info (const char *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))
+      m_name (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; }
+  gdb::string_view name () const { return m_name; }
   const bool ignore_parameters () const { return m_ignore_parameters; }
 
+  /* Like the "name" method but guarantees that the returned string is
+     \0-terminated.  */
+  const char *c_str () const
+  {
+    /* Actually this is always guaranteed due to how the class is
+       constructed.  */
+    return m_name.data ();
+  }
+
   /* 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,
+    return lookup_name_info (c_str (), m_match_type, m_completion_mode,
                             true /* ignore params */);
   }
 
     if (!m_demangled_hashes_p[lang])
       {
        m_demangled_hashes[lang]
-         = ::search_name_hash (lang, language_lookup_name (lang).c_str ());
+         = ::search_name_hash (lang, language_lookup_name (lang));
        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
+  const char *language_lookup_name (language lang) const
   {
     switch (lang)
       {
       case language_ada:
-       return ada ().lookup_name ();
+       return ada ().lookup_name ().c_str ();
       case language_cplus:
-       return cplus ().lookup_name ();
+       return cplus ().lookup_name ().c_str ();
       case language_d:
-       return d ().lookup_name ();
+       return d ().lookup_name ().c_str ();
       case language_go:
-       return go ().lookup_name ();
+       return go ().lookup_name ().c_str ();
       default:
-       return m_name;
+       return m_name.data ();
       }
   }
 
   symbol_name_match_type m_match_type;
   bool m_completion_mode;
   bool m_ignore_parameters;
-  std::string m_name;
+  gdb::string_view m_name;
 
   /* Language-specific info.  These fields are filled lazily the first
      time a lookup is done in the corresponding language.  They're