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

   Copyright (C) 1986-2022 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 "defs.h"
#include "symtab.h"
#include "frame.h"
#include "command.h"
#include "symfile.h"
#include "objfiles.h"
#include "source.h"
#include "demangle.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 "mi/mi-cmds.h"
#include "target.h"
#include "arch-utils.h"
#include <ctype.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"

/* 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,
};

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

struct address_entry
{
  struct program_space *pspace;
  CORE_ADDR addr;
};

/* 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 describing the SaLs.  */
  struct explicit_location 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.  */
  char *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
{
  /* 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.  */
  int funfirstline;

  /* Nonzero if we are running in 'list' mode; see decode_line_list.  */
  int 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.  */
  struct linespec_canonical_name *canonical_names;

  /* This is a set of address_entry objects which is used to prevent
     duplicate symbols from being entered into the result.  */
  htab_t addr_set;

  /* Are we building a linespec?  */
  int is_linespec;
};

/* 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->aclass () == LOC_BLOCK || this->state->list_mode)
    this->result.symbols->push_back (*bsym);

  /* Continue iterating.  */
  return true;
}

/* Custom collect_info for symbol_searcher.  */

struct symbol_searcher_collect_info
  : collect_info
{
  bool add_symbol (block_symbol *bsym) override
  {
    /* Add everything.  */
    this->result.symbols->push_back (*bsym);

    /* Continue iterating.  */
    return true;
  }
};

/* Token types  */

enum ls_token_type
{
  /* 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
};
typedef enum ls_token_type linespec_token_type;

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

/* 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;
};

#define LS_TOKEN_STOKEN(TOK) (TOK).data.string
#define LS_TOKEN_KEYWORD(TOK) (TOK).data.keyword

/* 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);

  ~linespec_parser ();

  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;
#define PARSER_STREAM(P) ((P)->lexer.stream)

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

  /* Is the entire linespec quote-enclosed?  */
  int is_quote_enclosed = 0;

  /* The state of the parse.  */
  struct linespec_state state {};
#define PARSER_STATE(PPTR) (&(PPTR)->state)

  /* The result of the parse.  */
  linespec result;
#define PARSER_RESULT(PPTR) (&(PPTR)->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;
};

/* A convenience macro for accessing the explicit location result of
   the parser.  */
#define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc)

/* Prototypes for local functions.  */

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

static void initialize_defaults (struct symtab **default_symtab,
				 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 int symbol_to_sal (struct symtab_and_line *result,
			  int funfirstline, struct symbol *sym);

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

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

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,
   linetable_entry **best_entry);

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

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;
  LS_TOKEN_STOKEN (*tokenp).length = 0;
  LS_TOKEN_STOKEN (*tokenp).ptr = PARSER_STREAM (parser);

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

  while (isdigit (*PARSER_STREAM (parser)))
    {
      ++LS_TOKEN_STOKEN (*tokenp).length;
      ++(PARSER_STREAM (parser));
    }

  /* 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_STREAM (parser) != '\0'
      && !isspace (*PARSER_STREAM (parser)) && *PARSER_STREAM (parser) != ','
      && *PARSER_STREAM (parser) != ':'
      && !strchr (linespec_quote_characters, *PARSER_STREAM (parser)))
    {
      PARSER_STREAM (parser) = LS_TOKEN_STOKEN (*tokenp).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 (!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
			  && 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
			  && 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 (LS_TOKEN_KEYWORD (token));

  str = LS_TOKEN_STOKEN (token).ptr;
  s = remove_trailing_whitespace (str, str + LS_TOKEN_STOKEN (token).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_STREAM (parser);

  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_STREAM (parser)))
    {
      const char *end;
      char quote_char = *PARSER_STREAM (parser);

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

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

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

      /* Skip past the beginning quote.  */
      ++(PARSER_STREAM (parser));

      /* Mark the start of the string.  */
      LS_TOKEN_STOKEN (token).ptr = PARSER_STREAM (parser);

      /* Skip to the ending quote.  */
      end = skip_quote_char (PARSER_STREAM (parser), 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_STREAM (parser) != '\0')
	    PARSER_STREAM (parser)++;
	  LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 1 - start;
	}
      else
	{
	  /* Skip over the ending quote and mark the length of the string.  */
	  PARSER_STREAM (parser) = (char *) ++end;
	  LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 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 (isspace (*PARSER_STREAM (parser)))
	    {
	      p = skip_spaces (PARSER_STREAM (parser));
	      /* When we get here we know we've found something followed by
		 a space (we skip over parens and templates below).
		 So if we find a keyword now, we know it is a keyword and not,
		 say, a function name.  */
	      if (linespec_lexer_lex_keyword (p) != NULL)
		{
		  LS_TOKEN_STOKEN (token).ptr = start;
		  LS_TOKEN_STOKEN (token).length
		    = PARSER_STREAM (parser) - start;
		  return token;
		}

	      /* Advance past the whitespace.  */
	      PARSER_STREAM (parser) = p;
	    }

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

	      /* Do not tokenize ABI tags such as "[abi:cxx11]".  */
	      else if (PARSER_STREAM (parser) - start > 4
		       && startswith (PARSER_STREAM (parser) - 4, "[abi"))
		{
		  /* 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_STREAM (parser) - start) != 1
		       || !IS_DIR_SEPARATOR (PARSER_STREAM (parser)[1]))
		{
		  LS_TOKEN_STOKEN (token).ptr = start;
		  LS_TOKEN_STOKEN (token).length
		    = PARSER_STREAM (parser) - start;
		  return token;
		}
	    }
	  /* Special case: permit quote-enclosed linespecs.  */
	  else if (parser->is_quote_enclosed
		   && strchr (linespec_quote_characters,
			      *PARSER_STREAM (parser))
		   && is_closing_quote_enclosed (PARSER_STREAM (parser)))
	    {
	      LS_TOKEN_STOKEN (token).ptr = start;
	      LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 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_STREAM (parser) == '<'
		   || *PARSER_STREAM (parser) == '(')
	    {
	      /* Don't interpret 'operator<' / 'operator<<' as a
		 template parameter list though.  */
	      if (*PARSER_STREAM (parser) == '<'
		  && (PARSER_STATE (parser)->language->la_language
		      == language_cplus)
		  && (PARSER_STREAM (parser) - start) >= CP_OPERATOR_LEN)
		{
		  const char *op = PARSER_STREAM (parser);

		  while (op > start && 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
			      || !(isalnum (op[-1]) || op[-1] == '_')))
			{
			  /* This is an operator name.  Keep going.  */
			  ++(PARSER_STREAM (parser));
			  if (*PARSER_STREAM (parser) == '<')
			    ++(PARSER_STREAM (parser));
			  continue;
			}
		    }
		}

	      const char *end = find_parameter_list_end (PARSER_STREAM (parser));
	      PARSER_STREAM (parser) = 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')
		{
		  LS_TOKEN_STOKEN (token).ptr = start;
		  LS_TOKEN_STOKEN (token).length
		    = PARSER_STREAM (parser) - start;
		  return token;
		}
	      else
		continue;
	    }
	  /* Commas are terminators, but not if they are part of an
	     operator name.  */
	  else if (*PARSER_STREAM (parser) == ',')
	    {
	      if ((PARSER_STATE (parser)->language->la_language
		   == language_cplus)
		  && (PARSER_STREAM (parser) - 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_STREAM (parser));
		      continue;
		    }
		}

	      /* Comma terminates the string.  */
	      LS_TOKEN_STOKEN (token).ptr = start;
	      LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - start;
	      return token;
	    }

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

  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_STREAM (parser) = skip_spaces (PARSER_STREAM (parser));

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

	     PARSER_STREAM (parser) +=  strlen (keyword);  */

	  return parser->lexer.current;
	}

      /* Handle other tokens.  */
      switch (*PARSER_STREAM (parser))
	{
	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_STREAM (parser)[1] == ':')
	    parser->lexer.current = linespec_lexer_lex_string (parser);
	  else
	    {
	      parser->lexer.current.type = LSTOKEN_COLON;
	      ++(PARSER_STREAM (parser));
	    }
	  break;

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

	case ',':
	  parser->lexer.current.type = LSTOKEN_COMMA;
	  LS_TOKEN_STOKEN (parser->lexer.current).ptr
	    = PARSER_STREAM (parser);
	  LS_TOKEN_STOKEN (parser->lexer.current).length = 1;
	  ++(PARSER_STREAM (parser));
	  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_STREAM (parser) != '\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_STREAM (parser) != '\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 = LS_TOKEN_STOKEN (parser->lexer.current).ptr;
    }
  else if (advance_word)
    {
      /* Advance the completion word past any whitespace.  */
      parser->completion_word = PARSER_STREAM (parser);
    }

  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_STREAM (parser);
  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_STREAM (parser) = 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 non-zero, 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,
		 struct symtab_and_line *sal,
		 const char *symname, int literal_canonical)
{
  sals->push_back (*sal);

  if (self->canonical)
    {
      struct linespec_canonical_name *canonical;

      self->canonical_names = XRESIZEVEC (struct linespec_canonical_name,
					  self->canonical_names,
					  sals->size ());
      canonical = &self->canonical_names[sals->size () - 1];
      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 = xstrprintf ("%s:%d", symname,
					    sal->line).release ();
	  else if (symname != NULL)
	    canonical->suffix = xstrdup (symname);
	  else
	    canonical->suffix = xstrprintf ("%d", sal->line).release ();
	  canonical->symtab = sal->symtab;
	}
      else
	{
	  if (symname != NULL)
	    canonical->suffix = xstrdup (symname);
	  else
	    canonical->suffix = xstrdup ("<unknown>");
	  canonical->symtab = NULL;
	}
    }
}

/* A hash function for address_entry.  */

static hashval_t
hash_address_entry (const void *p)
{
  const struct address_entry *aep = (const struct address_entry *) p;
  hashval_t hash;

  hash = iterative_hash_object (aep->pspace, 0);
  return iterative_hash_object (aep->addr, hash);
}

/* An equality function for address_entry.  */

static int
eq_address_entry (const void *a, const void *b)
{
  const struct address_entry *aea = (const struct address_entry *) a;
  const struct address_entry *aeb = (const struct address_entry *) b;

  return aea->pspace == aeb->pspace && aea->addr == aeb->addr;
}

/* Check whether the address, represented by PSPACE and ADDR, is
   already in the set.  If so, return 0.  Otherwise, add it and return
   1.  */

static int
maybe_add_address (htab_t set, struct program_space *pspace, CORE_ADDR addr)
{
  struct address_entry e, *p;
  void **slot;

  e.pspace = pspace;
  e.addr = addr;
  slot = htab_find_slot (set, &e, INSERT);
  if (*slot)
    return 0;

  p = XNEW (struct address_entry);
  memcpy (p, &e, sizeof (struct address_entry));
  *slot = p;

  return 1;
}

/* 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_enum name_domain,
   enum search_domain search_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 : current_program_space->objfiles ())
	{
	  objfile->expand_symtabs_matching (NULL, &lookup_name, NULL, NULL,
					    (SEARCH_GLOBAL_BLOCK
					     | SEARCH_STATIC_BLOCK),
					    UNDEF_DOMAIN,
					    search_domain);

	  for (compunit_symtab *cu : objfile->compunits ())
	    {
	      struct symtab *symtab = cu->primary_filetab ();

	      iterate_over_file_blocks (symtab, lookup_name, name_domain,
					callback);

	      if (include_inline)
		{
		  const struct block *block;
		  int i;

		  for (i = FIRST_LOCAL_BLOCK;
		       i < BLOCKVECTOR_NBLOCKS (symtab->blockvector ());
		       i++)
		    {
		      block = BLOCKVECTOR_BLOCK (symtab->blockvector (), i);
		      state->language->iterate_over_symbols
			(block, lookup_name, 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;
			 });
		    }
		}
	    }
	}
    }
}

/* 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_enum domain, gdb::function_view<symbol_found_callback_ftype> callback)
{
  const struct block *block;

  for (block = BLOCKVECTOR_BLOCK (symtab->blockvector (), STATIC_BLOCK);
       block != NULL;
       block = BLOCK_SUPERBLOCK (block))
    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);
}

/* 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_)
  {
  }

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

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

  /* Field is initialized to zero and it is set to one if the user
     requested breakpoint for this entry.  */
  unsigned int selected : 1;
};

/* Helper for std::sort to sort decode_line_2_item entries by
   DISPLAYFORM and secondarily by FULLFORM.  */

static bool
decode_line_2_compare_items (const decode_line_2_item &a,
			     const decode_line_2_item &b)
{
  if (a.displayform != b.displayform)
    return a.displayform < b.displayform;
  return a.fullform < b.fullform;
}

/* Handle multiple results in RESULT depending on SELECT_MODE.  This
   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];
      gdb_assert (canonical->suffix != NULL);

      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);
	}

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

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

  /* 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 = "> ";
    }
  args = command_line_input (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 = 1;
	    }
	  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).  */

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

  if (!have_full_symbols ()
      && !have_partial_symbols ()
      && !have_minimal_symbols ())
    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.  */

static void ATTRIBUTE_NORETURN
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.  */

static void ATTRIBUTE_NORETURN
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.  */

static void ATTRIBUTE_NORETURN
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_STREAM (parser);
  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 = {0, LINE_OFFSET_NONE};

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

  if (*string != '\0' && !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_STREAM (parser) == ' ')
    {
      parser->completion_word = skip_spaces (PARSER_STREAM (parser) + 1);
      parser->complete_what = next;
    }
  else
    {
      parser->completion_word = PARSER_STREAM (parser);
      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_EXPLICIT (parser)->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_STREAM (parser), ":") == 0)
	{
	  completion_tracker tmp_tracker;
	  const char *source_filename
	    = PARSER_EXPLICIT (parser)->source_filename;
	  symbol_name_match_type match_type
	    = PARSER_EXPLICIT (parser)->func_name_match_type;

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

	  if (tmp_tracker.have_completions ())
	    {
	      PARSER_STREAM (parser)++;
	      LS_TOKEN_STOKEN (token).length++;

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

      PARSER_EXPLICIT (parser)->function_name = name.release ();
    }
  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),
			     PARSER_RESULT (parser)->file_symtabs, name.get (),
			     PARSER_EXPLICIT (parser)->func_name_match_type,
			     &symbols, &minimal_symbols);

      if (!symbols.empty () || !minimal_symbols.empty ())
	{
	  PARSER_RESULT (parser)->function_symbols = std::move (symbols);
	  PARSER_RESULT (parser)->minimal_symbols = std::move (minimal_symbols);
	  PARSER_EXPLICIT (parser)->function_name = name.release ();
	}
      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 (parser), {}, &symbols,
				  name.get ());

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

	      if (PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN)
		{
		  /* The user-specified variable was not valid.  Do not
		     throw an error here.  parse_linespec will do it for us.  */
		  PARSER_EXPLICIT (parser)->function_name = name.release ();
		  return;
		}
	    }
	  else
	    {
	      /* The name is also not a label.  Abort parsing.  Do not throw
		 an error here.  parse_linespec will do it for us.  */

	      /* Save a copy of the name we were trying to lookup.  */
	      PARSER_EXPLICIT (parser)->function_name = name.release ();
	      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_EXPLICIT (parser)->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 = LS_TOKEN_STOKEN (token).ptr;
	      for (size_t i = 0; i < LS_TOKEN_STOKEN (token).length; i++)
		{
		  if (ptr[i] == ' ')
		    {
		      LS_TOKEN_STOKEN (token).length = i;
		      PARSER_STREAM (parser) = skip_spaces (ptr + i + 1);
		      break;
		    }
		}
	    }

	  if (parser->completion_tracker != NULL)
	    {
	      if (PARSER_STREAM (parser)[-1] == ' ')
		{
		  parser->completion_word = PARSER_STREAM (parser);
		  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),
				      PARSER_RESULT (parser)->function_symbols,
				      &symbols, name.get ());

	      if (!labels.empty ())
		{
		  PARSER_RESULT (parser)->labels.label_symbols
		    = std::move (labels);
		  PARSER_RESULT (parser)->labels.function_symbols
		    = std::move (symbols);
		  PARSER_EXPLICIT (parser)->label_name = name.release ();
		}
	      else
		{
		  /* We don't know what it was, but it isn't a label.  */
		  undefined_label_error
		    (PARSER_EXPLICIT (parser)->function_name, 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_EXPLICIT (parser)->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)
{
  struct event_location *canon;
  struct explicit_location *explicit_loc;

  /* If canonicalization was not requested, no need to do anything.  */
  if (!state->canonical)
    return;

  /* Save everything as an explicit location.  */
  state->canonical->location
    = new_explicit_location (&ls->explicit_loc);
  canon = state->canonical->location.get ();
  explicit_loc = get_explicit_location (canon);

  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 = 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)
    set_event_location_string (canon,
			       explicit_location_to_linespec (explicit_loc));
}

/* 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)
{
  int use_default = 0;

  /* This is where we need to make sure we have good defaults.
     We must guarantee that this section of code is never executed
     when we are called with just a function name, since
     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 = 1;
    }

  symtab_and_line val;
  val.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)
	val.line = 5;
      if (use_default)
	val.line = self->default_line + val.line;
      break;

    case LINE_OFFSET_MINUS:
      if (ls->explicit_loc.line_offset.offset == 0)
	val.line = 15;
      if (use_default)
	val.line = self->default_line - val.line;
      else
	val.line = -val.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, val);
  else
    {
      struct linetable_entry *best_entry = NULL;
      int i, j;

      std::vector<symtab_and_line> intermediate_results
	= decode_digits_ordinary (self, ls, val.line, &best_entry);
      if (intermediate_results.empty () && best_entry != NULL)
	intermediate_results = decode_digits_ordinary (self, ls,
						       best_entry->line,
						       &best_entry);

      /* For optimized code, the compiler can scatter one source line
	 across disjoint ranges of PC values, even when no duplicate
	 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]
				  ? block_containing_function (blocks[i])
				  : NULL);

	    if (self->funfirstline)
	      skip_prologue_sal (&intermediate_results[i]);
	    intermediate_results[i].symbol = sym;
	    add_sal_to_sals (self, &values, &intermediate_results[i],
			     sym ? sym->natural_name () : NULL, 0);
	  }
    }

  if (values.empty ())
    {
      if (ls->explicit_loc.source_filename)
	throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
		     val.line, ls->explicit_loc.source_filename);
      else
	throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."),
		     val.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_pc_line (address, 0);
  sal.pc = address;
  sal.section = find_pc_overlay (address);
  sal.explicit_pc = 1;
  sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section);

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

  return sals;
}

/* 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.  */
      struct symtab_and_line sal;

      for (const auto &sym : ls->labels.label_symbols)
	{
	  struct program_space *pspace
	    = symbol_symtab (sym.symbol)->pspace ();

	  if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
	      && maybe_add_address (state->addr_set, pspace, sal.pc))
	    add_sal_to_sals (state, &sals, &sal,
			     sym.symbol->natural_name (), 0);
	}
    }
  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
		= symbol_symtab (sym.symbol)->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->aclass () == LOC_BLOCK)
		{
		  const CORE_ADDR addr
		    = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol));

		  for (const auto &elem : ls->minimal_symbols)
		    {
		      if (MSYMBOL_TYPE (elem.minsym) == mst_text_gnu_ifunc
			  || MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
			{
			  CORE_ADDR msym_addr = BMSYMBOL_VALUE_ADDRESS (elem);
			  if (MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
			    {
			      struct gdbarch *gdbarch
				= 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)
		{
		  symtab_and_line sal;
		  if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
		      && maybe_add_address (state->addr_set, pspace, sal.pc))
		    add_sal_to_sals (state, &sals, &sal,
				     sym.symbol->natural_name (), 0);
		}
	    }
	}

      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 *fullname = symtab_to_fullname (state->default_symtab);

	    /* 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 = xstrdup (fullname);
	  }
    }
  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 components SOURCE_FILENAME,
   FUNCTION_NAME, LABEL_NAME and LINE_OFFSET.  */

static void
convert_explicit_location_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 = 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);

      result->explicit_loc.function_name = 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,
			       label_name);

      result->explicit_loc.label_name = 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_to_sals (struct linespec_state *self,
				   linespec *result,
				   const struct explicit_location *explicit_loc)
{
  convert_explicit_location_to_linespec (self, result,
					 explicit_loc->source_filename,
					 explicit_loc->function_name,
					 explicit_loc->func_name_match_type,
					 explicit_loc->label_name,
					 explicit_loc->line_offset);
  return convert_linespec_to_sals (self, result);
}

/* 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 = 0;
  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 = 1;
	}
    }

  parser->lexer.saved_arg = arg;
  parser->lexer.stream = arg;
  parser->completion_word = arg;
  parser->complete_what = linespec_complete_what::FUNCTION;
  PARSER_EXPLICIT (parser)->func_name_match_type = match_type;

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

  /* Objective-C shortcut.  */
  if (parser->completion_tracker == NULL)
    {
      std::vector<symtab_and_line> values
	= decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), 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 && *LS_TOKEN_STOKEN (token).ptr == '$')
    {
      /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB.  */
      if (parser->completion_tracker == NULL)
	PARSER_RESULT (parser)->file_symtabs.push_back (nullptr);

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

      /* If a line_offset wasn't found (VAR is the name of a user
	 variable/function), then skip to normal symbol processing.  */
      if (PARSER_EXPLICIT (parser)->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 (parser)->file_symtabs
	    = symtabs_from_filename (user_filename.get (),
				     PARSER_STATE (parser)->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_EXPLICIT (parser)->source_filename = user_filename.release ();

	  /* 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 (parser)->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 (parser)->file_symtabs.push_back (nullptr);
    }

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

  if (parser->completion_tracker == NULL
      && PARSER_RESULT (parser)->function_symbols.empty ()
      && PARSER_RESULT (parser)->labels.label_symbols.empty ()
      && PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN
      && PARSER_RESULT (parser)->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_EXPLICIT (parser)->function_name,
			      PARSER_EXPLICIT (parser)->source_filename);
    }

 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_STREAM (parser)));
      parser->complete_what = linespec_complete_what::EXPRESSION;
    }

  /* Convert the data in PARSER_RESULT to SALs.  */
  if (parser->completion_tracker == NULL)
    return convert_linespec_to_sals (PARSER_STATE (parser),
				     PARSER_RESULT (parser));

  return {};
}


/* A constructor for linespec_state.  */

static void
linespec_state_constructor (struct linespec_state *self,
			    int flags, const struct language_defn *language,
			    struct program_space *search_pspace,
			    struct symtab *default_symtab,
			    int default_line,
			    struct linespec_result *canonical)
{
  memset (self, 0, sizeof (*self));
  self->language = language;
  self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
  self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
  self->search_pspace = search_pspace;
  self->default_symtab = default_symtab;
  self->default_line = default_line;
  self->canonical = canonical;
  self->program_space = current_program_space;
  self->addr_set = htab_create_alloc (10, hash_address_entry, eq_address_entry,
				      xfree, xcalloc, xfree);
  self->is_linespec = 0;
}

/* 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)
{
  lexer.current.type = LSTOKEN_CONSUMED;
  PARSER_EXPLICIT (this)->func_name_match_type
    = symbol_name_match_type::WILD;
  PARSER_EXPLICIT (this)->line_offset.sign = LINE_OFFSET_UNKNOWN;
  linespec_state_constructor (PARSER_STATE (this), flags, language,
			      search_pspace,
			      default_symtab, default_line, canonical);
}

/* A destructor for linespec_state.  */

static void
linespec_state_destructor (struct linespec_state *self)
{
  htab_delete (self->addr_set);
  xfree (self->canonical_names);
}

/* Delete a linespec parser.  */

linespec_parser::~linespec_parser ()
{
  xfree (PARSER_EXPLICIT (this)->source_filename);
  xfree (PARSER_EXPLICIT (this)->label_name);
  xfree (PARSER_EXPLICIT (this)->function_name);

  linespec_state_destructor (PARSER_STATE (this));
}

/* 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_STREAM (&parser) = 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_STREAM (&parser) - 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_EXPLICIT (parser)->func_name_match_type;
      linespec_complete_function (tracker, text, match_type, source_filename);
      if (source_filename == NULL)
	{
	  /* Haven't seen a source component, like in "b
	     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),
			  PARSER_RESULT (parser)->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 = { 0, LINE_OFFSET_UNKNOWN };

  try
    {
      convert_explicit_location_to_linespec (PARSER_STATE (&parser),
					     PARSER_RESULT (&parser),
					     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_EXPLICIT (&parser)->func_name_match_type = match_type;
  PARSER_STREAM (&parser) = text;

  parser.completion_tracker = &tracker;
  PARSER_STATE (&parser)->is_linespec = 1;

  /* 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_EXPLICIT (&parser)->function_name;

      std::vector<block_symbol> function_symbols;
      std::vector<bound_minimal_symbol> minimal_symbols;
      find_linespec_symbols (PARSER_STATE (&parser),
			     PARSER_RESULT (&parser)->file_symtabs,
			     func_name, match_type,
			     &function_symbols, &minimal_symbols);

      PARSER_RESULT (&parser)->function_symbols = std::move (function_symbols);
      PARSER_RESULT (&parser)->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_EXPLICIT (&parser)->source_filename);

      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_EXPLICIT (&parser)->source_filename);

  /* 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 LOCATION into std::vector<symtab_and_line>.  */

static std::vector<symtab_and_line>
event_location_to_sals (linespec_parser *parser,
			const struct event_location *location)
{
  std::vector<symtab_and_line> result;

  switch (event_location_type (location))
    {
    case LINESPEC_LOCATION:
      {
	PARSER_STATE (parser)->is_linespec = 1;
	try
	  {
	    const linespec_location *ls = get_linespec_location (location);
	    result = parse_linespec (parser,
				     ls->spec_string, ls->match_type);
	  }
	catch (const gdb_exception_error &except)
	  {
	    throw;
	  }
      }
      break;

    case ADDRESS_LOCATION:
      {
	const char *addr_string = get_address_string_location (location);
	CORE_ADDR addr = get_address_location (location);

	if (addr_string != NULL)
	  {
	    addr = linespec_expression_to_pc (&addr_string);
	    if (PARSER_STATE (parser)->canonical != NULL)
	      PARSER_STATE (parser)->canonical->location
		= copy_event_location (location);
	  }

	result = convert_address_location_to_sals (PARSER_STATE (parser),
						   addr);
      }
      break;

    case EXPLICIT_LOCATION:
      {
	const struct explicit_location *explicit_loc;

	explicit_loc = get_explicit_location_const (location);
	result = convert_explicit_location_to_sals (PARSER_STATE (parser),
						    PARSER_RESULT (parser),
						    explicit_loc);
      }
      break;

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

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

  return result;
}

/* See linespec.h.  */

void
decode_line_full (struct event_location *location, 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;
  struct linespec_state *state;

  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 = event_location_to_sals (&parser,
								location);
  state = PARSER_STATE (&parser);

  if (result.size () == 0)
    throw_error (NOT_SUPPORTED_ERROR, _("Location %s not available"),
		 event_location_to_string (location));

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

  /* Arrange for allocated canonical names to be freed.  */
  std::vector<gdb::unique_xmalloc_ptr<char>> hold_names;
  for (int i = 0; i < result.size (); ++i)
    {
      gdb_assert (state->canonical_names[i].suffix != NULL);
      hold_names.emplace_back (state->canonical_names[i].suffix);
    }

  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 struct event_location *location, 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 event_location_to_sals (&parser, location);
}

/* 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 ();

  event_location_up location = string_to_event_location (&string,
							 current_language);
  std::vector<symtab_and_line> sals
    = decode_line_1 (location.get (), flags, NULL, cursal.symtab, cursal.line);

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

  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."));

  event_location_up location = string_to_event_location (&string,
							 current_language);
  std::vector<symtab_and_line> sals
    = (last_displayed_sal_is_valid ()
       ? decode_line_1 (location.get (), flags, NULL,
			get_last_displayed_symtab (),
			get_last_displayed_line ())
       : decode_line_1 (location.get (), flags, NULL, 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!  */
      struct symtab_and_line cursal = 
	get_current_source_symtab_and_line ();
      
      *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,
				    FUNCTIONS_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 = 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,
				      saved_arg);
	      str = holder.c_str ();
	    }
	  else
	    str = saved_arg;

	  self->canonical->location
	    = new_linespec_location (&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 ()
    : m_unique_syms (htab_create_alloc (1, htab_hash_pointer,
					htab_eq_pointer, NULL,
					xcalloc, xfree))
  {
  }

  /* 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.  */
  htab_up m_unique_syms;

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

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

  if (sym->aclass () != 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.  */

  slot = htab_find_slot (m_unique_syms.get (), sym, INSERT);
  if (!*slot)
    {
      *slot = sym;
      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,
					     STRUCT_DOMAIN, ALL_DOMAIN,
					     NULL, false, collector);
	  iterate_over_all_matching_symtabs (state, lookup_name,
					     VAR_DOMAIN, ALL_DOMAIN,
					     NULL, false, collector);
	}
      else
	{
	  /* Program spaces that are executing startup should have
	     been filtered out earlier.  */
	  gdb_assert (!elt->pspace ()->executing_startup);
	  set_current_program_space (elt->pspace ());
	  iterate_over_file_blocks (elt, lookup_name, STRUCT_DOMAIN, collector);
	  iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN, collector);
	}
    }

  return collector.release_symbols ();
}

/* A std::sort comparison function for symbols.  The resulting order does
   not actually matter; we just need to be able to sort them so that
   symbols with the same program space end up next to each other.  */

static bool
compare_symbols (const block_symbol &a, const block_symbol &b)
{
  uintptr_t uia, uib;

  uia = (uintptr_t) symbol_symtab (a.symbol)->pspace ();
  uib = (uintptr_t) symbol_symtab (b.symbol)->pspace ();

  if (uia < uib)
    return true;
  if (uia > uib)
    return false;

  uia = (uintptr_t) a.symbol;
  uib = (uintptr_t) b.symbol;

  if (uia < uib)
    return true;

  return false;
}

/* Like compare_symbols but for minimal symbols.  */

static bool
compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
{
  uintptr_t uia, uib;

  uia = (uintptr_t) a.objfile->pspace;
  uib = (uintptr_t) a.objfile->pspace;

  if (uia < uib)
    return true;
  if (uia > uib)
    return false;

  uia = (uintptr_t) a.minsym;
  uib = (uintptr_t) b.minsym;

  if (uia < uib)
    return true;

  return false;
}

/* 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,
				  enum search_domain search_domain)
{
  for (const char *iter : names)
    add_matching_symbols_to_info (iter,
				  symbol_name_match_type::FULL,
				  search_domain, info, pspace);
}

static void
find_superclass_methods (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 = symbol_symtab (sym)->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
	      != symbol_symtab (sym_classes->at (ix + 1).symbol)->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,
					    FUNCTIONS_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"));
}



namespace {

/* This function object is a callback for iterate_over_symtabs, used
   when collecting all matching symtabs.  */

class symtab_collector
{
public:
  symtab_collector ()
    : m_symtab_table (htab_create (1, htab_hash_pointer, htab_eq_pointer,
				   NULL))
  {
  }

  /* Callable as a symbol_found_callback_ftype callback.  */
  bool operator () (symtab *sym);

  /* Return an rvalue reference to the collected symtabs.  */
  std::vector<symtab *> &&release_symtabs ()
  {
    return std::move (m_symtabs);
  }

private:
  /* The result vector of symtabs.  */
  std::vector<symtab *> m_symtabs;

  /* This is used to ensure the symtabs are unique.  */
  htab_up m_symtab_table;
};

bool
symtab_collector::operator () (struct symtab *symtab)
{
  void **slot;

  slot = htab_find_slot (m_symtab_table.get (), symtab, INSERT);
  if (!*slot)
    {
      *slot = symtab;
      m_symtabs.push_back (symtab);
    }

  return false;
}

} // namespace

/* 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)
{
  symtab_collector collector;

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

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

  return collector.release_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 () && !have_partial_symbols ())
	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,
				   enum search_domain search_domain,
				   std::vector<symtab *> *search_symtabs,
				   struct program_space *search_pspace)
{
  symbol_searcher_collect_info info;
  struct linespec_state state;

  memset (&state, 0, sizeof (state));
  state.language = language;
  info.state = &state;

  info.result.symbols = &m_symbols;
  info.result.minimal_symbols = &m_minimal_symbols;
  std::vector<symtab *> all_symtabs;
  if (search_symtabs == nullptr)
    {
      all_symtabs.push_back (nullptr);
      search_symtabs = &all_symtabs;
    }
  info.file_symtabs = search_symtabs;

  add_matching_symbols_to_info (name.c_str (), symbol_name_match_type::WILD,
				search_domain, &info, search_pspace);
}

/* Look up a function symbol named NAME in symtabs FILE_SYMTABS.  Matching
   debug symbols are returned in SYMBOLS.  Matching minimal symbols are
   returned in MINSYMS.  */

static void
find_function_symbols (struct linespec_state *state,
		       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);
  if (!symbol_names.empty ())
    add_all_symbol_names_from_pspace (&info, state->search_pspace,
				      symbol_names, FUNCTIONS_DOMAIN);
  else
    add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
				  &info, state->search_pspace);
}

/* 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 expand_symtabs_matching 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)
    {
      struct block_iterator iter;
      struct symbol *sym;
      size_t name_len = strlen (name);

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

      ALL_BLOCK_SYMBOLS (block, iter, sym)
	{
	  if (symbol_matches_domain (sym->language (),
				     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, 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 = BLOCK_SUPERBLOCK (block))
	;

      if (!block)
	return {};

      fn_sym = BLOCK_FUNCTION (block);

      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 (symbol_symtab (fn_sym)->pspace ());
	  block = SYMBOL_BLOCK_VALUE (fn_sym);

	  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 (struct linespec_state *self,
			 linespec *ls,
			 struct symtab_and_line val)
{
  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);

      set_current_program_space (elt->pspace ());

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

      add_sal_to_sals (self, &values, &val, NULL, 0);
    }

  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,
			struct linetable_entry **best_entry)
{
  std::vector<symtab_and_line> sals;
  for (const auto &elt : ls->file_symtabs)
    {
      std::vector<CORE_ADDR> pcs;

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

      set_current_program_space (elt->pspace ());

      pcs = find_pcs_for_symtab_line (elt, line, best_entry);
      for (CORE_ADDR pc : pcs)
	{
	  symtab_and_line sal;
	  sal.pspace = elt->pspace ();
	  sal.symtab = elt;
	  sal.line = line;
	  sal.explicit_line = true;
	  sal.pc = pc;
	  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;
  struct line_offset offset = {0, LINE_OFFSET_NONE};

  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 (value_type (val_history)->code () != TYPE_CODE_INT)
	error (_("History values used in line "
		 "specs must have integer values."));
      offset.offset = value_as_long (val_history);
    }
  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 (ivar == NULL)
	/* No internal variable with that name.  Mark the offset
	   as unknown to allow the name to be looked up as a symbol.  */
	offset.sign = LINE_OFFSET_UNKNOWN;
      else
	{
	  /* 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;
	}
    }

  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;

  CORE_ADDR func_addr;
  bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);

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

      if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
	  || MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc)
	want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
      else
	want_start_sal = true;
    }

  symtab_and_line sal;

  if (is_function && want_start_sal)
    sal = find_function_start_sal (func_addr, NULL, self->funfirstline);
  else
    {
      sal.objfile = objfile;
      sal.msymbol = msymbol;
      /* Store func_addr, not the minsym's address in case this was an
	 ifunc that hasn't been resolved yet.  */
      if (is_function)
	sal.pc = func_addr;
      else
	sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
      sal.pspace = current_program_space;
    }

  sal.section = msymbol->obj_section (objfile);

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

/* 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, int list_mode,
	    std::vector<struct 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_pc_sect_line (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))
    return;

  msyms->emplace_back (minsym, objfile);
  return;
}

/* 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<struct 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 : current_program_space->objfiles ())
	    {
	      iterate_over_minimal_symbols (objfile, name,
					    [&] (struct minimal_symbol *msym)
					    {
					      add_minsym (msym, objfile, nullptr,
							  info->state->list_mode,
							  &minsyms);
					      return false;
					    });
	    }
	}
    }
  else
    {
      if (search_pspace == NULL || symtab->pspace () == search_pspace)
	{
	  set_current_program_space (symtab->pspace ());
	  iterate_over_minimal_symbols
	    (symtab->objfile (), name,
	     [&] (struct minimal_symbol *msym)
	       {
		 add_minsym (msym, symtab->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 (MSYMBOL_TYPE (item.minsym) == mst_solib_trampoline)
	{
	  for (const bound_minimal_symbol &item2 : minsyms)
	    {
	      if (&item2 == &item)
		continue;

	      /* Trampoline symbols can only jump to exported
		 symbols.  */
	      if (msymbol_type_is_static (MSYMBOL_TYPE (item2.minsym)))
		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,
			      enum search_domain search_domain,
			      struct collect_info *info,
			      struct program_space *pspace)
{
  lookup_name_info lookup_name (name, name_match_type);

  for (const auto &elt : *info->file_symtabs)
    {
      if (elt == nullptr)
	{
	  iterate_over_all_matching_symtabs (info->state, lookup_name,
					     VAR_DOMAIN, search_domain,
					     pspace, true,
					     [&] (block_symbol *bsym)
	    { return info->add_symbol (bsym); });
	  search_minsyms_for_name (info, lookup_name, pspace, NULL);
	}
      else if (pspace == NULL || pspace == elt->pspace ())
	{
	  int prev_len = info->result.symbols->size ();

	  /* Program spaces that are executing startup should have
	     been filtered out earlier.  */
	  gdb_assert (!elt->pspace ()->executing_startup);
	  set_current_program_space (elt->pspace ());
	  iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
				    [&] (block_symbol *bsym)
	    { return info->add_symbol (bsym); });

	  /* If no new symbols were found in this iteration and this symtab
	     is in assembler, we might actually be looking for a label for
	     which we don't have debug info.  Check for a minimal symbol in
	     this case.  */
	  if (prev_len == 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 int
symbol_to_sal (struct symtab_and_line *result,
	       int funfirstline, struct symbol *sym)
{
  if (sym->aclass () == LOC_BLOCK)
    {
      *result = find_function_start_sal (sym, funfirstline);
      return 1;
    }
  else
    {
      if (sym->aclass () == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
	{
	  *result = {};
	  result->symtab = symbol_symtab (sym);
	  result->symbol = sym;
	  result->line = sym->line ();
	  result->pc = SYMBOL_VALUE_ADDRESS (sym);
	  result->pspace = result->symtab->pspace ();
	  result->explicit_pc = 1;
	  return 1;
	}
      else if (funfirstline)
	{
	  /* Nothing.  */
	}
      else if (sym->line () != 0)
	{
	  /* We know its line number.  */
	  *result = {};
	  result->symtab = symbol_symtab (sym);
	  result->symbol = sym;
	  result->line = sym->line ();
	  result->pc = SYMBOL_VALUE_ADDRESS (sym);
	  result->pspace = result->symtab->pspace ();
	  return 1;
	}
    }

  return 0;
}

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;
}
