/* Parser for linespec for the GNU debugger, GDB.

   Copyright (C) 1986-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "symtab.h"
#include "frame.h"
#include "command.h"
#include "symfile.h"
#include "objfiles.h"
#include "source.h"
#include "value.h"
#include "completer.h"
#include "cp-abi.h"
#include "cp-support.h"
#include "parser-defs.h"
#include "block.h"
#include "objc-lang.h"
#include "linespec.h"
#include "language.h"
#include "interps.h"
#include "target.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
#include "filenames.h"
#include "ada-lang.h"
#include "stack.h"
#include "location.h"
#include "gdbsupport/function-view.h"
#include "gdbsupport/def-vector.h"
#include <algorithm>
#include "inferior.h"
#include "gdbsupport/unordered_set.h"

/* An enumeration of the various things a user might attempt to
   complete for a linespec location.  */

enum class linespec_complete_what
{
  /* Nothing, no possible completion.  */
  NOTHING,

  /* A function/method name.  Due to ambiguity between

       (gdb) b source[TAB]
       source_file.c
       source_function

     this can also indicate a source filename, iff we haven't seen a
     separate source filename component, as in "b source.c:function".  */
  FUNCTION,

  /* A label symbol.  E.g., break file.c:function:LABEL.  */
  LABEL,

  /* An expression.  E.g., "break foo if EXPR", or "break *EXPR".  */
  EXPRESSION,

  /* A linespec keyword ("if"/"thread"/"task"/"-force-condition").
     E.g., "break func threa<tab>".  */
  KEYWORD,
};

/* 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.  */

struct linespec
{
  /* An explicit location spec describing the SaLs.  */
  explicit_location_spec explicit_loc;

  /* The list of symtabs to search to which to limit the search.

     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.  */
  std::vector<symtab *> file_symtabs;

  /* A list of matching function symbols and minimal symbols.  Both lists
     may be 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 empty
     or both must be non-empty.  */
  struct
  {
    std::vector<block_symbol> label_symbols;
    std::vector<block_symbol> function_symbols;
  } labels;
};

/* A canonical linespec represented as a symtab-related string.

   Each entry represents the "SYMTAB:SUFFIX" linespec string.
   SYMTAB can be converted for example by symtab_to_fullname or
   symtab_to_filename_for_display as needed.  */

struct linespec_canonical_name
{
  /* Remaining text part of the linespec string.  */
  std::string suffix;

  /* If NULL then SUFFIX is the whole linespec string.  */
  struct symtab *symtab;
};

/* An instance of this is used to keep all state while linespec
   operates.  This instance is passed around as a 'this' pointer to
   the various implementation methods.  */

struct linespec_state
{
  linespec_state (int flags, const language_defn *language,
		  program_space *pspace,
		  program_space *search_pspace,
		  symtab *default_symtab,
		  int default_line,
		  linespec_result *canonical)
    : language (language),
      program_space (pspace),
      search_pspace (search_pspace),
      default_symtab (default_symtab),
      default_line (default_line),
      funfirstline ((flags & DECODE_LINE_FUNFIRSTLINE) != 0),
      list_mode ((flags & DECODE_LINE_LIST_MODE) != 0),
      canonical (canonical)
  {
  }

  linespec_state (const language_defn *language, program_space *program_space)
    : linespec_state (0, language, program_space, nullptr, nullptr, 0, nullptr)
  {
  }

  DISABLE_COPY_AND_ASSIGN (linespec_state);

  /* Add ADDR to the address set.  Return true if this is a new
     entry.  */
  bool maybe_add_address (program_space *pspace, CORE_ADDR addr)
  {
    return addr_set.emplace (pspace, addr).second;
  }

  /* The language in use during linespec processing.  */
  const struct language_defn *language;

  /* The program space as seen when the module was entered.  */
  struct program_space *program_space;

  /* If not NULL, the search is restricted to just this program
     space.  */
  struct program_space *search_pspace;

  /* The default symtab to use, if no other symtab is specified.  */
  struct symtab *default_symtab;

  /* The default line to use.  */
  int default_line;

  /* The 'funfirstline' value that was passed in to decode_line_1 or
     decode_line_full.  */
  bool funfirstline;

  /* True if we are running in 'list' mode; see decode_line_list.  */
  bool list_mode;

  /* The 'canonical' value passed to decode_line_full, or NULL.  */
  struct linespec_result *canonical;

  /* Canonical strings that mirror the std::vector<symtab_and_line> result.  */
  std::vector<linespec_canonical_name> canonical_names;

  /* Are we building a linespec?  */
  bool is_linespec = false;

private:

  /* 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.  */
  using address_entry = std::pair<::program_space *, CORE_ADDR>;

  /* This is a set of address_entry objects which is used to prevent
     duplicate symbols from being entered into the result.  */
  gdb::unordered_set<address_entry> addr_set;
};

/* This is a helper object that is used when collecting symbols into a
   result.  */

struct collect_info
{
  /* The linespec object in use.  */
  struct linespec_state *state;

  /* A list of symtabs to which to restrict matches.  */
  const std::vector<symtab *> *file_symtabs;

  /* The result being accumulated.  */
  struct
  {
    std::vector<block_symbol> *symbols;
    std::vector<bound_minimal_symbol> *minimal_symbols;
  } result;

  /* Possibly add a symbol to the results.  */
  virtual bool add_symbol (block_symbol *bsym);
};

bool
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 (bsym->symbol->loc_class () == 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 linespec_token_type
{
  /* A keyword  */
  LSTOKEN_KEYWORD = 0,

  /* A colon "separator"  */
  LSTOKEN_COLON,

  /* A string  */
  LSTOKEN_STRING,

  /* A number  */
  LSTOKEN_NUMBER,

  /* A comma  */
  LSTOKEN_COMMA,

  /* EOI (end of input)  */
  LSTOKEN_EOI,

  /* Consumed token  */
  LSTOKEN_CONSUMED
};

/* List of keywords.  This is NULL-terminated so that it can be used
   as enum completer.  */
const char * const linespec_keywords[] = { "if", "thread", "task", "inferior", "-force-condition", NULL };
#define IF_KEYWORD_INDEX 0
#define FORCE_KEYWORD_INDEX 4

/* A token of the linespec lexer  */

struct linespec_token
{
  /* The type of the token  */
  linespec_token_type type;

  /* Data for the token  */
  union
  {
    /* A string, given as a stoken  */
    struct stoken string;

    /* A keyword  */
    const char *keyword;
  } data;
};

/* An instance of the linespec parser.  */

struct linespec_parser
{
  linespec_parser (int flags, const struct language_defn *language,
		   struct program_space *search_pspace,
		   struct symtab *default_symtab,
		   int default_line,
		   struct linespec_result *canonical);

  DISABLE_COPY_AND_ASSIGN (linespec_parser);

  /* Lexer internal data  */
  struct
  {
    /* Save head of input stream.  */
    const char *saved_arg;

    /* Head of the input stream.  */
    const char *stream;

    /* The current token.  */
    linespec_token current;
  } lexer {};

  /* Is the entire linespec quote-enclosed?  */
  bool is_quote_enclosed = false;

  /* The state of the parse.  */
  linespec_state state;

  /* The result of the parse.  */
  linespec result;

  /* What the parser believes the current word point should complete
     to.  */
  linespec_complete_what complete_what = linespec_complete_what::NOTHING;

  /* The completion word point.  The parser advances this as it skips
     tokens.  At some point the input string will end or parsing will
     fail, and then we attempt completion at the captured completion
     word point, interpreting the string at completion_word as
     COMPLETE_WHAT.  */
  const char *completion_word = nullptr;

  /* If the current token was a quoted string, then this is the
     quoting character (either " or ').  */
  int completion_quote_char = 0;

  /* If the current token was a quoted string, then this points at the
     end of the quoted string.  */
  const char *completion_quote_end = nullptr;

  /* If parsing for completion, then this points at the completion
     tracker.  Otherwise, this is NULL.  */
  struct completion_tracker *completion_tracker = nullptr;
};

/* Prototypes for local functions.  */

static void iterate_over_file_blocks
  (struct symtab *symtab, const lookup_name_info &name,
   domain_search_flags domain,
   gdb::function_view<symbol_found_callback_ftype> callback);

static void initialize_defaults (struct symtab **default_symtab,
				 int *default_line);

CORE_ADDR linespec_expression_to_pc (const char **exp_ptr);

static std::vector<symtab_and_line> decode_objc (struct linespec_state *self,
						 linespec *ls,
						 const char *arg);

static std::vector<symtab *> symtabs_from_filename
  (const char *, struct program_space *pspace);

static std::vector<block_symbol> find_label_symbols
  (struct linespec_state *self,
   const 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,
				   const std::vector<symtab *> &file_symtabs,
				   const char *name,
				   symbol_name_match_type name_match_type,
				   std::vector<block_symbol> *symbols,
				   std::vector<bound_minimal_symbol> *minsyms);

static struct line_offset
     linespec_parse_variable (struct linespec_state *self,
			      const char *variable);

static std::optional<symtab_and_line> symbol_to_sal (bool funfirstline,
						     symbol *sym);

static void add_matching_symbols_to_info (const char *name,
					  symbol_name_match_type name_match_type,
					  domain_search_flags domain_search_flags,
					  struct collect_info *info,
					  struct program_space *pspace);

static void add_all_symbol_names_from_pspace
    (struct collect_info *info, struct program_space *pspace,
     const std::vector<const char *> &names, domain_search_flags domain_search_flags);

static std::vector<symtab *>
  collect_symtabs_from_filename (const char *file,
				 struct program_space *pspace);

static std::vector<symtab_and_line> decode_digits_ordinary
  (struct linespec_state *self,
   linespec *ls,
   int line,
   const linetable_entry **best_entry);

static std::vector<symtab_and_line> decode_digits_list_mode
  (linespec_state *self, linespec *ls, int line);

static void minsym_found (struct linespec_state *self, struct objfile *objfile,
			  struct minimal_symbol *msymbol,
			  std::vector<symtab_and_line> &result);

static bool compare_symbols (const block_symbol &a, const block_symbol &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
   previous parser.  */
static const char linespec_quote_characters[] = "\"\'";

/* Lexer functions.  */

/* Lex a number from the input in PARSER.  This only supports
   decimal numbers.

   Return true if input is decimal numbers.  Return false if not.  */

static int
linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp)
{
  tokenp->type = LSTOKEN_NUMBER;
  tokenp->data.string.length = 0;
  tokenp->data.string.ptr = parser->lexer.stream;

  /* Keep any sign at the start of the stream.  */
  if (*parser->lexer.stream == '+' || *parser->lexer.stream == '-')
    {
      ++tokenp->data.string.length;
      ++(parser->lexer.stream);
    }

  while (c_isdigit (*parser->lexer.stream))
    {
      ++tokenp->data.string.length;
      ++(parser->lexer.stream);
    }

  /* If the next character in the input buffer is not a space, comma,
     quote, or colon, this input does not represent a number.  */
  if (*parser->lexer.stream != '\0'
      && !c_isspace (*parser->lexer.stream) && *parser->lexer.stream != ','
      && *parser->lexer.stream != ':'
      && !strchr (linespec_quote_characters, *parser->lexer.stream))
    {
      parser->lexer.stream = tokenp->data.string.ptr;
      return 0;
    }

  return 1;
}

/* See linespec.h.  */

const char *
linespec_lexer_lex_keyword (const char *p)
{
  int i;

  if (p != NULL)
    {
      for (i = 0; linespec_keywords[i] != NULL; ++i)
	{
	  int len = strlen (linespec_keywords[i]);

	  /* If P begins with

	     - "thread" or "task" and the next character is
	     whitespace, we may have found a keyword.  It is only a
	     keyword if it is not followed by another keyword.

	     - "-force-condition", the next character may be EOF
	     since this keyword does not take any arguments.  Otherwise,
	     it should be followed by a keyword.

	     - "if", ALWAYS stop the lexer, since it is not possible to
	     predict what is going to appear in the condition, which can
	     only be parsed after SaLs have been found.  */
	  if (strncmp (p, linespec_keywords[i], len) == 0)
	    {
	      int j;

	      if (i == FORCE_KEYWORD_INDEX && p[len] == '\0')
		return linespec_keywords[i];

	      if (!c_isspace (p[len]))
		continue;

	      if (i == FORCE_KEYWORD_INDEX)
		{
		  p += len;
		  p = skip_spaces (p);
		  for (j = 0; linespec_keywords[j] != NULL; ++j)
		    {
		      int nextlen = strlen (linespec_keywords[j]);

		      if (strncmp (p, linespec_keywords[j], nextlen) == 0
			  && c_isspace (p[nextlen]))
			return linespec_keywords[i];
		    }
		}
	      else if (i != IF_KEYWORD_INDEX)
		{
		  /* We matched a "thread" or "task".  */
		  p += len;
		  p = skip_spaces (p);
		  for (j = 0; linespec_keywords[j] != NULL; ++j)
		    {
		      int nextlen = strlen (linespec_keywords[j]);

		      if (strncmp (p, linespec_keywords[j], nextlen) == 0
			  && c_isspace (p[nextlen]))
			return NULL;
		    }
		}

	      return linespec_keywords[i];
	    }
	}
    }

  return NULL;
}

/*  See description in linespec.h.  */

int
is_ada_operator (const char *string)
{
  const struct ada_opname_map *mapping;

  for (mapping = ada_opname_table;
       mapping->encoded != NULL
	 && !startswith (string, mapping->decoded); ++mapping)
    ;

  return mapping->decoded == NULL ? 0 : strlen (mapping->decoded);
}

/* Find QUOTE_CHAR in STRING, accounting for the ':' terminal.  Return
   the location of QUOTE_CHAR, or NULL if not found.  */

static const char *
skip_quote_char (const char *string, char quote_char)
{
  const char *p, *last;

  p = last = find_toplevel_char (string, quote_char);
  while (p && *p != '\0' && *p != ':')
    {
      p = find_toplevel_char (p, quote_char);
      if (p != NULL)
	last = p++;
    }

  return last;
}

/* Make a writable copy of the string given in TOKEN, trimming
   any trailing whitespace.  */

static gdb::unique_xmalloc_ptr<char>
copy_token_string (linespec_token token)
{
  const char *str, *s;

  if (token.type == LSTOKEN_KEYWORD)
    return make_unique_xstrdup (token.data.keyword);

  str = token.data.string.ptr;
  s = remove_trailing_whitespace (str, str + token.data.string.length);

  return gdb::unique_xmalloc_ptr<char> (savestring (str, s - str));
}

/* Does P represent the end of a quote-enclosed linespec?  */

static int
is_closing_quote_enclosed (const char *p)
{
  if (strchr (linespec_quote_characters, *p))
    ++p;
  p = skip_spaces ((char *) p);
  return (*p == '\0' || linespec_lexer_lex_keyword (p));
}

/* Find the end of the parameter list that starts with *INPUT.
   This helper function assists with lexing string segments
   which might contain valid (non-terminating) commas.  */

static const char *
find_parameter_list_end (const char *input)
{
  char end_char, start_char;
  int depth;
  const char *p;

  start_char = *input;
  if (start_char == '(')
    end_char = ')';
  else if (start_char == '<')
    end_char = '>';
  else
    return NULL;

  p = input;
  depth = 0;
  while (*p)
    {
      if (*p == start_char)
	++depth;
      else if (*p == end_char)
	{
	  if (--depth == 0)
	    {
	      ++p;
	      break;
	    }
	}
      ++p;
    }

  return p;
}

/* If the [STRING, STRING_LEN) string ends with what looks like a
   keyword, return the keyword start offset in STRING.  Return -1
   otherwise.  */

static size_t
string_find_incomplete_keyword_at_end (const char * const *keywords,
				       const char *string, size_t string_len)
{
  const char *end = string + string_len;
  const char *p = end;

  while (p > string && *p != ' ')
    --p;
  if (p > string)
    {
      p++;
      size_t len = end - p;
      for (size_t i = 0; keywords[i] != NULL; ++i)
	if (strncmp (keywords[i], p, len) == 0)
	  return p - string;
    }

  return -1;
}

/* Lex a string from the input in PARSER.  */

static linespec_token
linespec_lexer_lex_string (linespec_parser *parser)
{
  linespec_token token;
  const char *start = parser->lexer.stream;

  token.type = LSTOKEN_STRING;

  /* If the input stream starts with a quote character, skip to the next
     quote character, regardless of the content.  */
  if (strchr (linespec_quote_characters, *parser->lexer.stream))
    {
      const char *end;
      char quote_char = *parser->lexer.stream;

      /* Special case: Ada operators.  */
      if (parser->state.language->la_language == language_ada
	  && quote_char == '\"')
	{
	  int len = is_ada_operator (parser->lexer.stream);

	  if (len != 0)
	    {
	      /* The input is an Ada operator.  Return the quoted string
		 as-is.  */
	      token.data.string.ptr = parser->lexer.stream;
	      token.data.string.length = len;
	      parser->lexer.stream += len;
	      return token;
	    }

	  /* The input does not represent an Ada operator -- fall through
	     to normal quoted string handling.  */
	}

      /* Skip past the beginning quote.  */
      ++(parser->lexer.stream);

      /* Mark the start of the string.  */
      token.data.string.ptr = parser->lexer.stream;

      /* Skip to the ending quote.  */
      end = skip_quote_char (parser->lexer.stream, quote_char);

      /* This helps the completer mode decide whether we have a
	 complete string.  */
      parser->completion_quote_char = quote_char;
      parser->completion_quote_end = end;

      /* Error if the input did not terminate properly, unless in
	 completion mode.  */
      if (end == NULL)
	{
	  if (parser->completion_tracker == NULL)
	    error (_("unmatched quote"));

	  /* In completion mode, we'll try to complete the incomplete
	     token.  */
	  token.type = LSTOKEN_STRING;
	  while (*parser->lexer.stream != '\0')
	    parser->lexer.stream++;
	  token.data.string.length = parser->lexer.stream - 1 - start;
	}
      else
	{
	  /* Skip over the ending quote and mark the length of the string.  */
	  parser->lexer.stream = (char *) ++end;
	  token.data.string.length = parser->lexer.stream - 2 - start;
	}
    }
  else
    {
      const char *p;

      /* Otherwise, only identifier characters are permitted.
	 Spaces are the exception.  In general, we keep spaces,
	 but only if the next characters in the input do not resolve
	 to one of the keywords.

	 This allows users to forgo quoting CV-qualifiers, template arguments,
	 and similar common language constructs.  */

      while (1)
	{
	  if (c_isspace (*parser->lexer.stream))
	    {
	      p = skip_spaces (parser->lexer.stream);
	      /* 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,
		 say, a function name.  */
	      if (linespec_lexer_lex_keyword (p) != NULL)
		{
		  token.data.string.ptr = start;
		  token.data.string.length
		    = parser->lexer.stream - start;
		  return token;
		}

	      /* Advance past the whitespace.  */
	      parser->lexer.stream = p;
	    }

	  /* If the next character is EOI or (single) ':', the
	     string is complete;  return the token.  */
	  if (*parser->lexer.stream == 0)
	    {
	      token.data.string.ptr = start;
	      token.data.string.length = parser->lexer.stream - start;
	      return token;
	    }
	  else if (parser->lexer.stream[0] == ':')
	    {
	      /* Do not tokenize the C++ scope operator. */
	      if (parser->lexer.stream[1] == ':')
		++(parser->lexer.stream);

	      /* Do not tokenize ABI tags such as "[abi:cxx11]".  */
	      else if (parser->lexer.stream - start > 4
		       && startswith (parser->lexer.stream - 4, "[abi"))
		{
		  /* Nothing.  */
		}

	      /* 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
		 paths to be recognized as filenames without quoting it.  */
	      else if ((parser->lexer.stream - start) != 1
		       || !IS_DIR_SEPARATOR (parser->lexer.stream[1]))
		{
		  token.data.string.ptr = start;
		  token.data.string.length
		    = parser->lexer.stream - start;
		  return token;
		}
	    }
	  /* Special case: permit quote-enclosed linespecs.  */
	  else if (parser->is_quote_enclosed
		   && strchr (linespec_quote_characters,
			      *parser->lexer.stream)
		   && is_closing_quote_enclosed (parser->lexer.stream))
	    {
	      token.data.string.ptr = start;
	      token.data.string.length = parser->lexer.stream - start;
	      return token;
	    }
	  /* Because commas may terminate a linespec and appear in
	     the middle of valid string input, special cases for
	     '<' and '(' are necessary.  */
	  else if (*parser->lexer.stream == '<'
		   || *parser->lexer.stream == '(')
	    {
	      /* Don't interpret 'operator<' / 'operator<<' as a
		 template parameter list though.  */
	      if (*parser->lexer.stream == '<'
		  && (parser->state.language->la_language
		      == language_cplus)
		  && (parser->lexer.stream - start) >= CP_OPERATOR_LEN)
		{
		  const char *op = parser->lexer.stream;

		  while (op > start && c_isspace (op[-1]))
		    op--;
		  if (op - start >= CP_OPERATOR_LEN)
		    {
		      op -= CP_OPERATOR_LEN;
		      if (strncmp (op, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0
			  && (op == start
			      || !(c_isalnum (op[-1]) || op[-1] == '_')))
			{
			  /* This is an operator name.  Keep going.  */
			  ++(parser->lexer.stream);
			  if (*parser->lexer.stream == '<')
			    ++(parser->lexer.stream);
			  continue;
			}
		    }
		}

	      const char *end = find_parameter_list_end (parser->lexer.stream);
	      parser->lexer.stream = end;

	      /* Don't loop around to the normal \0 case above because
		 we don't want to misinterpret a potential keyword at
		 the end of the token when the string isn't
		 "()<>"-balanced.  This handles "b
		 function(thread<tab>" in completion mode.  */
	      if (*end == '\0')
		{
		  token.data.string.ptr = start;
		  token.data.string.length
		    = parser->lexer.stream - start;
		  return token;
		}
	      else
		continue;
	    }
	  /* Commas are terminators, but not if they are part of an
	     operator name.  */
	  else if (*parser->lexer.stream == ',')
	    {
	      if ((parser->state.language->la_language
		   == language_cplus)
		  && (parser->lexer.stream - start) > CP_OPERATOR_LEN)
		{
		  const char *op = strstr (start, CP_OPERATOR_STR);

		  if (op != NULL && is_operator_name (op))
		    {
		      /* This is an operator name.  Keep going.  */
		      ++(parser->lexer.stream);
		      continue;
		    }
		}

	      /* Comma terminates the string.  */
	      token.data.string.ptr = start;
	      token.data.string.length = parser->lexer.stream - start;
	      return token;
	    }

	  /* Advance the stream.  */
	  gdb_assert (*(parser->lexer.stream) != '\0');
	  ++(parser->lexer.stream);
	}
    }

  return token;
}

/* Lex a single linespec token from PARSER.  */

static linespec_token
linespec_lexer_lex_one (linespec_parser *parser)
{
  const char *keyword;

  if (parser->lexer.current.type == LSTOKEN_CONSUMED)
    {
      /* Skip any whitespace.  */
      parser->lexer.stream = skip_spaces (parser->lexer.stream);

      /* Check for a keyword, they end the linespec.  */
      keyword = linespec_lexer_lex_keyword (parser->lexer.stream);
      if (keyword != NULL)
	{
	  parser->lexer.current.type = LSTOKEN_KEYWORD;
	  parser->lexer.current.data.keyword = keyword;
	  /* We do not advance the stream here intentionally:
	     we would like lexing to stop when a keyword is seen.

	     parser->lexer.stream +=  strlen (keyword);  */

	  return parser->lexer.current;
	}

      /* Handle other tokens.  */
      switch (*parser->lexer.stream)
	{
	case 0:
	  parser->lexer.current.type = LSTOKEN_EOI;
	  break;

	case '+': case '-':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	   if (!linespec_lexer_lex_number (parser, &(parser->lexer.current)))
	     parser->lexer.current = linespec_lexer_lex_string (parser);
	  break;

	case ':':
	  /* If we have a scope operator, lex the input as a string.
	     Otherwise, return LSTOKEN_COLON.  */
	  if (parser->lexer.stream[1] == ':')
	    parser->lexer.current = linespec_lexer_lex_string (parser);
	  else
	    {
	      parser->lexer.current.type = LSTOKEN_COLON;
	      ++(parser->lexer.stream);
	    }
	  break;

	case '\'': case '\"':
	  /* Special case: permit quote-enclosed linespecs.  */
	  if (parser->is_quote_enclosed
	      && is_closing_quote_enclosed (parser->lexer.stream))
	    {
	      ++(parser->lexer.stream);
	      parser->lexer.current.type = LSTOKEN_EOI;
	    }
	  else
	    parser->lexer.current = linespec_lexer_lex_string (parser);
	  break;

	case ',':
	  parser->lexer.current.type = LSTOKEN_COMMA;
	  parser->lexer.current.data.string.ptr
	    = parser->lexer.stream;
	  parser->lexer.current.data.string.length = 1;
	  ++(parser->lexer.stream);
	  break;

	default:
	  /* If the input is not a number, it must be a string.
	     [Keywords were already considered above.]  */
	  parser->lexer.current = linespec_lexer_lex_string (parser);
	  break;
	}
    }

  return parser->lexer.current;
}

/* Consume the current token and return the next token in PARSER's
   input stream.  Also advance the completion word for completion
   mode.  */

static linespec_token
linespec_lexer_consume_token (linespec_parser *parser)
{
  gdb_assert (parser->lexer.current.type != LSTOKEN_EOI);

  bool advance_word = (parser->lexer.current.type != LSTOKEN_STRING
		       || *parser->lexer.stream != '\0');

  /* If we're moving past a string to some other token, it must be the
     quote was terminated.  */
  if (parser->completion_quote_char)
    {
      gdb_assert (parser->lexer.current.type == LSTOKEN_STRING);

      /* If the string was the last (non-EOI) token, we're past the
	 quote, but remember that for later.  */
      if (*parser->lexer.stream != '\0')
	{
	  parser->completion_quote_char = '\0';
	  parser->completion_quote_end = NULL;
	}
    }

  parser->lexer.current.type = LSTOKEN_CONSUMED;
  linespec_lexer_lex_one (parser);

  if (parser->lexer.current.type == LSTOKEN_STRING)
    {
      /* Advance the completion word past a potential initial
	 quote-char.  */
      parser->completion_word = parser->lexer.current.data.string.ptr;
    }
  else if (advance_word)
    {
      /* Advance the completion word past any whitespace.  */
      parser->completion_word = parser->lexer.stream;
    }

  return parser->lexer.current;
}

/* Return the next token without consuming the current token.  */

static linespec_token
linespec_lexer_peek_token (linespec_parser *parser)
{
  linespec_token next;
  const char *saved_stream = parser->lexer.stream;
  linespec_token saved_token = parser->lexer.current;
  int saved_completion_quote_char = parser->completion_quote_char;
  const char *saved_completion_quote_end = parser->completion_quote_end;
  const char *saved_completion_word = parser->completion_word;

  next = linespec_lexer_consume_token (parser);
  parser->lexer.stream = saved_stream;
  parser->lexer.current = saved_token;
  parser->completion_quote_char = saved_completion_quote_char;
  parser->completion_quote_end = saved_completion_quote_end;
  parser->completion_word = saved_completion_word;
  return next;
}

/* Helper functions.  */

/* 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.

   If LITERAL_CANONICAL is true, SYMNAME will be used as the
   canonical name for the SAL.  */

static void
add_sal_to_sals (struct linespec_state *self,
		 std::vector<symtab_and_line> &sals,
		 const symtab_and_line &sal,
		 const char *symname, bool literal_canonical)
{
  /* We don't want two SALs with the same PC from the same program space.
     However, for the 'list' command we force the pc value to be 0, and in
     this case we do want to see all SALs.  See decode_digits_list_mode
     for where the 0 originates from.  */
  if (sal.pc != 0)
    {
      for (const auto &s : sals)
	if (sal.pc == s.pc && sal.pspace == s.pspace)
	  return;
    }

  sals.push_back (sal);

  if (self->canonical)
    {
      linespec_canonical_name &canonical
	= self->canonical_names.emplace_back ();

      if (!literal_canonical && sal.symtab)
	{
	  symtab_to_fullname (sal.symtab);

	  /* Note that the filter doesn't have to be a valid linespec
	     input.  We only apply the ":LINE" treatment to Ada for
	     the time being.  */
	  if (symname != NULL && sal.line != 0
	      && self->language->la_language == language_ada)
	    canonical.suffix = string_printf ("%s:%d", symname,
					      sal.line);
	  else if (symname != NULL)
	    canonical.suffix = symname;
	  else
	    canonical.suffix = string_printf ("%d", sal.line);
	  canonical.symtab = sal.symtab;
	}
      else
	{
	  if (symname != NULL)
	    canonical.suffix = symname;
	  else
	    canonical.suffix = "<unknown>";
	  canonical.symtab = NULL;
	}
    }
}

/* A helper that walks over all matching symtabs in all objfiles and
   calls CALLBACK for each symbol matching NAME.  If SEARCH_PSPACE is
   not NULL, then the search is restricted to just that program
   space.  If INCLUDE_INLINE is true then symbols representing
   inlined instances of functions will be included in the result.  */

static void
iterate_over_all_matching_symtabs
  (struct linespec_state *state,
   const lookup_name_info &lookup_name,
   const domain_search_flags domain,
   struct program_space *search_pspace, bool include_inline,
   gdb::function_view<symbol_found_callback_ftype> callback)
{
  for (struct program_space *pspace : program_spaces)
    {
      if (search_pspace != NULL && search_pspace != pspace)
	continue;
      if (pspace->executing_startup)
	continue;

      set_current_program_space (pspace);

      for (objfile &objfile : pspace->objfiles ())
	{
	  auto expand_callback = [&] (compunit_symtab *cu)
	    {
	      struct symtab *symtab = cu->primary_filetab ();

	      iterate_over_file_blocks (symtab, lookup_name, domain, callback);

	      if (include_inline)
		{
		  const struct block *block;
		  int i;
		  const blockvector *bv = symtab->compunit ()->blockvector ();

		  for (i = FIRST_LOCAL_BLOCK; i < bv->num_blocks (); i++)
		    {
		      block = bv->block (i);
		      state->language->iterate_over_symbols
			(block, lookup_name, domain,
			 [&] (block_symbol *bsym)
			 {
			   /* Restrict calls to CALLBACK to symbols
			      representing inline symbols only.  */
			   if (bsym->symbol->is_inlined ())
			     return callback (bsym);
			   return true;
			 });
		    }
		}

	      return true;
	    };

	  objfile.search (nullptr, &lookup_name, nullptr, expand_callback,
			  SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK, domain);
	}
    }
}

/* Returns the block to be used for symbol searches from
   the current location.  */

static const struct block *
get_current_search_block (void)
{
  /* get_selected_block can change the current language when there is
     no selected frame yet.  */
  scoped_restore_current_language save_language;
  return get_selected_block (0);
}

/* Iterate over static and global blocks.  */

static void
iterate_over_file_blocks
  (struct symtab *symtab, const lookup_name_info &name,
   domain_search_flags domain,
   gdb::function_view<symbol_found_callback_ftype> callback)
{
  const struct block *block;

  for (block = symtab->compunit ()->blockvector ()->static_block ();
       block != NULL;
       block = block->superblock ())
    current_language->iterate_over_symbols (block, name, domain, callback);
}

/* 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, enum language t_lang, const char *name,
	      std::vector<const char *> *result_names,
	      std::vector<struct type *> *superclasses)
{
  int ibase;
  const char *class_name = t->name ();

  /* 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
     the class, then the loop can't do any good.  */
  if (class_name)
    {
      int method_counter;
      lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
      symbol_name_matcher_ftype *symbol_name_compare
	= language_def (t_lang)->get_symbol_name_matcher (lookup_name);

      t = check_typedef (t);

      /* Loop over each method name.  At this level, all overloads of a name
	 are counted as a single name.  There is an inner loop which loops over
	 each overload.  */

      for (method_counter = TYPE_NFN_FIELDS (t) - 1;
	   method_counter >= 0;
	   --method_counter)
	{
	  const char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);

	  if (symbol_name_compare (method_name, lookup_name, NULL))
	    {
	      int field_counter;

	      for (field_counter = (TYPE_FN_FIELDLIST_LENGTH (t, method_counter)
				    - 1);
		   field_counter >= 0;
		   --field_counter)
		{
		  struct fn_field *f;
		  const char *phys_name;

		  f = TYPE_FN_FIELDLIST1 (t, method_counter);
		  if (TYPE_FN_FIELD_STUB (f, field_counter))
		    continue;
		  phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
		  result_names->push_back (phys_name);
		}
	    }
	}
    }

  for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
    superclasses->push_back (TYPE_BASECLASS (t, ibase));
}

/* The string equivalent of find_toplevel_char.  Returns a pointer
   to the location of NEEDLE in HAYSTACK, ignoring any occurrences
   inside "()" and "<>".  Returns NULL if NEEDLE was not found.  */

static const char *
find_toplevel_string (const char *haystack, const char *needle)
{
  const char *s = haystack;

  do
    {
      s = find_toplevel_char (s, *needle);

      if (s != NULL)
	{
	  /* Found first char in HAYSTACK;  check rest of string.  */
	  if (startswith (s, needle))
	    return s;

	  /* Didn't find it; loop over HAYSTACK, looking for the next
	     instance of the first character of NEEDLE.  */
	  ++s;
	}
    }
  while (s != NULL && *s != '\0');

  /* NEEDLE was not found in HAYSTACK.  */
  return NULL;
}

/* Convert CANONICAL to its string representation using
   symtab_to_fullname for SYMTAB.  */

static std::string
canonical_to_fullform (const struct linespec_canonical_name *canonical)
{
  if (canonical->symtab == NULL)
    return canonical->suffix;
  else
    return string_printf ("%s:%s", symtab_to_fullname (canonical->symtab),
			  canonical->suffix.c_str ());
}

/* Given FILTERS, a list of canonical names, filter the sals in RESULT
   and store the result in SELF->CANONICAL.  */

static void
filter_results (struct linespec_state *self,
		std::vector<symtab_and_line> *result,
		const std::vector<const char *> &filters)
{
  for (const char *name : filters)
    {
      linespec_sals lsal;

      for (size_t j = 0; j < result->size (); ++j)
	{
	  const struct linespec_canonical_name *canonical;

	  canonical = &self->canonical_names[j];
	  std::string fullform = canonical_to_fullform (canonical);

	  if (name == fullform)
	    lsal.sals.push_back ((*result)[j]);
	}

      if (!lsal.sals.empty ())
	{
	  lsal.canonical = xstrdup (name);
	  self->canonical->lsals.push_back (std::move (lsal));
	}
    }

  self->canonical->pre_expanded = 0;
}

/* Store RESULT into SELF->CANONICAL.  */

static void
convert_results_to_lsals (struct linespec_state *self,
			  std::vector<symtab_and_line> *result)
{
  struct linespec_sals lsal;

  lsal.canonical = NULL;
  lsal.sals = std::move (*result);
  self->canonical->lsals.push_back (std::move (lsal));
}

/* A structure that contains two string representations of a struct
   linespec_canonical_name:
     - one where the symtab's fullname is used;
     - one where the filename followed the "set filename-display"
       setting.  */

struct decode_line_2_item
{
  decode_line_2_item (std::string &&fullform_, std::string &&displayform_,
		      bool selected_)
    : fullform (std::move (fullform_)),
      displayform (std::move (displayform_)),
      selected (selected_)
  {
  }

  /* Used for sorting.  */
  bool operator< (const decode_line_2_item &other) const
  {
    if (displayform != other.displayform)
      return displayform < other.displayform;
    return fullform < other.fullform;
  }

  /* The form using symtab_to_fullname.  */
  std::string fullform;

  /* The form using symtab_to_filename_for_display.  */
  std::string displayform;

  /* True if the user requested breakpoint for this entry.  */
  bool selected;
};

/* Handle multiple results in RESULT depending on SELECT_MODE.  This
   will either return normally, throw an exception on multiple
   results, or present a menu to the user.  On return, the SALS vector
   in SELF->CANONICAL is set up properly.  */

static void
decode_line_2 (struct linespec_state *self,
	       std::vector<symtab_and_line> *result,
	       const char *select_mode)
{
  const char *args;
  const char *prompt;
  int i;
  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->empty ());

  /* Prepare ITEMS array.  */
  for (i = 0; i < result->size (); ++i)
    {
      const struct linespec_canonical_name *canonical;
      std::string displayform;

      canonical = &self->canonical_names[i];

      std::string fullform = canonical_to_fullform (canonical);

      if (canonical->symtab == NULL)
	displayform = canonical->suffix;
      else
	{
	  const char *fn_for_display;

	  fn_for_display = symtab_to_filename_for_display (canonical->symtab);
	  displayform = string_printf ("%s:%s", fn_for_display,
				       canonical->suffix.c_str ());
	}

      items.emplace_back (std::move (fullform), std::move (displayform),
			  false);
    }

  /* Sort the list of method names.  */
  std::sort (items.begin (), items.end ());

  /* Remove entries with the same FULLFORM.  */
  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.size () == 1)
    {
      convert_results_to_lsals (self, result);
      return;
    }

  printf_unfiltered (_("[0] cancel\n[1] all\n"));
  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)
    {
      prompt = "> ";
    }

  std::string buffer;
  args = command_line_input (buffer, prompt, "overload-choice");

  if (args == 0 || *args == 0)
    error_no_arg (_("one or more choice numbers"));

  number_or_range_parser parser (args);
  while (!parser.finished ())
    {
      int num = parser.get_number ();

      if (num == 0)
	error (_("canceled"));
      else if (num == 1)
	{
	  /* We intentionally make this result in a single breakpoint,
	     contrary to what older versions of gdb did.  The
	     rationale is that this lets a user get the
	     multiple_symbols_all behavior even with the 'ask'
	     setting; and he can get separate breakpoints by entering
	     "2-57" at the query.  */
	  convert_results_to_lsals (self, result);
	  return;
	}

      num -= 2;
      if (num >= items.size ())
	printf_unfiltered (_("No choice number %d.\n"), num);
      else
	{
	  struct decode_line_2_item *item = &items[num];

	  if (!item->selected)
	    {
	      filters.push_back (item->fullform.c_str ());
	      item->selected = true;
	    }
	  else
	    {
	      printf_unfiltered (_("duplicate request for %d ignored.\n"),
				 num + 2);
	    }
	}
    }

  filter_results (self, result, filters);
}



/* The parser of linespec itself.  */

/* Throw an appropriate error when SYMBOL is not found (optionally in
   FILENAME).  */

[[noreturn]] static void
symbol_not_found_error (const char *symbol, const char *filename)
{
  if (symbol == NULL)
    symbol = "";

  if (!have_full_symbols (current_program_space)
      && !have_partial_symbols (current_program_space)
      && !have_minimal_symbols (current_program_space))
    throw_error (NOT_FOUND_ERROR,
		 _("No symbol table is loaded.  Use the \"file\" command."));

  /* If SYMBOL starts with '$', the user attempted to either lookup
     a function/variable in his code starting with '$' or an internal
     variable of that name.  Since we do not know which, be concise and
     explain both possibilities.  */
  if (*symbol == '$')
    {
      if (filename)
	throw_error (NOT_FOUND_ERROR,
		     _("Undefined convenience variable or function \"%s\" "
		       "not defined in \"%s\"."), symbol, filename);
      else
	throw_error (NOT_FOUND_ERROR,
		     _("Undefined convenience variable or function \"%s\" "
		       "not defined."), symbol);
    }
  else
    {
      if (filename)
	throw_error (NOT_FOUND_ERROR,
		     _("Function \"%s\" not defined in \"%s\"."),
		     symbol, filename);
      else
	throw_error (NOT_FOUND_ERROR,
		     _("Function \"%s\" not defined."), symbol);
    }
}

/* Throw an appropriate error when an unexpected token is encountered
   in the input.  */

[[noreturn]] static void
unexpected_linespec_error (linespec_parser *parser)
{
  linespec_token token;
  static const char * token_type_strings[]
    = {"keyword", "colon", "string", "number", "comma", "end of input"};

  /* Get the token that generated the error.  */
  token = linespec_lexer_lex_one (parser);

  /* Finally, throw the error.  */
  if (token.type == LSTOKEN_STRING || token.type == LSTOKEN_NUMBER
      || token.type == LSTOKEN_KEYWORD)
    {
      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.get ());
    }
  else
    throw_error (GENERIC_ERROR,
		 _("malformed linespec error: unexpected %s"),
		 token_type_strings[token.type]);
}

/* Throw an undefined label error.  */

[[noreturn]] static void
undefined_label_error (const char *function, const char *label)
{
  if (function != NULL)
    throw_error (NOT_FOUND_ERROR,
		_("No label \"%s\" defined in function \"%s\"."),
		label, function);
  else
    throw_error (NOT_FOUND_ERROR,
		_("No label \"%s\" defined in current function."),
		label);
}

/* Throw a source file not found error.  */

[[noreturn]] static void
source_file_not_found_error (const char *name)
{
  throw_error (NOT_FOUND_ERROR, _("No source file named %s."), name);
}

/* Unless at EIO, save the current stream position as completion word
   point, and consume the next token.  */

static linespec_token
save_stream_and_consume_token (linespec_parser *parser)
{
  if (linespec_lexer_peek_token (parser).type != LSTOKEN_EOI)
    parser->completion_word = parser->lexer.stream;
  return linespec_lexer_consume_token (parser);
}

/* See description in linespec.h.  */

struct line_offset
linespec_parse_line_offset (const char *string)
{
  const char *start = string;
  struct line_offset line_offset;

  if (*string == '+')
    {
      line_offset.sign = LINE_OFFSET_PLUS;
      ++string;
    }
  else if (*string == '-')
    {
      line_offset.sign = LINE_OFFSET_MINUS;
      ++string;
    }
  else
    line_offset.sign = LINE_OFFSET_NONE;

  if (*string != '\0' && !c_isdigit (*string))
    error (_("malformed line offset: \"%s\""), start);

  /* Right now, we only allow base 10 for offsets.  */
  line_offset.offset = atoi (string);
  return line_offset;
}

/* In completion mode, if the user is still typing the number, there's
   no possible completion to offer.  But if there's already input past
   the number, setup to expect NEXT.  */

static void
set_completion_after_number (linespec_parser *parser,
			     linespec_complete_what next)
{
  if (*parser->lexer.stream == ' ')
    {
      parser->completion_word = skip_spaces (parser->lexer.stream + 1);
      parser->complete_what = next;
    }
  else
    {
      parser->completion_word = parser->lexer.stream;
      parser->complete_what = linespec_complete_what::NOTHING;
    }
}

/* Parse the basic_spec in PARSER's input.  */

static void
linespec_parse_basic (linespec_parser *parser)
{
  gdb::unique_xmalloc_ptr<char> name;
  linespec_token token;

  /* Get the next token.  */
  token = linespec_lexer_lex_one (parser);

  /* If it is EOI or KEYWORD, issue an error.  */
  if (token.type == LSTOKEN_KEYWORD)
    {
      parser->complete_what = linespec_complete_what::NOTHING;
      unexpected_linespec_error (parser);
    }
  else if (token.type == LSTOKEN_EOI)
    {
      unexpected_linespec_error (parser);
    }
  /* If it is a LSTOKEN_NUMBER, we have an offset.  */
  else if (token.type == LSTOKEN_NUMBER)
    {
      set_completion_after_number (parser, linespec_complete_what::KEYWORD);

      /* Record the line offset and get the next token.  */
      name = copy_token_string (token);
      parser->result.explicit_loc.line_offset
	= linespec_parse_line_offset (name.get ());

      /* Get the next token.  */
      token = linespec_lexer_consume_token (parser);

      /* If the next token is a comma, stop parsing and return.  */
      if (token.type == LSTOKEN_COMMA)
	{
	  parser->complete_what = linespec_complete_what::NOTHING;
	  return;
	}

      /* If the next token is anything but EOI or KEYWORD, issue
	 an error.  */
      if (token.type != LSTOKEN_KEYWORD && token.type != LSTOKEN_EOI)
	unexpected_linespec_error (parser);
    }

  if (token.type == LSTOKEN_KEYWORD || token.type == LSTOKEN_EOI)
    return;

  /* Next token must be LSTOKEN_STRING.  */
  if (token.type != LSTOKEN_STRING)
    {
      parser->complete_what = linespec_complete_what::NOTHING;
      unexpected_linespec_error (parser);
    }

  /* The current token will contain the name of a function, method,
     or label.  */
  name = copy_token_string (token);

  if (parser->completion_tracker != NULL)
    {
      /* If the function name ends with a ":", then this may be an
	 incomplete "::" scope operator instead of a label separator.
	 E.g.,
	   "b klass:<tab>"
	 which should expand to:
	   "b klass::method()"

	 Do a tentative completion assuming the later.  If we find
	 completions, advance the stream past the colon token and make
	 it part of the function name/token.  */

      if (!parser->completion_quote_char
	  && strcmp (parser->lexer.stream, ":") == 0)
	{
	  completion_tracker tmp_tracker (false);
	  const char *source_filename
	    = parser->result.explicit_loc.source_filename.get ();
	  symbol_name_match_type match_type
	    = parser->result.explicit_loc.func_name_match_type;

	  linespec_complete_function (tmp_tracker,
				      parser->completion_word,
				      match_type,
				      source_filename);

	  if (tmp_tracker.have_completions ())
	    {
	      parser->lexer.stream++;
	      token.data.string.length++;

	      name.reset (savestring (parser->completion_word,
				      (parser->lexer.stream
				       - parser->completion_word)));
	    }
	}

      parser->result.explicit_loc.function_name = std::move (name);
    }
  else
    {
      std::vector<block_symbol> symbols;
      std::vector<bound_minimal_symbol> minimal_symbols;

      /* Try looking it up as a function/method.  */
      find_linespec_symbols (&parser->state,
			     parser->result.file_symtabs, name.get (),
			     parser->result.explicit_loc.func_name_match_type,
			     &symbols, &minimal_symbols);

      if (!symbols.empty () || !minimal_symbols.empty ())
	{
	  parser->result.function_symbols = std::move (symbols);
	  parser->result.minimal_symbols = std::move (minimal_symbols);
	  parser->result.explicit_loc.function_name = std::move (name);
	}
      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".  */
	  std::vector<block_symbol> labels
	    = find_label_symbols (&parser->state, {}, &symbols,
				  name.get ());

	  if (!labels.empty ())
	    {
	      parser->result.labels.label_symbols = std::move (labels);
	      parser->result.labels.function_symbols = std::move (symbols);
	      parser->result.explicit_loc.label_name = std::move (name);
	    }
	  else if (token.type == LSTOKEN_STRING
		   && *token.data.string.ptr == '$')
	    {
	      /* User specified a convenience variable or history value.  */
	      parser->result.explicit_loc.line_offset
		= linespec_parse_variable (&parser->state, name.get ());

	      if (parser->result.explicit_loc.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->result.explicit_loc.function_name = std::move (name);
		  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->result.explicit_loc.function_name = std::move (name);
	      return;
	    }
	}
    }

  int previous_qc = parser->completion_quote_char;

  /* Get the next token.  */
  token = linespec_lexer_consume_token (parser);

  if (token.type == LSTOKEN_EOI)
    {
      if (previous_qc && !parser->completion_quote_char)
	parser->complete_what = linespec_complete_what::KEYWORD;
    }
  else if (token.type == LSTOKEN_COLON)
    {
      /* User specified a label or a lineno.  */
      token = linespec_lexer_consume_token (parser);

      if (token.type == LSTOKEN_NUMBER)
	{
	  /* User specified an offset.  Record the line offset and
	     get the next token.  */
	  set_completion_after_number (parser, linespec_complete_what::KEYWORD);

	  name = copy_token_string (token);
	  parser->result.explicit_loc.line_offset
	    = linespec_parse_line_offset (name.get ());

	  /* Get the next token.  */
	  token = linespec_lexer_consume_token (parser);
	}
      else if (token.type == LSTOKEN_EOI && parser->completion_tracker != NULL)
	{
	  parser->complete_what = linespec_complete_what::LABEL;
	}
      else if (token.type == LSTOKEN_STRING)
	{
	  parser->complete_what = linespec_complete_what::LABEL;

	  /* If we have text after the label separated by whitespace
	     (e.g., "b func():lab i<tab>"), don't consider it part of
	     the label.  In completion mode that should complete to
	     "if", in normal mode, the 'i' should be treated as
	     garbage.  */
	  if (parser->completion_quote_char == '\0')
	    {
	      const char *ptr = token.data.string.ptr;
	      for (size_t i = 0; i < token.data.string.length; i++)
		{
		  if (ptr[i] == ' ')
		    {
		      token.data.string.length = i;
		      parser->lexer.stream = skip_spaces (ptr + i + 1);
		      break;
		    }
		}
	    }

	  if (parser->completion_tracker != NULL)
	    {
	      if (parser->lexer.stream[-1] == ' ')
		{
		  parser->completion_word = parser->lexer.stream;
		  parser->complete_what = linespec_complete_what::KEYWORD;
		}
	    }
	  else
	    {
	      std::vector<block_symbol> symbols;

	      /* Grab a copy of the label's name and look it up.  */
	      name = copy_token_string (token);
	      std::vector<block_symbol> labels
		= find_label_symbols (&parser->state,
				      parser->result.function_symbols,
				      &symbols, name.get ());

	      if (!labels.empty ())
		{
		  parser->result.labels.label_symbols = std::move (labels);
		  parser->result.labels.function_symbols = std::move (symbols);
		  parser->result.explicit_loc.label_name = std::move (name);
		}
	      else
		{
		  /* We don't know what it was, but it isn't a label.  */
		  undefined_label_error
		    (parser->result.explicit_loc.function_name.get (),
		     name.get ());
		}

	    }

	  /* Check for a line offset.  */
	  token = save_stream_and_consume_token (parser);
	  if (token.type == LSTOKEN_COLON)
	    {
	      /* Get the next token.  */
	      token = linespec_lexer_consume_token (parser);

	      /* It must be a line offset.  */
	      if (token.type != LSTOKEN_NUMBER)
		unexpected_linespec_error (parser);

	      /* Record the line offset and get the next token.  */
	      name = copy_token_string (token);

	      parser->result.explicit_loc.line_offset
		= linespec_parse_line_offset (name.get ());

	      /* Get the next token.  */
	      token = linespec_lexer_consume_token (parser);
	    }
	}
      else
	{
	  /* Trailing ':' in the input. Issue an error.  */
	  unexpected_linespec_error (parser);
	}
    }
}

/* Canonicalize the linespec contained in LS.  The result is saved into
   STATE->canonical.  This function handles both linespec and explicit
   locations.  */

static void
canonicalize_linespec (struct linespec_state *state, const linespec *ls)
{
  /* If canonicalization was not requested, no need to do anything.  */
  if (!state->canonical)
    return;

  /* Save everything as an explicit location.  */
  state->canonical->locspec = ls->explicit_loc.clone ();
  explicit_location_spec *explicit_loc
    = as_explicit_location_spec (state->canonical->locspec.get ());

  if (explicit_loc->label_name != NULL)
    {
      state->canonical->special_display = 1;

      if (explicit_loc->function_name == NULL)
	{
	  /* No function was specified, so add the symbol name.  */
	  gdb_assert (ls->labels.function_symbols.size () == 1);
	  block_symbol s = ls->labels.function_symbols.front ();
	  explicit_loc->function_name
	    = make_unique_xstrdup (s.symbol->natural_name ());
	}
    }

  /* If this location originally came from a linespec, save a string
     representation of it for display and saving to file.  */
  if (state->is_linespec)
    explicit_loc->set_string (explicit_loc->to_linespec ());
}

/* Given a line offset in LS, construct the relevant SALs.  */

static std::vector<symtab_and_line>
create_sals_line_offset (struct linespec_state *self,
			 linespec *ls)
{
  bool use_default = false;

  /* 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
     set_default_source_symtab_and_line uses
     select_source_symtab that calls us with such an argument.  */

  if (ls->file_symtabs.size () == 1
      && ls->file_symtabs.front () == nullptr)
    {
      set_current_program_space (self->program_space);

      /* Make sure we have at least a default source line.  */
      set_default_source_symtab_and_line ();
      initialize_defaults (&self->default_symtab, &self->default_line);
      ls->file_symtabs
	= collect_symtabs_from_filename (self->default_symtab->filename (),
					 self->search_pspace);
      use_default = true;
    }

  int line = ls->explicit_loc.line_offset.offset;

  switch (ls->explicit_loc.line_offset.sign)
    {
    case LINE_OFFSET_PLUS:
      if (ls->explicit_loc.line_offset.offset == 0)
	line = 5;
      if (use_default)
	line = self->default_line + line;
      break;

    case LINE_OFFSET_MINUS:
      if (ls->explicit_loc.line_offset.offset == 0)
	line = 15;
      if (use_default)
	line = self->default_line - line;
      else
	line = -line;
      break;

    case LINE_OFFSET_NONE:
      break;			/* No need to adjust val.line.  */
    }

  std::vector<symtab_and_line> values;
  if (self->list_mode)
    values = decode_digits_list_mode (self, ls, line);
  else
    {
      const linetable_entry *best_entry = NULL;
      int i, j;

      /* True if the provided line gave an exact match.  False if we had to
	 search for the next following line with code.  */
      bool was_exact = true;

      std::vector<symtab_and_line> intermediate_results
	= decode_digits_ordinary (self, ls, line, &best_entry);
      if (intermediate_results.empty () && best_entry != NULL)
	{
	  was_exact = false;
	  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
	 functions or inline functions are involved.  For example,
	 'for (;;)' inside a non-template, non-inline, and non-ctor-or-dtor
	 function can result in two PC ranges.  In this case, we don't
	 want to set a breakpoint on the first PC of each range.  To filter
	 such cases, we use containing blocks -- for each PC found
	 above, we see if there are other PCs that are in the same
	 block.  If yes, the other PCs are filtered out.  */

      gdb::def_vector<int> filter (intermediate_results.size ());
      gdb::def_vector<const block *> blocks (intermediate_results.size ());

      for (i = 0; i < intermediate_results.size (); ++i)
	{
	  set_current_program_space (intermediate_results[i].pspace);

	  filter[i] = 1;
	  blocks[i] = block_for_pc_sect (intermediate_results[i].pc,
					 intermediate_results[i].section);
	}

      for (i = 0; i < intermediate_results.size (); ++i)
	{
	  if (blocks[i] != NULL)
	    for (j = i + 1; j < intermediate_results.size (); ++j)
	      {
		if (blocks[j] == blocks[i])
		  {
		    filter[j] = 0;
		    break;
		  }
	      }
	}

      for (i = 0; i < intermediate_results.size (); ++i)
	if (filter[i])
	  {
	    struct symbol *sym = (blocks[i]
				  ? blocks[i]->containing_function ()
				  : NULL);
	    symtab_and_line &sal = intermediate_results[i];

	    /* Don't consider a match if:

	       - the provided line did not give an exact match (so we
		 started looking for lines below until we found one with
		 code associated to it)
	       - the found location is exactly the start of a function
	       - the provided line is above the declaration line of the
		 function

	       Consider the following source:

	       10 } // end of a previous function
	       11
	       12 int
	       13 main (void)
	       14 {
	       15   int i = 1;
	       16
	       17   return 0;
	       18 }

	       The intent of this heuristic is that a breakpoint requested on
	       line 11 and 12 will not result in a breakpoint on main, but a
	       breakpoint on line 13 will.  A breakpoint requested on the empty
	       line 16 will also result in a breakpoint in main, at line 17.  */
	    if (!was_exact
		&& sym != nullptr
		&& sym->loc_class () == LOC_BLOCK
		&& sal.pc == sym->value_block ()->entry_pc ()
		&& line < sym->line ())
	      continue;

	    if (self->funfirstline)
	      skip_prologue_sal (&sal);

	    sal.symbol = sym;
	    add_sal_to_sals (self, values, sal,
			     sym ? sym->natural_name () : nullptr, false);
	  }
    }

  if (values.empty ())
    {
      if (ls->explicit_loc.source_filename)
	throw_error (NOT_FOUND_ERROR,
		     _("No compiled code for line %d in file \"%s\"."),
		     line, ls->explicit_loc.source_filename.get ());
      else
	throw_error (NOT_FOUND_ERROR,
		     _("No compiled code for line %d in the current file."),
		     line);
    }

  return values;
}

/* Convert the given ADDRESS into SaLs.  */

static std::vector<symtab_and_line>
convert_address_location_to_sals (struct linespec_state *self,
				  CORE_ADDR address)
{
  symtab_and_line sal = find_sal_for_pc (address, 0);
  sal.pc = address;
  sal.section = find_pc_overlay (address);

  if (sal.section == nullptr)
    sal.section = find_pc_section (address);

  sal.explicit_pc = 1;
  sal.symbol = find_symbol_for_pc_sect_maybe_inline (sal.pc, sal.section);

  std::vector<symtab_and_line> sals;
  add_sal_to_sals (self, sals, sal, core_addr_to_string (address), true);

  return sals;
}

/* Create and return SALs from the linespec LS.  */

static std::vector<symtab_and_line>
convert_linespec_to_sals (struct linespec_state *state, linespec *ls)
{
  std::vector<symtab_and_line> sals;

  if (!ls->labels.label_symbols.empty ())
    {
      /* We have just a bunch of functions/methods or labels.  */
      for (const auto &sym : ls->labels.label_symbols)
	{
	  struct program_space *pspace
	    = sym.symbol->symtab ()->compunit ()->objfile ()->pspace ();
	  std::optional<symtab_and_line> sal
	    = symbol_to_sal (state->funfirstline, sym.symbol);

	  if (sal.has_value () && state->maybe_add_address (pspace, sal->pc))
	    add_sal_to_sals (state, sals, *sal,
			     sym.symbol->natural_name (), false);
	}
    }
  else if (!ls->function_symbols.empty () || !ls->minimal_symbols.empty ())
    {
      /* We have just a bunch of functions and/or methods.  */
      if (!ls->function_symbols.empty ())
	{
	  /* Sort symbols so that symbols with the same program space are next
	     to each other.  */
	  std::sort (ls->function_symbols.begin (),
		     ls->function_symbols.end (),
		     compare_symbols);

	  for (const auto &sym : ls->function_symbols)
	    {
	      program_space *pspace
		= sym.symbol->symtab ()->compunit ()->objfile ()->pspace ();
	      set_current_program_space (pspace);

	      /* 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.empty ()
		   && sym.symbol->loc_class () == LOC_BLOCK)
		{
		  const CORE_ADDR addr
		    = sym.symbol->value_block ()->entry_pc ();

		  for (const auto &elem : ls->minimal_symbols)
		    {
		      if (elem.minsym->type () == mst_text_gnu_ifunc
			  || elem.minsym->type () == mst_data_gnu_ifunc)
			{
			  CORE_ADDR msym_addr = elem.value_address ();
			  if (elem.minsym->type () == mst_data_gnu_ifunc)
			    {
			      struct gdbarch *gdbarch
				= elem.objfile->arch ();
			      msym_addr
				= (gdbarch_convert_from_func_ptr_addr
				   (gdbarch,
				    msym_addr,
				    current_inferior ()->top_target ()));
			    }

			  if (msym_addr == addr)
			    {
			      found_ifunc = true;
			      break;
			    }
			}
		    }
		}

	      if (!found_ifunc)
		{
		  std::optional<symtab_and_line> sal
		    = symbol_to_sal (state->funfirstline, sym.symbol);

		  if (sal.has_value ()
		      && state->maybe_add_address (pspace, sal->pc))
		    add_sal_to_sals (state, sals, *sal,
				     sym.symbol->natural_name (), false);
		}
	    }
	}

      if (!ls->minimal_symbols.empty ())
	{
	  /* 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)
	    {
	      program_space *pspace = elem.objfile->pspace ();
	      set_current_program_space (pspace);
	      minsym_found (state, elem.objfile, elem.minsym, sals);
	    }
	}
    }
  else if (ls->explicit_loc.line_offset.sign != LINE_OFFSET_UNKNOWN)
    {
      /* Only an offset was specified.  */
	sals = create_sals_line_offset (state, ls);

	/* Make sure we have a filename for canonicalization.  */
	if (ls->explicit_loc.source_filename == NULL)
	  {
	    const char *filename = state->default_symtab->filename ();

	    /* It may be more appropriate to keep DEFAULT_SYMTAB in its symtab
	       form so that displaying SOURCE_FILENAME can follow the current
	       FILENAME_DISPLAY_STRING setting.  But as it is used only rarely
	       it has been kept for code simplicity only in absolute form.  */
	    ls->explicit_loc.source_filename = make_unique_xstrdup (filename);
	  }
    }
  else
    {
      /* We haven't found any results...  */
      return sals;
    }

  canonicalize_linespec (state, ls);

  if (!sals.empty () && state->canonical != NULL)
    state->canonical->pre_expanded = 1;

  return sals;
}

/* Build RESULT from the explicit location spec components
   SOURCE_FILENAME, FUNCTION_NAME, LABEL_NAME and LINE_OFFSET.  */

static void
convert_explicit_location_spec_to_linespec
  (struct linespec_state *self,
   linespec *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)
{
  std::vector<bound_minimal_symbol> minimal_symbols;

  result->explicit_loc.func_name_match_type = fname_match_type;

  if (source_filename != NULL)
    {
      try
	{
	  result->file_symtabs
	    = symtabs_from_filename (source_filename, self->search_pspace);
	}
      catch (const gdb_exception_error &except)
	{
	  source_file_not_found_error (source_filename);
	}
      result->explicit_loc.source_filename
	= make_unique_xstrdup (source_filename);
    }
  else
    {
      /* A NULL entry means to use the default symtab.  */
      result->file_symtabs.push_back (nullptr);
    }

  if (function_name != NULL)
    {
      std::vector<block_symbol> symbols;

      find_linespec_symbols (self, result->file_symtabs,
			     function_name, fname_match_type,
			     &symbols, &minimal_symbols);

      if (symbols.empty () && minimal_symbols.empty ())
	symbol_not_found_error (function_name,
				result->explicit_loc.source_filename.get ());

      result->explicit_loc.function_name
	= make_unique_xstrdup (function_name);
      result->function_symbols = std::move (symbols);
      result->minimal_symbols = std::move (minimal_symbols);
    }

  if (label_name != NULL)
    {
      std::vector<block_symbol> symbols;
      std::vector<block_symbol> labels
	= find_label_symbols (self, result->function_symbols,
			      &symbols, label_name);

      if (labels.empty ())
	undefined_label_error (result->explicit_loc.function_name.get (),
			       label_name);

      result->explicit_loc.label_name = make_unique_xstrdup (label_name);
      result->labels.label_symbols = labels;
      result->labels.function_symbols = std::move (symbols);
    }

  if (line_offset.sign != LINE_OFFSET_UNKNOWN)
    result->explicit_loc.line_offset = line_offset;
}

/* Convert the explicit location EXPLICIT_LOC into SaLs.  */

static std::vector<symtab_and_line>
convert_explicit_location_spec_to_sals
  (struct linespec_state *self,
   linespec *result,
   const explicit_location_spec *explicit_spec)
{
  convert_explicit_location_spec_to_linespec (self, result,
					      explicit_spec->source_filename.get (),
					      explicit_spec->function_name.get (),
					      explicit_spec->func_name_match_type,
					      explicit_spec->label_name.get (),
					      explicit_spec->line_offset);
  return convert_linespec_to_sals (self, result);
}

/* Parse a string that specifies a linespec.

   The basic grammar of linespecs:

   linespec -> var_spec | basic_spec
   var_spec -> '$' (STRING | NUMBER)

   basic_spec -> file_offset_spec | function_spec | label_spec
   file_offset_spec -> opt_file_spec offset_spec
   function_spec -> opt_file_spec function_name_spec opt_label_spec
   label_spec -> label_name_spec

   opt_file_spec -> "" | file_name_spec ':'
   opt_label_spec -> "" | ':' label_name_spec

   file_name_spec -> STRING
   function_name_spec -> STRING
   label_name_spec -> STRING
   function_name_spec -> STRING
   offset_spec -> NUMBER
	       -> '+' NUMBER
	       -> '-' NUMBER

   This may all be followed by several keywords such as "if EXPR",
   which we ignore.

   A comma will terminate parsing.

   The function may be an undebuggable function found in minimal symbol table.

   If the argument FUNFIRSTLINE is nonzero, we want the first line
   of real code inside a function when a function is specified, and it is
   not OK to specify a variable or type to get its line number.

   DEFAULT_SYMTAB specifies the file to use if none is specified.
   It defaults to current_source_symtab.
   DEFAULT_LINE specifies the line number to use for relative
   line numbers (that start with signs).  Defaults to current_source_line.
   If CANONICAL is non-NULL, store an array of strings containing the canonical
   line specs there if necessary.  Currently overloaded member functions and
   line numbers or static functions without a filename yield a canonical
   line spec.  The array and the line spec strings are allocated on the heap,
   it is the callers responsibility to free them.

   Note that it is possible to return zero for the symtab
   if no file is validly specified.  Callers must check that.
   Also, the line number returned may be invalid.  */

/* Parse the linespec in ARG, which must not be nullptr.  MATCH_TYPE
   indicates how function names should be matched.  */

static std::vector<symtab_and_line>
parse_linespec (linespec_parser *parser, const char *arg,
		symbol_name_match_type match_type)
{
  gdb_assert (arg != nullptr);

  struct gdb_exception file_exception;

  /* A special case to start.  It has become quite popular for
     IDEs to work around bugs in the previous parser by quoting
     the entire linespec, so we attempt to deal with this nicely.  */
  parser->is_quote_enclosed = false;
  if (parser->completion_tracker == NULL
      && !is_ada_operator (arg)
      && *arg != '\0'
      && strchr (linespec_quote_characters, *arg) != NULL)
    {
      const char *end = skip_quote_char (arg + 1, *arg);
      if (end != NULL && is_closing_quote_enclosed (end))
	{
	  /* Here's the special case.  Skip ARG past the initial
	     quote.  */
	  ++arg;
	  parser->is_quote_enclosed = true;
	}
    }

  parser->lexer.saved_arg = arg;
  parser->lexer.stream = arg;
  parser->completion_word = arg;
  parser->complete_what = linespec_complete_what::FUNCTION;
  parser->result.explicit_loc.func_name_match_type = match_type;

  /* Initialize the default symtab and line offset.  */
  initialize_defaults (&parser->state.default_symtab,
		       &parser->state.default_line);

  /* Objective-C shortcut.  */
  if (parser->completion_tracker == NULL)
    {
      std::vector<symtab_and_line> values
	= decode_objc (&parser->state, &parser->result, arg);
      if (!values.empty ())
	return values;
    }
  else
    {
      /* "-"/"+" is either an objc selector, or a number.  There's
	 nothing to complete the latter to, so just let the caller
	 complete on functions, which finds objc selectors, if there's
	 any.  */
      if ((arg[0] == '-' || arg[0] == '+') && arg[1] == '\0')
	return {};
    }

  /* Start parsing.  */

  /* Get the first token.  */
  linespec_token token = linespec_lexer_consume_token (parser);

  /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER.  */
  if (token.type == LSTOKEN_STRING && *token.data.string.ptr == '$')
    {
      /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
      if (parser->completion_tracker == NULL)
	parser->result.file_symtabs.push_back (nullptr);

      /* User specified a convenience variable or history value.  */
      gdb::unique_xmalloc_ptr<char> var = copy_token_string (token);
      parser->result.explicit_loc.line_offset
	= linespec_parse_variable (&parser->state, var.get ());

      /* If a line_offset wasn't found (VAR is the name of a user
	 variable/function), then skip to normal symbol processing.  */
      if (parser->result.explicit_loc.line_offset.sign != LINE_OFFSET_UNKNOWN)
	{
	  /* Consume this token.  */
	  linespec_lexer_consume_token (parser);

	  goto convert_to_sals;
	}
    }
  else if (token.type == LSTOKEN_EOI && parser->completion_tracker != NULL)
    {
      /* Let the default linespec_complete_what::FUNCTION kick in.  */
      unexpected_linespec_error (parser);
    }
  else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
    {
      parser->complete_what = linespec_complete_what::NOTHING;
      unexpected_linespec_error (parser);
    }

  /* Shortcut: If the next token is not LSTOKEN_COLON, we know that
     this token cannot represent a filename.  */
  token = linespec_lexer_peek_token (parser);

  if (token.type == LSTOKEN_COLON)
    {
      /* Get the current token again and extract the filename.  */
      token = linespec_lexer_lex_one (parser);
      gdb::unique_xmalloc_ptr<char> user_filename = copy_token_string (token);

      /* Check if the input is a filename.  */
      try
	{
	  parser->result.file_symtabs
	    = symtabs_from_filename (user_filename.get (),
				     parser->state.search_pspace);
	}
      catch (gdb_exception_error &ex)
	{
	  file_exception = std::move (ex);
	}

      if (file_exception.reason >= 0)
	{
	  /* Symtabs were found for the file.  Record the filename.  */
	  parser->result.explicit_loc.source_filename = std::move (user_filename);

	  /* Get the next token.  */
	  token = linespec_lexer_consume_token (parser);

	  /* This is LSTOKEN_COLON; consume it.  */
	  linespec_lexer_consume_token (parser);
	}
      else
	{
	  /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
	  parser->result.file_symtabs.push_back (nullptr);
	}
    }
  /* If the next token is not EOI, KEYWORD, or COMMA, issue an error.  */
  else if (parser->completion_tracker == NULL
	   && (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD
	       && token.type != LSTOKEN_COMMA))
    {
      /* TOKEN is the _next_ token, not the one currently in the parser.
	 Consuming the token will give the correct error message.  */
      linespec_lexer_consume_token (parser);
      unexpected_linespec_error (parser);
    }
  else
    {
      /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
      parser->result.file_symtabs.push_back (nullptr);
    }

  /* Parse the rest of the linespec.  */
  linespec_parse_basic (parser);

  if (parser->completion_tracker == NULL
      && parser->result.function_symbols.empty ()
      && parser->result.labels.label_symbols.empty ()
      && parser->result.explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN
      && parser->result.minimal_symbols.empty ())
    {
      /* The linespec didn't parse.  Re-throw the file exception if
	 there was one.  */
      if (file_exception.reason < 0)
	throw_exception (std::move (file_exception));

      /* Otherwise, the symbol is not found.  */
      symbol_not_found_error
	(parser->result.explicit_loc.function_name.get (),
	 parser->result.explicit_loc.source_filename.get ());
    }

 convert_to_sals:

  /* Get the last token and record how much of the input was parsed,
     if necessary.  */
  token = linespec_lexer_lex_one (parser);
  if (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD)
    unexpected_linespec_error (parser);
  else if (token.type == LSTOKEN_KEYWORD)
    {
      /* Setup the completion word past the keyword.  Lexing never
	 advances past a keyword automatically, so skip it
	 manually.  */
      parser->completion_word
	= skip_spaces (skip_to_space (parser->lexer.stream));
      parser->complete_what = linespec_complete_what::EXPRESSION;
    }

  /* Convert the data in the parser's result to SALs.  */
  if (parser->completion_tracker == NULL)
    return convert_linespec_to_sals (&parser->state, &parser->result);

  return {};
}


/* Initialize a new linespec parser.  */

linespec_parser::linespec_parser (int flags,
				  const struct language_defn *language,
				  struct program_space *search_pspace,
				  struct symtab *default_symtab,
				  int default_line,
				  struct linespec_result *canonical)
  : state (flags, language, current_program_space, search_pspace,
	     default_symtab, default_line, canonical)
{
  lexer.current.type = LSTOKEN_CONSUMED;
  result.explicit_loc.func_name_match_type
    = symbol_name_match_type::WILD;
  result.explicit_loc.line_offset.sign = LINE_OFFSET_UNKNOWN;
}

/* See description in linespec.h.  */

void
linespec_lex_to_end (const char **stringp)
{
  linespec_token token;
  const char *orig;

  if (stringp == NULL || *stringp == NULL)
    return;

  linespec_parser parser (0, current_language, NULL, NULL, 0, NULL);
  parser.lexer.saved_arg = *stringp;
  parser.lexer.stream = orig = *stringp;

  do
    {
      /* Stop before any comma tokens;  we need it to keep it
	 as the next token in the string.  */
      token = linespec_lexer_peek_token (&parser);
      if (token.type == LSTOKEN_COMMA)
	break;
      token = linespec_lexer_consume_token (&parser);
    }
  while (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD);

  *stringp += parser.lexer.stream - orig;
}

/* See linespec.h.  */

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, func_match_type,
					      function, function, source_filename);
    }
  else
    {
      collect_symbol_completion_matches (tracker, mode, func_match_type,
					 function, function);

    }
}

/* Helper for complete_linespec to simplify it.  SOURCE_FILENAME is
   only meaningful if COMPONENT is FUNCTION.  */

static void
complete_linespec_component (linespec_parser *parser,
			     completion_tracker &tracker,
			     const char *text,
			     linespec_complete_what component,
			     const char *source_filename)
{
  if (component == linespec_complete_what::KEYWORD)
    {
      complete_on_enum (tracker, linespec_keywords, text, text);
    }
  else if (component == linespec_complete_what::EXPRESSION)
    {
      const char *word
	= advance_to_expression_complete_word_point (tracker, text);
      complete_expression (tracker, text, word);
    }
  else if (component == linespec_complete_what::FUNCTION)
    {
      completion_list fn_list;

      symbol_name_match_type match_type
	= parser->result.explicit_loc.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
	     file.c:function[TAB]".  Maybe this wasn't a function, but
	     a filename instead, like "b file.[TAB]".  */
	  fn_list = complete_source_filenames (text);
	}

      /* If we only have a single filename completion, append a ':' for
	 the user, since that's the only thing that can usefully follow
	 the filename.  */
      if (fn_list.size () == 1 && !tracker.have_completions ())
	{
	  char *fn = fn_list[0].release ();

	  /* If we also need to append a quote char, it needs to be
	     appended before the ':'.  Append it now, and make ':' the
	     new "quote" char.  */
	  if (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 (':');
	    }
	  else
	    fn = reconcat (fn, fn, ":", (char *) NULL);
	  fn_list[0].reset (fn);

	  /* Tell readline to skip appending a space.  */
	  tracker.set_suppress_append_ws (true);
	}
      tracker.add_completions (std::move (fn_list));
    }
}

/* Helper for linespec_complete_label.  Find labels that match
   LABEL_NAME in the function symbols listed in the PARSER, and add
   them to the tracker.  */

static void
complete_label (completion_tracker &tracker,
		linespec_parser *parser,
		const char *label_name)
{
  std::vector<block_symbol> label_function_symbols;
  std::vector<block_symbol> labels
    = find_label_symbols (&parser->state,
			  parser->result.function_symbols,
			  &label_function_symbols,
			  label_name, true);

  for (const auto &label : labels)
    {
      char *match = xstrdup (label.symbol->search_name ());
      tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
    }
}

/* See linespec.h.  */

void
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 (0, language, NULL, NULL, 0, NULL);

  line_offset unknown_offset;

  try
    {
      convert_explicit_location_spec_to_linespec (&parser.state,
						  &parser.result,
						  source_filename,
						  function_name,
						  func_name_match_type,
						  NULL, unknown_offset);
    }
  catch (const gdb_exception_error &ex)
    {
      return;
    }

  complete_label (tracker, &parser, label_name);
}

/* See description in linespec.h.  */

void
linespec_complete (completion_tracker &tracker, const char *text,
		   symbol_name_match_type match_type)
{
  const char *orig = text;

  linespec_parser parser (0, current_language, NULL, NULL, 0, NULL);
  parser.lexer.saved_arg = text;
  parser.result.explicit_loc.func_name_match_type = match_type;
  parser.lexer.stream = text;

  parser.completion_tracker = &tracker;
  parser.state.is_linespec = true;

  /* Parse as much as possible.  parser.completion_word will hold
     furthest completion point we managed to parse to.  */
  try
    {
      parse_linespec (&parser, text, match_type);
    }
  catch (const gdb_exception_error &except)
    {
    }

  if (parser.completion_quote_char != '\0'
      && parser.completion_quote_end != NULL
      && parser.completion_quote_end[1] == '\0')
    {
      /* If completing a quoted string with the cursor right at
	 terminating quote char, complete the completion word without
	 interpretation, so that readline advances the cursor one
	 whitespace past the quote, even if there's no match.  This
	 makes these cases behave the same:

	   before: "b function()"
	   after:  "b function() "

	   before: "b 'function()'"
	   after:  "b 'function()' "

	 and trusts the user in this case:

	   before: "b 'not_loaded_function_yet()'"
	   after:  "b 'not_loaded_function_yet()' "
      */
      parser.complete_what = linespec_complete_what::NOTHING;
      parser.completion_quote_char = '\0';

      gdb::unique_xmalloc_ptr<char> text_copy
	(xstrdup (parser.completion_word));
      tracker.add_completion (std::move (text_copy));
    }

  tracker.set_quote_char (parser.completion_quote_char);

  if (parser.complete_what == linespec_complete_what::LABEL)
    {
      parser.complete_what = linespec_complete_what::NOTHING;

      const char *func_name = parser.result.explicit_loc.function_name.get ();

      std::vector<block_symbol> function_symbols;
      std::vector<bound_minimal_symbol> minimal_symbols;
      find_linespec_symbols (&parser.state,
			     parser.result.file_symtabs,
			     func_name, match_type,
			     &function_symbols, &minimal_symbols);

      parser.result.function_symbols = std::move (function_symbols);
      parser.result.minimal_symbols = std::move (minimal_symbols);
      complete_label (tracker, &parser, parser.completion_word);
    }
  else if (parser.complete_what == linespec_complete_what::FUNCTION)
    {
      /* While parsing/lexing, we didn't know whether the completion
	 word completes to a unique function/source name already or
	 not.

	 E.g.:
	   "b function() <tab>"
	 may need to complete either to:
	   "b function() const"
	 or to:
	   "b function() if/thread/task"

	 Or, this:
	   "b foo t"
	 may need to complete either to:
	   "b foo template_fun<T>()"
	 with "foo" being the template function's return type, or to:
	   "b foo thread/task"

	 Or, this:
	   "b file<TAB>"
	 may need to complete either to a source file name:
	   "b file.c"
	 or this, also a filename, but a unique completion:
	   "b file.c:"
	 or to a function name:
	   "b file_function"

	 Address that by completing assuming source or function, and
	 seeing if we find a completion that matches exactly the
	 completion word.  If so, then it must be a function (see note
	 below) and we advance the completion word to the end of input
	 and switch to KEYWORD completion mode.

	 Note: if we find a unique completion for a source filename,
	 then it won't match the completion word, because the LCD will
	 contain a trailing ':'.  And if we're completing at or after
	 the ':', then complete_linespec_component won't try to
	 complete on source filenames.  */

      const char *word = parser.completion_word;

      complete_linespec_component
	(&parser, tracker,
	 parser.completion_word,
	 linespec_complete_what::FUNCTION,
	 parser.result.explicit_loc.source_filename.get ());

      parser.complete_what = linespec_complete_what::NOTHING;

      if (tracker.quote_char ())
	{
	  /* The function/file name was not close-quoted, so this
	     can't be a keyword.  Note: complete_linespec_component
	     may have swapped the original quote char for ':' when we
	     get here, but that still indicates the same.  */
	}
      else if (!tracker.have_completions ())
	{
	  size_t key_start;
	  size_t wordlen = strlen (parser.completion_word);

	  key_start
	    = string_find_incomplete_keyword_at_end (linespec_keywords,
						     parser.completion_word,
						     wordlen);

	  if (key_start != -1
	      || (wordlen > 0
		  && parser.completion_word[wordlen - 1] == ' '))
	    {
	      parser.completion_word += key_start;
	      parser.complete_what = linespec_complete_what::KEYWORD;
	    }
	}
      else if (tracker.completes_to_completion_word (word))
	{
	  /* Skip the function and complete on keywords.  */
	  parser.completion_word += strlen (word);
	  parser.complete_what = linespec_complete_what::KEYWORD;
	  tracker.discard_completions ();
	}
    }

  tracker.advance_custom_word_point_by (parser.completion_word - orig);

  complete_linespec_component
    (&parser, tracker,
     parser.completion_word,
     parser.complete_what,
     parser.result.explicit_loc.source_filename.get ());

  /* If we're past the "filename:function:label:offset" linespec, and
     didn't find any match, then assume the user might want to create
     a pending breakpoint anyway and offer the keyword
     completions.  */
  if (!parser.completion_quote_char
      && (parser.complete_what == linespec_complete_what::FUNCTION
	  || parser.complete_what == linespec_complete_what::LABEL
	  || parser.complete_what == linespec_complete_what::NOTHING)
      && !tracker.have_completions ())
    {
      const char *end
	= parser.completion_word + strlen (parser.completion_word);

      if (end > orig && end[-1] == ' ')
	{
	  tracker.advance_custom_word_point_by (end - parser.completion_word);

	  complete_linespec_component (&parser, tracker, end,
				       linespec_complete_what::KEYWORD,
				       NULL);
	}
    }
}

/* A helper function for decode_line_full and decode_line_1 to
   turn LOCSPEC into std::vector<symtab_and_line>.  */

static std::vector<symtab_and_line>
location_spec_to_sals (linespec_parser *parser,
		       const location_spec *locspec)
{
  std::vector<symtab_and_line> result;

  switch (locspec->type ())
    {
    case LINESPEC_LOCATION_SPEC:
      {
	const linespec_location_spec *ls = as_linespec_location_spec (locspec);
	parser->state.is_linespec = true;
	result = parse_linespec (parser, ls->spec_string.get (),
				 ls->match_type);
      }
      break;

    case ADDRESS_LOCATION_SPEC:
      {
	const address_location_spec *addr_spec
	  = as_address_location_spec (locspec);
	const char *addr_string = addr_spec->to_string ();
	CORE_ADDR addr;

	if (addr_string != NULL)
	  {
	    addr = linespec_expression_to_pc (&addr_string);
	    if (parser->state.canonical != NULL)
	      parser->state.canonical->locspec	= locspec->clone ();
	  }
	else
	  addr = addr_spec->address;

	result = convert_address_location_to_sals (&parser->state,
						   addr);
      }
      break;

    case EXPLICIT_LOCATION_SPEC:
      {
	const explicit_location_spec *explicit_locspec
	  = as_explicit_location_spec (locspec);
	result = convert_explicit_location_spec_to_sals (&parser->state,
							 &parser->result,
							 explicit_locspec);
      }
      break;

    case PROBE_LOCATION_SPEC:
      /* Probes are handled by their own decoders.  */
      gdb_assert_not_reached ("attempt to decode probe location");
      break;

    default:
      gdb_assert_not_reached ("unhandled location spec type");
    }

  return result;
}

/* See linespec.h.  */

void
decode_line_full (struct location_spec *locspec, int flags,
		  struct program_space *search_pspace,
		  struct symtab *default_symtab,
		  int default_line, struct linespec_result *canonical,
		  const char *select_mode,
		  const char *filter)
{
  std::vector<const char *> filters;

  gdb_assert (canonical != NULL);
  /* The filter only makes sense for 'all'.  */
  gdb_assert (filter == NULL || select_mode == multiple_symbols_all);
  gdb_assert (select_mode == NULL
	      || select_mode == multiple_symbols_all
	      || select_mode == multiple_symbols_ask
	      || select_mode == multiple_symbols_cancel);
  gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);

  linespec_parser parser (flags, current_language,
			  search_pspace, default_symtab,
			  default_line, canonical);

  scoped_restore_current_program_space restore_pspace;

  std::vector<symtab_and_line> result = location_spec_to_sals (&parser,
							       locspec);
  linespec_state *state = &parser.state;

  if (result.size () == 0)
    throw_error (NOT_SUPPORTED_ERROR, _("Location %s not available"),
		 locspec->to_string ());

  gdb_assert (result.size () == 1 || canonical->pre_expanded);
  canonical->pre_expanded = 1;

  if (select_mode == NULL)
    {
      if (top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
	select_mode = multiple_symbols_all;
      else
	select_mode = multiple_symbols_select_mode ();
    }

  if (select_mode == multiple_symbols_all)
    {
      if (filter != NULL)
	{
	  filters.push_back (filter);
	  filter_results (state, &result, filters);
	}
      else
	convert_results_to_lsals (state, &result);
    }
  else
    decode_line_2 (state, &result, select_mode);
}

/* See linespec.h.  */

std::vector<symtab_and_line>
decode_line_1 (const location_spec *locspec, int flags,
	       struct program_space *search_pspace,
	       struct symtab *default_symtab,
	       int default_line)
{
  linespec_parser parser (flags, current_language,
			  search_pspace, default_symtab,
			  default_line, NULL);

  scoped_restore_current_program_space restore_pspace;

  return location_spec_to_sals (&parser, locspec);
}

/* See linespec.h.  */

std::vector<symtab_and_line>
decode_line_with_current_source (const char *string, int flags)
{
  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!  */
  symtab_and_line cursal
    = get_current_source_symtab_and_line (current_program_space);

  location_spec_up locspec = string_to_location_spec (&string,
						      current_language);
  std::vector<symtab_and_line> sals
    = decode_line_1 (locspec.get (), flags, cursal.pspace, cursal.symtab,
		    cursal.line);

  if (*string)
    error (_("Junk at end of line specification: %s"), string);

  return sals;
}

/* See linespec.h.  */

std::vector<symtab_and_line>
decode_line_with_last_displayed (const char *string, int flags)
{
  if (string == 0)
    error (_("Empty line specification."));

  location_spec_up locspec = string_to_location_spec (&string,
						      current_language);
  std::vector<symtab_and_line> sals
    = (last_displayed_sal_is_valid ()
       ? decode_line_1 (locspec.get (), flags, NULL,
			get_last_displayed_symtab (),
			get_last_displayed_line ())
       : decode_line_1 (locspec.get (), flags, NULL, NULL, 0));

  if (*string)
    error (_("Junk at end of line specification: %s"), string);

  return sals;
}



/* First, some functions to initialize stuff at the beginning of the
   function.  */

static void
initialize_defaults (struct symtab **default_symtab, int *default_line)
{
  if (*default_symtab == 0)
    {
      /* Use whatever we have for the default source line.  We don't use
	 get_current_or_default_symtab_and_line as it can recurse and call
	 us back!  */
      symtab_and_line cursal
	= get_current_source_symtab_and_line (current_program_space);

      *default_symtab = cursal.symtab;
      *default_line = cursal.line;
    }
}



/* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR,
   advancing EXP_PTR past any parsed text.  */

CORE_ADDR
linespec_expression_to_pc (const char **exp_ptr)
{
  if (current_program_space->executing_startup)
    /* The error message doesn't really matter, because this case
       should only hit during breakpoint reset.  */
    throw_error (NOT_FOUND_ERROR, _("cannot evaluate expressions while "
				    "program space is in startup"));

  (*exp_ptr)++;
  return value_as_address (parse_to_comma_and_eval (exp_ptr));
}



/* Here's where we recognise an Objective-C Selector.  An Objective C
   selector may be implemented by more than one class, therefore it
   may represent more than one method/function.  This gives us a
   situation somewhat analogous to C++ overloading.  If there's more
   than one method that could represent the selector, then use some of
   the existing C++ code to let the user choose one.  */

static std::vector<symtab_and_line>
decode_objc (struct linespec_state *self, linespec *ls, const char *arg)
{
  struct collect_info info;
  std::vector<const char *> symbol_names;
  const char *new_argptr;

  info.state = self;
  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 (symbol_names.empty ())
    return {};

  add_all_symbol_names_from_pspace (&info, NULL, symbol_names,
				    SEARCH_FUNCTION_DOMAIN);

  std::vector<symtab_and_line> values;
  if (!symbols.empty () || !minimal_symbols.empty ())
    {
      char *saved_arg;

      saved_arg = (char *) alloca (new_argptr - arg + 1);
      memcpy (saved_arg, arg, new_argptr - arg);
      saved_arg[new_argptr - arg] = '\0';

      ls->explicit_loc.function_name = make_unique_xstrdup (saved_arg);
      ls->function_symbols = std::move (symbols);
      ls->minimal_symbols = std::move (minimal_symbols);
      values = convert_linespec_to_sals (self, ls);

      if (self->canonical)
	{
	  std::string holder;
	  const char *str;

	  self->canonical->pre_expanded = 1;

	  if (ls->explicit_loc.source_filename)
	    {
	      holder = string_printf ("%s:%s",
				      ls->explicit_loc.source_filename.get (),
				      saved_arg);
	      str = holder.c_str ();
	    }
	  else
	    str = saved_arg;

	  self->canonical->locspec
	    = new_linespec_location_spec (&str, symbol_name_match_type::FULL);
	}
    }

  return values;
}

namespace {

/* A function object that serves as symbol_found_callback_ftype
   callback for iterate_over_symbols.  This is used by
   lookup_prefix_sym to collect type symbols.  */
class decode_compound_collector
{
public:
  decode_compound_collector () = default;

  DISABLE_COPY_AND_ASSIGN (decode_compound_collector);

  /* Return all symbols collected.  */
  std::vector<block_symbol> release_symbols ()
  {
    return std::move (m_symbols);
  }

  /* Callable as a symbol_found_callback_ftype callback.  */
  bool operator () (block_symbol *bsym);

private:
  /* A hash table of all symbols we found.  We use this to avoid
     adding any symbol more than once.  */
  gdb::unordered_set<const symbol *> m_unique_syms;

  /* The result vector.  */
  std::vector<block_symbol>  m_symbols;
};

bool
decode_compound_collector::operator () (block_symbol *bsym)
{
  struct type *t;
  struct symbol *sym = bsym->symbol;

  if (sym->loc_class () != LOC_TYPEDEF)
    return true; /* Continue iterating.  */

  t = sym->type ();
  t = check_typedef (t);
  if (t->code () != TYPE_CODE_STRUCT
      && t->code () != TYPE_CODE_UNION
      && t->code () != TYPE_CODE_NAMESPACE)
    return true; /* Continue iterating.  */

  if (m_unique_syms.insert (sym).second)
    m_symbols.push_back (*bsym);

  return true; /* Continue iterating.  */
}

} // namespace

/* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS.  */

static std::vector<block_symbol>
lookup_prefix_sym (struct linespec_state *state,
		   const std::vector<symtab *> &file_symtabs,
		   const char *class_name)
{
  decode_compound_collector collector;

  lookup_name_info lookup_name (class_name, symbol_name_match_type::FULL);

  for (const auto &elt : file_symtabs)
    {
      if (elt == nullptr)
	iterate_over_all_matching_symtabs (state, lookup_name,
					   SEARCH_STRUCT_DOMAIN | SEARCH_VFT,
					   NULL, false, collector);
      else
	{
	  /* Program spaces that are executing startup should have
	     been filtered out earlier.  */
	  program_space *pspace = elt->compunit ()->objfile ()->pspace ();

	  gdb_assert (!pspace->executing_startup);
	  set_current_program_space (pspace);
	  iterate_over_file_blocks (elt, lookup_name,
				    SEARCH_STRUCT_DOMAIN | SEARCH_VFT,
				    collector);
	}
    }

  return collector.release_symbols ();
}

/* Compare pspace A and B based on program space ID.  Return 0 if equal,
   1 if A->num > B->num, -1 otherwise (modeled on strcmp).  */

static int
compare_pspace (const struct program_space *a, const struct program_space *b)
{
  if (a->num > b->num)
    return 1;

  if (a->num < b->num)
    return -1;

  return 0;
}

/* An std::sort comparison function for pointers.  Don't use this if stable
   sorting results are required.  */

static bool
compare_pointers (void *a, void *b)
{
  return (uintptr_t)a < (uintptr_t)b;
}

/* An std::sort comparison function for symbols.  The requirement is that
   symbols with the same program space end up next to each other.  This is for
   the purpose of iterating over the symbols and doing something once for each
   program space.  */

static bool
compare_symbols (const block_symbol &a, const block_symbol &b)
{
  /* To check for same program space, we could just use a pointer comparison,
     which gives unstable sorting results.  While the assumption is that this
     doesn't matter, play it safe and compare program space IDs instead.  */
  int cmp
    = compare_pspace (a.symbol->symtab ()->compunit ()->objfile ()->pspace (),
		      b.symbol->symtab ()->compunit ()->objfile ()->pspace ());
  if (cmp == -1)
    return true;
  if (cmp == 1)
    return false;

  /* This gives unstable sorting results.  We assume that this doesn't
     matter.  */
  return compare_pointers (a.symbol, b.symbol);
}

/* Like compare_symbols but for minimal symbols.  */

static bool
compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
{
  /* See comment in compare_symbols for use of compare_pspace.  */
  int cmp = compare_pspace (a.objfile->pspace (), a.objfile->pspace ());
  if (cmp == -1)
    return true;
  if (cmp == 1)
    return false;

  /* This gives unstable sorting results.  We assume that this doesn't
     matter.  */
  return compare_pointers (a.minsym, b.minsym);
}

/* Look for all the matching instances of each symbol in NAMES.  Only
   instances from PSPACE are considered; other program spaces are
   handled by our caller.  If PSPACE is NULL, then all program spaces
   are considered.  Results are stored into INFO.  */

static void
add_all_symbol_names_from_pspace (struct collect_info *info,
				  struct program_space *pspace,
				  const std::vector<const char *> &names,
				  domain_search_flags domain_search_flags)
{
  for (const char *iter : names)
    add_matching_symbols_to_info (iter,
				  symbol_name_match_type::FULL,
				  domain_search_flags, info, pspace);
}

static void
find_superclass_methods (std::vector<struct type *> &&superclasses,
			 const char *name, enum language name_lang,
			 std::vector<const char *> *result_names)
{
  size_t old_len = result_names->size ();

  while (1)
    {
      std::vector<struct type *> new_supers;

      for (type *t : superclasses)
	find_methods (t, name_lang, name, result_names, &new_supers);

      if (result_names->size () != old_len || new_supers.empty ())
	break;

      superclasses = std::move (new_supers);
    }
}

/* This finds the method METHOD_NAME in the class CLASS_NAME whose type is
   given by one of the symbols in SYM_CLASSES.  Matches are returned
   in SYMBOLS (for debug symbols) and MINSYMS (for minimal symbols).  */

static void
find_method (struct linespec_state *self,
	     const std::vector<symtab *> &file_symtabs,
	     const char *class_name, const char *method_name,
	     std::vector<block_symbol> *sym_classes,
	     std::vector<block_symbol> *symbols,
	     std::vector<bound_minimal_symbol> *minsyms)
{
  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.  */
  std::sort (sym_classes->begin (), sym_classes->end (),
	     compare_symbols);

  info.state = self;
  info.file_symtabs = &file_symtabs;
  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
     given program space, then we consider inherited methods; this is
     not ideal (ideal would be to respect C++ hiding rules), but it
     seems good enough and is what GDB has historically done.  We only
     need to collect the names because later we find all symbols with
     those names.  This loop is written in a somewhat funny way
     because we collect data across the program space before deciding
     what to do.  */
  last_result_len = 0;
  for (const auto &elt : *sym_classes)
    {
      struct type *t;
      struct program_space *pspace;
      struct symbol *sym = elt.symbol;
      unsigned int ix = &elt - &*sym_classes->begin ();

      /* Program spaces that are executing startup should have
	 been filtered out earlier.  */
      pspace = sym->symtab ()->compunit ()->objfile ()->pspace ();
      gdb_assert (!pspace->executing_startup);
      set_current_program_space (pspace);
      t = check_typedef (sym->type ());
      find_methods (t, sym->language (),
		    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.  */
      if (ix == sym_classes->size () - 1
	  || (pspace
	      != (sym_classes->at (ix + 1).symbol->symtab ()
		  ->compunit ()->objfile ()->pspace ())))
	{
	  /* If we did not find a direct implementation anywhere in
	     this program space, consider superclasses.  */
	  if (result_names.size () == last_result_len)
	    find_superclass_methods (std::move (superclass_vec), method_name,
				     sym->language (), &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,
					    SEARCH_FUNCTION_DOMAIN);

	  superclass_vec.clear ();
	  last_result_len = result_names.size ();
	}
    }

  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.  */
  throw_error (NOT_FOUND_ERROR, _("see caller, this text doesn't matter"));
}



/* 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 std::vector<symtab *>
collect_symtabs_from_filename (const char *file,
			       struct program_space *search_pspace)
{
  /* The result vector of symtabs.  */
  std::vector<symtab *> symtabs;
  /* This is used to ensure the symtabs are unique.  */
  gdb::unordered_set<const symtab *> symtab_table;

  auto collector = [&] (struct symtab *symtab)
    {
      if (symtab_table.insert (symtab).second)
	symtabs.push_back (symtab);
      return false;
    };

  /* Find that file's data.  */
  if (search_pspace == NULL)
    {
      for (struct program_space *pspace : program_spaces)
	{
	  if (pspace->executing_startup)
	    continue;

	  iterate_over_symtabs (pspace, file, collector);
	}
    }
  else
    iterate_over_symtabs (search_pspace, file, collector);

  /* It is tempting to use the unordered_dense 'extract' method here,
     and remove the separate vector -- but it's unclear if ordering
     matters.  */
  return symtabs;
}

/* Return all the symtabs associated to the FILENAME.  If SEARCH_PSPACE is
   not NULL, the search is restricted to just that program space.  */

static std::vector<symtab *>
symtabs_from_filename (const char *filename,
		       struct program_space *search_pspace)
{
  std::vector<symtab *> result
    = collect_symtabs_from_filename (filename, search_pspace);

  if (result.empty ())
    {
      if (!have_full_symbols (current_program_space)
	  && !have_partial_symbols (current_program_space))
	throw_error (NOT_FOUND_ERROR,
		     _("No symbol table is loaded.  "
		       "Use the \"file\" command."));
      source_file_not_found_error (filename);
    }

  return result;
}

/* See symtab.h.  */

void
symbol_searcher::find_all_symbols (const std::string &name,
				   const struct language_defn *language,
				   domain_search_flags domain_search_flags,
				   std::vector<symtab *> *search_symtabs,
				   struct program_space *search_pspace)
{
  symbol_searcher_collect_info info;
  linespec_state state (language, current_program_space);

  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,
				domain_search_flags, &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,
		       const std::vector<symtab *> &file_symtabs, const char *name,
		       symbol_name_match_type name_match_type,
		       std::vector<block_symbol> *symbols,
		       std::vector<bound_minimal_symbol> *minsyms)
{
  struct collect_info info;
  std::vector<const char *> symbol_names;

  info.state = state;
  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);

  domain_search_flags flags = SEARCH_FUNCTION_DOMAIN;
  if (state->list_mode)
    flags = SEARCH_VFT;

  if (!symbol_names.empty ())
    add_all_symbol_names_from_pspace (&info, state->search_pspace,
				      symbol_names, flags);
  else
    add_matching_symbols_to_info (name, name_match_type, flags,
				  &info, state->search_pspace);
}

/* Find all symbols named NAME in FILE_SYMTABS, returning debug symbols
   in SYMBOLS and minimal symbols in MINSYMS.  */

static void
find_linespec_symbols (struct linespec_state *state,
		       const std::vector<symtab *> &file_symtabs,
		       const char *lookup_name,
		       symbol_name_match_type name_match_type,
		       std::vector <block_symbol> *symbols,
		       std::vector<bound_minimal_symbol> *minsyms)
{
  gdb::unique_xmalloc_ptr<char> canon
    = cp_canonicalize_string_no_typedefs (lookup_name);
  if (canon != nullptr)
    lookup_name = canon.get ();

  /* It's important to not call search unnecessarily
     as it can really slow things down (by unnecessarily expanding
     potentially 1000s of symtabs, which when debugging some apps can
     cost 100s of seconds).  Avoid this to some extent by *first* calling
     find_function_symbols, and only if that doesn't find anything
     *then* call find_method.  This handles two important cases:
     1) break (anonymous namespace)::foo
     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
     the name into class and method names and searching the class and its
     baseclasses.  */
  if (symbols->empty () && minsyms->empty ())
    {
      std::string klass, method;
      const char *last, *p, *scope_op;

      /* See if we can find a scope operator and break this symbol
	 name into namespaces${SCOPE_OPERATOR}class_name and method_name.  */
      scope_op = "::";
      p = find_toplevel_string (lookup_name, scope_op);

      last = NULL;
      while (p != NULL)
	{
	  last = p;
	  p = find_toplevel_string (p + strlen (scope_op), scope_op);
	}

      /* If no scope operator was found, there is nothing more we can do;
	 we already attempted to lookup the entire name as a symbol
	 and failed.  */
      if (last == NULL)
	return;

      /* LOOKUP_NAME points to the class name.
	 LAST points to the method name.  */
      klass = std::string (lookup_name, last - lookup_name);

      /* Skip past the scope operator.  */
      last += strlen (scope_op);
      method = last;

      /* Find a list of classes named KLASS.  */
      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);
	    }

	  /* If successful, we're done.  If NOT_FOUND_ERROR
	     was not thrown, rethrow the exception that we did get.  */
	  catch (const gdb_exception_error &except)
	    {
	      if (except.error != NOT_FOUND_ERROR)
		throw;
	    }
	}
    }
}

/* Helper for find_label_symbols.  Find all labels that match name
   NAME in BLOCK.  Return all labels that match in FUNCTION_SYMBOLS.
   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 a label named
   exactly NAME match.  */

static void
find_label_symbols_in_block (const struct block *block,
			     const char *name, struct symbol *fn_sym,
			     bool completion_mode,
			     std::vector<block_symbol> *result,
			     std::vector<block_symbol> *label_funcs_ret)
{
  if (completion_mode)
    {
      size_t name_len = strlen (name);

      int (*cmp) (const char *, const char *, size_t);
      cmp = case_sensitivity == case_sensitive_on ? strncmp : strncasecmp;

      for (struct symbol *sym : block_iterator_range (block))
	{
	  if (sym->domain () == LABEL_DOMAIN
	      && cmp (sym->search_name (), name, name_len) == 0)
	    {
	      result->push_back ({sym, block});
	      label_funcs_ret->push_back ({fn_sym, block});
	    }
	}
    }
  else
    {
      struct block_symbol label_sym
	= lookup_symbol (name, block, SEARCH_LABEL_DOMAIN, 0);

      if (label_sym.symbol != NULL)
	{
	  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
   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 std::vector<block_symbol>
find_label_symbols (struct linespec_state *self,
		    const std::vector<block_symbol> &function_symbols,
		    std::vector<block_symbol> *label_funcs_ret,
		    const char *name,
		    bool completion_mode)
{
  const struct block *block;
  struct symbol *fn_sym;
  std::vector<block_symbol> result;

  if (function_symbols.empty ())
    {
      set_current_program_space (self->program_space);
      block = get_current_search_block ();

      for (;
	   block && !block->function ();
	   block = block->superblock ())
	;

      if (!block)
	return {};

      fn_sym = block->function ();

      find_label_symbols_in_block (block, name, fn_sym, completion_mode,
				   &result, label_funcs_ret);
    }
  else
    {
      for (const auto &elt : function_symbols)
	{
	  fn_sym = elt.symbol;
	  set_current_program_space
	    (fn_sym->symtab ()->compunit ()->objfile ()->pspace ());
	  block = fn_sym->value_block ();

	  find_label_symbols_in_block (block, name, fn_sym, completion_mode,
				       &result, label_funcs_ret);
	}
    }

  return result;
}



/* A helper for create_sals_line_offset that handles the 'list_mode' case.  */

static std::vector<symtab_and_line>
decode_digits_list_mode (linespec_state *self, linespec *ls, int line)
{
  gdb_assert (self->list_mode);

  std::vector<symtab_and_line> values;

  for (const auto &elt : ls->file_symtabs)
    {
      /* The logic above should ensure this.  */
      gdb_assert (elt != NULL);

      program_space *pspace = elt->compunit ()->objfile ()->pspace ();
      set_current_program_space (pspace);

      /* Simplistic search just for the list command.  */
      symtab_and_line val;
      val.line = line;
      val.symtab = find_line_symtab (elt, line, nullptr);
      if (val.symtab == NULL)
	val.symtab = elt;
      val.pspace = pspace;
      val.pc = 0;
      val.explicit_line = true;

      add_sal_to_sals (self, values, val, NULL, false);
    }

  return values;
}

/* A helper for create_sals_line_offset that iterates over the symtabs
   associated with LS and returns a vector of corresponding symtab_and_line
   structures.  */

static std::vector<symtab_and_line>
decode_digits_ordinary (struct linespec_state *self,
			linespec *ls,
			int line,
			const linetable_entry **best_entry)
{
  std::vector<symtab_and_line> sals;
  for (const auto &elt : ls->file_symtabs)
    {
      std::vector<const linetable_entry *> pcs;

      /* The logic above should ensure this.  */
      gdb_assert (elt != NULL);

      objfile *objfile = elt->compunit ()->objfile ();
      program_space *pspace = objfile->pspace ();
      set_current_program_space (pspace);

      pcs = find_linetable_entries_for_symtab_line (elt, line, best_entry);
      for (auto linetable_entry : pcs)
	{
	  symtab_and_line sal;
	  sal.pspace = pspace;
	  sal.symtab = elt;
	  sal.line = line;
	  sal.explicit_line = true;
	  sal.pc = linetable_entry->pc (objfile);
	  sals.push_back (std::move (sal));
	}
    }

  return sals;
}



/* Return the line offset represented by VARIABLE.  */

static struct line_offset
linespec_parse_variable (struct linespec_state *self, const char *variable)
{
  int index = 0;
  const char *p;
  line_offset offset;

  p = (variable[1] == '$') ? variable + 2 : variable + 1;
  if (*p == '$')
    ++p;
  while (*p >= '0' && *p <= '9')
    ++p;
  if (!*p)		/* Reached end of token without hitting non-digit.  */
    {
      /* We have a value history reference.  */
      struct value *val_history;

      sscanf ((variable[1] == '$') ? variable + 2 : variable + 1, "%d", &index);
      val_history
	= access_value_history ((variable[1] == '$') ? -index : index);
      if (val_history->type ()->code () != TYPE_CODE_INT)
	error (_("History values used in line "
		 "specs must have integer values."));
      offset.offset = value_as_long (val_history);
      offset.sign = LINE_OFFSET_NONE;
    }
  else
    {
      /* Not all digits -- may be user variable/function or a
	 convenience variable.  */
      LONGEST valx;
      struct internalvar *ivar;

      /* Try it as a convenience variable.  If it is not a convenience
	 variable, return and allow normal symbol lookup to occur.  */
      ivar = lookup_only_internalvar (variable + 1);
	/* If there's no internal variable with that name, let the
	   offset remain as unknown to allow the name to be looked up
	   as a symbol.  */
      if (ivar != nullptr)
	{
	  /* We found a valid variable name.  If it is not an integer,
	     throw an error.  */
	  if (!get_internalvar_integer (ivar, &valx))
	    error (_("Convenience variables used in line "
		     "specs must have integer values."));
	  else
	    {
	      offset.offset = valx;
	      offset.sign = LINE_OFFSET_NONE;
	    }
	}
    }

  return offset;
}


/* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
   linespec; return the SAL in RESULT.  This function should return SALs
   matching those from find_function_start_sal, otherwise false
   multiple-locations breakpoints could be placed.  */

static void
minsym_found (struct linespec_state *self, struct objfile *objfile,
	      struct minimal_symbol *msymbol,
	      std::vector<symtab_and_line> &result)
{
  bool want_start_sal = false;

  CORE_ADDR func_addr;
  bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
  obj_section *section = msymbol->obj_section (objfile);

  if (is_function)
    {
      const char *msym_name = msymbol->linkage_name ();

      if (msymbol->type () == mst_text_gnu_ifunc
	  || msymbol->type () == mst_data_gnu_ifunc)
	{
	  want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);

	  /* We have found a different pc by resolving the ifunc. The
	     section from the minsym may not be the same as the ifunc
	     implementation.  Do not trust it.  */
	  if (want_start_sal)
	    section = nullptr;
	}
      else
	want_start_sal = true;
    }

  symtab_and_line sal;

  if (is_function && want_start_sal)
    sal = find_function_start_sal (func_addr, section, self->funfirstline);
  else
    {
      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
	sal.pc = msymbol->value_address (objfile);
      sal.pspace = current_program_space;

      /* The minsym does not correspond to an ifunc that could be
	 resolved.  The section from the minsym may thus be trusted,
	 and cannot be nullptr (since the minsym is from an objfile).
	 Ensure all resulting sals have a non-null section when
	 possible.  */
      gdb_assert (section != nullptr);
      sal.section = section;
    }

  if (self->maybe_add_address (objfile->pspace (), sal.pc))
    add_sal_to_sals (self, result, sal, msymbol->natural_name (), false);
}

/* Helper for search_minsyms_for_name that adds the symbol to the
   result.  */

static void
add_minsym (struct minimal_symbol *minsym, struct objfile *objfile,
	    struct symtab *symtab, bool list_mode,
	    std::vector<bound_minimal_symbol> *msyms)
{
  if (symtab != NULL)
    {
      /* 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_sal_for_pc_sect (func_addr, NULL, 0);

	  if (symtab != sal.symtab)
	    return;
	}
    }

  /* Exclude data symbols when looking for breakpoint locations.  */
  if (list_mode || msymbol_is_function (objfile, minsym))
    msyms->emplace_back (minsym, objfile);
}

/* Search for minimal symbols called NAME.  If SEARCH_PSPACE
   is not NULL, the search is restricted to just that program
   space.

   If SYMTAB is NULL, search all objfiles, otherwise
   restrict results to the given SYMTAB.  */

static void
search_minsyms_for_name (struct collect_info *info,
			 const lookup_name_info &name,
			 struct program_space *search_pspace,
			 struct symtab *symtab)
{
  std::vector<bound_minimal_symbol> minsyms;

  if (symtab == NULL)
    {
      for (struct program_space *pspace : program_spaces)
	{
	  if (search_pspace != NULL && search_pspace != pspace)
	    continue;
	  if (pspace->executing_startup)
	    continue;

	  set_current_program_space (pspace);

	  for (objfile &objfile : pspace->objfiles ())
	    {
	      iterate_over_minimal_symbols (&objfile, name,
					    [&] (struct minimal_symbol *msym)
					    {
					      add_minsym (msym, &objfile, nullptr,
							  info->state->list_mode,
							  &minsyms);
					      return false;
					    });
	    }
	}
    }
  else
    {
      program_space *pspace = symtab->compunit ()->objfile ()->pspace ();

      if (search_pspace == NULL || pspace == search_pspace)
	{
	  set_current_program_space (pspace);
	  iterate_over_minimal_symbols
	    (symtab->compunit ()->objfile (), name,
	     [&] (struct minimal_symbol *msym)
	       {
		 add_minsym (msym, symtab->compunit ()->objfile (), symtab,
			     info->state->list_mode, &minsyms);
		 return false;
	       });
	}
    }

  /* Return true if TYPE is a static symbol.  */
  auto msymbol_type_is_static = [] (enum minimal_symbol_type type)
    {
      switch (type)
	{
	case mst_file_text:
	case mst_file_data:
	case mst_file_bss:
	return true;
	default:
	return false;
	}
    };

  /* Add minsyms to the result set, but filter out trampoline symbols
     if we also found extern symbols with the same name.  I.e., don't
     set a breakpoint on both '<foo@plt>' and 'foo', assuming that
     'foo' is the symbol that the plt resolves to.  */
  for (const bound_minimal_symbol &item : minsyms)
    {
      bool skip = false;
      if (item.minsym->type () == mst_solib_trampoline)
	{
	  for (const bound_minimal_symbol &item2 : minsyms)
	    {
	      if (&item2 == &item)
		continue;

	      /* Ignore other trampoline symbols.  */
	      if (item2.minsym->type () == mst_solib_trampoline)
		continue;

	      /* Trampoline symbols can only jump to exported
		 symbols.  */
	      if (msymbol_type_is_static (item2.minsym->type ()))
		continue;

	      if (strcmp (item.minsym->linkage_name (),
			  item2.minsym->linkage_name ()) != 0)
		continue;

	      /* Found a global minsym with the same name as the
		 trampoline.  Don't create a location for this
		 trampoline.  */
	      skip = true;
	      break;
	    }
	}

      if (!skip)
	info->result.minimal_symbols->push_back (item);
    }
}

/* A helper function to add all symbols matching NAME to INFO.  If
   PSPACE is not NULL, the search is restricted to just that program
   space.  */

static void
add_matching_symbols_to_info (const char *name,
			      symbol_name_match_type name_match_type,
			      domain_search_flags domain_search_flags,
			      struct collect_info *info,
			      struct program_space *pspace)
{
  lookup_name_info lookup_name (name, name_match_type);

  auto add_symbol = [&] (block_symbol *bsym)
    {
      return info->add_symbol (bsym);
    };

  for (const auto &elt : *info->file_symtabs)
    {
      if (elt == nullptr)
	{
	  iterate_over_all_matching_symtabs (info->state, lookup_name,
					     domain_search_flags,
					     pspace, true,
					     add_symbol);
	  search_minsyms_for_name (info, lookup_name, pspace, NULL);
	}
      else if (pspace == NULL || pspace == elt->compunit ()->objfile ()->pspace ())
	{
	  int prev_len = info->result.symbols->size ();

	  /* Program spaces that are executing startup should have
	     been filtered out earlier.  */
	  program_space *elt_pspace = elt->compunit ()->objfile ()->pspace ();
	  gdb_assert (!elt_pspace->executing_startup);
	  set_current_program_space (elt_pspace);
	  iterate_over_file_blocks (elt, lookup_name, SEARCH_VFT, add_symbol);

	  /* 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 == info->result.symbols->size ()
	      && elt->language () == language_asm)
	    search_minsyms_for_name (info, lookup_name, pspace, elt);
	}
    }
}



/* Now come some functions that are called from multiple places within
   decode_line_1.  */

static std::optional<symtab_and_line>
symbol_to_sal (bool funfirstline, symbol *sym)
{
  if (sym->loc_class () == LOC_BLOCK)
    return find_function_start_sal (sym, funfirstline);
  else
    {
      if (sym->loc_class () == LOC_LABEL && sym->value_address () != 0)
	{
	  symtab_and_line result;
	  result.symtab = sym->symtab ();
	  result.symbol = sym;
	  result.line = sym->line ();
	  result.pc = sym->value_address ();
	  result.pspace = result.symtab->compunit ()->objfile ()->pspace ();
	  result.explicit_pc = 1;
	  return result;
	}
      else if (funfirstline)
	{
	  /* Nothing.  */
	}
      else if (sym->line () != 0)
	{
	  /* We know its line number.  */
	  symtab_and_line result;
	  result.symtab = sym->symtab ();
	  result.symbol = sym;
	  result.line = sym->line ();
	  result.pc = sym->value_address ();
	  result.pspace = result.symtab->compunit ()->objfile ()->pspace ();
	  return result;
	}
    }

  return std::nullopt;
}

linespec_result::~linespec_result ()
{
  for (linespec_sals &lsal : lsals)
    xfree (lsal.canonical);
}

/* Return the quote characters permitted by the linespec parser.  */

const char *
get_gdb_linespec_parser_quote_characters (void)
{
  return linespec_quote_characters;
}
