RISC-V: Pc-rel to gp-rel relaxation function cleanup.
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 91dabb6117fd211032197ee45964bc765e667de0..84258ad007a4c243f67d96d474e4b243f606a218 100644 (file)
@@ -77,11 +77,9 @@ enum class linespec_complete_what
   KEYWORD,
 };
 
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
+/* Typedef for unique_ptrs of vectors of symtabs.  */
 
-typedef struct type *typep;
-DEF_VEC_P (typep);
+typedef std::unique_ptr<std::vector<symtab *>> symtab_vector_up;
 
 /* 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
@@ -93,10 +91,6 @@ struct address_entry
   CORE_ADDR addr;
 };
 
-typedef struct bound_minimal_symbol bound_minimal_symbol_d;
-
-DEF_VEC_O (bound_minimal_symbol_d);
-
 /* A linespec.  Elements of this structure are filled in by a parser
    (either parse_linespec or some other function).  The structure is
    then converted into SALs by convert_linespec_to_sals.  */
@@ -110,20 +104,20 @@ struct linespec
      be NULL.  If explicit.SOURCE_FILENAME is NULL (no user-specified
      filename), FILE_SYMTABS should contain one single NULL member.  This
      will cause the code to use the default symtab.  */
-  VEC (symtab_ptr) *file_symtabs;
+  std::vector<symtab *> *file_symtabs;
 
   /* A list of matching function symbols and minimal symbols.  Both lists
-     may be NULL if no matching symbols were found.  */
-  VEC (symbolp) *function_symbols;
-  VEC (bound_minimal_symbol_d) *minimal_symbols;
+     may be NULL (or empty) if no matching symbols were found.  */
+  std::vector<block_symbol> *function_symbols;
+  std::vector<bound_minimal_symbol> *minimal_symbols;
 
   /* A structure of matching label symbols and the corresponding
      function symbol in which the label was found.  Both may be NULL
      or both must be non-NULL.  */
   struct
   {
-    VEC (symbolp) *label_symbols;
-    VEC (symbolp) *function_symbols;
+    std::vector<block_symbol> *label_symbols;
+    std::vector<block_symbol> *function_symbols;
   } labels;
 };
 typedef struct linespec *linespec_p;
@@ -195,31 +189,46 @@ struct collect_info
   struct linespec_state *state;
 
   /* A list of symtabs to which to restrict matches.  */
-  VEC (symtab_ptr) *file_symtabs;
+  std::vector<symtab *> *file_symtabs;
 
   /* The result being accumulated.  */
   struct
   {
-    VEC (symbolp) *symbols;
-    VEC (bound_minimal_symbol_d) *minimal_symbols;
+    std::vector<block_symbol> *symbols;
+    std::vector<bound_minimal_symbol> *minimal_symbols;
   } result;
 
   /* Possibly add a symbol to the results.  */
-  bool add_symbol (symbol *sym);
+  virtual bool add_symbol (block_symbol *bsym);
 };
 
 bool
-collect_info::add_symbol (symbol *sym)
+collect_info::add_symbol (block_symbol *bsym)
 {
   /* In list mode, add all matching symbols, regardless of class.
      This allows the user to type "list a_global_variable".  */
-  if (SYMBOL_CLASS (sym) == LOC_BLOCK || this->state->list_mode)
-    VEC_safe_push (symbolp, this->result.symbols, sym);
+  if (SYMBOL_CLASS (bsym->symbol) == LOC_BLOCK || this->state->list_mode)
+    this->result.symbols->push_back (*bsym);
 
   /* Continue iterating.  */
   return true;
 }
 
+/* Custom collect_info for symbol_searcher.  */
+
+struct symbol_searcher_collect_info
+  : collect_info
+{
+  bool add_symbol (block_symbol *bsym) override
+  {
+    /* Add everything.  */
+    this->result.symbols->push_back (*bsym);
+
+    /* Continue iterating.  */
+    return true;
+  }
+};
+
 /* Token types  */
 
 enum ls_token_type
@@ -348,21 +357,20 @@ 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);
+static symtab_vector_up symtabs_from_filename
+  (const char *, struct program_space *pspace);
 
-static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
-                                         VEC (symbolp) *function_symbols,
-                                         VEC (symbolp) **label_funcs_ret,
-                                         const char *name,
-                                         bool completion_mode = false);
+static std::vector<block_symbol> *find_label_symbols
+  (struct linespec_state *self, std::vector<block_symbol> *function_symbols,
+   std::vector<block_symbol> *label_funcs_ret, const char *name,
+   bool completion_mode = false);
 
 static void find_linespec_symbols (struct linespec_state *self,
-                                  VEC (symtab_ptr) *file_symtabs,
+                                  std::vector<symtab *> *file_symtabs,
                                   const char *name,
                                   symbol_name_match_type name_match_type,
-                                  VEC (symbolp) **symbols,
-                                  VEC (bound_minimal_symbol_d) **minsyms);
+                                  std::vector<block_symbol> *symbols,
+                                  std::vector<bound_minimal_symbol> *minsyms);
 
 static struct line_offset
      linespec_parse_variable (struct linespec_state *self,
@@ -377,12 +385,11 @@ static void add_matching_symbols_to_info (const char *name,
                                          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,
-                                             enum search_domain search_domain);
+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) *
+static symtab_vector_up
   collect_symtabs_from_filename (const char *file,
                                 struct program_space *pspace);
 
@@ -401,9 +408,10 @@ static void minsym_found (struct linespec_state *self, struct objfile *objfile,
                          struct minimal_symbol *msymbol,
                          std::vector<symtab_and_line> *result);
 
-static int compare_symbols (const void *a, const void *b);
+static bool compare_symbols (const block_symbol &a, const block_symbol &b);
 
-static int compare_msymbols (const void *a, const void *b);
+static bool compare_msymbols (const bound_minimal_symbol &a,
+                             const bound_minimal_symbol &b);
 
 /* Permitted quote characters for the parser.  This is different from the
    completer's quote characters to allow backward compatibility with the
@@ -1157,12 +1165,12 @@ iterate_over_all_matching_symtabs
                {
                  block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
                  state->language->la_iterate_over_symbols
-                   (block, lookup_name, name_domain, [&] (symbol *sym)
+                   (block, lookup_name, name_domain, [&] (block_symbol *bsym)
                     {
                       /* Restrict calls to CALLBACK to symbols
                          representing inline symbols only.  */
-                      if (SYMBOL_INLINED (sym))
-                        return callback (sym);
+                      if (SYMBOL_INLINED (bsym->symbol))
+                        return callback (bsym);
                       return true;
                     });
                }
@@ -1211,11 +1219,11 @@ iterate_over_file_blocks
 
 static void
 find_methods (struct type *t, enum language t_lang, const char *name,
-             VEC (const_char_ptr) **result_names,
-             VEC (typep) **superclasses)
+             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
@@ -1266,14 +1274,14 @@ find_methods (struct type *t, enum language t_lang, 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
@@ -1505,8 +1513,6 @@ decode_line_2 (struct linespec_state *self,
   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];
@@ -1560,7 +1566,7 @@ decode_line_2 (struct linespec_state *self,
     {
       prompt = "> ";
     }
-  args = command_line_input (prompt, 0, "overload-choice");
+  args = command_line_input (prompt, "overload-choice");
 
   if (args == 0 || *args == 0)
     error_no_arg (_("one or more choice numbers"));
@@ -1769,8 +1775,9 @@ linespec_parse_basic (linespec_parser *parser)
 {
   gdb::unique_xmalloc_ptr<char> name;
   linespec_token token;
-  VEC (symbolp) *symbols, *labels;
-  VEC (bound_minimal_symbol_d) *minimal_symbols;
+  std::vector<block_symbol> symbols;
+  std::vector<block_symbol> *labels;
+  std::vector<bound_minimal_symbol> minimal_symbols;
 
   /* Get the next token.  */
   token = linespec_lexer_lex_one (parser);
@@ -1873,12 +1880,14 @@ linespec_parse_basic (linespec_parser *parser)
                             PARSER_EXPLICIT (parser)->func_name_match_type,
                             &symbols, &minimal_symbols);
 
-      if (symbols != NULL || minimal_symbols != NULL)
+      if (!symbols.empty () || !minimal_symbols.empty ())
        {
-         PARSER_RESULT (parser)->function_symbols = symbols;
-         PARSER_RESULT (parser)->minimal_symbols = minimal_symbols;
+         PARSER_RESULT (parser)->function_symbols
+           = new std::vector<block_symbol> (std::move (symbols));
+         PARSER_RESULT (parser)->minimal_symbols
+           = new std::vector<bound_minimal_symbol>
+               (std::move (minimal_symbols));
          PARSER_EXPLICIT (parser)->function_name = name.release ();
-         symbols = NULL;
        }
       else
        {
@@ -1889,9 +1898,9 @@ linespec_parse_basic (linespec_parser *parser)
          if (labels != NULL)
            {
              PARSER_RESULT (parser)->labels.label_symbols = labels;
-             PARSER_RESULT (parser)->labels.function_symbols = symbols;
+             PARSER_RESULT (parser)->labels.function_symbols
+               = new std::vector<block_symbol> (std::move (symbols));
              PARSER_EXPLICIT (parser)->label_name = name.release ();
-             symbols = NULL;
            }
          else if (token.type == LSTOKEN_STRING
                   && *LS_TOKEN_STOKEN (token).ptr == '$')
@@ -1995,9 +2004,9 @@ linespec_parse_basic (linespec_parser *parser)
              if (labels != NULL)
                {
                  PARSER_RESULT (parser)->labels.label_symbols = labels;
-                 PARSER_RESULT (parser)->labels.function_symbols = symbols;
+                 PARSER_RESULT (parser)->labels.function_symbols
+                   = new std::vector<block_symbol> (std::move (symbols));
                  PARSER_EXPLICIT (parser)->label_name = name.release ();
-                 symbols = NULL;
                }
              else
                {
@@ -2063,14 +2072,12 @@ canonicalize_linespec (struct linespec_state *state, const linespec_p ls)
 
       if (explicit_loc->function_name == NULL)
        {
-         struct symbol *s;
-
          /* No function was specified, so add the symbol name.  */
-         gdb_assert (ls->labels.function_symbols != NULL
-                     && (VEC_length (symbolp, ls->labels.function_symbols)
-                         == 1));
-         s = VEC_index (symbolp, ls->labels.function_symbols, 0);
-         explicit_loc->function_name = xstrdup (SYMBOL_NATURAL_NAME (s));
+         gdb_assert (!ls->labels.function_symbols->empty ()
+                     && (ls->labels.function_symbols->size () == 1));
+         block_symbol s = ls->labels.function_symbols->front ();
+         explicit_loc->function_name
+           = xstrdup (SYMBOL_NATURAL_NAME (s.symbol));
        }
     }
 
@@ -2099,8 +2106,8 @@ create_sals_line_offset (struct linespec_state *self,
      set_default_source_symtab_and_line uses
      select_source_symtab that calls us with such an argument.  */
 
-  if (VEC_length (symtab_ptr, ls->file_symtabs) == 1
-      && VEC_index (symtab_ptr, ls->file_symtabs, 0) == NULL)
+  if (ls->file_symtabs->size () == 1
+      && ls->file_symtabs->front () == nullptr)
     {
       const char *fullname;
 
@@ -2110,10 +2117,9 @@ create_sals_line_offset (struct linespec_state *self,
       set_default_source_symtab_and_line ();
       initialize_defaults (&self->default_symtab, &self->default_line);
       fullname = symtab_to_fullname (self->default_symtab);
-      VEC_pop (symtab_ptr, ls->file_symtabs);
-      VEC_free (symtab_ptr, ls->file_symtabs);
-      ls->file_symtabs = collect_symtabs_from_filename (fullname,
-                                                       self->search_pspace);
+      symtab_vector_up r =
+       collect_symtabs_from_filename (fullname, self->search_pspace);
+      ls->file_symtabs = r.release ();
       use_default = 1;
     }
 
@@ -2200,6 +2206,7 @@ create_sals_line_offset (struct linespec_state *self,
 
            if (self->funfirstline)
              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);
          }
@@ -2228,6 +2235,7 @@ convert_address_location_to_sals (struct linespec_state *self,
   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);
@@ -2245,63 +2253,98 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
   if (ls->labels.label_symbols != NULL)
     {
       /* We have just a bunch of functions/methods or labels.  */
-      int i;
       struct symtab_and_line sal;
-      struct symbol *sym;
 
-      for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i)
+      for (const auto &sym : *ls->labels.label_symbols)
        {
-         struct program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+         struct program_space *pspace
+           = SYMTAB_PSPACE (symbol_symtab (sym.symbol));
 
-         if (symbol_to_sal (&sal, state->funfirstline, sym)
+         if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
              && maybe_add_address (state->addr_set, pspace, sal.pc))
            add_sal_to_sals (state, &sals, &sal,
-                            SYMBOL_NATURAL_NAME (sym), 0);
+                            SYMBOL_NATURAL_NAME (sym.symbol), 0);
        }
     }
   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
             to each other.  */
-         qsort (VEC_address (symbolp, ls->function_symbols),
-                VEC_length (symbolp, ls->function_symbols),
-                sizeof (symbolp), compare_symbols);
+         std::sort (ls->function_symbols->begin (),
+                    ls->function_symbols->end (),
+                    compare_symbols);
 
-         for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
+         for (const auto &sym : *ls->function_symbols)
            {
-             pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+             program_space *pspace
+               = SYMTAB_PSPACE (symbol_symtab (sym.symbol));
              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.symbol) == LOC_BLOCK)
+               {
+                 const CORE_ADDR addr
+                   = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol));
+
+                 for (const auto &elem : *ls->minimal_symbols)
+                   {
+                     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.symbol)
+                     && maybe_add_address (state->addr_set, pspace, sal.pc))
+                   add_sal_to_sals (state, &sals, &sal,
+                                    SYMBOL_NATURAL_NAME (sym.symbol), 0);
+               }
            }
        }
 
       if (ls->minimal_symbols != NULL)
        {
-         /* 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;
-              VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
-                           i, elem);
-              ++i)
+         /* Sort minimal symbols by program space, too  */
+         std::sort (ls->minimal_symbols->begin (),
+                    ls->minimal_symbols->end (),
+                    compare_msymbols);
+
+         for (const auto &elem : *ls->minimal_symbols)
            {
-             pspace = elem->objfile->pspace;
+             program_space *pspace = elem.objfile->pspace;
              set_current_program_space (pspace);
-             minsym_found (state, elem->objfile, elem->minsym, &sals);
+             minsym_found (state, elem.objfile, elem.minsym, &sals);
            }
        }
     }
@@ -2348,8 +2391,9 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
                                       const char *label_name,
                                       struct line_offset line_offset)
 {
-  VEC (symbolp) *symbols, *labels;
-  VEC (bound_minimal_symbol_d) *minimal_symbols;
+  std::vector<block_symbol> symbols;
+  std::vector<block_symbol> *labels;
+  std::vector<bound_minimal_symbol> minimal_symbols;
 
   result->explicit_loc.func_name_match_type = fname_match_type;
 
@@ -2358,7 +2402,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
       TRY
        {
          result->file_symtabs
-           = symtabs_from_filename (source_filename, self->search_pspace);
+           = symtabs_from_filename (source_filename,
+                                    self->search_pspace).release ();
        }
       CATCH (except, RETURN_MASK_ERROR)
        {
@@ -2370,7 +2415,7 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
   else
     {
       /* A NULL entry means to use the default symtab.  */
-      VEC_safe_push (symtab_ptr, result->file_symtabs, NULL);
+      result->file_symtabs->push_back (nullptr);
     }
 
   if (function_name != NULL)
@@ -2379,18 +2424,19 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
                             function_name, fname_match_type,
                             &symbols, &minimal_symbols);
 
-      if (symbols == NULL && minimal_symbols == NULL)
+      if (symbols.empty () && minimal_symbols.empty ())
        symbol_not_found_error (function_name,
                                result->explicit_loc.source_filename);
 
       result->explicit_loc.function_name = xstrdup (function_name);
-      result->function_symbols = symbols;
-      result->minimal_symbols = minimal_symbols;
+      result->function_symbols
+       = new std::vector<block_symbol> (std::move (symbols));
+      result->minimal_symbols
+       = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
     }
 
   if (label_name != NULL)
     {
-      symbols = NULL;
       labels = find_label_symbols (self, result->function_symbols,
                                   &symbols, label_name);
 
@@ -2400,7 +2446,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
 
       result->explicit_loc.label_name = xstrdup (label_name);
       result->labels.label_symbols = labels;
-      result->labels.function_symbols = symbols;
+      result->labels.function_symbols
+       = new std::vector<block_symbol> (std::move (symbols));
     }
 
   if (line_offset.sign != LINE_OFFSET_UNKNOWN)
@@ -2539,7 +2586,7 @@ parse_linespec (linespec_parser *parser, const char *arg,
     {
       /* 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);
+       PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
 
       /* User specified a convenience variable or history value.  */
       gdb::unique_xmalloc_ptr<char> var = copy_token_string (token);
@@ -2580,9 +2627,10 @@ parse_linespec (linespec_parser *parser, const char *arg,
       /* Check if the input is a filename.  */
       TRY
        {
-         PARSER_RESULT (parser)->file_symtabs
+         symtab_vector_up r
            = symtabs_from_filename (user_filename.get (),
                                     PARSER_STATE (parser)->search_pspace);
+         PARSER_RESULT (parser)->file_symtabs = r.release ();
        }
       CATCH (ex, RETURN_MASK_ERROR)
        {
@@ -2604,7 +2652,7 @@ parse_linespec (linespec_parser *parser, const char *arg,
       else
        {
          /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
-         VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL);
+         PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
        }
     }
   /* If the next token is not EOI, KEYWORD, or COMMA, issue an error.  */
@@ -2620,7 +2668,7 @@ parse_linespec (linespec_parser *parser, const char *arg,
   else
     {
       /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
-      VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL);
+      PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
     }
 
   /* Parse the rest of the linespec.  */
@@ -2705,6 +2753,7 @@ 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_RESULT (parser)->file_symtabs = new std::vector<symtab *> ();
   PARSER_EXPLICIT (parser)->func_name_match_type
     = symbol_name_match_type::WILD;
   PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
@@ -2732,20 +2781,11 @@ linespec_parser_delete (void *arg)
   xfree (PARSER_EXPLICIT (parser)->label_name);
   xfree (PARSER_EXPLICIT (parser)->function_name);
 
-  if (PARSER_RESULT (parser)->file_symtabs != NULL)
-    VEC_free (symtab_ptr, PARSER_RESULT (parser)->file_symtabs);
-
-  if (PARSER_RESULT (parser)->function_symbols != NULL)
-    VEC_free (symbolp, PARSER_RESULT (parser)->function_symbols);
-
-  if (PARSER_RESULT (parser)->minimal_symbols != NULL)
-    VEC_free (bound_minimal_symbol_d, PARSER_RESULT (parser)->minimal_symbols);
-
-  if (PARSER_RESULT (parser)->labels.label_symbols != NULL)
-    VEC_free (symbolp, PARSER_RESULT (parser)->labels.label_symbols);
-
-  if (PARSER_RESULT (parser)->labels.function_symbols != NULL)
-    VEC_free (symbolp, PARSER_RESULT (parser)->labels.function_symbols);
+  delete PARSER_RESULT (parser)->file_symtabs;
+  delete PARSER_RESULT (parser)->function_symbols;
+  delete PARSER_RESULT (parser)->minimal_symbols;
+  delete PARSER_RESULT (parser)->labels.label_symbols;
+  delete PARSER_RESULT (parser)->labels.function_symbols;
 
   linespec_state_destructor (PARSER_STATE (parser));
 }
@@ -2853,7 +2893,7 @@ complete_linespec_component (linespec_parser *parser,
             new "quote" char.  */
          if (tracker.quote_char ())
            {
-             char quote_char_str[2] = { tracker.quote_char () };
+             char quote_char_str[2] = { (char) tracker.quote_char () };
 
              fn = reconcat (fn, fn, quote_char_str, (char *) NULL);
              tracker.set_quote_char (':');
@@ -2878,21 +2918,22 @@ complete_label (completion_tracker &tracker,
                linespec_parser *parser,
                const char *label_name)
 {
-  VEC (symbolp) *label_function_symbols = NULL;
-  VEC (symbolp) *labels
+  std::vector<block_symbol> label_function_symbols;
+  std::vector<block_symbol> *labels
     = find_label_symbols (PARSER_STATE (parser),
                          PARSER_RESULT (parser)->function_symbols,
                          &label_function_symbols,
                          label_name, true);
 
-  symbol *label;
-  for (int ix = 0;
-       VEC_iterate (symbolp, labels, ix, label); ++ix)
+  if (labels != nullptr)
     {
-      char *match = xstrdup (SYMBOL_SEARCH_NAME (label));
-      tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
+      for (const auto &label : *labels)
+       {
+         char *match = xstrdup (SYMBOL_SEARCH_NAME (label.symbol));
+         tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
+       }
+      delete labels;
     }
-  VEC_free (symbolp, labels);
 }
 
 /* See linespec.h.  */
@@ -3001,15 +3042,17 @@ linespec_complete (completion_tracker &tracker, const char *text,
 
       const char *func_name = PARSER_EXPLICIT (&parser)->function_name;
 
-      VEC (symbolp) *function_symbols;
-      VEC (bound_minimal_symbol_d) *minimal_symbols;
+      std::vector<block_symbol> function_symbols;
+      std::vector<bound_minimal_symbol> minimal_symbols;
       find_linespec_symbols (PARSER_STATE (&parser),
                             PARSER_RESULT (&parser)->file_symtabs,
                             func_name, match_type,
                             &function_symbols, &minimal_symbols);
 
-      PARSER_RESULT (&parser)->function_symbols = function_symbols;
-      PARSER_RESULT (&parser)->minimal_symbols = minimal_symbols;
+      PARSER_RESULT (&parser)->function_symbols
+       = new std::vector<block_symbol> (std::move (function_symbols));
+      PARSER_RESULT (&parser)->minimal_symbols
+       = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
 
       complete_label (tracker, &parser, parser.completion_word);
     }
@@ -3165,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),
@@ -3258,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 ();
@@ -3404,31 +3441,29 @@ 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;
+  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);
-  info.result.symbols = NULL;
-  info.result.minimal_symbols = NULL;
+  std::vector<symtab *> symtabs;
+  symtabs.push_back (nullptr);
+
+  info.file_symtabs = &symtabs;
+
+  std::vector<block_symbol> symbols;
+  info.result.symbols = &symbols;
+  std::vector<bound_minimal_symbol> minimal_symbols;
+  info.result.minimal_symbols = &minimal_symbols;
 
   new_argptr = find_imps (arg, &symbol_names);
-  if (VEC_empty (const_char_ptr, symbol_names))
-    {
-      do_cleanups (cleanup);
-      return {};
-    }
+  if (symbol_names.empty ())
+    return {};
 
   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))
+  if (!symbols.empty () || !minimal_symbols.empty ())
     {
       char *saved_arg;
 
@@ -3437,8 +3472,10 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
       saved_arg[new_argptr - arg] = '\0';
 
       ls->explicit_loc.function_name = xstrdup (saved_arg);
-      ls->function_symbols = info.result.symbols;
-      ls->minimal_symbols = info.result.minimal_symbols;
+      ls->function_symbols
+       = new std::vector<block_symbol> (std::move (symbols));
+      ls->minimal_symbols
+       = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
       values = convert_linespec_to_sals (self, ls);
 
       if (self->canonical)
@@ -3463,8 +3500,6 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
        }
     }
 
-  do_cleanups (cleanup);
-
   return values;
 }
 
@@ -3477,7 +3512,6 @@ class decode_compound_collector
 {
 public:
   decode_compound_collector ()
-    : m_symbols (NULL)
   {
     m_unique_syms = htab_create_alloc (1, htab_hash_pointer,
                                       htab_eq_pointer, NULL,
@@ -3490,16 +3524,14 @@ public:
       htab_delete (m_unique_syms);
   }
 
-  /* Releases ownership of the collected symbols and returns them.  */
-  VEC (symbolp) *release_symbols ()
+  /* Return all symbols collected.  */
+  std::vector<block_symbol> release_symbols ()
   {
-    VEC (symbolp) *res = m_symbols;
-    m_symbols = NULL;
-    return res;
+    return std::move (m_symbols);
   }
 
   /* Callable as a symbol_found_callback_ftype callback.  */
-  bool operator () (symbol *sym);
+  bool operator () (block_symbol *bsym);
 
 private:
   /* A hash table of all symbols we found.  We use this to avoid
@@ -3507,14 +3539,15 @@ private:
   htab_t m_unique_syms;
 
   /* The result vector.  */
-  VEC (symbolp) *m_symbols;
+  std::vector<block_symbol>  m_symbols;
 };
 
 bool
-decode_compound_collector::operator () (symbol *sym)
+decode_compound_collector::operator () (block_symbol *bsym)
 {
   void **slot;
   struct type *t;
+  struct symbol *sym = bsym->symbol;
 
   if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
     return true; /* Continue iterating.  */
@@ -3530,7 +3563,7 @@ decode_compound_collector::operator () (symbol *sym)
   if (!*slot)
     {
       *slot = sym;
-      VEC_safe_push (symbolp, m_symbols, sym);
+      m_symbols.push_back (*bsym);
     }
 
   return true; /* Continue iterating.  */
@@ -3540,19 +3573,18 @@ decode_compound_collector::operator () (symbol *sym)
 
 /* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS.  */
 
-static VEC (symbolp) *
-lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
+static std::vector<block_symbol>
+lookup_prefix_sym (struct linespec_state *state,
+                  std::vector<symtab *> *file_symtabs,
                   const char *class_name)
 {
-  int ix;
-  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)
+  for (const auto &elt : *file_symtabs)
     {
-      if (elt == NULL)
+      if (elt == nullptr)
        {
          iterate_over_all_matching_symtabs (state, lookup_name,
                                             STRUCT_DOMAIN, ALL_DOMAIN,
@@ -3575,64 +3607,54 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
   return collector.release_symbols ();
 }
 
-/* A qsort comparison function for symbols.  The resulting order does
+/* A std::sort comparison function for symbols.  The resulting order does
    not actually matter; we just need to be able to sort them so that
    symbols with the same program space end up next to each other.  */
 
-static int
-compare_symbols (const void *a, const void *b)
+static bool
+compare_symbols (const block_symbol &a, const block_symbol &b)
 {
-  struct symbol * const *sa = (struct symbol * const*) a;
-  struct symbol * const *sb = (struct symbol * const*) b;
   uintptr_t uia, uib;
 
-  uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa));
-  uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sb));
+  uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (a.symbol));
+  uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (b.symbol));
 
   if (uia < uib)
-    return -1;
+    return true;
   if (uia > uib)
-    return 1;
+    return false;
 
-  uia = (uintptr_t) *sa;
-  uib = (uintptr_t) *sb;
+  uia = (uintptr_t) a.symbol;
+  uib = (uintptr_t) b.symbol;
 
   if (uia < uib)
-    return -1;
-  if (uia > uib)
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 /* Like compare_symbols but for minimal symbols.  */
 
-static int
-compare_msymbols (const void *a, const void *b)
+static bool
+compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
 {
-  const struct bound_minimal_symbol *sa
-    = (const struct bound_minimal_symbol *) a;
-  const struct bound_minimal_symbol *sb
-    = (const struct bound_minimal_symbol *) b;
   uintptr_t uia, uib;
 
-  uia = (uintptr_t) sa->objfile->pspace;
-  uib = (uintptr_t) sa->objfile->pspace;
+  uia = (uintptr_t) a.objfile->pspace;
+  uib = (uintptr_t) a.objfile->pspace;
 
   if (uia < uib)
-    return -1;
+    return true;
   if (uia > uib)
-    return 1;
+    return false;
 
-  uia = (uintptr_t) sa->minsym;
-  uib = (uintptr_t) sb->minsym;
+  uia = (uintptr_t) a.minsym;
+  uib = (uintptr_t) b.minsym;
 
   if (uia < uib)
-    return -1;
-  if (uia > uib)
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 /* Look for all the matching instances of each symbol in NAMES.  Only
@@ -3643,46 +3665,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)
+  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,
+find_superclass_methods (std::vector<struct type *> &&superclasses,
                         const char *name, enum language name_lang,
-                        VEC (const_char_ptr) **result_names)
+                        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)
+      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
@@ -3690,30 +3700,26 @@ find_superclass_methods (VEC (typep) *superclasses,
    in SYMBOLS (for debug symbols) and MINSYMS (for minimal symbols).  */
 
 static void
-find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
+find_method (struct linespec_state *self, std::vector<symtab *> *file_symtabs,
             const char *class_name, const char *method_name,
-            VEC (symbolp) *sym_classes, VEC (symbolp) **symbols,
-            VEC (bound_minimal_symbol_d) **minsyms)
+            std::vector<block_symbol> *sym_classes,
+            std::vector<block_symbol> *symbols,
+            std::vector<bound_minimal_symbol> *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
      to each other.  */
-  qsort (VEC_address (symbolp, sym_classes),
-        VEC_length (symbolp, sym_classes),
-        sizeof (symbolp),
-        compare_symbols);
+  std::sort (sym_classes->begin (), sym_classes->end (),
+            compare_symbols);
 
   info.state = self;
   info.file_symtabs = file_symtabs;
-  info.result.symbols = NULL;
-  info.result.minimal_symbols = NULL;
+  info.result.symbols = symbols;
+  info.result.minimal_symbols = minsyms;
 
   /* Iterate over all the types, looking for the names of existing
      methods matching METHOD_NAME.  If we cannot find a direct method in a
@@ -3724,15 +3730,13 @@ 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)
+  unsigned int ix = 0;
+  for (const auto &elt : *sym_classes)
     {
       struct type *t;
       struct program_space *pspace;
+      struct symbol *sym = elt.symbol;
 
       /* Program spaces that are executing startup should have
         been filtered out earlier.  */
@@ -3745,15 +3749,14 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
 
       /* Handle all items from a single program space at once; and be
         sure not to miss the last batch.  */
-      if (ix == VEC_length (symbolp, sym_classes) - 1
+      if (ix == sym_classes->size () - 1
          || (pspace
-             != SYMTAB_PSPACE (symbol_symtab (VEC_index (symbolp, sym_classes,
-                                                         ix + 1)))))
+             != SYMTAB_PSPACE (symbol_symtab (sym_classes->at (ix + 1).symbol))))
        {
          /* 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,
+         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
@@ -3762,19 +3765,14 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
          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 ();
+         ++ix;
        }
     }
 
-  if (!VEC_empty (symbolp, info.result.symbols)
-      || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols))
-    {
-      *symbols = info.result.symbols;
-      *minsyms = info.result.minimal_symbols;
-      do_cleanups (cleanup);
-      return;
-    }
+  if (!symbols->empty () || !minsyms->empty ())
+    return;
 
   /* Throw an NOT_FOUND_ERROR.  This will be caught by the caller
      and other attempts to locate the symbol will be made.  */
@@ -3792,8 +3790,8 @@ class symtab_collector
 {
 public:
   symtab_collector ()
+    : m_symtabs (new std::vector<symtab *> ())
   {
-    m_symtabs = NULL;
     m_symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
                                  NULL);
   }
@@ -3808,16 +3806,14 @@ public:
   bool operator () (symtab *sym);
 
   /* Releases ownership of the collected symtabs and returns them.  */
-  VEC (symtab_ptr) *release_symtabs ()
+  symtab_vector_up release_symtabs ()
   {
-    VEC (symtab_ptr) *res = m_symtabs;
-    m_symtabs = NULL;
-    return res;
+    return std::move (m_symtabs);
   }
 
 private:
   /* The result vector of symtabs.  */
-  VEC (symtab_ptr) *m_symtabs;
+  symtab_vector_up m_symtabs;
 
   /* This is used to ensure the symtabs are unique.  */
   htab_t m_symtab_table;
@@ -3832,7 +3828,7 @@ symtab_collector::operator () (struct symtab *symtab)
   if (!*slot)
     {
       *slot = symtab;
-      VEC_safe_push (symtab_ptr, m_symtabs, symtab);
+      m_symtabs->push_back (symtab);
     }
 
   return false;
@@ -3840,11 +3836,11 @@ symtab_collector::operator () (struct symtab *symtab)
 
 } // namespace
 
-/* Given a file name, return a VEC of all matching symtabs.  If
+/* Given a file name, return a list of all matching symtabs.  If
    SEARCH_PSPACE is not NULL, the search is restricted to just that
    program space.  */
 
-static VEC (symtab_ptr) *
+static symtab_vector_up
 collect_symtabs_from_filename (const char *file,
                               struct program_space *search_pspace)
 {
@@ -3876,15 +3872,14 @@ collect_symtabs_from_filename (const char *file,
 /* Return all the symtabs associated to the FILENAME.  If SEARCH_PSPACE is
    not NULL, the search is restricted to just that program space.  */
 
-static VEC (symtab_ptr) *
+static symtab_vector_up
 symtabs_from_filename (const char *filename,
                       struct program_space *search_pspace)
 {
-  VEC (symtab_ptr) *result;
-  
-  result = collect_symtabs_from_filename (filename, search_pspace);
+  symtab_vector_up result
+    = collect_symtabs_from_filename (filename, search_pspace);
 
-  if (VEC_empty (symtab_ptr, result))
+  if (result->empty ())
     {
       if (!have_full_symbols () && !have_partial_symbols ())
        throw_error (NOT_FOUND_ERROR,
@@ -3896,53 +3891,63 @@ symtabs_from_filename (const char *filename,
   return result;
 }
 
+/* See symtab.h.  */
+
+void
+symbol_searcher::find_all_symbols (const std::string &name,
+                                  const struct language_defn *language,
+                                  enum search_domain search_domain,
+                                  std::vector<symtab *> *search_symtabs,
+                                  struct program_space *search_pspace)
+{
+  symbol_searcher_collect_info info;
+  struct linespec_state state;
+
+  memset (&state, 0, sizeof (state));
+  state.language = language;
+  info.state = &state;
+
+  info.result.symbols = &m_symbols;
+  info.result.minimal_symbols = &m_minimal_symbols;
+  std::vector<symtab *> all_symtabs;
+  if (search_symtabs == nullptr)
+    {
+      all_symtabs.push_back (nullptr);
+      search_symtabs = &all_symtabs;
+    }
+  info.file_symtabs = search_symtabs;
+
+  add_matching_symbols_to_info (name.c_str (), symbol_name_match_type::WILD,
+                               search_domain, &info, search_pspace);
+}
+
 /* Look up a function symbol named NAME in symtabs FILE_SYMTABS.  Matching
    debug symbols are returned in SYMBOLS.  Matching minimal symbols are
    returned in MINSYMS.  */
 
 static void
 find_function_symbols (struct linespec_state *state,
-                      VEC (symtab_ptr) *file_symtabs, const char *name,
+                      std::vector<symtab *> *file_symtabs, const char *name,
                       symbol_name_match_type name_match_type,
-                      VEC (symbolp) **symbols,
-                      VEC (bound_minimal_symbol_d) **minsyms)
+                      std::vector<block_symbol> *symbols,
+                      std::vector<bound_minimal_symbol> *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;
-  info.result.minimal_symbols = NULL;
+  info.result.symbols = symbols;
+  info.result.minimal_symbols = minsyms;
   info.file_symtabs = file_symtabs;
 
   /* 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, FUNCTIONS_DOMAIN);
   else
     add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
                                  &info, state->search_pspace);
-
-  do_cleanups (cleanup);
-
-  if (VEC_empty (symbolp, info.result.symbols))
-    {
-      VEC_free (symbolp, info.result.symbols);
-      *symbols = NULL;
-    }
-  else
-    *symbols = info.result.symbols;
-
-  if (VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols))
-    {
-      VEC_free (bound_minimal_symbol_d, info.result.minimal_symbols);
-      *minsyms = NULL;
-    }
-  else
-    *minsyms = info.result.minimal_symbols;
 }
 
 /* Find all symbols named NAME in FILE_SYMTABS, returning debug symbols
@@ -3950,11 +3955,11 @@ find_function_symbols (struct linespec_state *state,
 
 static void
 find_linespec_symbols (struct linespec_state *state,
-                      VEC (symtab_ptr) *file_symtabs,
+                      std::vector<symtab *> *file_symtabs,
                       const char *lookup_name,
                       symbol_name_match_type name_match_type,
-                      VEC (symbolp) **symbols,
-                      VEC (bound_minimal_symbol_d) **minsyms)
+                      std::vector <block_symbol> *symbols,
+                      std::vector<bound_minimal_symbol> *minsyms)
 {
   std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
   if (!canon.empty ())
@@ -3970,18 +3975,15 @@ 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);
+                        name_match_type, symbols, minsyms);
 
   /* If we were unable to locate a symbol of the same name, try dividing
      the name into class and method names and searching the class and its
      baseclasses.  */
-  if (VEC_empty (symbolp, *symbols)
-      && VEC_empty (bound_minimal_symbol_d, *minsyms))
+  if (symbols->empty () && minsyms->empty ())
     {
       std::string klass, method;
       const char *last, *p, *scope_op;
-      VEC (symbolp) *classes;
 
       /* See if we can find a scope operator and break this symbol
         name into namespaces${SCOPE_OPERATOR}class_name and method_name.  */
@@ -4010,18 +4012,16 @@ find_linespec_symbols (struct linespec_state *state,
       method = last;
 
       /* Find a list of classes named KLASS.  */
-      classes = lookup_prefix_sym (state, file_symtabs, klass.c_str ());
-      struct cleanup *old_chain
-       = make_cleanup (VEC_cleanup (symbolp), &classes);
-
-      if (!VEC_empty (symbolp, classes))
+      std::vector<block_symbol> classes
+       = lookup_prefix_sym (state, file_symtabs, klass.c_str ());
+      if (!classes.empty ())
        {
          /* Now locate a list of suitable methods named METHOD.  */
          TRY
            {
              find_method (state, file_symtabs,
                           klass.c_str (), method.c_str (),
-                          classes, symbols, minsyms);
+                          &classes, symbols, minsyms);
            }
 
          /* If successful, we're done.  If NOT_FOUND_ERROR
@@ -4033,8 +4033,6 @@ find_linespec_symbols (struct linespec_state *state,
            }
          END_CATCH
        }
-
-      do_cleanups (old_chain);
     }
 }
 
@@ -4049,8 +4047,8 @@ static void
 find_label_symbols_in_block (const struct block *block,
                             const char *name, struct symbol *fn_sym,
                             bool completion_mode,
-                            VEC (symbolp) **result,
-                            VEC (symbolp) **label_funcs_ret)
+                            std::vector<block_symbol> *result,
+                            std::vector<block_symbol> *label_funcs_ret)
 {
   if (completion_mode)
     {
@@ -4067,39 +4065,43 @@ find_label_symbols_in_block (const struct block *block,
                                     SYMBOL_DOMAIN (sym), LABEL_DOMAIN)
              && cmp (SYMBOL_SEARCH_NAME (sym), name, name_len) == 0)
            {
-             VEC_safe_push (symbolp, *result, sym);
-             VEC_safe_push (symbolp, *label_funcs_ret, fn_sym);
+             result->push_back ({sym, block});
+             label_funcs_ret->push_back ({fn_sym, block});
            }
        }
     }
   else
     {
-      struct symbol *sym = lookup_symbol (name, block, LABEL_DOMAIN, 0).symbol;
+      struct block_symbol label_sym
+       = lookup_symbol (name, block, LABEL_DOMAIN, 0);
 
-      if (sym != NULL)
+      if (label_sym.symbol != NULL)
        {
-         VEC_safe_push (symbolp, *result, sym);
-         VEC_safe_push (symbolp, *label_funcs_ret, fn_sym);
+         result->push_back (label_sym);
+         label_funcs_ret->push_back ({fn_sym, block});
        }
     }
 }
 
-/* Return all labels that match name NAME in FUNCTION_SYMBOLS.  Return
-   the actual function symbol in which the label was found in
+/* Return all labels that match name NAME in FUNCTION_SYMBOLS or NULL
+   if no matches were found.
+
+   Return the actual function symbol in which the label was found in
    LABEL_FUNC_RET.  If COMPLETION_MODE is true, then NAME is
    interpreted as a label name prefix.  Otherwise, only labels named
    exactly NAME match.  */
 
-static VEC (symbolp) *
+
+static std::vector<block_symbol> *
 find_label_symbols (struct linespec_state *self,
-                   VEC (symbolp) *function_symbols,
-                   VEC (symbolp) **label_funcs_ret, const char *name,
+                   std::vector<block_symbol> *function_symbols,
+                   std::vector<block_symbol> *label_funcs_ret,
+                   const char *name,
                    bool completion_mode)
 {
-  int ix;
   const struct block *block;
   struct symbol *fn_sym;
-  VEC (symbolp) *result = NULL;
+  std::vector<block_symbol> result;
 
   if (function_symbols == NULL)
     {
@@ -4119,9 +4121,9 @@ find_label_symbols (struct linespec_state *self,
     }
   else
     {
-      for (ix = 0;
-          VEC_iterate (symbolp, function_symbols, ix, fn_sym); ++ix)
+      for (const auto &elt : *function_symbols)
        {
+         fn_sym = elt.symbol;
          set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym)));
          block = SYMBOL_BLOCK_VALUE (fn_sym);
 
@@ -4130,7 +4132,9 @@ find_label_symbols (struct linespec_state *self,
        }
     }
 
-  return result;
+  if (!result.empty ())
+    return new std::vector<block_symbol> (std::move (result));
+  return nullptr;
 }
 
 \f
@@ -4142,15 +4146,11 @@ decode_digits_list_mode (struct linespec_state *self,
                         linespec_p ls,
                         struct symtab_and_line val)
 {
-  int ix;
-  struct symtab *elt;
-
   gdb_assert (self->list_mode);
 
   std::vector<symtab_and_line> values;
 
-  for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt);
-       ++ix)
+  for (const auto &elt : *ls->file_symtabs)
     {
       /* The logic above should ensure this.  */
       gdb_assert (elt != NULL);
@@ -4180,11 +4180,8 @@ decode_digits_ordinary (struct linespec_state *self,
                        int line,
                        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)
+  for (const auto &elt : *ls->file_symtabs)
     {
       std::vector<CORE_ADDR> pcs;
 
@@ -4277,33 +4274,36 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
              struct minimal_symbol *msymbol,
              std::vector<symtab_and_line> *result)
 {
-  struct symtab_and_line sal;
+  bool want_start_sal;
 
   CORE_ADDR func_addr;
-  if (msymbol_is_function (objfile, msymbol, &func_addr))
-    {
-      sal = find_pc_sect_line (func_addr, NULL, 0);
+  bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
 
-      if (self->funfirstline)
-       {
-         if (sal.symtab != NULL
-             && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
-                 || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
-           {
-             struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  if (is_function)
+    {
+      const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol);
 
-             sal.pc = func_addr;
-             if (gdbarch_skip_entrypoint_p (gdbarch))
-               sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
-           }
-         else
-           skip_prologue_sal (&sal);
-       }
+      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 (is_function && want_start_sal)
+    sal = find_function_start_sal (func_addr, NULL, self->funfirstline);
   else
     {
       sal.objfile = objfile;
-      sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+      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
+       sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
       sal.pspace = current_program_space;
     }
 
@@ -4376,6 +4376,7 @@ add_minsym (struct minimal_symbol *minsym, struct objfile *objfile,
 
   struct bound_minimal_symbol mo = {minsym, objfile};
   msyms->push_back (mo);
+  return;
 }
 
 /* Search for minimal symbols called NAME.  If SEARCH_PSPACE
@@ -4416,6 +4417,7 @@ search_minsyms_for_name (struct collect_info *info,
                                            add_minsym (msym, objfile, nullptr,
                                                        info->state->list_mode,
                                                        &minsyms);
+                                           return false;
                                          });
        }
       }
@@ -4431,6 +4433,7 @@ search_minsyms_for_name (struct collect_info *info,
               {
                 add_minsym (msym, SYMTAB_OBJFILE (symtab), symtab,
                             info->state->list_mode, &minsyms);
+                return false;
               });
        }
     }
@@ -4446,13 +4449,12 @@ search_minsyms_for_name (struct collect_info *info,
         classification as the very first minsym in the list.  */
       classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym));
 
-      for (const struct bound_minimal_symbol &item : minsyms)
+      for (const bound_minimal_symbol &item : minsyms)
        {
          if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification)
            break;
 
-         VEC_safe_push (bound_minimal_symbol_d,
-                        info->result.minimal_symbols, &item);
+         info->result.minimal_symbols->push_back (item);
        }
     }
 }
@@ -4468,38 +4470,36 @@ add_matching_symbols_to_info (const char *name,
                              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)
+  for (const auto &elt : *info->file_symtabs)
     {
-      if (elt == NULL)
+      if (elt == nullptr)
        {
          iterate_over_all_matching_symtabs (info->state, lookup_name,
                                             VAR_DOMAIN, search_domain,
-                                            pspace, true, [&] (symbol *sym)
-           { return info->add_symbol (sym); });
+                                            pspace, true,
+                                            [&] (block_symbol *bsym)
+           { return info->add_symbol (bsym); });
          search_minsyms_for_name (info, lookup_name, pspace, NULL);
        }
       else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
        {
-         int prev_len = VEC_length (symbolp, info->result.symbols);
+         int prev_len = info->result.symbols->size ();
 
          /* Program spaces that are executing startup should have
             been filtered out earlier.  */
          gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
          set_current_program_space (SYMTAB_PSPACE (elt));
          iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
-                                   [&] (symbol *sym)
-           { return info->add_symbol (sym); });
+                                   [&] (block_symbol *bsym)
+           { return info->add_symbol (bsym); });
 
          /* If no new symbols were found in this iteration and this symtab
             is in assembler, we might actually be looking for a label for
             which we don't have debug info.  Check for a minimal symbol in
             this case.  */
-         if (prev_len == VEC_length (symbolp, info->result.symbols)
+         if (prev_len == info->result.symbols->size ()
              && elt->language == language_asm)
            search_minsyms_for_name (info, lookup_name, pspace, elt);
        }
This page took 0.04727 seconds and 4 git commands to generate.