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

   Copyright (C) 1986-2019 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>

/* 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").
     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.  May not
     be NULL.  If explicit.SOURCE_FILENAME is NULL (no user-specified
     filename), FILE_SYMTABS should contain one single NULL member.  This
     will cause the code to use the default symtab.  */
  std::vector<symtab *> *file_symtabs;

  /* A list of matching function symbols and minimal symbols.  Both lists
     may be NULL (or empty) if no matching symbols were found.  */
  std::vector<block_symbol> *function_symbols;
  std::vector<bound_minimal_symbol> *minimal_symbols;

  /* A structure of matching label symbols and the corresponding
     function symbol in which the label was found.  Both may be NULL
     or both must be non-NULL.  */
  struct
  {
    std::vector<block_symbol> *label_symbols;
    std::vector<block_symbol> *function_symbols;
  } labels;
};
typedef struct linespec *linespec_p;

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

  /* Continue iterating.  */
  return true;
}

/* Custom collect_info for symbol_searcher.  */

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

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

/* Token types  */

enum ls_token_type
{
  /* 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", NULL };
#define IF_KEYWORD_INDEX 0

/* A token of the linespec lexer  */

struct ls_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;
};
typedef struct ls_token linespec_token;

#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.  */
  struct 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_p 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, 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,
				   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_p ls,
   int line,
   linetable_entry **best_entry);

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

static void minsym_found (struct linespec_state *self, struct objfile *objfile,
			  struct minimal_symbol *msymbol,
			  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 *const 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 one of the keywords 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.  */
	  if (strncmp (p, linespec_keywords[i], len) == 0
	      && isspace (p[len]))
	    {
	      int j;

	      /* Special case: "if" ALWAYS stops 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 (i != IF_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 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);
	  else if (symname != NULL)
	    canonical->suffix = xstrdup (symname);
	  else
	    canonical->suffix = xstrprintf ("%d", sal->line);
	  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)
{
  struct program_space *pspace;

  ALL_PSPACES (pspace)
  {
    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 ())
      {
	if (objfile->sf)
	  objfile->sf->qf->expand_symtabs_matching (objfile,
						    NULL,
						    lookup_name,
						    NULL, NULL,
						    search_domain);

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

	    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 (symtab));
		     i++)
		  {
		    block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
		    state->language->la_iterate_over_symbols
		      (block, lookup_name, name_domain,
		       [&] (block_symbol *bsym)
		       {
			 /* Restrict calls to CALLBACK to symbols
			    representing inline symbols only.  */
			 if (SYMBOL_INLINED (bsym->symbol))
			   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 (symtab), STATIC_BLOCK);
       block != NULL;
       block = BLOCK_SUPERBLOCK (block))
    LA_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 = TYPE_NAME (t);

  /* Ignore this class if it doesn't have a name.  This is ugly, but
     unless we figure out how to get the physname without the name of
     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
	= get_symbol_name_matcher (language_def (t_lang), 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));
}

/* Find an instance of the character C in the string S that is outside
   of all parenthesis pairs, single-quoted strings, and double-quoted
   strings.  Also, ignore the char within a template name, like a ','
   within foo<int, int>, while considering C++ operator</operator<<.  */

const char *
find_toplevel_char (const char *s, char c)
{
  int quoted = 0;		/* zero if we're not in quotes;
				   '"' if we're in a double-quoted string;
				   '\'' if we're in a single-quoted string.  */
  int depth = 0;		/* Number of unclosed parens we've seen.  */
  const char *scan;

  for (scan = s; *scan; scan++)
    {
      if (quoted)
	{
	  if (*scan == quoted)
	    quoted = 0;
	  else if (*scan == '\\' && *(scan + 1))
	    scan++;
	}
      else if (*scan == c && ! quoted && depth == 0)
	return scan;
      else if (*scan == '"' || *scan == '\'')
	quoted = *scan;
      else if (*scan == '(' || *scan == '<')
	depth++;
      else if ((*scan == ')' || *scan == '>') && depth > 0)
	depth--;
      else if (*scan == 'o' && !quoted && depth == 0)
	{
	  /* Handle C++ operator names.  */
	  if (strncmp (scan, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0)
	    {
	      scan += CP_OPERATOR_LEN;
	      if (*scan == c)
		return scan;
	      while (isspace (*scan))
		{
		  ++scan;
		  if (*scan == c)
		    return scan;
		}
	      if (*scan == '\0')
		break;

	      switch (*scan)
		{
		  /* Skip over one less than the appropriate number of
		     characters: the for loop will skip over the last
		     one.  */
		case '<':
		  if (scan[1] == '<')
		    {
		      scan++;
		      if (*scan == c)
			return scan;
		    }
		  break;
		case '>':
		  if (scan[1] == '>')
		    {
		      scan++;
		      if (*scan == c)
			return scan;
		    }
		  break;
		}
	    }
	}
    }

  return 0;
}

/* 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)
{
  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;
  std::vector<block_symbol> symbols;
  std::vector<block_symbol> *labels;
  std::vector<bound_minimal_symbol> minimal_symbols;

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

  /* 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
    {
      /* 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
	    = new std::vector<block_symbol> (std::move (symbols));
	  PARSER_RESULT (parser)->minimal_symbols
	    = new std::vector<bound_minimal_symbol>
	        (std::move (minimal_symbols));
	  PARSER_EXPLICIT (parser)->function_name = name.release ();
	}
      else
	{
	  /* NAME was not a function or a method.  So it must be a label
	     name or user specified variable like "break foo.c:$zippo".  */
	  labels = find_label_symbols (PARSER_STATE (parser), NULL,
				       &symbols, name.get ());
	  if (labels != NULL)
	    {
	      PARSER_RESULT (parser)->labels.label_symbols = labels;
	      PARSER_RESULT (parser)->labels.function_symbols
		= new std::vector<block_symbol> (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
	    {
	      /* Grab a copy of the label's name and look it up.  */
	      name = copy_token_string (token);
	      labels
		= find_label_symbols (PARSER_STATE (parser),
				      PARSER_RESULT (parser)->function_symbols,
				      &symbols, name.get ());

	      if (labels != NULL)
		{
		  PARSER_RESULT (parser)->labels.label_symbols = labels;
		  PARSER_RESULT (parser)->labels.function_symbols
		    = new std::vector<block_symbol> (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_p 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->empty ()
		      && (ls->labels.function_symbols->size () == 1));
	  block_symbol s = ls->labels.function_symbols->front ();
	  explicit_loc->function_name
	    = xstrdup (SYMBOL_NATURAL_NAME (s.symbol));
	}
    }

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

      set_event_location_string (canon, linespec);
      xfree (linespec);
    }
}

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

static std::vector<symtab_and_line>
create_sals_line_offset (struct linespec_state *self,
			 linespec_p 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 ? SYMBOL_NATURAL_NAME (sym) : 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_p ls)
{
  std::vector<symtab_and_line> sals;

  if (ls->labels.label_symbols != NULL)
    {
      /* 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
	    = SYMTAB_PSPACE (symbol_symtab (sym.symbol));

	  if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
	      && maybe_add_address (state->addr_set, pspace, sal.pc))
	    add_sal_to_sals (state, &sals, &sal,
			     SYMBOL_NATURAL_NAME (sym.symbol), 0);
	}
    }
  else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
    {
      /* We have just a bunch of functions and/or methods.  */
      if (ls->function_symbols != NULL)
	{
	  /* 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
		= SYMTAB_PSPACE (symbol_symtab (sym.symbol));
	      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 != NULL
		   && SYMBOL_CLASS (sym.symbol) == LOC_BLOCK)
		{
		  const CORE_ADDR addr
		    = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol));

		  for (const auto &elem : *ls->minimal_symbols)
		    {
		      if (MSYMBOL_TYPE (elem.minsym) == mst_text_gnu_ifunc
			  || MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
			{
			  CORE_ADDR msym_addr = BMSYMBOL_VALUE_ADDRESS (elem);
			  if (MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
			    {
			      struct gdbarch *gdbarch
				= get_objfile_arch (elem.objfile);
			      msym_addr
				= (gdbarch_convert_from_func_ptr_addr
				   (gdbarch,
				    msym_addr,
				    current_top_target ()));
			    }

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

	      if (!found_ifunc)
		{
		  symtab_and_line sal;
		  if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
		      && maybe_add_address (state->addr_set, pspace, sal.pc))
		    add_sal_to_sals (state, &sals, &sal,
				     SYMBOL_NATURAL_NAME (sym.symbol), 0);
		}
	    }
	}

      if (ls->minimal_symbols != NULL)
	{
	  /* Sort minimal symbols by program space, too  */
	  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_p result,
				       const char *source_filename,
				       const char *function_name,
				       symbol_name_match_type fname_match_type,
				       const char *label_name,
				       struct line_offset line_offset)
{
  std::vector<block_symbol> symbols;
  std::vector<block_symbol> *labels;
  std::vector<bound_minimal_symbol> minimal_symbols;

  result->explicit_loc.func_name_match_type = fname_match_type;

  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)
    {
      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
	= new std::vector<block_symbol> (std::move (symbols));
      result->minimal_symbols
	= new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
    }

  if (label_name != NULL)
    {
      labels = find_label_symbols (self, result->function_symbols,
				   &symbols, label_name);

      if (labels == NULL)
	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
	= new std::vector<block_symbol> (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_p 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.  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)
{
  linespec_token token;
  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)
      && strchr (linespec_quote_characters, *arg) != NULL)
    {
      const char *end;

      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.  */
  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 == NULL
      && PARSER_RESULT (parser)->labels.label_symbols == NULL
      && PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN
      && PARSER_RESULT (parser)->minimal_symbols == NULL)
    {
      /* 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_RESULT (this)->file_symtabs = new std::vector<symtab *> ();
  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);

  delete PARSER_RESULT (this)->file_symtabs;
  delete PARSER_RESULT (this)->function_symbols;
  delete PARSER_RESULT (this)->minimal_symbols;
  delete PARSER_RESULT (this)->labels.label_symbols;
  delete PARSER_RESULT (this)->labels.function_symbols;

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

  if (labels != nullptr)
    {
      for (const auto &label : *labels)
	{
	  char *match = xstrdup (SYMBOL_SEARCH_NAME (label.symbol));
	  tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
	}
      delete labels;
    }
}

/* 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
	= new std::vector<block_symbol> (std::move (function_symbols));
      PARSER_RESULT (&parser)->minimal_symbols
	= new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));

      complete_label (tracker, &parser, parser.completion_word);
    }
  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 (const 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);

  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 beggining 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_p 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
	= new std::vector<block_symbol> (std::move (symbols));
      ls->minimal_symbols
	= new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
      values = convert_linespec_to_sals (self, ls);

      if (self->canonical)
	{
	  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);
  }

  ~decode_compound_collector ()
  {
    if (m_unique_syms != NULL)
      htab_delete (m_unique_syms);
  }

  /* 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_t 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 (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
    return true; /* Continue iterating.  */

  t = SYMBOL_TYPE (sym);
  t = check_typedef (t);
  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
      && TYPE_CODE (t) != TYPE_CODE_UNION
      && TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
    return true; /* Continue iterating.  */

  slot = htab_find_slot (m_unique_syms, 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,
		   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 (!SYMTAB_PSPACE (elt)->executing_startup);
	  set_current_program_space (SYMTAB_PSPACE (elt));
	  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) SYMTAB_PSPACE (symbol_symtab (a.symbol));
  uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (b.symbol));

  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, 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;
  unsigned int ix = 0;
  for (const auto &elt : *sym_classes)
    {
      struct type *t;
      struct program_space *pspace;
      struct symbol *sym = elt.symbol;

      /* Program spaces that are executing startup should have
	 been filtered out earlier.  */
      pspace = SYMTAB_PSPACE (symbol_symtab (sym));
      gdb_assert (!pspace->executing_startup);
      set_current_program_space (pspace);
      t = check_typedef (SYMBOL_TYPE (sym));
      find_methods (t, SYMBOL_LANGUAGE (sym),
		    method_name, &result_names, &superclass_vec);

      /* Handle all items from a single program space at once; and be
	 sure not to miss the last batch.  */
      if (ix == sym_classes->size () - 1
	  || (pspace
	      != SYMTAB_PSPACE (symbol_symtab (sym_classes->at (ix + 1).symbol))))
	{
	  /* If we did not find a direct implementation anywhere in
	     this program space, consider superclasses.  */
	  if (result_names.size () == last_result_len)
	    find_superclass_methods (std::move (superclass_vec), method_name,
				     SYMBOL_LANGUAGE (sym), &result_names);

	  /* We have a list of candidate symbol names, so now we
	     iterate over the symbol tables looking for all
	     matches in this pspace.  */
	  add_all_symbol_names_from_pspace (&info, pspace, result_names,
					    FUNCTIONS_DOMAIN);

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

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

  ~symtab_collector ()
  {
    if (m_symtab_table != NULL)
      htab_delete (m_symtab_table);
  }

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

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

  slot = htab_find_slot (m_symtab_table, 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)
    {
      struct program_space *pspace;

      ALL_PSPACES (pspace)
        {
	  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,
		       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,
		       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)
{
  std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
  if (!canon.empty ())
    lookup_name = canon.c_str ();

  /* 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 (SYMBOL_LANGUAGE (sym),
				     SYMBOL_DOMAIN (sym), LABEL_DOMAIN)
	      && cmp (SYMBOL_SEARCH_NAME (sym), 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 or NULL
   if no matches were found.

   Return the actual function symbol in which the label was found in
   LABEL_FUNC_RET.  If COMPLETION_MODE is true, then NAME is
   interpreted as a label name prefix.  Otherwise, only labels named
   exactly NAME match.  */


static std::vector<block_symbol> *
find_label_symbols (struct linespec_state *self,
		    std::vector<block_symbol> *function_symbols,
		    std::vector<block_symbol> *label_funcs_ret,
		    const char *name,
		    bool completion_mode)
{
  const struct block *block;
  struct symbol *fn_sym;
  std::vector<block_symbol> result;

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

      for (;
	   block && !BLOCK_FUNCTION (block);
	   block = BLOCK_SUPERBLOCK (block))
	;
      if (!block)
	return NULL;
      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 (SYMTAB_PSPACE (symbol_symtab (fn_sym)));
	  block = SYMBOL_BLOCK_VALUE (fn_sym);

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

  if (!result.empty ())
    return new std::vector<block_symbol> (std::move (result));
  return nullptr;
}



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

      /* 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 = SYMTAB_PSPACE (elt);
      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,
   adding lines to the VEC.  */

static std::vector<symtab_and_line>
decode_digits_ordinary (struct linespec_state *self,
			linespec_p 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 (SYMTAB_PSPACE (elt));

      pcs = find_pcs_for_symtab_line (elt, line, best_entry);
      for (CORE_ADDR pc : pcs)
	{
	  symtab_and_line sal;
	  sal.pspace = SYMTAB_PSPACE (elt);
	  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 (TYPE_CODE (value_type (val_history)) != 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 (msymbol);

      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, msymbol);

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

/* A helper function to classify a minimal_symbol_type according to
   priority.  */

static int
classify_mtype (enum minimal_symbol_type t)
{
  switch (t)
    {
    case mst_file_text:
    case mst_file_data:
    case mst_file_bss:
      /* Intermediate priority.  */
      return 1;

    case mst_solib_trampoline:
      /* Lowest priority.  */
      return 2;

    default:
      /* Highest priority.  */
      return 0;
    }
}

/* Callback for std::sort that sorts symbols by priority.  */

static bool
compare_msyms (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
{
  enum minimal_symbol_type ta = MSYMBOL_TYPE (a.minsym);
  enum minimal_symbol_type tb = MSYMBOL_TYPE (b.minsym);

  return classify_mtype (ta) < classify_mtype (tb);
}

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

  struct bound_minimal_symbol mo = {minsym, objfile};
  msyms->push_back (mo);
  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)
    {
      struct program_space *pspace;

      ALL_PSPACES (pspace)
      {
	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 (symtab) == search_pspace)
	{
	  set_current_program_space (SYMTAB_PSPACE (symtab));
	  iterate_over_minimal_symbols
	    (SYMTAB_OBJFILE (symtab), name,
	     [&] (struct minimal_symbol *msym)
	       {
		 add_minsym (msym, SYMTAB_OBJFILE (symtab), symtab,
			     info->state->list_mode, &minsyms);
		 return false;
	       });
	}
    }

  if (!minsyms.empty ())
    {
      int classification;

      std::sort (minsyms.begin (), minsyms.end (), compare_msyms);

      /* Now the minsyms are in classification order.  So, we walk
	 over them and process just the minsyms with the same
	 classification as the very first minsym in the list.  */
      classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym));

      for (const bound_minimal_symbol &item : minsyms)
	{
	  if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification)
	    break;

	  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 == SYMTAB_PSPACE (elt))
	{
	  int prev_len = info->result.symbols->size ();

	  /* Program spaces that are executing startup should have
	     been filtered out earlier.  */
	  gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
	  set_current_program_space (SYMTAB_PSPACE (elt));
	  iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
				    [&] (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 (SYMBOL_CLASS (sym) == LOC_BLOCK)
    {
      *result = find_function_start_sal (sym, funfirstline);
      return 1;
    }
  else
    {
      if (SYMBOL_CLASS (sym) == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
	{
	  *result = {};
	  result->symtab = symbol_symtab (sym);
	  result->symbol = sym;
	  result->line = SYMBOL_LINE (sym);
	  result->pc = SYMBOL_VALUE_ADDRESS (sym);
	  result->pspace = SYMTAB_PSPACE (result->symtab);
	  result->explicit_pc = 1;
	  return 1;
	}
      else if (funfirstline)
	{
	  /* Nothing.  */
	}
      else if (SYMBOL_LINE (sym) != 0)
	{
	  /* We know its line number.  */
	  *result = {};
	  result->symtab = symbol_symtab (sym);
	  result->symbol = sym;
	  result->line = SYMBOL_LINE (sym);
	  result->pc = SYMBOL_VALUE_ADDRESS (sym);
	  result->pspace = SYMTAB_PSPACE (result->symtab);
	  return 1;
	}
    }

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