Remove ptid_get_pid
[binutils-gdb.git] / gdb / linespec.c
index 136cb6553fc9f6134fa22c694d590bc2423da235..2a4189278ef57847b5cfd2046c470b9c77a9d9f8 100644 (file)
@@ -1,6 +1,6 @@
 /* Parser for linespec for the GNU debugger, GDB.
 
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -45,6 +45,8 @@
 #include "stack.h"
 #include "location.h"
 #include "common/function-view.h"
+#include "common/def-vector.h"
+#include <algorithm>
 
 /* An enumeration of the various things a user might attempt to
    complete for a linespec location.  */
@@ -78,9 +80,6 @@ enum class linespec_complete_what
 typedef struct symbol *symbolp;
 DEF_VEC_P (symbolp);
 
-typedef struct type *typep;
-DEF_VEC_P (typep);
-
 /* An address entry is used to ensure that any given location is only
    added to the result a single time.  It holds an address and the
    program space from which the address came.  */
@@ -173,7 +172,7 @@ struct linespec_state
   /* The 'canonical' value passed to decode_line_full, or NULL.  */
   struct linespec_result *canonical;
 
-  /* Canonical strings that mirror the symtabs_and_lines result.  */
+  /* Canonical strings that mirror the std::vector<symtab_and_line> result.  */
   struct linespec_canonical_name *canonical_names;
 
   /* This is a set of address_entry objects which is used to prevent
@@ -333,7 +332,8 @@ typedef struct ls_parser linespec_parser;
 /* Prototypes for local functions.  */
 
 static void iterate_over_file_blocks
-  (struct symtab *symtab, const char *name, domain_enum domain,
+  (struct symtab *symtab, const lookup_name_info &name,
+   domain_enum domain,
    gdb::function_view<symbol_found_callback_ftype> callback);
 
 static void initialize_defaults (struct symtab **default_symtab,
@@ -341,9 +341,9 @@ static void initialize_defaults (struct symtab **default_symtab,
 
 CORE_ADDR linespec_expression_to_pc (const char **exp_ptr);
 
-static struct symtabs_and_lines decode_objc (struct linespec_state *self,
-                                            linespec_p ls,
-                                            const char *arg);
+static std::vector<symtab_and_line> decode_objc (struct linespec_state *self,
+                                                linespec_p ls,
+                                                const char *arg);
 
 static VEC (symtab_ptr) *symtabs_from_filename (const char *,
                                                struct program_space *pspace);
@@ -357,6 +357,7 @@ static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
 static void find_linespec_symbols (struct linespec_state *self,
                                   VEC (symtab_ptr) *file_symtabs,
                                   const char *name,
+                                  symbol_name_match_type name_match_type,
                                   VEC (symbolp) **symbols,
                                   VEC (bound_minimal_symbol_d) **minsyms);
 
@@ -368,31 +369,33 @@ static int symbol_to_sal (struct symtab_and_line *result,
                          int funfirstline, struct symbol *sym);
 
 static void add_matching_symbols_to_info (const char *name,
+                                         symbol_name_match_type name_match_type,
+                                         enum search_domain search_domain,
                                          struct collect_info *info,
                                          struct program_space *pspace);
 
-static void add_all_symbol_names_from_pspace (struct collect_info *info,
-                                             struct program_space *pspace,
-                                             VEC (const_char_ptr) *names);
+static void add_all_symbol_names_from_pspace
+    (struct collect_info *info, struct program_space *pspace,
+     const std::vector<const char *> &names, enum search_domain search_domain);
 
 static VEC (symtab_ptr) *
   collect_symtabs_from_filename (const char *file,
                                 struct program_space *pspace);
 
-static void decode_digits_ordinary (struct linespec_state *self,
-                                   linespec_p ls,
-                                   int line,
-                                   struct symtabs_and_lines *sals,
-                                   struct linetable_entry **best_entry);
+static std::vector<symtab_and_line> decode_digits_ordinary
+  (struct linespec_state *self,
+   linespec_p ls,
+   int line,
+   linetable_entry **best_entry);
 
-static void decode_digits_list_mode (struct linespec_state *self,
-                                    linespec_p ls,
-                                    struct symtabs_and_lines *values,
-                                    struct symtab_and_line val);
+static std::vector<symtab_and_line> decode_digits_list_mode
+  (struct linespec_state *self,
+   linespec_p ls,
+   struct symtab_and_line val);
 
 static void minsym_found (struct linespec_state *self, struct objfile *objfile,
                          struct minimal_symbol *msymbol,
-                         struct symtabs_and_lines *result);
+                         std::vector<symtab_and_line> *result);
 
 static int compare_symbols (const void *a, const void *b);
 
@@ -473,7 +476,7 @@ linespec_lexer_lex_keyword (const char *p)
              if (i != IF_KEYWORD_INDEX)
                {
                  p += len;
-                 p = skip_spaces_const (p);
+                 p = skip_spaces (p);
                  for (j = 0; linespec_keywords[j] != NULL; ++j)
                    {
                      int nextlen = strlen (linespec_keywords[j]);
@@ -529,20 +532,18 @@ skip_quote_char (const char *string, char quote_char)
 /* Make a writable copy of the string given in TOKEN, trimming
    any trailing whitespace.  */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 copy_token_string (linespec_token token)
 {
-  char *str, *s;
+  const char *str, *s;
 
   if (token.type == LSTOKEN_KEYWORD)
-    return xstrdup (LS_TOKEN_KEYWORD (token));
+    return gdb::unique_xmalloc_ptr<char> (xstrdup (LS_TOKEN_KEYWORD (token)));
 
-  str = savestring (LS_TOKEN_STOKEN (token).ptr,
-                   LS_TOKEN_STOKEN (token).length);
+  str = LS_TOKEN_STOKEN (token).ptr;
   s = remove_trailing_whitespace (str, str + LS_TOKEN_STOKEN (token).length);
-  *s = '\0';
 
-  return str;
+  return gdb::unique_xmalloc_ptr<char> (savestring (str, s - str));
 }
 
 /* Does P represent the end of a quote-enclosed linespec?  */
@@ -708,7 +709,7 @@ linespec_lexer_lex_string (linespec_parser *parser)
        {
          if (isspace (*PARSER_STREAM (parser)))
            {
-             p = skip_spaces_const (PARSER_STREAM (parser));
+             p = skip_spaces (PARSER_STREAM (parser));
              /* When we get here we know we've found something followed by
                 a space (we skip over parens and templates below).
                 So if we find a keyword now, we know it is a keyword and not,
@@ -739,6 +740,11 @@ linespec_lexer_lex_string (linespec_parser *parser)
              if (PARSER_STREAM (parser)[1] == ':')
                ++(PARSER_STREAM (parser));
 
+             /* Do not tokenize ABI tags such as "[abi:cxx11]".  */
+             else if (PARSER_STREAM (parser) - start > 4
+                      && startswith (PARSER_STREAM (parser) - 4, "[abi"))
+               ++(PARSER_STREAM (parser));
+
              /* Do not tokenify if the input length so far is one
                 (i.e, a single-letter drive name) and the next character
                 is a directory separator.  This allows Windows-style
@@ -855,7 +861,7 @@ linespec_lexer_lex_one (linespec_parser *parser)
   if (parser->lexer.current.type == LSTOKEN_CONSUMED)
     {
       /* Skip any whitespace.  */
-      PARSER_STREAM (parser) = skip_spaces_const (PARSER_STREAM (parser));
+      PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser));
 
       /* Check for a keyword, they end the linespec.  */
       keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
@@ -996,17 +1002,6 @@ linespec_lexer_peek_token (linespec_parser *parser)
 
 /* Helper functions.  */
 
-/* Add SAL to SALS.  */
-
-static void
-add_sal_to_sals_basic (struct symtabs_and_lines *sals,
-                      struct symtab_and_line *sal)
-{
-  ++sals->nelts;
-  sals->sals = XRESIZEVEC (struct symtab_and_line, sals->sals, sals->nelts);
-  sals->sals[sals->nelts - 1] = *sal;
-}
-
 /* Add SAL to SALS, and also update SELF->CANONICAL_NAMES to reflect
    the new sal, if needed.  If not NULL, SYMNAME is the name of the
    symbol to use when constructing the new canonical name.
@@ -1016,19 +1011,20 @@ add_sal_to_sals_basic (struct symtabs_and_lines *sals,
 
 static void
 add_sal_to_sals (struct linespec_state *self,
-                struct symtabs_and_lines *sals,
+                std::vector<symtab_and_line> *sals,
                 struct symtab_and_line *sal,
                 const char *symname, int literal_canonical)
 {
-  add_sal_to_sals_basic (sals, sal);
+  sals->push_back (*sal);
 
   if (self->canonical)
     {
       struct linespec_canonical_name *canonical;
 
       self->canonical_names = XRESIZEVEC (struct linespec_canonical_name,
-                                         self->canonical_names, sals->nelts);
-      canonical = &self->canonical_names[sals->nelts - 1];
+                                         self->canonical_names,
+                                         sals->size ());
+      canonical = &self->canonical_names[sals->size () - 1];
       if (!literal_canonical && sal->symtab)
        {
          symtab_to_fullname (sal->symtab);
@@ -1110,19 +1106,16 @@ maybe_add_address (htab_t set, struct program_space *pspace, CORE_ADDR addr)
 
 static void
 iterate_over_all_matching_symtabs
-  (struct linespec_state *state, const char *name, const domain_enum domain,
+  (struct linespec_state *state,
+   const lookup_name_info &lookup_name,
+   const domain_enum name_domain,
+   enum search_domain search_domain,
    struct program_space *search_pspace, bool include_inline,
    gdb::function_view<symbol_found_callback_ftype> callback)
 {
   struct objfile *objfile;
   struct program_space *pspace;
 
-  /* The routine to be used for comparison.  */
-  symbol_name_cmp_ftype symbol_name_cmp
-    = (state->language->la_get_symbol_name_cmp != NULL
-       ? state->language->la_get_symbol_name_cmp (name)
-       : strcmp_iw);
-
   ALL_PSPACES (pspace)
   {
     if (search_pspace != NULL && search_pspace != pspace)
@@ -1137,21 +1130,17 @@ iterate_over_all_matching_symtabs
       struct compunit_symtab *cu;
 
       if (objfile->sf)
-       objfile->sf->qf->expand_symtabs_matching
-         (objfile,
-          NULL,
-          [&] (const char *symbol_name)
-          {
-            return symbol_name_cmp (symbol_name, name) == 0;
-          },
-          NULL,
-          ALL_DOMAIN);
+       objfile->sf->qf->expand_symtabs_matching (objfile,
+                                                 NULL,
+                                                 lookup_name,
+                                                 NULL, NULL,
+                                                 search_domain);
 
       ALL_OBJFILE_COMPUNITS (objfile, cu)
        {
          struct symtab *symtab = COMPUNIT_FILETABS (cu);
 
-         iterate_over_file_blocks (symtab, name, domain, callback);
+         iterate_over_file_blocks (symtab, lookup_name, name_domain, callback);
 
          if (include_inline)
            {
@@ -1164,7 +1153,7 @@ iterate_over_all_matching_symtabs
                {
                  block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
                  state->language->la_iterate_over_symbols
-                   (block, name, domain, [&] (symbol *sym)
+                   (block, lookup_name, name_domain, [&] (symbol *sym)
                     {
                       /* Restrict calls to CALLBACK to symbols
                          representing inline symbols only.  */
@@ -1201,8 +1190,8 @@ get_current_search_block (void)
 
 static void
 iterate_over_file_blocks
-  (struct symtab *symtab, const char *name, domain_enum domain,
-   gdb::function_view<symbol_found_callback_ftype> callback)
+  (struct symtab *symtab, const lookup_name_info &name,
+   domain_enum domain, gdb::function_view<symbol_found_callback_ftype> callback)
 {
   struct block *block;
 
@@ -1212,17 +1201,17 @@ iterate_over_file_blocks
     LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
 }
 
-/* A helper for find_method.  This finds all methods in type T which
-   match NAME.  It adds matching symbol names to RESULT_NAMES, and
-   adds T's direct superclasses to SUPERCLASSES.  */
+/* A helper for find_method.  This finds all methods in type T of
+   language T_LANG which match NAME.  It adds matching symbol names to
+   RESULT_NAMES, and adds T's direct superclasses to SUPERCLASSES.  */
 
 static void
-find_methods (struct type *t, const char *name,
-             VEC (const_char_ptr) **result_names,
-             VEC (typep) **superclasses)
+find_methods (struct type *t, enum language t_lang, const char *name,
+             std::vector<const char *> *result_names,
+             std::vector<struct type *> *superclasses)
 {
   int ibase;
-  const char *class_name = type_name_no_tag (t);
+  const char *class_name = TYPE_NAME (t);
 
   /* Ignore this class if it doesn't have a name.  This is ugly, but
      unless we figure out how to get the physname without the name of
@@ -1230,6 +1219,9 @@ find_methods (struct type *t, const char *name,
   if (class_name)
     {
       int method_counter;
+      lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
+      symbol_name_matcher_ftype *symbol_name_compare
+       = get_symbol_name_matcher (language_def (t_lang), lookup_name);
 
       t = check_typedef (t);
 
@@ -1254,7 +1246,7 @@ find_methods (struct type *t, const char *name,
                method_name = dem_opname;
            }
 
-         if (strcmp_iw (method_name, name) == 0)
+         if (symbol_name_compare (method_name, lookup_name, NULL))
            {
              int field_counter;
 
@@ -1270,14 +1262,14 @@ find_methods (struct type *t, const char *name,
                  if (TYPE_FN_FIELD_STUB (f, field_counter))
                    continue;
                  phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
-                 VEC_safe_push (const_char_ptr, *result_names, phys_name);
+                 result_names->push_back (phys_name);
                }
            }
        }
     }
 
   for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
-    VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase));
+    superclasses->push_back (TYPE_BASECLASS (t, ibase));
 }
 
 /* Find an instance of the character C in the string S that is outside
@@ -1388,16 +1380,16 @@ find_toplevel_string (const char *haystack, const char *needle)
 }
 
 /* Convert CANONICAL to its string representation using
-   symtab_to_fullname for SYMTAB.  The caller must xfree the result.  */
+   symtab_to_fullname for SYMTAB.  */
 
-static char *
+static std::string
 canonical_to_fullform (const struct linespec_canonical_name *canonical)
 {
   if (canonical->symtab == NULL)
-    return xstrdup (canonical->suffix);
+    return canonical->suffix;
   else
-    return xstrprintf ("%s:%s", symtab_to_fullname (canonical->symtab),
-                      canonical->suffix);
+    return string_printf ("%s:%s", symtab_to_fullname (canonical->symtab),
+                         canonical->suffix);
 }
 
 /* Given FILTERS, a list of canonical names, filter the sals in RESULT
@@ -1405,39 +1397,28 @@ canonical_to_fullform (const struct linespec_canonical_name *canonical)
 
 static void
 filter_results (struct linespec_state *self,
-               struct symtabs_and_lines *result,
-               VEC (const_char_ptr) *filters)
+               std::vector<symtab_and_line> *result,
+               const std::vector<const char *> &filters)
 {
-  int i;
-  const char *name;
-
-  for (i = 0; VEC_iterate (const_char_ptr, filters, i, name); ++i)
+  for (const char *name : filters)
     {
-      struct linespec_sals lsal;
-      int j;
-
-      memset (&lsal, 0, sizeof (lsal));
+      linespec_sals lsal;
 
-      for (j = 0; j < result->nelts; ++j)
+      for (size_t j = 0; j < result->size (); ++j)
        {
          const struct linespec_canonical_name *canonical;
-         char *fullform;
-         struct cleanup *cleanup;
 
          canonical = &self->canonical_names[j];
-         fullform = canonical_to_fullform (canonical);
-         cleanup = make_cleanup (xfree, fullform);
+         std::string fullform = canonical_to_fullform (canonical);
 
-         if (strcmp (name, fullform) == 0)
-           add_sal_to_sals_basic (&lsal.sals, &result->sals[j]);
-
-         do_cleanups (cleanup);
+         if (name == fullform)
+           lsal.sals.push_back ((*result)[j]);
        }
 
-      if (lsal.sals.nelts > 0)
+      if (!lsal.sals.empty ())
        {
          lsal.canonical = xstrdup (name);
-         VEC_safe_push (linespec_sals, self->canonical->sals, &lsal);
+         self->canonical->lsals.push_back (std::move (lsal));
        }
     }
 
@@ -1448,13 +1429,13 @@ filter_results (struct linespec_state *self,
 
 static void
 convert_results_to_lsals (struct linespec_state *self,
-                         struct symtabs_and_lines *result)
+                         std::vector<symtab_and_line> *result)
 {
   struct linespec_sals lsal;
 
   lsal.canonical = NULL;
-  lsal.sals = *result;
-  VEC_safe_push (linespec_sals, self->canonical->sals, &lsal);
+  lsal.sals = std::move (*result);
+  self->canonical->lsals.push_back (std::move (lsal));
 }
 
 /* A structure that contains two string representations of a struct
@@ -1465,34 +1446,35 @@ convert_results_to_lsals (struct linespec_state *self,
 
 struct decode_line_2_item
 {
-  /* The form using symtab_to_fullname.
-     It must be xfree'ed after use.  */
-  char *fullform;
+  decode_line_2_item (std::string &&fullform_, std::string &&displayform_,
+                     bool selected_)
+    : fullform (std::move (fullform_)),
+      displayform (std::move (displayform_)),
+      selected (selected_)
+  {
+  }
 
-  /* The form using symtab_to_filename_for_display.
-     It must be xfree'ed after use.  */
-  char *displayform;
+  /* The form using symtab_to_fullname.  */
+  std::string fullform;
+
+  /* The form using symtab_to_filename_for_display.  */
+  std::string displayform;
 
   /* Field is initialized to zero and it is set to one if the user
      requested breakpoint for this entry.  */
   unsigned int selected : 1;
 };
 
-/* Helper for qsort to sort decode_line_2_item entries by DISPLAYFORM and
-   secondarily by FULLFORM.  */
+/* Helper for std::sort to sort decode_line_2_item entries by
+   DISPLAYFORM and secondarily by FULLFORM.  */
 
-static int
-decode_line_2_compare_items (const void *ap, const void *bp)
+static bool
+decode_line_2_compare_items (const decode_line_2_item &a,
+                            const decode_line_2_item &b)
 {
-  const struct decode_line_2_item *a = (const struct decode_line_2_item *) ap;
-  const struct decode_line_2_item *b = (const struct decode_line_2_item *) bp;
-  int retval;
-
-  retval = strcmp (a->displayform, b->displayform);
-  if (retval != 0)
-    return retval;
-
-  return strcmp (a->fullform, b->fullform);
+  if (a.displayform != b.displayform)
+    return a.displayform < b.displayform;
+  return a.fullform < b.fullform;
 }
 
 /* Handle multiple results in RESULT depending on SELECT_MODE.  This
@@ -1502,83 +1484,72 @@ decode_line_2_compare_items (const void *ap, const void *bp)
 
 static void
 decode_line_2 (struct linespec_state *self,
-              struct symtabs_and_lines *result,
+              std::vector<symtab_and_line> *result,
               const char *select_mode)
 {
   char *args;
   const char *prompt;
   int i;
-  struct cleanup *old_chain;
-  VEC (const_char_ptr) *filters = NULL;
-  struct decode_line_2_item *items;
-  int items_count;
+  std::vector<const char *> filters;
+  std::vector<struct decode_line_2_item> items;
 
   gdb_assert (select_mode != multiple_symbols_all);
   gdb_assert (self->canonical != NULL);
-  gdb_assert (result->nelts >= 1);
-
-  old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &filters);
+  gdb_assert (!result->empty ());
 
   /* Prepare ITEMS array.  */
-  items_count = result->nelts;
-  items = XNEWVEC (struct decode_line_2_item, items_count);
-  make_cleanup (xfree, items);
-  for (i = 0; i < items_count; ++i)
+  for (i = 0; i < result->size (); ++i)
     {
       const struct linespec_canonical_name *canonical;
       struct decode_line_2_item *item;
 
+      std::string displayform;
+
       canonical = &self->canonical_names[i];
       gdb_assert (canonical->suffix != NULL);
-      item = &items[i];
 
-      item->fullform = canonical_to_fullform (canonical);
-      make_cleanup (xfree, item->fullform);
+      std::string fullform = canonical_to_fullform (canonical);
 
       if (canonical->symtab == NULL)
-       item->displayform = canonical->suffix;
+       displayform = canonical->suffix;
       else
        {
          const char *fn_for_display;
 
          fn_for_display = symtab_to_filename_for_display (canonical->symtab);
-         item->displayform = xstrprintf ("%s:%s", fn_for_display,
-                                         canonical->suffix);
-         make_cleanup (xfree, item->displayform);
+         displayform = string_printf ("%s:%s", fn_for_display,
+                                      canonical->suffix);
        }
 
-      item->selected = 0;
+      items.emplace_back (std::move (fullform), std::move (displayform),
+                         false);
     }
 
   /* Sort the list of method names.  */
-  qsort (items, items_count, sizeof (*items), decode_line_2_compare_items);
+  std::sort (items.begin (), items.end (), decode_line_2_compare_items);
 
   /* Remove entries with the same FULLFORM.  */
-  if (items_count >= 2)
-    {
-      struct decode_line_2_item *dst, *src;
-
-      dst = items;
-      for (src = &items[1]; src < &items[items_count]; src++)
-       if (strcmp (src->fullform, dst->fullform) != 0)
-         *++dst = *src;
-      items_count = dst + 1 - items;
-    }
-
-  if (select_mode == multiple_symbols_cancel && items_count > 1)
+  items.erase (std::unique (items.begin (), items.end (),
+                           [] (const struct decode_line_2_item &a,
+                               const struct decode_line_2_item &b)
+                             {
+                               return a.fullform == b.fullform;
+                             }),
+              items.end ());
+
+  if (select_mode == multiple_symbols_cancel && items.size () > 1)
     error (_("canceled because the command is ambiguous\n"
             "See set/show multiple-symbol."));
   
-  if (select_mode == multiple_symbols_all || items_count == 1)
+  if (select_mode == multiple_symbols_all || items.size () == 1)
     {
-      do_cleanups (old_chain);
       convert_results_to_lsals (self, result);
       return;
     }
 
   printf_unfiltered (_("[0] cancel\n[1] all\n"));
-  for (i = 0; i < items_count; i++)
-    printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform);
+  for (i = 0; i < items.size (); i++)
+    printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform.c_str ());
 
   prompt = getenv ("PS2");
   if (prompt == NULL)
@@ -1605,13 +1576,12 @@ decode_line_2 (struct linespec_state *self,
             multiple_symbols_all behavior even with the 'ask'
             setting; and he can get separate breakpoints by entering
             "2-57" at the query.  */
-         do_cleanups (old_chain);
          convert_results_to_lsals (self, result);
          return;
        }
 
       num -= 2;
-      if (num >= items_count)
+      if (num >= items.size ())
        printf_unfiltered (_("No choice number %d.\n"), num);
       else
        {
@@ -1619,7 +1589,7 @@ decode_line_2 (struct linespec_state *self,
 
          if (!item->selected)
            {
-             VEC_safe_push (const_char_ptr, filters, item->fullform);
+             filters.push_back (item->fullform.c_str ());
              item->selected = 1;
            }
          else
@@ -1631,7 +1601,6 @@ decode_line_2 (struct linespec_state *self,
     }
 
   filter_results (self, result, filters);
-  do_cleanups (old_chain);
 }
 
 \f
@@ -1697,13 +1666,10 @@ unexpected_linespec_error (linespec_parser *parser)
   if (token.type == LSTOKEN_STRING || token.type == LSTOKEN_NUMBER
       || token.type == LSTOKEN_KEYWORD)
     {
-      char *string;
-
-      string = copy_token_string (token);
-      make_cleanup (xfree, string);
+      gdb::unique_xmalloc_ptr<char> string = copy_token_string (token);
       throw_error (GENERIC_ERROR,
                   _("malformed linespec error: unexpected %s, \"%s\""),
-                  token_type_strings[token.type], string);
+                  token_type_strings[token.type], string.get ());
     }
   else
     throw_error (GENERIC_ERROR,
@@ -1782,7 +1748,7 @@ set_completion_after_number (linespec_parser *parser,
 {
   if (*PARSER_STREAM (parser) == ' ')
     {
-      parser->completion_word = skip_spaces_const (PARSER_STREAM (parser) + 1);
+      parser->completion_word = skip_spaces (PARSER_STREAM (parser) + 1);
       parser->complete_what = next;
     }
   else
@@ -1797,11 +1763,10 @@ set_completion_after_number (linespec_parser *parser,
 static void
 linespec_parse_basic (linespec_parser *parser)
 {
-  char *name;
+  gdb::unique_xmalloc_ptr<char> name;
   linespec_token token;
   VEC (symbolp) *symbols, *labels;
   VEC (bound_minimal_symbol_d) *minimal_symbols;
-  struct cleanup *cleanup;
 
   /* Get the next token.  */
   token = linespec_lexer_lex_one (parser);
@@ -1823,9 +1788,8 @@ linespec_parse_basic (linespec_parser *parser)
 
       /* Record the line offset and get the next token.  */
       name = copy_token_string (token);
-      cleanup = make_cleanup (xfree, name);
-      PARSER_EXPLICIT (parser)->line_offset = linespec_parse_line_offset (name);
-      do_cleanups (cleanup);
+      PARSER_EXPLICIT (parser)->line_offset
+       = linespec_parse_line_offset (name.get ());
 
       /* Get the next token.  */
       token = linespec_lexer_consume_token (parser);
@@ -1856,7 +1820,6 @@ linespec_parse_basic (linespec_parser *parser)
   /* The current token will contain the name of a function, method,
      or label.  */
   name = copy_token_string (token);
-  cleanup = make_cleanup (free_current_contents, &name);
 
   if (parser->completion_tracker != NULL)
     {
@@ -1877,9 +1840,12 @@ linespec_parse_basic (linespec_parser *parser)
          completion_tracker tmp_tracker;
          const char *source_filename
            = PARSER_EXPLICIT (parser)->source_filename;
+         symbol_name_match_type match_type
+           = PARSER_EXPLICIT (parser)->func_name_match_type;
 
          linespec_complete_function (tmp_tracker,
                                      parser->completion_word,
+                                     match_type,
                                      source_filename);
 
          if (tmp_tracker.have_completions ())
@@ -1887,79 +1853,68 @@ linespec_parse_basic (linespec_parser *parser)
              PARSER_STREAM (parser)++;
              LS_TOKEN_STOKEN (token).length++;
 
-             xfree (name);
-             name = savestring (parser->completion_word,
-                                (PARSER_STREAM (parser)
-                                 - parser->completion_word));
+             name.reset (savestring (parser->completion_word,
+                                     (PARSER_STREAM (parser)
+                                      - parser->completion_word)));
            }
        }
 
-      PARSER_EXPLICIT (parser)->function_name = name;
-      discard_cleanups (cleanup);
+      PARSER_EXPLICIT (parser)->function_name = name.release ();
     }
   else
     {
-      /* XXX Reindent before pushing.  */
-
-  /* Try looking it up as a function/method.  */
-  find_linespec_symbols (PARSER_STATE (parser),
-                        PARSER_RESULT (parser)->file_symtabs, name,
-                        &symbols, &minimal_symbols);
+      /* Try looking it up as a function/method.  */
+      find_linespec_symbols (PARSER_STATE (parser),
+                            PARSER_RESULT (parser)->file_symtabs, name.get (),
+                            PARSER_EXPLICIT (parser)->func_name_match_type,
+                            &symbols, &minimal_symbols);
 
-  if (symbols != NULL || minimal_symbols != NULL)
-    {
-      PARSER_RESULT (parser)->function_symbols = symbols;
-      PARSER_RESULT (parser)->minimal_symbols = minimal_symbols;
-      PARSER_EXPLICIT (parser)->function_name = name;
-      symbols = NULL;
-      discard_cleanups (cleanup);
-    }
-  else
-    {
-      /* NAME was not a function or a method.  So it must be a label
-        name or user specified variable like "break foo.c:$zippo".  */
-      labels = find_label_symbols (PARSER_STATE (parser), NULL,
-                                  &symbols, name);
-      if (labels != NULL)
+      if (symbols != NULL || minimal_symbols != NULL)
        {
-         PARSER_RESULT (parser)->labels.label_symbols = labels;
-         PARSER_RESULT (parser)->labels.function_symbols = symbols;
-         PARSER_EXPLICIT (parser)->label_name = name;
+         PARSER_RESULT (parser)->function_symbols = symbols;
+         PARSER_RESULT (parser)->minimal_symbols = minimal_symbols;
+         PARSER_EXPLICIT (parser)->function_name = name.release ();
          symbols = NULL;
-         discard_cleanups (cleanup);
        }
-      else if (token.type == LSTOKEN_STRING
-              && *LS_TOKEN_STOKEN (token).ptr == '$')
+      else
        {
-         /* User specified a convenience variable or history value.  */
-         PARSER_EXPLICIT (parser)->line_offset
-           = linespec_parse_variable (PARSER_STATE (parser), name);
-
-         if (PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN)
+         /* NAME was not a function or a method.  So it must be a label
+            name or user specified variable like "break foo.c:$zippo".  */
+         labels = find_label_symbols (PARSER_STATE (parser), NULL,
+                                      &symbols, name.get ());
+         if (labels != NULL)
            {
-             /* The user-specified variable was not valid.  Do not
-                throw an error here.  parse_linespec will do it for us.  */
-             PARSER_EXPLICIT (parser)->function_name = name;
-             discard_cleanups (cleanup);
-             return;
+             PARSER_RESULT (parser)->labels.label_symbols = labels;
+             PARSER_RESULT (parser)->labels.function_symbols = symbols;
+             PARSER_EXPLICIT (parser)->label_name = name.release ();
+             symbols = NULL;
            }
+         else if (token.type == LSTOKEN_STRING
+                  && *LS_TOKEN_STOKEN (token).ptr == '$')
+           {
+             /* User specified a convenience variable or history value.  */
+             PARSER_EXPLICIT (parser)->line_offset
+               = linespec_parse_variable (PARSER_STATE (parser), name.get ());
 
-         /* The convenience variable/history value parsed correctly.
-            NAME is no longer needed.  */
-         do_cleanups (cleanup);
-       }
-      else
-       {
-         /* The name is also not a label.  Abort parsing.  Do not throw
-            an error here.  parse_linespec will do it for us.  */
+             if (PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN)
+               {
+                 /* The user-specified variable was not valid.  Do not
+                    throw an error here.  parse_linespec will do it for us.  */
+                 PARSER_EXPLICIT (parser)->function_name = name.release ();
+                 return;
+               }
+           }
+         else
+           {
+             /* The name is also not a label.  Abort parsing.  Do not throw
+                an error here.  parse_linespec will do it for us.  */
 
-         /* Save a copy of the name we were trying to lookup.  */
-         PARSER_EXPLICIT (parser)->function_name = name;
-         discard_cleanups (cleanup);
-         return;
+             /* Save a copy of the name we were trying to lookup.  */
+             PARSER_EXPLICIT (parser)->function_name = name.release ();
+             return;
+           }
        }
     }
-    }
 
   int previous_qc = parser->completion_quote_char;
 
@@ -1983,10 +1938,8 @@ linespec_parse_basic (linespec_parser *parser)
          set_completion_after_number (parser, linespec_complete_what::KEYWORD);
 
          name = copy_token_string (token);
-         cleanup = make_cleanup (xfree, name);
          PARSER_EXPLICIT (parser)->line_offset
-           = linespec_parse_line_offset (name);
-         do_cleanups (cleanup);
+           = linespec_parse_line_offset (name.get ());
 
          /* Get the next token.  */
          token = linespec_lexer_consume_token (parser);
@@ -2012,7 +1965,7 @@ linespec_parse_basic (linespec_parser *parser)
                  if (ptr[i] == ' ')
                    {
                      LS_TOKEN_STOKEN (token).length = i;
-                     PARSER_STREAM (parser) = skip_spaces_const (ptr + i + 1);
+                     PARSER_STREAM (parser) = skip_spaces (ptr + i + 1);
                      break;
                    }
                }
@@ -2028,29 +1981,26 @@ linespec_parse_basic (linespec_parser *parser)
            }
          else
            {
-             /* XXX Reindent before pushing.  */
-
-         /* Grab a copy of the label's name and look it up.  */
-         name = copy_token_string (token);
-         cleanup = make_cleanup (xfree, name);
-         labels = find_label_symbols (PARSER_STATE (parser),
-                                      PARSER_RESULT (parser)->function_symbols,
-                                      &symbols, name);
+             /* Grab a copy of the label's name and look it up.  */
+             name = copy_token_string (token);
+             labels
+               = find_label_symbols (PARSER_STATE (parser),
+                                     PARSER_RESULT (parser)->function_symbols,
+                                     &symbols, name.get ());
 
-         if (labels != NULL)
-           {
-             PARSER_RESULT (parser)->labels.label_symbols = labels;
-             PARSER_RESULT (parser)->labels.function_symbols = symbols;
-             PARSER_EXPLICIT (parser)->label_name = name;
-             symbols = NULL;
-             discard_cleanups (cleanup);
-           }
-         else
-           {
-             /* We don't know what it was, but it isn't a label.  */
-             undefined_label_error (PARSER_EXPLICIT (parser)->function_name,
-                                    name);
-           }
+             if (labels != NULL)
+               {
+                 PARSER_RESULT (parser)->labels.label_symbols = labels;
+                 PARSER_RESULT (parser)->labels.function_symbols = symbols;
+                 PARSER_EXPLICIT (parser)->label_name = name.release ();
+                 symbols = NULL;
+               }
+             else
+               {
+                 /* We don't know what it was, but it isn't a label.  */
+                 undefined_label_error
+                   (PARSER_EXPLICIT (parser)->function_name, name.get ());
+               }
 
            }
 
@@ -2067,11 +2017,9 @@ linespec_parse_basic (linespec_parser *parser)
 
              /* Record the line offset and get the next token.  */
              name = copy_token_string (token);
-             cleanup = make_cleanup (xfree, name);
 
              PARSER_EXPLICIT (parser)->line_offset
-               = linespec_parse_line_offset (name);
-             do_cleanups (cleanup);
+               = linespec_parse_line_offset (name.get ());
 
              /* Get the next token.  */
              token = linespec_lexer_consume_token (parser);
@@ -2135,18 +2083,12 @@ canonicalize_linespec (struct linespec_state *state, const linespec_p ls)
 
 /* Given a line offset in LS, construct the relevant SALs.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 create_sals_line_offset (struct linespec_state *self,
                         linespec_p ls)
 {
-  struct symtabs_and_lines values;
-  struct symtab_and_line val;
   int use_default = 0;
 
-  init_sal (&val);
-  values.sals = NULL;
-  values.nelts = 0;
-
   /* This is where we need to make sure we have good defaults.
      We must guarantee that this section of code is never executed
      when we are called with just a function name, since
@@ -2171,6 +2113,7 @@ create_sals_line_offset (struct linespec_state *self,
       use_default = 1;
     }
 
+  symtab_and_line val;
   val.line = ls->explicit_loc.line_offset.offset;
   switch (ls->explicit_loc.line_offset.sign)
     {
@@ -2194,27 +2137,20 @@ create_sals_line_offset (struct linespec_state *self,
       break;                   /* No need to adjust val.line.  */
     }
 
+  std::vector<symtab_and_line> values;
   if (self->list_mode)
-    decode_digits_list_mode (self, ls, &values, val);
+    values = decode_digits_list_mode (self, ls, val);
   else
     {
       struct linetable_entry *best_entry = NULL;
-      int *filter;
-      const struct block **blocks;
-      struct cleanup *cleanup;
-      struct symtabs_and_lines intermediate_results;
       int i, j;
 
-      intermediate_results.sals = NULL;
-      intermediate_results.nelts = 0;
-
-      decode_digits_ordinary (self, ls, val.line, &intermediate_results,
-                             &best_entry);
-      if (intermediate_results.nelts == 0 && best_entry != NULL)
-       decode_digits_ordinary (self, ls, best_entry->line,
-                               &intermediate_results, &best_entry);
-
-      cleanup = make_cleanup (xfree, intermediate_results.sals);
+      std::vector<symtab_and_line> intermediate_results
+       = decode_digits_ordinary (self, ls, val.line, &best_entry);
+      if (intermediate_results.empty () && best_entry != NULL)
+       intermediate_results = decode_digits_ordinary (self, ls,
+                                                      best_entry->line,
+                                                      &best_entry);
 
       /* For optimized code, the compiler can scatter one source line
         across disjoint ranges of PC values, even when no duplicate
@@ -2226,24 +2162,22 @@ create_sals_line_offset (struct linespec_state *self,
         above, we see if there are other PCs that are in the same
         block.  If yes, the other PCs are filtered out.  */
 
-      filter = XNEWVEC (int, intermediate_results.nelts);
-      make_cleanup (xfree, filter);
-      blocks = XNEWVEC (const struct block *, intermediate_results.nelts);
-      make_cleanup (xfree, blocks);
+      gdb::def_vector<int> filter (intermediate_results.size ());
+      gdb::def_vector<const block *> blocks (intermediate_results.size ());
 
-      for (i = 0; i < intermediate_results.nelts; ++i)
+      for (i = 0; i < intermediate_results.size (); ++i)
        {
-         set_current_program_space (intermediate_results.sals[i].pspace);
+         set_current_program_space (intermediate_results[i].pspace);
 
          filter[i] = 1;
-         blocks[i] = block_for_pc_sect (intermediate_results.sals[i].pc,
-                                        intermediate_results.sals[i].section);
+         blocks[i] = block_for_pc_sect (intermediate_results[i].pc,
+                                        intermediate_results[i].section);
        }
 
-      for (i = 0; i < intermediate_results.nelts; ++i)
+      for (i = 0; i < intermediate_results.size (); ++i)
        {
          if (blocks[i] != NULL)
-           for (j = i + 1; j < intermediate_results.nelts; ++j)
+           for (j = i + 1; j < intermediate_results.size (); ++j)
              {
                if (blocks[j] == blocks[i])
                  {
@@ -2253,7 +2187,7 @@ create_sals_line_offset (struct linespec_state *self,
              }
        }
 
-      for (i = 0; i < intermediate_results.nelts; ++i)
+      for (i = 0; i < intermediate_results.size (); ++i)
        if (filter[i])
          {
            struct symbol *sym = (blocks[i]
@@ -2261,18 +2195,14 @@ create_sals_line_offset (struct linespec_state *self,
                                  : NULL);
 
            if (self->funfirstline)
-             skip_prologue_sal (&intermediate_results.sals[i]);
-           /* Make sure the line matches the request, not what was
-              found.  */
-           intermediate_results.sals[i].line = val.line;
-           add_sal_to_sals (self, &values, &intermediate_results.sals[i],
+             skip_prologue_sal (&intermediate_results[i]);
+           intermediate_results[i].symbol = sym;
+           add_sal_to_sals (self, &values, &intermediate_results[i],
                             sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0);
          }
-
-      do_cleanups (cleanup);
     }
 
-  if (values.nelts == 0)
+  if (values.empty ())
     {
       if (ls->explicit_loc.source_filename)
        throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
@@ -2287,17 +2217,17 @@ create_sals_line_offset (struct linespec_state *self,
 
 /* Convert the given ADDRESS into SaLs.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 convert_address_location_to_sals (struct linespec_state *self,
                                  CORE_ADDR address)
 {
-  struct symtab_and_line sal;
-  struct symtabs_and_lines sals = {NULL, 0};
-
-  sal = find_pc_line (address, 0);
+  symtab_and_line sal = find_pc_line (address, 0);
   sal.pc = address;
   sal.section = find_pc_overlay (address);
   sal.explicit_pc = 1;
+  sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section);
+
+  std::vector<symtab_and_line> sals;
   add_sal_to_sals (self, &sals, &sal, core_addr_to_string (address), 1);
 
   return sals;
@@ -2305,10 +2235,10 @@ convert_address_location_to_sals (struct linespec_state *self,
 
 /* Create and return SALs from the linespec LS.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 {
-  struct symtabs_and_lines sals = {NULL, 0};
+  std::vector<symtab_and_line> sals;
 
   if (ls->labels.label_symbols != NULL)
     {
@@ -2330,12 +2260,6 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
   else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
     {
       /* We have just a bunch of functions and/or methods.  */
-      int i;
-      struct symtab_and_line sal;
-      struct symbol *sym;
-      bound_minimal_symbol_d *elem;
-      struct program_space *pspace;
-
       if (ls->function_symbols != NULL)
        {
          /* Sort symbols so that symbols with the same program space are next
@@ -2344,30 +2268,81 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
                 VEC_length (symbolp, ls->function_symbols),
                 sizeof (symbolp), compare_symbols);
 
-         for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
+         struct symbol *sym;
+         for (int i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
            {
-             pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+             program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym));
              set_current_program_space (pspace);
-             if (symbol_to_sal (&sal, state->funfirstline, sym)
-                 && maybe_add_address (state->addr_set, pspace, sal.pc))
-               add_sal_to_sals (state, &sals, &sal,
-                                SYMBOL_NATURAL_NAME (sym), 0);
+
+             /* Don't skip to the first line of the function if we
+                had found an ifunc minimal symbol for this function,
+                because that means that this function is an ifunc
+                resolver with the same name as the ifunc itself.  */
+             bool found_ifunc = false;
+
+             if (state->funfirstline
+                  && ls->minimal_symbols != NULL
+                  && SYMBOL_CLASS (sym) == LOC_BLOCK)
+               {
+                 const CORE_ADDR addr
+                   = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+
+                 bound_minimal_symbol_d *elem;
+                 for (int m = 0;
+                      VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
+                                   m, elem);
+                      ++m)
+                   {
+                     if (MSYMBOL_TYPE (elem->minsym) == mst_text_gnu_ifunc
+                         || MSYMBOL_TYPE (elem->minsym) == mst_data_gnu_ifunc)
+                       {
+                         CORE_ADDR msym_addr = BMSYMBOL_VALUE_ADDRESS (*elem);
+                         if (MSYMBOL_TYPE (elem->minsym) == mst_data_gnu_ifunc)
+                           {
+                             struct gdbarch *gdbarch
+                               = get_objfile_arch (elem->objfile);
+                             msym_addr
+                               = (gdbarch_convert_from_func_ptr_addr
+                                  (gdbarch,
+                                   msym_addr,
+                                   current_top_target ()));
+                           }
+
+                         if (msym_addr == addr)
+                           {
+                             found_ifunc = true;
+                             break;
+                           }
+                       }
+                   }
+               }
+
+             if (!found_ifunc)
+               {
+                 symtab_and_line sal;
+                 if (symbol_to_sal (&sal, state->funfirstline, sym)
+                     && maybe_add_address (state->addr_set, pspace, sal.pc))
+                   add_sal_to_sals (state, &sals, &sal,
+                                    SYMBOL_NATURAL_NAME (sym), 0);
+               }
            }
        }
 
       if (ls->minimal_symbols != NULL)
        {
-         /* Sort minimal symbols by program space, too.  */
+         /* Sort minimal symbols by program space, too  */
          qsort (VEC_address (bound_minimal_symbol_d, ls->minimal_symbols),
                 VEC_length (bound_minimal_symbol_d, ls->minimal_symbols),
                 sizeof (bound_minimal_symbol_d), compare_msymbols);
 
-         for (i = 0;
+         bound_minimal_symbol_d *elem;
+
+         for (int i = 0;
               VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
                            i, elem);
               ++i)
            {
-             pspace = elem->objfile->pspace;
+             program_space *pspace = elem->objfile->pspace;
              set_current_program_space (pspace);
              minsym_found (state, elem->objfile, elem->minsym, &sals);
            }
@@ -2398,7 +2373,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
   canonicalize_linespec (state, ls);
 
-  if (sals.nelts > 0 && state->canonical != NULL)
+  if (!sals.empty () && state->canonical != NULL)
     state->canonical->pre_expanded = 1;
 
   return sals;
@@ -2412,12 +2387,15 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
                                       linespec_p result,
                                       const char *source_filename,
                                       const char *function_name,
+                                      symbol_name_match_type fname_match_type,
                                       const char *label_name,
                                       struct line_offset line_offset)
 {
   VEC (symbolp) *symbols, *labels;
   VEC (bound_minimal_symbol_d) *minimal_symbols;
 
+  result->explicit_loc.func_name_match_type = fname_match_type;
+
   if (source_filename != NULL)
     {
       TRY
@@ -2441,8 +2419,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
   if (function_name != NULL)
     {
       find_linespec_symbols (self, result->file_symtabs,
-                            function_name, &symbols,
-                            &minimal_symbols);
+                            function_name, fname_match_type,
+                            &symbols, &minimal_symbols);
 
       if (symbols == NULL && minimal_symbols == NULL)
        symbol_not_found_error (function_name,
@@ -2474,7 +2452,7 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
 
 /* Convert the explicit location EXPLICIT_LOC into SaLs.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 convert_explicit_location_to_sals (struct linespec_state *self,
                                   linespec_p result,
                                   const struct explicit_location *explicit_loc)
@@ -2482,6 +2460,7 @@ convert_explicit_location_to_sals (struct linespec_state *self,
   convert_explicit_location_to_linespec (self, result,
                                         explicit_loc->source_filename,
                                         explicit_loc->function_name,
+                                        explicit_loc->func_name_match_type,
                                         explicit_loc->label_name,
                                         explicit_loc->line_offset);
   return convert_linespec_to_sals (self, result);
@@ -2535,18 +2514,15 @@ convert_explicit_location_to_sals (struct linespec_state *self,
    if no file is validly specified.  Callers must check that.
    Also, the line number returned may be invalid.  */
 
-/* Parse the linespec in ARG.  */
+/* Parse the linespec in ARG.  MATCH_TYPE indicates how function names
+   should be matched.  */
 
-static struct symtabs_and_lines
-parse_linespec (linespec_parser *parser, const char *arg)
+static std::vector<symtab_and_line>
+parse_linespec (linespec_parser *parser, const char *arg,
+               symbol_name_match_type match_type)
 {
   linespec_token token;
-  struct symtabs_and_lines values;
   struct gdb_exception file_exception = exception_none;
-  struct cleanup *cleanup;
-
-  values.nelts = 0;
-  values.sals = NULL;
 
   /* A special case to start.  It has become quite popular for
      IDEs to work around bugs in the previous parser by quoting
@@ -2572,6 +2548,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
   parser->lexer.stream = arg;
   parser->completion_word = arg;
   parser->complete_what = linespec_complete_what::FUNCTION;
+  PARSER_EXPLICIT (parser)->func_name_match_type = match_type;
 
   /* Initialize the default symtab and line offset.  */
   initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@@ -2580,8 +2557,9 @@ parse_linespec (linespec_parser *parser, const char *arg)
   /* Objective-C shortcut.  */
   if (parser->completion_tracker == NULL)
     {
-      values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg);
-      if (values.sals != NULL)
+      std::vector<symtab_and_line> values
+       = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg);
+      if (!values.empty ())
        return values;
     }
   else
@@ -2602,18 +2580,14 @@ parse_linespec (linespec_parser *parser, const char *arg)
   /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER.  */
   if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$')
     {
-      char *var;
-
       /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
       if (parser->completion_tracker == NULL)
        VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL);
 
       /* User specified a convenience variable or history value.  */
-      var = copy_token_string (token);
-      cleanup = make_cleanup (xfree, var);
+      gdb::unique_xmalloc_ptr<char> var = copy_token_string (token);
       PARSER_EXPLICIT (parser)->line_offset
-       = linespec_parse_variable (PARSER_STATE (parser), var);
-      do_cleanups (cleanup);
+       = linespec_parse_variable (PARSER_STATE (parser), var.get ());
 
       /* If a line_offset wasn't found (VAR is the name of a user
         variable/function), then skip to normal symbol processing.  */
@@ -2642,17 +2616,15 @@ parse_linespec (linespec_parser *parser, const char *arg)
 
   if (token.type == LSTOKEN_COLON)
     {
-      char *user_filename;
-
       /* Get the current token again and extract the filename.  */
       token = linespec_lexer_lex_one (parser);
-      user_filename = copy_token_string (token);
+      gdb::unique_xmalloc_ptr<char> user_filename = copy_token_string (token);
 
       /* Check if the input is a filename.  */
       TRY
        {
          PARSER_RESULT (parser)->file_symtabs
-           = symtabs_from_filename (user_filename,
+           = symtabs_from_filename (user_filename.get (),
                                     PARSER_STATE (parser)->search_pspace);
        }
       CATCH (ex, RETURN_MASK_ERROR)
@@ -2664,7 +2636,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
       if (file_exception.reason >= 0)
        {
          /* Symtabs were found for the file.  Record the filename.  */
-         PARSER_EXPLICIT (parser)->source_filename = user_filename;
+         PARSER_EXPLICIT (parser)->source_filename = user_filename.release ();
 
          /* Get the next token.  */
          token = linespec_lexer_consume_token (parser);
@@ -2674,9 +2646,6 @@ parse_linespec (linespec_parser *parser, const char *arg)
        }
       else
        {
-         /* No symtabs found -- discard user_filename.  */
-         xfree (user_filename);
-
          /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
          VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL);
        }
@@ -2729,16 +2698,16 @@ parse_linespec (linespec_parser *parser, const char *arg)
         advances past a keyword automatically, so skip it
         manually.  */
       parser->completion_word
-       = skip_spaces_const (skip_to_space_const (PARSER_STREAM (parser)));
+       = skip_spaces (skip_to_space (PARSER_STREAM (parser)));
       parser->complete_what = linespec_complete_what::EXPRESSION;
     }
 
   /* Convert the data in PARSER_RESULT to SALs.  */
   if (parser->completion_tracker == NULL)
-    values = convert_linespec_to_sals (PARSER_STATE (parser),
-                                      PARSER_RESULT (parser));
+    return convert_linespec_to_sals (PARSER_STATE (parser),
+                                    PARSER_RESULT (parser));
 
-  return values;
+  return {};
 }
 
 
@@ -2779,6 +2748,8 @@ linespec_parser_new (linespec_parser *parser,
   memset (parser, 0, sizeof (linespec_parser));
   parser->lexer.current.type = LSTOKEN_CONSUMED;
   memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
+  PARSER_EXPLICIT (parser)->func_name_match_type
+    = symbol_name_match_type::WILD;
   PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
   linespec_state_constructor (PARSER_STATE (parser), flags, language,
                              search_pspace,
@@ -2825,7 +2796,7 @@ linespec_parser_delete (void *arg)
 /* See description in linespec.h.  */
 
 void
-linespec_lex_to_end (char **stringp)
+linespec_lex_to_end (const char **stringp)
 {
   linespec_parser parser;
   struct cleanup *cleanup;
@@ -2860,18 +2831,22 @@ linespec_lex_to_end (char **stringp)
 void
 linespec_complete_function (completion_tracker &tracker,
                            const char *function,
+                           symbol_name_match_type func_match_type,
                            const char *source_filename)
 {
   complete_symbol_mode mode = complete_symbol_mode::LINESPEC;
 
   if (source_filename != NULL)
     {
-      collect_file_symbol_completion_matches (tracker, mode,
-                                             function, function,
-                                             source_filename);
+      collect_file_symbol_completion_matches (tracker, mode, func_match_type,
+                                             function, function, source_filename);
     }
   else
-    collect_symbol_completion_matches (tracker, mode, function, function);
+    {
+      collect_symbol_completion_matches (tracker, mode, func_match_type,
+                                        function, function);
+
+    }
 }
 
 /* Helper for complete_linespec to simplify it.  SOURCE_FILENAME is
@@ -2898,7 +2873,9 @@ complete_linespec_component (linespec_parser *parser,
     {
       completion_list fn_list;
 
-      linespec_complete_function (tracker, text, source_filename);
+      symbol_name_match_type match_type
+       = PARSER_EXPLICIT (parser)->func_name_match_type;
+      linespec_complete_function (tracker, text, match_type, source_filename);
       if (source_filename == NULL)
        {
          /* Haven't seen a source component, like in "b
@@ -2968,6 +2945,7 @@ linespec_complete_label (completion_tracker &tracker,
                         const struct language_defn *language,
                         const char *source_filename,
                         const char *function_name,
+                        symbol_name_match_type func_name_match_type,
                         const char *label_name)
 {
   linespec_parser parser;
@@ -2984,6 +2962,7 @@ linespec_complete_label (completion_tracker &tracker,
                                             PARSER_RESULT (&parser),
                                             source_filename,
                                             function_name,
+                                            func_name_match_type,
                                             NULL, unknown_offset);
     }
   CATCH (ex, RETURN_MASK_ERROR)
@@ -3001,7 +2980,8 @@ linespec_complete_label (completion_tracker &tracker,
 /* See description in linespec.h.  */
 
 void
-linespec_complete (completion_tracker &tracker, const char *text)
+linespec_complete (completion_tracker &tracker, const char *text,
+                  symbol_name_match_type match_type)
 {
   linespec_parser parser;
   struct cleanup *cleanup;
@@ -3010,6 +2990,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
   linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
   cleanup = make_cleanup (linespec_parser_delete, &parser);
   parser.lexer.saved_arg = text;
+  PARSER_EXPLICIT (&parser)->func_name_match_type = match_type;
   PARSER_STREAM (&parser) = text;
 
   parser.completion_tracker = &tracker;
@@ -3019,7 +3000,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
      furthest completion point we managed to parse to.  */
   TRY
     {
-      parse_linespec (&parser, text);
+      parse_linespec (&parser, text, match_type);
     }
   CATCH (except, RETURN_MASK_ERROR)
     {
@@ -3067,7 +3048,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
       VEC (bound_minimal_symbol_d) *minimal_symbols;
       find_linespec_symbols (PARSER_STATE (&parser),
                             PARSER_RESULT (&parser)->file_symtabs,
-                            func_name,
+                            func_name, match_type,
                             &function_symbols, &minimal_symbols);
 
       PARSER_RESULT (&parser)->function_symbols = function_symbols;
@@ -3116,7 +3097,6 @@ linespec_complete (completion_tracker &tracker, const char *text)
         the ':', then complete_linespec_component won't try to
         complete on source filenames.  */
 
-      const char *text = parser.completion_word;
       const char *word = parser.completion_word;
 
       complete_linespec_component (&parser, tracker,
@@ -3194,13 +3174,13 @@ linespec_complete (completion_tracker &tracker, const char *text)
 }
 
 /* A helper function for decode_line_full and decode_line_1 to
-   turn LOCATION into symtabs_and_lines.  */
+   turn LOCATION into std::vector<symtab_and_line>.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 event_location_to_sals (linespec_parser *parser,
                        const struct event_location *location)
 {
-  struct symtabs_and_lines result = {NULL, 0};
+  std::vector<symtab_and_line> result;
 
   switch (event_location_type (location))
     {
@@ -3209,7 +3189,9 @@ event_location_to_sals (linespec_parser *parser,
        PARSER_STATE (parser)->is_linespec = 1;
        TRY
          {
-           result = parse_linespec (parser, get_linespec_location (location));
+           const linespec_location *ls = get_linespec_location (location);
+           result = parse_linespec (parser,
+                                    ls->spec_string, ls->match_type);
          }
        CATCH (except, RETURN_MASK_ERROR)
          {
@@ -3226,16 +3208,10 @@ event_location_to_sals (linespec_parser *parser,
 
        if (addr_string != NULL)
          {
-           char *expr = xstrdup (addr_string);
-           const char *const_expr = expr;
-           struct cleanup *cleanup = make_cleanup (xfree, expr);
-
-           addr = linespec_expression_to_pc (&const_expr);
+           addr = linespec_expression_to_pc (&addr_string);
            if (PARSER_STATE (parser)->canonical != NULL)
              PARSER_STATE (parser)->canonical->location
                = copy_event_location (location);
-
-           do_cleanups (cleanup);
          }
 
        result = convert_address_location_to_sals (PARSER_STATE (parser),
@@ -3276,9 +3252,8 @@ decode_line_full (const struct event_location *location, int flags,
                  const char *select_mode,
                  const char *filter)
 {
-  struct symtabs_and_lines result;
   struct cleanup *cleanups;
-  VEC (const_char_ptr) *filters = NULL;
+  std::vector<const char *> filters;
   linespec_parser parser;
   struct linespec_state *state;
 
@@ -3298,19 +3273,20 @@ decode_line_full (const struct event_location *location, int flags,
 
   scoped_restore_current_program_space restore_pspace;
 
-  result = event_location_to_sals (&parser, location);
+  std::vector<symtab_and_line> result = event_location_to_sals (&parser,
+                                                               location);
   state = PARSER_STATE (&parser);
 
-  gdb_assert (result.nelts == 1 || canonical->pre_expanded);
+  gdb_assert (result.size () == 1 || canonical->pre_expanded);
   canonical->pre_expanded = 1;
 
   /* Arrange for allocated canonical names to be freed.  */
-  if (result.nelts > 0)
+  if (!result.empty ())
     {
       int i;
 
       make_cleanup (xfree, state->canonical_names);
-      for (i = 0; i < result.nelts; ++i)
+      for (i = 0; i < result.size (); ++i)
        {
          gdb_assert (state->canonical_names[i].suffix != NULL);
          make_cleanup (xfree, state->canonical_names[i].suffix);
@@ -3319,7 +3295,7 @@ decode_line_full (const struct event_location *location, int flags,
 
   if (select_mode == NULL)
     {
-      if (interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
+      if (top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
        select_mode = multiple_symbols_all;
       else
        select_mode = multiple_symbols_select_mode ();
@@ -3329,8 +3305,7 @@ decode_line_full (const struct event_location *location, int flags,
     {
       if (filter != NULL)
        {
-         make_cleanup (VEC_cleanup (const_char_ptr), &filters);
-         VEC_safe_push (const_char_ptr, filters, filter);
+         filters.push_back (filter);
          filter_results (state, &result, filters);
        }
       else
@@ -3344,13 +3319,12 @@ decode_line_full (const struct event_location *location, int flags,
 
 /* See linespec.h.  */
 
-struct symtabs_and_lines
+std::vector<symtab_and_line>
 decode_line_1 (const struct event_location *location, int flags,
               struct program_space *search_pspace,
               struct symtab *default_symtab,
               int default_line)
 {
-  struct symtabs_and_lines result;
   linespec_parser parser;
   struct cleanup *cleanups;
 
@@ -3361,7 +3335,8 @@ decode_line_1 (const struct event_location *location, int flags,
 
   scoped_restore_current_program_space restore_pspace;
 
-  result = event_location_to_sals (&parser, location);
+  std::vector<symtab_and_line> result = event_location_to_sals (&parser,
+                                                               location);
 
   do_cleanups (cleanups);
   return result;
@@ -3369,23 +3344,20 @@ decode_line_1 (const struct event_location *location, int flags,
 
 /* See linespec.h.  */
 
-struct symtabs_and_lines
-decode_line_with_current_source (char *string, int flags)
+std::vector<symtab_and_line>
+decode_line_with_current_source (const char *string, int flags)
 {
-  struct symtabs_and_lines sals;
-  struct symtab_and_line cursal;
-
   if (string == 0)
     error (_("Empty line specification."));
 
   /* We use whatever is set as the current source line.  We do not try
      and get a default source symtab+line or it will recursively call us!  */
-  cursal = get_current_source_symtab_and_line ();
+  symtab_and_line cursal = get_current_source_symtab_and_line ();
 
   event_location_up location = string_to_event_location (&string,
                                                         current_language);
-  sals = decode_line_1 (location.get (), flags, NULL,
-                       cursal.symtab, cursal.line);
+  std::vector<symtab_and_line> sals
+    = decode_line_1 (location.get (), flags, NULL, cursal.symtab, cursal.line);
 
   if (*string)
     error (_("Junk at end of line specification: %s"), string);
@@ -3395,23 +3367,21 @@ decode_line_with_current_source (char *string, int flags)
 
 /* See linespec.h.  */
 
-struct symtabs_and_lines
-decode_line_with_last_displayed (char *string, int flags)
+std::vector<symtab_and_line>
+decode_line_with_last_displayed (const char *string, int flags)
 {
-  struct symtabs_and_lines sals;
-
   if (string == 0)
     error (_("Empty line specification."));
 
   event_location_up location = string_to_event_location (&string,
                                                         current_language);
-  if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (location.get (), flags, NULL,
-                         get_last_displayed_symtab (),
-                         get_last_displayed_line ());
-  else
-    sals = decode_line_1 (location.get (), flags, NULL,
-                         (struct symtab *) NULL, 0);
+  std::vector<symtab_and_line> sals
+    = (last_displayed_sal_is_valid ()
+       ? decode_line_1 (location.get (), flags, NULL,
+                       get_last_displayed_symtab (),
+                       get_last_displayed_line ())
+       : decode_line_1 (location.get (), flags, NULL,
+                       (struct symtab *) NULL, 0));
 
   if (*string)
     error (_("Junk at end of line specification: %s"), string);
@@ -3467,34 +3437,32 @@ linespec_expression_to_pc (const char **exp_ptr)
    than one method that could represent the selector, then use some of
    the existing C++ code to let the user choose one.  */
 
-static struct symtabs_and_lines
+static std::vector<symtab_and_line>
 decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
 {
   struct collect_info info;
-  VEC (const_char_ptr) *symbol_names = NULL;
-  struct symtabs_and_lines values;
+  std::vector<const char *> symbol_names;
   const char *new_argptr;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-                                         &symbol_names);
 
   info.state = self;
   info.file_symtabs = NULL;
   VEC_safe_push (symtab_ptr, info.file_symtabs, NULL);
-  make_cleanup (VEC_cleanup (symtab_ptr), &info.file_symtabs);
+  struct cleanup *cleanup = make_cleanup (VEC_cleanup (symtab_ptr),
+                                         &info.file_symtabs);
   info.result.symbols = NULL;
   info.result.minimal_symbols = NULL;
-  values.nelts = 0;
-  values.sals = NULL;
 
   new_argptr = find_imps (arg, &symbol_names);
-  if (VEC_empty (const_char_ptr, symbol_names))
+  if (symbol_names.empty ())
     {
       do_cleanups (cleanup);
-      return values;
+      return {};
     }
 
-  add_all_symbol_names_from_pspace (&info, NULL, symbol_names);
+  add_all_symbol_names_from_pspace (&info, NULL, symbol_names,
+                                   FUNCTIONS_DOMAIN);
 
+  std::vector<symtab_and_line> values;
   if (!VEC_empty (symbolp, info.result.symbols)
       || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols))
     {
@@ -3511,20 +3479,23 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
 
       if (self->canonical)
        {
-         char *str;
+         std::string holder;
+         const char *str;
 
          self->canonical->pre_expanded = 1;
 
          if (ls->explicit_loc.source_filename)
            {
-             str = xstrprintf ("%s:%s",
-                               ls->explicit_loc.source_filename, saved_arg);
+             holder = string_printf ("%s:%s",
+                                     ls->explicit_loc.source_filename,
+                                     saved_arg);
+             str = holder.c_str ();
            }
          else
-           str = xstrdup (saved_arg);
+           str = saved_arg;
 
-         make_cleanup (xfree, str);
-         self->canonical->location = new_linespec_location (&str);
+         self->canonical->location
+           = new_linespec_location (&str, symbol_name_match_type::FULL);
        }
     }
 
@@ -3613,13 +3584,17 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
   struct symtab *elt;
   decode_compound_collector collector;
 
+  lookup_name_info lookup_name (class_name, symbol_name_match_type::FULL);
+
   for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix)
     {
       if (elt == NULL)
        {
-         iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN,
+         iterate_over_all_matching_symtabs (state, lookup_name,
+                                            STRUCT_DOMAIN, ALL_DOMAIN,
                                             NULL, false, collector);
-         iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN,
+         iterate_over_all_matching_symtabs (state, lookup_name,
+                                            VAR_DOMAIN, ALL_DOMAIN,
                                             NULL, false, collector);
        }
       else
@@ -3628,8 +3603,8 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
-         iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN, collector);
-         iterate_over_file_blocks (elt, class_name, VAR_DOMAIN, collector);
+         iterate_over_file_blocks (elt, lookup_name, STRUCT_DOMAIN, collector);
+         iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN, collector);
        }
     }
 
@@ -3704,43 +3679,34 @@ compare_msymbols (const void *a, const void *b)
 static void
 add_all_symbol_names_from_pspace (struct collect_info *info,
                                  struct program_space *pspace,
-                                 VEC (const_char_ptr) *names)
+                                 const std::vector<const char *> &names,
+                                 enum search_domain search_domain)
 {
-  int ix;
-  const char *iter;
-
-  for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix)
-    add_matching_symbols_to_info (iter, info, pspace);
+  for (const char *iter : names)
+    add_matching_symbols_to_info (iter,
+                                 symbol_name_match_type::FULL,
+                                 search_domain, info, pspace);
 }
 
 static void
-find_superclass_methods (VEC (typep) *superclasses,
-                        const char *name,
-                        VEC (const_char_ptr) **result_names)
+find_superclass_methods (std::vector<struct type *> &&superclasses,
+                        const char *name, enum language name_lang,
+                        std::vector<const char *> *result_names)
 {
-  int old_len = VEC_length (const_char_ptr, *result_names);
-  VEC (typep) *iter_classes;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  size_t old_len = result_names->size ();
 
-  iter_classes = superclasses;
   while (1)
     {
-      VEC (typep) *new_supers = NULL;
-      int ix;
-      struct type *t;
+      std::vector<struct type *> new_supers;
 
-      make_cleanup (VEC_cleanup (typep), &new_supers);
-      for (ix = 0; VEC_iterate (typep, iter_classes, ix, t); ++ix)
-       find_methods (t, name, result_names, &new_supers);
+      for (type *t : superclasses)
+       find_methods (t, name_lang, name, result_names, &new_supers);
 
-      if (VEC_length (const_char_ptr, *result_names) != old_len
-         || VEC_empty (typep, new_supers))
+      if (result_names->size () != old_len || new_supers.empty ())
        break;
 
-      iter_classes = new_supers;
+      superclasses = std::move (new_supers);
     }
-
-  do_cleanups (cleanup);
 }
 
 /* This finds the method METHOD_NAME in the class CLASS_NAME whose type is
@@ -3754,11 +3720,10 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
             VEC (bound_minimal_symbol_d) **minsyms)
 {
   struct symbol *sym;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
   int ix;
-  int last_result_len;
-  VEC (typep) *superclass_vec;
-  VEC (const_char_ptr) *result_names;
+  size_t last_result_len;
+  std::vector<struct type *> superclass_vec;
+  std::vector<const char *> result_names;
   struct collect_info info;
 
   /* Sort symbols so that symbols with the same program space are next
@@ -3782,10 +3747,6 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
      those names.  This loop is written in a somewhat funny way
      because we collect data across the program space before deciding
      what to do.  */
-  superclass_vec = NULL;
-  make_cleanup (VEC_cleanup (typep), &superclass_vec);
-  result_names = NULL;
-  make_cleanup (VEC_cleanup (const_char_ptr), &result_names);
   last_result_len = 0;
   for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
     {
@@ -3798,7 +3759,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
       gdb_assert (!pspace->executing_startup);
       set_current_program_space (pspace);
       t = check_typedef (SYMBOL_TYPE (sym));
-      find_methods (t, method_name, &result_names, &superclass_vec);
+      find_methods (t, SYMBOL_LANGUAGE (sym),
+                   method_name, &result_names, &superclass_vec);
 
       /* Handle all items from a single program space at once; and be
         sure not to miss the last batch.  */
@@ -3809,17 +3771,18 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
        {
          /* If we did not find a direct implementation anywhere in
             this program space, consider superclasses.  */
-         if (VEC_length (const_char_ptr, result_names) == last_result_len)
-           find_superclass_methods (superclass_vec, method_name,
-                                    &result_names);
+         if (result_names.size () == last_result_len)
+           find_superclass_methods (std::move (superclass_vec), method_name,
+                                    SYMBOL_LANGUAGE (sym), &result_names);
 
          /* We have a list of candidate symbol names, so now we
             iterate over the symbol tables looking for all
             matches in this pspace.  */
-         add_all_symbol_names_from_pspace (&info, pspace, result_names);
+         add_all_symbol_names_from_pspace (&info, pspace, result_names,
+                                           FUNCTIONS_DOMAIN);
 
-         VEC_truncate (typep, superclass_vec, 0);
-         last_result_len = VEC_length (const_char_ptr, result_names);
+         superclass_vec.clear ();
+         last_result_len = result_names.size ();
        }
     }
 
@@ -3828,7 +3791,6 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
     {
       *symbols = info.result.symbols;
       *minsyms = info.result.minimal_symbols;
-      do_cleanups (cleanup);
       return;
     }
 
@@ -3959,13 +3921,12 @@ symtabs_from_filename (const char *filename,
 static void
 find_function_symbols (struct linespec_state *state,
                       VEC (symtab_ptr) *file_symtabs, const char *name,
+                      symbol_name_match_type name_match_type,
                       VEC (symbolp) **symbols,
                       VEC (bound_minimal_symbol_d) **minsyms)
 {
   struct collect_info info;
-  VEC (const_char_ptr) *symbol_names = NULL;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-                                         &symbol_names);
+  std::vector<const char *> symbol_names;
 
   info.state = state;
   info.result.symbols = NULL;
@@ -3974,13 +3935,12 @@ find_function_symbols (struct linespec_state *state,
 
   /* Try NAME as an Objective-C selector.  */
   find_imps (name, &symbol_names);
-  if (!VEC_empty (const_char_ptr, symbol_names))
+  if (!symbol_names.empty ())
     add_all_symbol_names_from_pspace (&info, state->search_pspace,
-                                     symbol_names);
+                                     symbol_names, FUNCTIONS_DOMAIN);
   else
-    add_matching_symbols_to_info (name, &info, state->search_pspace);
-
-  do_cleanups (cleanup);
+    add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
+                                 &info, state->search_pspace);
 
   if (VEC_empty (symbolp, info.result.symbols))
     {
@@ -4005,28 +3965,11 @@ find_function_symbols (struct linespec_state *state,
 static void
 find_linespec_symbols (struct linespec_state *state,
                       VEC (symtab_ptr) *file_symtabs,
-                      const char *name,
+                      const char *lookup_name,
+                      symbol_name_match_type name_match_type,
                       VEC (symbolp) **symbols,
                       VEC (bound_minimal_symbol_d) **minsyms)
 {
-  demangle_result_storage demangle_storage;
-  std::string ada_lookup_storage;
-  const char *lookup_name;
-
-  if (state->language->la_language == language_ada)
-    {
-      /* In Ada, the symbol lookups are performed using the encoded
-         name rather than the demangled name.  */
-      ada_lookup_storage = ada_name_for_lookup (name);
-      lookup_name = ada_lookup_storage.c_str ();
-    }
-  else
-    {
-      lookup_name = demangle_for_lookup (name,
-                                        state->language->la_language,
-                                        demangle_storage);
-    }
-
   std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
   if (!canon.empty ())
     lookup_name = canon.c_str ();
@@ -4041,6 +3984,7 @@ find_linespec_symbols (struct linespec_state *state,
      2) break class::method where method is in class (and not a baseclass)  */
 
   find_function_symbols (state, file_symtabs, lookup_name,
+                        name_match_type,
                         symbols, minsyms);
 
   /* If we were unable to locate a symbol of the same name, try dividing
@@ -4168,7 +4112,6 @@ find_label_symbols (struct linespec_state *self,
 {
   int ix;
   const struct block *block;
-  struct symbol *sym;
   struct symbol *fn_sym;
   VEC (symbolp) *result = NULL;
 
@@ -4208,10 +4151,9 @@ find_label_symbols (struct linespec_state *self,
 
 /* A helper for create_sals_line_offset that handles the 'list_mode' case.  */
 
-static void
+static std::vector<symtab_and_line>
 decode_digits_list_mode (struct linespec_state *self,
                         linespec_p ls,
-                        struct symtabs_and_lines *values,
                         struct symtab_and_line val)
 {
   int ix;
@@ -4219,6 +4161,8 @@ decode_digits_list_mode (struct linespec_state *self,
 
   gdb_assert (self->list_mode);
 
+  std::vector<symtab_and_line> values;
+
   for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt);
        ++ix)
     {
@@ -4235,23 +4179,25 @@ decode_digits_list_mode (struct linespec_state *self,
       val.pc = 0;
       val.explicit_line = 1;
 
-      add_sal_to_sals (self, values, &val, NULL, 0);
+      add_sal_to_sals (self, &values, &val, NULL, 0);
     }
+
+  return values;
 }
 
 /* A helper for create_sals_line_offset that iterates over the symtabs,
    adding lines to the VEC.  */
 
-static void
+static std::vector<symtab_and_line>
 decode_digits_ordinary (struct linespec_state *self,
                        linespec_p ls,
                        int line,
-                       struct symtabs_and_lines *sals,
                        struct linetable_entry **best_entry)
 {
   int ix;
   struct symtab *elt;
 
+  std::vector<symtab_and_line> sals;
   for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix)
     {
       std::vector<CORE_ADDR> pcs;
@@ -4264,16 +4210,16 @@ decode_digits_ordinary (struct linespec_state *self,
       pcs = find_pcs_for_symtab_line (elt, line, best_entry);
       for (CORE_ADDR pc : pcs)
        {
-         struct symtab_and_line sal;
-
-         init_sal (&sal);
+         symtab_and_line sal;
          sal.pspace = SYMTAB_PSPACE (elt);
          sal.symtab = elt;
          sal.line = line;
          sal.pc = pc;
-         add_sal_to_sals_basic (sals, &sal);
+         sals.push_back (std::move (sal));
        }
     }
+
+  return sals;
 }
 
 \f
@@ -4343,68 +4289,47 @@ linespec_parse_variable (struct linespec_state *self, const char *variable)
 static void
 minsym_found (struct linespec_state *self, struct objfile *objfile,
              struct minimal_symbol *msymbol,
-             struct symtabs_and_lines *result)
+             std::vector<symtab_and_line> *result)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  CORE_ADDR pc;
-  struct symtab_and_line sal;
+  bool want_start_sal;
 
-  sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol),
-                          (struct obj_section *) 0, 0);
-  sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
+  CORE_ADDR func_addr;
+  bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
+
+  if (is_function)
+    {
+      const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol);
 
-  /* The minimal symbol might point to a function descriptor;
-     resolve it to the actual code address instead.  */
-  pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, &current_target);
-  if (pc != sal.pc)
-    sal = find_pc_sect_line (pc, NULL, 0);
+      if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
+         || MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc)
+       want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
+      else
+       want_start_sal = true;
+    }
+
+  symtab_and_line sal;
 
-  if (self->funfirstline)
+  if (is_function && want_start_sal)
+    sal = find_function_start_sal (func_addr, NULL, self->funfirstline);
+  else
     {
-      if (sal.symtab != NULL
-         && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
-             || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
-       {
-         /* If gdbarch_convert_from_func_ptr_addr does not apply then
-            sal.SECTION, sal.LINE&co. will stay correct from above.
-            If gdbarch_convert_from_func_ptr_addr applies then
-            sal.SECTION is cleared from above and sal.LINE&co. will
-            stay correct from the last find_pc_sect_line above.  */
-         sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
-         sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
-                                                      &current_target);
-         if (gdbarch_skip_entrypoint_p (gdbarch))
-           sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
-       }
+      sal.objfile = objfile;
+      sal.msymbol = msymbol;
+      /* Store func_addr, not the minsym's address in case this was an
+        ifunc that hasn't been resolved yet.  */
+      if (is_function)
+       sal.pc = func_addr;
       else
-       skip_prologue_sal (&sal);
+       sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+      sal.pspace = current_program_space;
     }
 
+  sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
+
   if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
     add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
 }
 
-/* A helper struct to pass some data through
-   iterate_over_minimal_symbols.  */
-
-struct collect_minsyms
-{
-  /* The objfile we're examining.  */
-  struct objfile *objfile;
-
-  /* Only search the given symtab, or NULL to search for all symbols.  */
-  struct symtab *symtab;
-
-  /* The funfirstline setting from the initial call.  */
-  int funfirstline;
-
-  /* The list_mode setting from the initial call.  */
-  int list_mode;
-
-  /* The resulting symbols.  */
-  VEC (bound_minimal_symbol_d) *msyms;
-};
-
 /* A helper function to classify a minimal_symbol_type according to
    priority.  */
 
@@ -4429,73 +4354,46 @@ classify_mtype (enum minimal_symbol_type t)
     }
 }
 
-/* Callback for qsort that sorts symbols by priority.  */
+/* Callback for std::sort that sorts symbols by priority.  */
 
-static int
-compare_msyms (const void *a, const void *b)
+static bool
+compare_msyms (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
 {
-  const bound_minimal_symbol_d *moa = (const bound_minimal_symbol_d *) a;
-  const bound_minimal_symbol_d *mob = (const bound_minimal_symbol_d *) b;
-  enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym);
-  enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym);
+  enum minimal_symbol_type ta = MSYMBOL_TYPE (a.minsym);
+  enum minimal_symbol_type tb = MSYMBOL_TYPE (b.minsym);
 
-  return classify_mtype (ta) - classify_mtype (tb);
+  return classify_mtype (ta) < classify_mtype (tb);
 }
 
-/* Callback for iterate_over_minimal_symbols that adds the symbol to
-   the result.  */
+/* Helper for search_minsyms_for_name that adds the symbol to the
+   result.  */
 
 static void
-add_minsym (struct minimal_symbol *minsym, void *d)
+add_minsym (struct minimal_symbol *minsym, struct objfile *objfile,
+           struct symtab *symtab, int list_mode,
+           std::vector<struct bound_minimal_symbol> *msyms)
 {
-  struct collect_minsyms *info = (struct collect_minsyms *) d;
-  bound_minimal_symbol_d mo;
-
-  mo.minsym = minsym;
-  mo.objfile = info->objfile;
-
-  if (info->symtab != NULL)
+  if (symtab != NULL)
     {
-      CORE_ADDR pc;
-      struct symtab_and_line sal;
-      struct gdbarch *gdbarch = get_objfile_arch (info->objfile);
-
-      sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (info->objfile, minsym),
-                              NULL, 0);
-      sal.section = MSYMBOL_OBJ_SECTION (info->objfile, minsym);
-      pc
-       = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc, &current_target);
-      if (pc != sal.pc)
-       sal = find_pc_sect_line (pc, NULL, 0);
+      /* We're looking for a label for which we don't have debug
+        info.  */
+      CORE_ADDR func_addr;
+      if (msymbol_is_function (objfile, minsym, &func_addr))
+       {
+         symtab_and_line sal = find_pc_sect_line (func_addr, NULL, 0);
 
-      if (info->symtab != sal.symtab)
-       return;
+         if (symtab != sal.symtab)
+           return;
+       }
     }
 
-  /* Exclude data symbols when looking for breakpoint locations.   */
-  if (!info->list_mode)
-    switch (minsym->type)
-      {
-       case mst_slot_got_plt:
-       case mst_data:
-       case mst_bss:
-       case mst_abs:
-       case mst_file_data:
-       case mst_file_bss:
-         {
-           /* Make sure this minsym is not a function descriptor
-              before we decide to discard it.  */
-           struct gdbarch *gdbarch = get_objfile_arch (info->objfile);
-           CORE_ADDR addr = gdbarch_convert_from_func_ptr_addr
-                              (gdbarch, BMSYMBOL_VALUE_ADDRESS (mo),
-                               &current_target);
-
-           if (addr == BMSYMBOL_VALUE_ADDRESS (mo))
-             return;
-         }
-      }
+  /* Exclude data symbols when looking for breakpoint locations.  */
+  if (!list_mode && !msymbol_is_function (objfile, minsym))
+    return;
 
-  VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo);
+  struct bound_minimal_symbol mo = {minsym, objfile};
+  msyms->push_back (mo);
+  return;
 }
 
 /* Search for minimal symbols called NAME.  If SEARCH_PSPACE
@@ -4506,19 +4404,12 @@ add_minsym (struct minimal_symbol *minsym, void *d)
    restrict results to the given SYMTAB.  */
 
 static void
-search_minsyms_for_name (struct collect_info *info, const char *name,
+search_minsyms_for_name (struct collect_info *info,
+                        const lookup_name_info &name,
                         struct program_space *search_pspace,
                         struct symtab *symtab)
 {
-  struct collect_minsyms local;
-  struct cleanup *cleanup;
-
-  memset (&local, 0, sizeof (local));
-  local.funfirstline = info->state->funfirstline;
-  local.list_mode = info->state->list_mode;
-  local.symtab = symtab;
-
-  cleanup = make_cleanup (VEC_cleanup (bound_minimal_symbol_d), &local.msyms);
+  std::vector<struct bound_minimal_symbol> minsyms;
 
   if (symtab == NULL)
     {
@@ -4537,8 +4428,14 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
 
        ALL_OBJFILES (objfile)
        {
-         local.objfile = objfile;
-         iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
+         iterate_over_minimal_symbols (objfile, name,
+                                       [&] (struct minimal_symbol *msym)
+                                         {
+                                           add_minsym (msym, objfile, nullptr,
+                                                       info->state->list_mode,
+                                                       &minsyms);
+                                           return false;
+                                         });
        }
       }
     }
@@ -4547,42 +4444,37 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
       if (search_pspace == NULL || SYMTAB_PSPACE (symtab) == search_pspace)
        {
          set_current_program_space (SYMTAB_PSPACE (symtab));
-         local.objfile = SYMTAB_OBJFILE(symtab);
-         iterate_over_minimal_symbols (local.objfile, name, add_minsym,
-                                       &local);
+         iterate_over_minimal_symbols
+           (SYMTAB_OBJFILE (symtab), name,
+            [&] (struct minimal_symbol *msym)
+              {
+                add_minsym (msym, SYMTAB_OBJFILE (symtab), symtab,
+                            info->state->list_mode, &minsyms);
+                return false;
+              });
        }
     }
 
-    if (!VEC_empty (bound_minimal_symbol_d, local.msyms))
-      {
-       int classification;
-       int ix;
-       bound_minimal_symbol_d *item;
-
-       qsort (VEC_address (bound_minimal_symbol_d, local.msyms),
-              VEC_length (bound_minimal_symbol_d, local.msyms),
-              sizeof (bound_minimal_symbol_d),
-              compare_msyms);
-
-       /* Now the minsyms are in classification order.  So, we walk
-          over them and process just the minsyms with the same
-          classification as the very first minsym in the list.  */
-       item = VEC_index (bound_minimal_symbol_d, local.msyms, 0);
-       classification = classify_mtype (MSYMBOL_TYPE (item->minsym));
-
-       for (ix = 0;
-            VEC_iterate (bound_minimal_symbol_d, local.msyms, ix, item);
-            ++ix)
-         {
-           if (classify_mtype (MSYMBOL_TYPE (item->minsym)) != classification)
-             break;
+  if (!minsyms.empty ())
+    {
+      int classification;
 
-           VEC_safe_push (bound_minimal_symbol_d,
-                          info->result.minimal_symbols, item);
-         }
-      }
+      std::sort (minsyms.begin (), minsyms.end (), compare_msyms);
+
+      /* Now the minsyms are in classification order.  So, we walk
+        over them and process just the minsyms with the same
+        classification as the very first minsym in the list.  */
+      classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym));
+
+      for (const bound_minimal_symbol &item : minsyms)
+       {
+         if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification)
+           break;
 
-    do_cleanups (cleanup);
+         VEC_safe_push (bound_minimal_symbol_d,
+                        info->result.minimal_symbols, &item);
+       }
+    }
 }
 
 /* A helper function to add all symbols matching NAME to INFO.  If
@@ -4591,20 +4483,25 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
 
 static void
 add_matching_symbols_to_info (const char *name,
+                             symbol_name_match_type name_match_type,
+                             enum search_domain search_domain,
                              struct collect_info *info,
                              struct program_space *pspace)
 {
   int ix;
   struct symtab *elt;
 
+  lookup_name_info lookup_name (name, name_match_type);
+
   for (ix = 0; VEC_iterate (symtab_ptr, info->file_symtabs, ix, elt); ++ix)
     {
       if (elt == NULL)
        {
-         iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
+         iterate_over_all_matching_symtabs (info->state, lookup_name,
+                                            VAR_DOMAIN, search_domain,
                                             pspace, true, [&] (symbol *sym)
            { return info->add_symbol (sym); });
-         search_minsyms_for_name (info, name, pspace, NULL);
+         search_minsyms_for_name (info, lookup_name, pspace, NULL);
        }
       else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
        {
@@ -4614,7 +4511,8 @@ add_matching_symbols_to_info (const char *name,
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
-         iterate_over_file_blocks (elt, name, VAR_DOMAIN, [&] (symbol *sym)
+         iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
+                                   [&] (symbol *sym)
            { return info->add_symbol (sym); });
 
          /* If no new symbols were found in this iteration and this symtab
@@ -4623,7 +4521,7 @@ add_matching_symbols_to_info (const char *name,
             this case.  */
          if (prev_len == VEC_length (symbolp, info->result.symbols)
              && elt->language == language_asm)
-           search_minsyms_for_name (info, name, pspace, elt);
+           search_minsyms_for_name (info, lookup_name, pspace, elt);
        }
     }
 }
@@ -4646,8 +4544,9 @@ symbol_to_sal (struct symtab_and_line *result,
     {
       if (SYMBOL_CLASS (sym) == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
        {
-         init_sal (result);
+         *result = {};
          result->symtab = symbol_symtab (sym);
+         result->symbol = sym;
          result->line = SYMBOL_LINE (sym);
          result->pc = SYMBOL_VALUE_ADDRESS (sym);
          result->pspace = SYMTAB_PSPACE (result->symtab);
@@ -4661,9 +4560,11 @@ symbol_to_sal (struct symtab_and_line *result,
       else if (SYMBOL_LINE (sym) != 0)
        {
          /* We know its line number.  */
-         init_sal (result);
+         *result = {};
          result->symtab = symbol_symtab (sym);
+         result->symbol = sym;
          result->line = SYMBOL_LINE (sym);
+         result->pc = SYMBOL_VALUE_ADDRESS (sym);
          result->pspace = SYMTAB_PSPACE (result->symtab);
          return 1;
        }
@@ -4674,15 +4575,8 @@ symbol_to_sal (struct symtab_and_line *result,
 
 linespec_result::~linespec_result ()
 {
-  int i;
-  struct linespec_sals *lsal;
-
-  for (i = 0; VEC_iterate (linespec_sals, sals, i, lsal); ++i)
-    {
-      xfree (lsal->canonical);
-      xfree (lsal->sals.sals);
-    }
-  VEC_free (linespec_sals, sals);
+  for (linespec_sals &lsal : lsals)
+    xfree (lsal.canonical);
 }
 
 /* Return the quote characters permitted by the linespec parser.  */