/* Parse expressions for GDB.

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

   Modified from expread.y by the Department of Computer Science at the
   State University of New York at Buffalo, 1991.

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

/* Parse an expression from text in a string,
   and return the result as a struct expression pointer.
   That structure contains arithmetic operations in reverse polish,
   with constants represented by operations that are followed by special data.
   See expression.h for the details of the format.
   What is important here is that it can be built up sequentially
   during the process of parsing; the lower levels of the tree always
   come first in the result.  */

#include "defs.h"
#include <ctype.h>
#include "arch-utils.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "expression.h"
#include "value.h"
#include "command.h"
#include "language.h"
#include "f-lang.h"
#include "parser-defs.h"
#include "gdbcmd.h"
#include "symfile.h"		/* for overlay functions */
#include "inferior.h"
#include "target-float.h"
#include "block.h"
#include "source.h"
#include "objfiles.h"
#include "user-regs.h"
#include <algorithm>
#include "common/gdb_optional.h"

/* Standard set of definitions for printing, dumping, prefixifying,
 * and evaluating expressions.  */

const struct exp_descriptor exp_descriptor_standard = 
  {
    print_subexp_standard,
    operator_length_standard,
    operator_check_standard,
    op_name_standard,
    dump_subexp_body_standard,
    evaluate_subexp_standard
  };

/* Global variables declared in parser-defs.h (and commented there).  */
const struct block *expression_context_block;
CORE_ADDR expression_context_pc;
const struct block *innermost_block;
int arglist_len;
static struct type_stack type_stack;
const char *lexptr;
const char *prev_lexptr;
int paren_depth;
int comma_terminates;

/* True if parsing an expression to attempt completion.  */
int parse_completion;

/* The index of the last struct expression directly before a '.' or
   '->'.  This is set when parsing and is only used when completing a
   field name.  It is -1 if no dereference operation was found.  */
static int expout_last_struct = -1;

/* If we are completing a tagged type name, this will be nonzero.  */
static enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;

/* The token for tagged type name completion.  */
static char *expout_completion_name;


static unsigned int expressiondebug = 0;
static void
show_expressiondebug (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Expression debugging is %s.\n"), value);
}


/* Non-zero if an expression parser should set yydebug.  */
int parser_debug;

static void
show_parserdebug (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Parser debugging is %s.\n"), value);
}


static int prefixify_subexp (struct expression *, struct expression *, int,
			     int);

static expression_up parse_exp_in_context (const char **, CORE_ADDR,
					   const struct block *, int,
					   int, int *);
static expression_up parse_exp_in_context_1 (const char **, CORE_ADDR,
					     const struct block *, int,
					     int, int *);

/* Data structure for saving values of arglist_len for function calls whose
   arguments contain other function calls.  */

static std::vector<int> *funcall_chain;

/* Begin counting arguments for a function call,
   saving the data about any containing call.  */

void
start_arglist (void)
{
  funcall_chain->push_back (arglist_len);
  arglist_len = 0;
}

/* Return the number of arguments in a function call just terminated,
   and restore the data for the containing function call.  */

int
end_arglist (void)
{
  int val = arglist_len;
  arglist_len = funcall_chain->back ();
  funcall_chain->pop_back ();
  return val;
}



/* See definition in parser-defs.h.  */

parser_state::parser_state (size_t initial_size,
			    const struct language_defn *lang,
			    struct gdbarch *gdbarch)
  : expout_size (initial_size),
    expout (XNEWVAR (expression,
		     (sizeof (expression)
		      + EXP_ELEM_TO_BYTES (expout_size)))),
    expout_ptr (0)
{
  expout->language_defn = lang;
  expout->gdbarch = gdbarch;
}

expression_up
parser_state::release ()
{
  /* Record the actual number of expression elements, and then
     reallocate the expression memory so that we free up any
     excess elements.  */

  expout->nelts = expout_ptr;
  expout.reset (XRESIZEVAR (expression, expout.release (),
			    (sizeof (expression)
			     + EXP_ELEM_TO_BYTES (expout_ptr))));

  return std::move (expout);
}

/* This page contains the functions for adding data to the struct expression
   being constructed.  */

/* Add one element to the end of the expression.  */

/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into
   a register through here.  */

static void
write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
{
  if (ps->expout_ptr >= ps->expout_size)
    {
      ps->expout_size *= 2;
      ps->expout.reset (XRESIZEVAR (expression, ps->expout.release (),
				    (sizeof (expression)
				     + EXP_ELEM_TO_BYTES (ps->expout_size))));
    }
  ps->expout->elts[ps->expout_ptr++] = *expelt;
}

void
write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.opcode = expelt;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.symbol = expelt;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_msym (struct parser_state *ps, minimal_symbol *expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.msymbol = expelt;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_block (struct parser_state *ps, const struct block *b)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.block = b;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.objfile = objfile;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.longconst = expelt;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_floatcst (struct parser_state *ps, const gdb_byte expelt[16])
{
  union exp_element tmp;
  int index;

  for (index = 0; index < 16; index++)
    tmp.floatconst[index] = expelt[index];

  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_type (struct parser_state *ps, struct type *expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.type = expelt;
  write_exp_elt (ps, &tmp);
}

void
write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
{
  union exp_element tmp;

  memset (&tmp, 0, sizeof (union exp_element));
  tmp.internalvar = expelt;
  write_exp_elt (ps, &tmp);
}

/* Add a string constant to the end of the expression.

   String constants are stored by first writing an expression element
   that contains the length of the string, then stuffing the string
   constant itself into however many expression elements are needed
   to hold it, and then writing another expression element that contains
   the length of the string.  I.e. an expression element at each end of
   the string records the string length, so you can skip over the 
   expression elements containing the actual string bytes from either
   end of the string.  Note that this also allows gdb to handle
   strings with embedded null bytes, as is required for some languages.

   Don't be fooled by the fact that the string is null byte terminated,
   this is strictly for the convenience of debugging gdb itself.
   Gdb does not depend up the string being null terminated, since the
   actual length is recorded in expression elements at each end of the
   string.  The null byte is taken into consideration when computing how
   many expression elements are required to hold the string constant, of
   course.  */


void
write_exp_string (struct parser_state *ps, struct stoken str)
{
  int len = str.length;
  size_t lenelt;
  char *strdata;

  /* Compute the number of expression elements required to hold the string
     (including a null byte terminator), along with one expression element
     at each end to record the actual string length (not including the
     null byte terminator).  */

  lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);

  increase_expout_size (ps, lenelt);

  /* Write the leading length expression element (which advances the current
     expression element index), then write the string constant followed by a
     terminating null byte, and then write the trailing length expression
     element.  */

  write_exp_elt_longcst (ps, (LONGEST) len);
  strdata = (char *) &ps->expout->elts[ps->expout_ptr];
  memcpy (strdata, str.ptr, len);
  *(strdata + len) = '\0';
  ps->expout_ptr += lenelt - 2;
  write_exp_elt_longcst (ps, (LONGEST) len);
}

/* Add a vector of string constants to the end of the expression.

   This adds an OP_STRING operation, but encodes the contents
   differently from write_exp_string.  The language is expected to
   handle evaluation of this expression itself.
   
   After the usual OP_STRING header, TYPE is written into the
   expression as a long constant.  The interpretation of this field is
   up to the language evaluator.
   
   Next, each string in VEC is written.  The length is written as a
   long constant, followed by the contents of the string.  */

void
write_exp_string_vector (struct parser_state *ps, int type,
			 struct stoken_vector *vec)
{
  int i, len;
  size_t n_slots;

  /* Compute the size.  We compute the size in number of slots to
     avoid issues with string padding.  */
  n_slots = 0;
  for (i = 0; i < vec->len; ++i)
    {
      /* One slot for the length of this element, plus the number of
	 slots needed for this string.  */
      n_slots += 1 + BYTES_TO_EXP_ELEM (vec->tokens[i].length);
    }

  /* One more slot for the type of the string.  */
  ++n_slots;

  /* Now compute a phony string length.  */
  len = EXP_ELEM_TO_BYTES (n_slots) - 1;

  n_slots += 4;
  increase_expout_size (ps, n_slots);

  write_exp_elt_opcode (ps, OP_STRING);
  write_exp_elt_longcst (ps, len);
  write_exp_elt_longcst (ps, type);

  for (i = 0; i < vec->len; ++i)
    {
      write_exp_elt_longcst (ps, vec->tokens[i].length);
      memcpy (&ps->expout->elts[ps->expout_ptr], vec->tokens[i].ptr,
	      vec->tokens[i].length);
      ps->expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length);
    }

  write_exp_elt_longcst (ps, len);
  write_exp_elt_opcode (ps, OP_STRING);
}

/* Add a bitstring constant to the end of the expression.

   Bitstring constants are stored by first writing an expression element
   that contains the length of the bitstring (in bits), then stuffing the
   bitstring constant itself into however many expression elements are
   needed to hold it, and then writing another expression element that
   contains the length of the bitstring.  I.e. an expression element at
   each end of the bitstring records the bitstring length, so you can skip
   over the expression elements containing the actual bitstring bytes from
   either end of the bitstring.  */

void
write_exp_bitstring (struct parser_state *ps, struct stoken str)
{
  int bits = str.length;	/* length in bits */
  int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
  size_t lenelt;
  char *strdata;

  /* Compute the number of expression elements required to hold the bitstring,
     along with one expression element at each end to record the actual
     bitstring length in bits.  */

  lenelt = 2 + BYTES_TO_EXP_ELEM (len);

  increase_expout_size (ps, lenelt);

  /* Write the leading length expression element (which advances the current
     expression element index), then write the bitstring constant, and then
     write the trailing length expression element.  */

  write_exp_elt_longcst (ps, (LONGEST) bits);
  strdata = (char *) &ps->expout->elts[ps->expout_ptr];
  memcpy (strdata, str.ptr, len);
  ps->expout_ptr += lenelt - 2;
  write_exp_elt_longcst (ps, (LONGEST) bits);
}

/* Return the type of MSYMBOL, a minimal symbol of OBJFILE.  If
   ADDRESS_P is not NULL, set it to the MSYMBOL's resolved
   address.  */

type *
find_minsym_type_and_address (minimal_symbol *msymbol,
			      struct objfile *objfile,
			      CORE_ADDR *address_p)
{
  bound_minimal_symbol bound_msym = {msymbol, objfile};
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
  enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);
  CORE_ADDR pc;

  bool is_tls = (section != NULL
		 && section->the_bfd_section->flags & SEC_THREAD_LOCAL);

  /* Addresses of TLS symbols are really offsets into a
     per-objfile/per-thread storage block.  */
  CORE_ADDR addr = (is_tls
		    ? MSYMBOL_VALUE_RAW_ADDRESS (bound_msym.minsym)
		    : BMSYMBOL_VALUE_ADDRESS (bound_msym));

  /* The minimal symbol might point to a function descriptor;
     resolve it to the actual code address instead.  */
  pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
  if (pc != addr)
    {
      struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc);

      /* In this case, assume we have a code symbol instead of
	 a data symbol.  */

      if (ifunc_msym.minsym != NULL
	  && MSYMBOL_TYPE (ifunc_msym.minsym) == mst_text_gnu_ifunc
	  && BMSYMBOL_VALUE_ADDRESS (ifunc_msym) == pc)
	{
	  /* A function descriptor has been resolved but PC is still in the
	     STT_GNU_IFUNC resolver body (such as because inferior does not
	     run to be able to call it).  */

	  type = mst_text_gnu_ifunc;
	}
      else
	type = mst_text;
      section = NULL;
      addr = pc;
    }

  if (overlay_debugging)
    addr = symbol_overlayed_address (addr, section);

  if (is_tls)
    {
      /* Skip translation if caller does not need the address.  */
      if (address_p != NULL)
	*address_p = target_translate_tls_address (objfile, addr);
      return objfile_type (objfile)->nodebug_tls_symbol;
    }

  if (address_p != NULL)
    *address_p = addr;

  switch (type)
    {
    case mst_text:
    case mst_file_text:
    case mst_solib_trampoline:
      return objfile_type (objfile)->nodebug_text_symbol;

    case mst_text_gnu_ifunc:
      return objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;

    case mst_data:
    case mst_file_data:
    case mst_bss:
    case mst_file_bss:
      return objfile_type (objfile)->nodebug_data_symbol;

    case mst_slot_got_plt:
      return objfile_type (objfile)->nodebug_got_plt_symbol;

    default:
      return objfile_type (objfile)->nodebug_unknown_symbol;
    }
}

/* Add the appropriate elements for a minimal symbol to the end of
   the expression.  */

void
write_exp_msymbol (struct parser_state *ps,
		   struct bound_minimal_symbol bound_msym)
{
  write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
  write_exp_elt_objfile (ps, bound_msym.objfile);
  write_exp_elt_msym (ps, bound_msym.minsym);
  write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
}

/* Mark the current index as the starting location of a structure
   expression.  This is used when completing on field names.  */

void
mark_struct_expression (struct parser_state *ps)
{
  gdb_assert (parse_completion
	      && expout_tag_completion_type == TYPE_CODE_UNDEF);
  expout_last_struct = ps->expout_ptr;
}

/* Indicate that the current parser invocation is completing a tag.
   TAG is the type code of the tag, and PTR and LENGTH represent the
   start of the tag name.  */

void
mark_completion_tag (enum type_code tag, const char *ptr, int length)
{
  gdb_assert (parse_completion
	      && expout_tag_completion_type == TYPE_CODE_UNDEF
	      && expout_completion_name == NULL
	      && expout_last_struct == -1);
  gdb_assert (tag == TYPE_CODE_UNION
	      || tag == TYPE_CODE_STRUCT
	      || tag == TYPE_CODE_ENUM);
  expout_tag_completion_type = tag;
  expout_completion_name = (char *) xmalloc (length + 1);
  memcpy (expout_completion_name, ptr, length);
  expout_completion_name[length] = '\0';
}


/* Recognize tokens that start with '$'.  These include:

   $regname     A native register name or a "standard
   register name".

   $variable    A convenience variable with a name chosen
   by the user.

   $digits              Value history with index <digits>, starting
   from the first value which has index 1.

   $$digits     Value history with index <digits> relative
   to the last value.  I.e. $$0 is the last
   value, $$1 is the one previous to that, $$2
   is the one previous to $$1, etc.

   $ | $0 | $$0 The last value in the value history.

   $$           An abbreviation for the second to the last
   value in the value history, I.e. $$1  */

void
write_dollar_variable (struct parser_state *ps, struct stoken str)
{
  struct block_symbol sym;
  struct bound_minimal_symbol msym;
  struct internalvar *isym = NULL;

  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
     and $$digits (equivalent to $<-digits> if you could type that).  */

  int negate = 0;
  int i = 1;
  /* Double dollar means negate the number and add -1 as well.
     Thus $$ alone means -1.  */
  if (str.length >= 2 && str.ptr[1] == '$')
    {
      negate = 1;
      i = 2;
    }
  if (i == str.length)
    {
      /* Just dollars (one or two).  */
      i = -negate;
      goto handle_last;
    }
  /* Is the rest of the token digits?  */
  for (; i < str.length; i++)
    if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
      break;
  if (i == str.length)
    {
      i = atoi (str.ptr + 1 + negate);
      if (negate)
	i = -i;
      goto handle_last;
    }

  /* Handle tokens that refer to machine registers:
     $ followed by a register name.  */
  i = user_reg_map_name_to_regnum (parse_gdbarch (ps),
				   str.ptr + 1, str.length - 1);
  if (i >= 0)
    goto handle_register;

  /* Any names starting with $ are probably debugger internal variables.  */

  isym = lookup_only_internalvar (copy_name (str) + 1);
  if (isym)
    {
      write_exp_elt_opcode (ps, OP_INTERNALVAR);
      write_exp_elt_intern (ps, isym);
      write_exp_elt_opcode (ps, OP_INTERNALVAR);
      return;
    }

  /* On some systems, such as HP-UX and hppa-linux, certain system routines 
     have names beginning with $ or $$.  Check for those, first.  */

  sym = lookup_symbol (copy_name (str), (struct block *) NULL,
		       VAR_DOMAIN, NULL);
  if (sym.symbol)
    {
      write_exp_elt_opcode (ps, OP_VAR_VALUE);
      write_exp_elt_block (ps, sym.block);
      write_exp_elt_sym (ps, sym.symbol);
      write_exp_elt_opcode (ps, OP_VAR_VALUE);
      return;
    }
  msym = lookup_bound_minimal_symbol (copy_name (str));
  if (msym.minsym)
    {
      write_exp_msymbol (ps, msym);
      return;
    }

  /* Any other names are assumed to be debugger internal variables.  */

  write_exp_elt_opcode (ps, OP_INTERNALVAR);
  write_exp_elt_intern (ps, create_internalvar (copy_name (str) + 1));
  write_exp_elt_opcode (ps, OP_INTERNALVAR);
  return;
handle_last:
  write_exp_elt_opcode (ps, OP_LAST);
  write_exp_elt_longcst (ps, (LONGEST) i);
  write_exp_elt_opcode (ps, OP_LAST);
  return;
handle_register:
  write_exp_elt_opcode (ps, OP_REGISTER);
  str.length--;
  str.ptr++;
  write_exp_string (ps, str);
  write_exp_elt_opcode (ps, OP_REGISTER);
  return;
}


const char *
find_template_name_end (const char *p)
{
  int depth = 1;
  int just_seen_right = 0;
  int just_seen_colon = 0;
  int just_seen_space = 0;

  if (!p || (*p != '<'))
    return 0;

  while (*++p)
    {
      switch (*p)
	{
	case '\'':
	case '\"':
	case '{':
	case '}':
	  /* In future, may want to allow these??  */
	  return 0;
	case '<':
	  depth++;		/* start nested template */
	  if (just_seen_colon || just_seen_right || just_seen_space)
	    return 0;		/* but not after : or :: or > or space */
	  break;
	case '>':
	  if (just_seen_colon || just_seen_right)
	    return 0;		/* end a (nested?) template */
	  just_seen_right = 1;	/* but not after : or :: */
	  if (--depth == 0)	/* also disallow >>, insist on > > */
	    return ++p;		/* if outermost ended, return */
	  break;
	case ':':
	  if (just_seen_space || (just_seen_colon > 1))
	    return 0;		/* nested class spec coming up */
	  just_seen_colon++;	/* we allow :: but not :::: */
	  break;
	case ' ':
	  break;
	default:
	  if (!((*p >= 'a' && *p <= 'z') ||	/* allow token chars */
		(*p >= 'A' && *p <= 'Z') ||
		(*p >= '0' && *p <= '9') ||
		(*p == '_') || (*p == ',') ||	/* commas for template args */
		(*p == '&') || (*p == '*') ||	/* pointer and ref types */
		(*p == '(') || (*p == ')') ||	/* function types */
		(*p == '[') || (*p == ']')))	/* array types */
	    return 0;
	}
      if (*p != ' ')
	just_seen_space = 0;
      if (*p != ':')
	just_seen_colon = 0;
      if (*p != '>')
	just_seen_right = 0;
    }
  return 0;
}


/* Return a null-terminated temporary copy of the name of a string token.

   Tokens that refer to names do so with explicit pointer and length,
   so they can share the storage that lexptr is parsing.
   When it is necessary to pass a name to a function that expects
   a null-terminated string, the substring is copied out
   into a separate block of storage.

   N.B. A single buffer is reused on each call.  */

char *
copy_name (struct stoken token)
{
  /* A temporary buffer for identifiers, so we can null-terminate them.
     We allocate this with xrealloc.  parse_exp_1 used to allocate with
     alloca, using the size of the whole expression as a conservative
     estimate of the space needed.  However, macro expansion can
     introduce names longer than the original expression; there's no
     practical way to know beforehand how large that might be.  */
  static char *namecopy;
  static size_t namecopy_size;

  /* Make sure there's enough space for the token.  */
  if (namecopy_size < token.length + 1)
    {
      namecopy_size = token.length + 1;
      namecopy = (char *) xrealloc (namecopy, token.length + 1);
    }
      
  memcpy (namecopy, token.ptr, token.length);
  namecopy[token.length] = 0;

  return namecopy;
}


/* See comments on parser-defs.h.  */

int
prefixify_expression (struct expression *expr)
{
  int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
  struct expression *temp;
  int inpos = expr->nelts, outpos = 0;

  temp = (struct expression *) alloca (len);

  /* Copy the original expression into temp.  */
  memcpy (temp, expr, len);

  return prefixify_subexp (temp, expr, inpos, outpos);
}

/* Return the number of exp_elements in the postfix subexpression 
   of EXPR whose operator is at index ENDPOS - 1 in EXPR.  */

static int
length_of_subexp (struct expression *expr, int endpos)
{
  int oplen, args;

  operator_length (expr, endpos, &oplen, &args);

  while (args > 0)
    {
      oplen += length_of_subexp (expr, endpos - oplen);
      args--;
    }

  return oplen;
}

/* Sets *OPLENP to the length of the operator whose (last) index is 
   ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that
   operator takes.  */

void
operator_length (const struct expression *expr, int endpos, int *oplenp,
		 int *argsp)
{
  expr->language_defn->la_exp_desc->operator_length (expr, endpos,
						     oplenp, argsp);
}

/* Default value for operator_length in exp_descriptor vectors.  */

void
operator_length_standard (const struct expression *expr, int endpos,
			  int *oplenp, int *argsp)
{
  int oplen = 1;
  int args = 0;
  enum range_type range_type;
  int i;

  if (endpos < 1)
    error (_("?error in operator_length_standard"));

  i = (int) expr->elts[endpos - 1].opcode;

  switch (i)
    {
      /* C++  */
    case OP_SCOPE:
      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
      oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
      break;

    case OP_LONG:
    case OP_FLOAT:
    case OP_VAR_VALUE:
    case OP_VAR_MSYM_VALUE:
      oplen = 4;
      break;

    case OP_FUNC_STATIC_VAR:
      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
      args = 1;
      break;

    case OP_TYPE:
    case OP_BOOL:
    case OP_LAST:
    case OP_INTERNALVAR:
    case OP_VAR_ENTRY_VALUE:
      oplen = 3;
      break;

    case OP_COMPLEX:
      oplen = 3;
      args = 2;
      break;

    case OP_FUNCALL:
    case OP_F77_UNDETERMINED_ARGLIST:
      oplen = 3;
      args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
      break;

    case TYPE_INSTANCE:
      oplen = 5 + longest_to_int (expr->elts[endpos - 2].longconst);
      args = 1;
      break;

    case OP_OBJC_MSGCALL:	/* Objective C message (method) call.  */
      oplen = 4;
      args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
      break;

    case UNOP_MAX:
    case UNOP_MIN:
      oplen = 3;
      break;

    case UNOP_CAST_TYPE:
    case UNOP_DYNAMIC_CAST:
    case UNOP_REINTERPRET_CAST:
    case UNOP_MEMVAL_TYPE:
      oplen = 1;
      args = 2;
      break;

    case BINOP_VAL:
    case UNOP_CAST:
    case UNOP_MEMVAL:
      oplen = 3;
      args = 1;
      break;

    case UNOP_ABS:
    case UNOP_CAP:
    case UNOP_CHR:
    case UNOP_FLOAT:
    case UNOP_HIGH:
    case UNOP_ODD:
    case UNOP_ORD:
    case UNOP_TRUNC:
    case OP_TYPEOF:
    case OP_DECLTYPE:
    case OP_TYPEID:
      oplen = 1;
      args = 1;
      break;

    case OP_ADL_FUNC:
      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
      oplen++;
      oplen++;
      break;

    case STRUCTOP_STRUCT:
    case STRUCTOP_PTR:
      args = 1;
      /* fall through */
    case OP_REGISTER:
    case OP_M2_STRING:
    case OP_STRING:
    case OP_OBJC_NSSTRING:	/* Objective C Foundation Class
				   NSString constant.  */
    case OP_OBJC_SELECTOR:	/* Objective C "@selector" pseudo-op.  */
    case OP_NAME:
      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
      break;

    case OP_ARRAY:
      oplen = 4;
      args = longest_to_int (expr->elts[endpos - 2].longconst);
      args -= longest_to_int (expr->elts[endpos - 3].longconst);
      args += 1;
      break;

    case TERNOP_COND:
    case TERNOP_SLICE:
      args = 3;
      break;

      /* Modula-2 */
    case MULTI_SUBSCRIPT:
      oplen = 3;
      args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
      break;

    case BINOP_ASSIGN_MODIFY:
      oplen = 3;
      args = 2;
      break;

      /* C++ */
    case OP_THIS:
      oplen = 2;
      break;

    case OP_RANGE:
      oplen = 3;
      range_type = (enum range_type)
	longest_to_int (expr->elts[endpos - 2].longconst);

      switch (range_type)
	{
	case LOW_BOUND_DEFAULT:
	case HIGH_BOUND_DEFAULT:
	  args = 1;
	  break;
	case BOTH_BOUND_DEFAULT:
	  args = 0;
	  break;
	case NONE_BOUND_DEFAULT:
	  args = 2;
	  break;
	}

      break;

    default:
      args = 1 + (i < (int) BINOP_END);
    }

  *oplenp = oplen;
  *argsp = args;
}

/* Copy the subexpression ending just before index INEND in INEXPR
   into OUTEXPR, starting at index OUTBEG.
   In the process, convert it from suffix to prefix form.
   If EXPOUT_LAST_STRUCT is -1, then this function always returns -1.
   Otherwise, it returns the index of the subexpression which is the
   left-hand-side of the expression at EXPOUT_LAST_STRUCT.  */

static int
prefixify_subexp (struct expression *inexpr,
		  struct expression *outexpr, int inend, int outbeg)
{
  int oplen;
  int args;
  int i;
  int *arglens;
  int result = -1;

  operator_length (inexpr, inend, &oplen, &args);

  /* Copy the final operator itself, from the end of the input
     to the beginning of the output.  */
  inend -= oplen;
  memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
	  EXP_ELEM_TO_BYTES (oplen));
  outbeg += oplen;

  if (expout_last_struct == inend)
    result = outbeg - oplen;

  /* Find the lengths of the arg subexpressions.  */
  arglens = (int *) alloca (args * sizeof (int));
  for (i = args - 1; i >= 0; i--)
    {
      oplen = length_of_subexp (inexpr, inend);
      arglens[i] = oplen;
      inend -= oplen;
    }

  /* Now copy each subexpression, preserving the order of
     the subexpressions, but prefixifying each one.
     In this loop, inend starts at the beginning of
     the expression this level is working on
     and marches forward over the arguments.
     outbeg does similarly in the output.  */
  for (i = 0; i < args; i++)
    {
      int r;

      oplen = arglens[i];
      inend += oplen;
      r = prefixify_subexp (inexpr, outexpr, inend, outbeg);
      if (r != -1)
	{
	  /* Return immediately.  We probably have only parsed a
	     partial expression, so we don't want to try to reverse
	     the other operands.  */
	  return r;
	}
      outbeg += oplen;
    }

  return result;
}

/* Read an expression from the string *STRINGPTR points to,
   parse it, and return a pointer to a struct expression that we malloc.
   Use block BLOCK as the lexical context for variable names;
   if BLOCK is zero, use the block of the selected stack frame.
   Meanwhile, advance *STRINGPTR to point after the expression,
   at the first nonwhite character that is not part of the expression
   (possibly a null character).

   If COMMA is nonzero, stop if a comma is reached.  */

expression_up
parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
	     int comma)
{
  return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL);
}

static expression_up
parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
		      const struct block *block,
		      int comma, int void_context_p, int *out_subexp)
{
  return parse_exp_in_context_1 (stringptr, pc, block, comma,
				 void_context_p, out_subexp);
}

/* As for parse_exp_1, except that if VOID_CONTEXT_P, then
   no value is expected from the expression.
   OUT_SUBEXP is set when attempting to complete a field name; in this
   case it is set to the index of the subexpression on the
   left-hand-side of the struct op.  If not doing such completion, it
   is left untouched.  */

static expression_up
parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
			const struct block *block,
			int comma, int void_context_p, int *out_subexp)
{
  const struct language_defn *lang = NULL;
  int subexp;

  lexptr = *stringptr;
  prev_lexptr = NULL;

  paren_depth = 0;
  type_stack.depth = 0;
  expout_last_struct = -1;
  expout_tag_completion_type = TYPE_CODE_UNDEF;
  xfree (expout_completion_name);
  expout_completion_name = NULL;

  comma_terminates = comma;

  if (lexptr == 0 || *lexptr == 0)
    error_no_arg (_("expression to compute"));

  std::vector<int> funcalls;
  scoped_restore save_funcall_chain = make_scoped_restore (&funcall_chain,
							   &funcalls);

  expression_context_block = block;

  /* If no context specified, try using the current frame, if any.  */
  if (!expression_context_block)
    expression_context_block = get_selected_block (&expression_context_pc);
  else if (pc == 0)
    expression_context_pc = BLOCK_START (expression_context_block);
  else
    expression_context_pc = pc;

  /* Fall back to using the current source static context, if any.  */

  if (!expression_context_block)
    {
      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
      if (cursal.symtab)
	expression_context_block
	  = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (cursal.symtab),
			       STATIC_BLOCK);
      if (expression_context_block)
	expression_context_pc = BLOCK_START (expression_context_block);
    }

  if (language_mode == language_mode_auto && block != NULL)
    {
      /* Find the language associated to the given context block.
         Default to the current language if it can not be determined.

         Note that using the language corresponding to the current frame
         can sometimes give unexpected results.  For instance, this
         routine is often called several times during the inferior
         startup phase to re-parse breakpoint expressions after
         a new shared library has been loaded.  The language associated
         to the current frame at this moment is not relevant for
         the breakpoint.  Using it would therefore be silly, so it seems
         better to rely on the current language rather than relying on
         the current frame language to parse the expression.  That's why
         we do the following language detection only if the context block
         has been specifically provided.  */
      struct symbol *func = block_linkage_function (block);

      if (func != NULL)
        lang = language_def (SYMBOL_LANGUAGE (func));
      if (lang == NULL || lang->la_language == language_unknown)
        lang = current_language;
    }
  else
    lang = current_language;

  /* get_current_arch may reset CURRENT_LANGUAGE via select_frame.
     While we need CURRENT_LANGUAGE to be set to LANG (for lookup_symbol
     and others called from *.y) ensure CURRENT_LANGUAGE gets restored
     to the value matching SELECTED_FRAME as set by get_current_arch.  */

  parser_state ps (10, lang, get_current_arch ());

  scoped_restore_current_language lang_saver;
  set_language (lang->la_language);

  TRY
    {
      if (lang->la_parser (&ps))
        lang->la_error (NULL);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      if (! parse_completion)
	throw_exception (except);
    }
  END_CATCH

  /* We have to operate on an "expression *", due to la_post_parser,
     which explains this funny-looking double release.  */
  expression_up result = ps.release ();

  /* Convert expression from postfix form as generated by yacc
     parser, to a prefix form.  */

  if (expressiondebug)
    dump_raw_expression (result.get (), gdb_stdlog,
			 "before conversion to prefix form");

  subexp = prefixify_expression (result.get ());
  if (out_subexp)
    *out_subexp = subexp;

  lang->la_post_parser (&result, void_context_p);

  if (expressiondebug)
    dump_prefix_expression (result.get (), gdb_stdlog);

  *stringptr = lexptr;
  return result;
}

/* Parse STRING as an expression, and complain if this fails
   to use up all of the contents of STRING.  */

expression_up
parse_expression (const char *string)
{
  expression_up exp = parse_exp_1 (&string, 0, 0, 0);
  if (*string)
    error (_("Junk after end of expression."));
  return exp;
}

/* Same as parse_expression, but using the given language (LANG)
   to parse the expression.  */

expression_up
parse_expression_with_language (const char *string, enum language lang)
{
  gdb::optional<scoped_restore_current_language> lang_saver;
  if (current_language->la_language != lang)
    {
      lang_saver.emplace ();
      set_language (lang);
    }

  return parse_expression (string);
}

/* Parse STRING as an expression.  If parsing ends in the middle of a
   field reference, return the type of the left-hand-side of the
   reference; furthermore, if the parsing ends in the field name,
   return the field name in *NAME.  If the parsing ends in the middle
   of a field reference, but the reference is somehow invalid, throw
   an exception.  In all other cases, return NULL.  Returned non-NULL
   *NAME must be freed by the caller.  */

struct type *
parse_expression_for_completion (const char *string, char **name,
				 enum type_code *code)
{
  expression_up exp;
  struct value *val;
  int subexp;

  TRY
    {
      parse_completion = 1;
      exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
    }
  CATCH (except, RETURN_MASK_ERROR)
    {
      /* Nothing, EXP remains NULL.  */
    }
  END_CATCH

  parse_completion = 0;
  if (exp == NULL)
    return NULL;

  if (expout_tag_completion_type != TYPE_CODE_UNDEF)
    {
      *code = expout_tag_completion_type;
      *name = expout_completion_name;
      expout_completion_name = NULL;
      return NULL;
    }

  if (expout_last_struct == -1)
    return NULL;

  *name = extract_field_op (exp.get (), &subexp);
  if (!*name)
    return NULL;

  /* This might throw an exception.  If so, we want to let it
     propagate.  */
  val = evaluate_subexpression_type (exp.get (), subexp);
  /* (*NAME) is a part of the EXP memory block freed below.  */
  *name = xstrdup (*name);

  return value_type (val);
}

/* A post-parser that does nothing.  */

void
null_post_parser (expression_up *exp, int void_context_p)
{
}

/* Parse floating point value P of length LEN.
   Return false if invalid, true if valid.
   The successfully parsed number is stored in DATA in
   target format for floating-point type TYPE.

   NOTE: This accepts the floating point syntax that sscanf accepts.  */

bool
parse_float (const char *p, int len,
	     const struct type *type, gdb_byte *data)
{
  return target_float_from_string (data, type, std::string (p, len));
}

/* Stuff for maintaining a stack of types.  Currently just used by C, but
   probably useful for any language which declares its types "backwards".  */

/* Ensure that there are HOWMUCH open slots on the type stack STACK.  */

static void
type_stack_reserve (struct type_stack *stack, int howmuch)
{
  if (stack->depth + howmuch >= stack->size)
    {
      stack->size *= 2;
      if (stack->size < howmuch)
	stack->size = howmuch;
      stack->elements = XRESIZEVEC (union type_stack_elt, stack->elements,
				    stack->size);
    }
}

/* Ensure that there is a single open slot in the global type stack.  */

static void
check_type_stack_depth (void)
{
  type_stack_reserve (&type_stack, 1);
}

/* A helper function for insert_type and insert_type_address_space.
   This does work of expanding the type stack and inserting the new
   element, ELEMENT, into the stack at location SLOT.  */

static void
insert_into_type_stack (int slot, union type_stack_elt element)
{
  check_type_stack_depth ();

  if (slot < type_stack.depth)
    memmove (&type_stack.elements[slot + 1], &type_stack.elements[slot],
	     (type_stack.depth - slot) * sizeof (union type_stack_elt));
  type_stack.elements[slot] = element;
  ++type_stack.depth;
}

/* Insert a new type, TP, at the bottom of the type stack.  If TP is
   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
   previous tp_pointer) if there is anything on the stack, or simply pushed
   if the stack is empty.  Other values for TP are invalid.  */

void
insert_type (enum type_pieces tp)
{
  union type_stack_elt element;
  int slot;

  gdb_assert (tp == tp_pointer || tp == tp_reference
	      || tp == tp_rvalue_reference || tp == tp_const
	      || tp == tp_volatile);

  /* If there is anything on the stack (we know it will be a
     tp_pointer), insert the qualifier above it.  Otherwise, simply
     push this on the top of the stack.  */
  if (type_stack.depth && (tp == tp_const || tp == tp_volatile))
    slot = 1;
  else
    slot = 0;

  element.piece = tp;
  insert_into_type_stack (slot, element);
}

void
push_type (enum type_pieces tp)
{
  check_type_stack_depth ();
  type_stack.elements[type_stack.depth++].piece = tp;
}

void
push_type_int (int n)
{
  check_type_stack_depth ();
  type_stack.elements[type_stack.depth++].int_val = n;
}

/* Insert a tp_space_identifier and the corresponding address space
   value into the stack.  STRING is the name of an address space, as
   recognized by address_space_name_to_int.  If the stack is empty,
   the new elements are simply pushed.  If the stack is not empty,
   this function assumes that the first item on the stack is a
   tp_pointer, and the new values are inserted above the first
   item.  */

void
insert_type_address_space (struct parser_state *pstate, char *string)
{
  union type_stack_elt element;
  int slot;

  /* If there is anything on the stack (we know it will be a
     tp_pointer), insert the address space qualifier above it.
     Otherwise, simply push this on the top of the stack.  */
  if (type_stack.depth)
    slot = 1;
  else
    slot = 0;

  element.piece = tp_space_identifier;
  insert_into_type_stack (slot, element);
  element.int_val = address_space_name_to_int (parse_gdbarch (pstate),
					       string);
  insert_into_type_stack (slot, element);
}

enum type_pieces
pop_type (void)
{
  if (type_stack.depth)
    return type_stack.elements[--type_stack.depth].piece;
  return tp_end;
}

int
pop_type_int (void)
{
  if (type_stack.depth)
    return type_stack.elements[--type_stack.depth].int_val;
  /* "Can't happen".  */
  return 0;
}

/* Pop a type list element from the global type stack.  */

static VEC (type_ptr) *
pop_typelist (void)
{
  gdb_assert (type_stack.depth);
  return type_stack.elements[--type_stack.depth].typelist_val;
}

/* Pop a type_stack element from the global type stack.  */

static struct type_stack *
pop_type_stack (void)
{
  gdb_assert (type_stack.depth);
  return type_stack.elements[--type_stack.depth].stack_val;
}

/* Append the elements of the type stack FROM to the type stack TO.
   Always returns TO.  */

struct type_stack *
append_type_stack (struct type_stack *to, struct type_stack *from)
{
  type_stack_reserve (to, from->depth);

  memcpy (&to->elements[to->depth], &from->elements[0],
	  from->depth * sizeof (union type_stack_elt));
  to->depth += from->depth;

  return to;
}

/* Push the type stack STACK as an element on the global type stack.  */

void
push_type_stack (struct type_stack *stack)
{
  check_type_stack_depth ();
  type_stack.elements[type_stack.depth++].stack_val = stack;
  push_type (tp_type_stack);
}

/* Copy the global type stack into a newly allocated type stack and
   return it.  The global stack is cleared.  The returned type stack
   must be freed with type_stack_cleanup.  */

struct type_stack *
get_type_stack (void)
{
  struct type_stack *result = XNEW (struct type_stack);

  *result = type_stack;
  type_stack.depth = 0;
  type_stack.size = 0;
  type_stack.elements = NULL;

  return result;
}

/* A cleanup function that destroys a single type stack.  */

void
type_stack_cleanup (void *arg)
{
  struct type_stack *stack = (struct type_stack *) arg;

  xfree (stack->elements);
  xfree (stack);
}

/* Push a function type with arguments onto the global type stack.
   LIST holds the argument types.  If the final item in LIST is NULL,
   then the function will be varargs.  */

void
push_typelist (VEC (type_ptr) *list)
{
  check_type_stack_depth ();
  type_stack.elements[type_stack.depth++].typelist_val = list;
  push_type (tp_function_with_arguments);
}

/* Pop the type stack and return a type_instance_flags that
   corresponds the const/volatile qualifiers on the stack.  This is
   called by the C++ parser when parsing methods types, and as such no
   other kind of type in the type stack is expected.  */

type_instance_flags
follow_type_instance_flags ()
{
  type_instance_flags flags = 0;

  for (;;)
    switch (pop_type ())
      {
      case tp_end:
	return flags;
      case tp_const:
	flags |= TYPE_INSTANCE_FLAG_CONST;
	break;
      case tp_volatile:
	flags |= TYPE_INSTANCE_FLAG_VOLATILE;
	break;
      default:
	gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
      }
}


/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
   as modified by all the stuff on the stack.  */
struct type *
follow_types (struct type *follow_type)
{
  int done = 0;
  int make_const = 0;
  int make_volatile = 0;
  int make_addr_space = 0;
  int array_size;

  while (!done)
    switch (pop_type ())
      {
      case tp_end:
	done = 1;
	if (make_const)
	  follow_type = make_cv_type (make_const, 
				      TYPE_VOLATILE (follow_type), 
				      follow_type, 0);
	if (make_volatile)
	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
				      make_volatile, 
				      follow_type, 0);
	if (make_addr_space)
	  follow_type = make_type_with_address_space (follow_type, 
						      make_addr_space);
	make_const = make_volatile = 0;
	make_addr_space = 0;
	break;
      case tp_const:
	make_const = 1;
	break;
      case tp_volatile:
	make_volatile = 1;
	break;
      case tp_space_identifier:
	make_addr_space = pop_type_int ();
	break;
      case tp_pointer:
	follow_type = lookup_pointer_type (follow_type);
	if (make_const)
	  follow_type = make_cv_type (make_const, 
				      TYPE_VOLATILE (follow_type), 
				      follow_type, 0);
	if (make_volatile)
	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
				      make_volatile, 
				      follow_type, 0);
	if (make_addr_space)
	  follow_type = make_type_with_address_space (follow_type, 
						      make_addr_space);
	make_const = make_volatile = 0;
	make_addr_space = 0;
	break;
      case tp_reference:
	 follow_type = lookup_lvalue_reference_type (follow_type);
	 goto process_reference;
	case tp_rvalue_reference:
	 follow_type = lookup_rvalue_reference_type (follow_type);
	process_reference:
	 if (make_const)
	   follow_type = make_cv_type (make_const,
				       TYPE_VOLATILE (follow_type),
				       follow_type, 0);
	 if (make_volatile)
	   follow_type = make_cv_type (TYPE_CONST (follow_type),
				       make_volatile,
				       follow_type, 0);
	 if (make_addr_space)
	   follow_type = make_type_with_address_space (follow_type,
						       make_addr_space);
	make_const = make_volatile = 0;
	make_addr_space = 0;
	break;
      case tp_array:
	array_size = pop_type_int ();
	/* FIXME-type-allocation: need a way to free this type when we are
	   done with it.  */
	follow_type =
	  lookup_array_range_type (follow_type,
				   0, array_size >= 0 ? array_size - 1 : 0);
	if (array_size < 0)
	  TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (follow_type))
	    = PROP_UNDEFINED;
	break;
      case tp_function:
	/* FIXME-type-allocation: need a way to free this type when we are
	   done with it.  */
	follow_type = lookup_function_type (follow_type);
	break;

      case tp_function_with_arguments:
	{
	  VEC (type_ptr) *args = pop_typelist ();

	  follow_type
	    = lookup_function_type_with_arguments (follow_type,
						   VEC_length (type_ptr, args),
						   VEC_address (type_ptr,
								args));
	  VEC_free (type_ptr, args);
	}
	break;

      case tp_type_stack:
	{
	  struct type_stack *stack = pop_type_stack ();
	  /* Sort of ugly, but not really much worse than the
	     alternatives.  */
	  struct type_stack save = type_stack;

	  type_stack = *stack;
	  follow_type = follow_types (follow_type);
	  gdb_assert (type_stack.depth == 0);

	  type_stack = save;
	}
	break;
      default:
	gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
      }
  return follow_type;
}

/* This function avoids direct calls to fprintf 
   in the parser generated debug code.  */
void
parser_fprintf (FILE *x, const char *y, ...)
{ 
  va_list args;

  va_start (args, y);
  if (x == stderr)
    vfprintf_unfiltered (gdb_stderr, y, args); 
  else
    {
      fprintf_unfiltered (gdb_stderr, " Unknown FILE used.\n");
      vfprintf_unfiltered (gdb_stderr, y, args);
    }
  va_end (args);
}

/* Implementation of the exp_descriptor method operator_check.  */

int
operator_check_standard (struct expression *exp, int pos,
			 int (*objfile_func) (struct objfile *objfile,
					      void *data),
			 void *data)
{
  const union exp_element *const elts = exp->elts;
  struct type *type = NULL;
  struct objfile *objfile = NULL;

  /* Extended operators should have been already handled by exp_descriptor
     iterate method of its specific language.  */
  gdb_assert (elts[pos].opcode < OP_EXTENDED0);

  /* Track the callers of write_exp_elt_type for this table.  */

  switch (elts[pos].opcode)
    {
    case BINOP_VAL:
    case OP_COMPLEX:
    case OP_FLOAT:
    case OP_LONG:
    case OP_SCOPE:
    case OP_TYPE:
    case UNOP_CAST:
    case UNOP_MAX:
    case UNOP_MEMVAL:
    case UNOP_MIN:
      type = elts[pos + 1].type;
      break;

    case TYPE_INSTANCE:
      {
	LONGEST arg, nargs = elts[pos + 2].longconst;

	for (arg = 0; arg < nargs; arg++)
	  {
	    struct type *type = elts[pos + 3 + arg].type;
	    struct objfile *objfile = TYPE_OBJFILE (type);

	    if (objfile && (*objfile_func) (objfile, data))
	      return 1;
	  }
      }
      break;

    case OP_VAR_VALUE:
      {
	const struct block *const block = elts[pos + 1].block;
	const struct symbol *const symbol = elts[pos + 2].symbol;

	/* Check objfile where the variable itself is placed.
	   SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
	if ((*objfile_func) (symbol_objfile (symbol), data))
	  return 1;

	/* Check objfile where is placed the code touching the variable.  */
	objfile = lookup_objfile_from_block (block);

	type = SYMBOL_TYPE (symbol);
      }
      break;
    case OP_VAR_MSYM_VALUE:
      objfile = elts[pos + 1].objfile;
      break;
    }

  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */

  if (type && TYPE_OBJFILE (type)
      && (*objfile_func) (TYPE_OBJFILE (type), data))
    return 1;
  if (objfile && (*objfile_func) (objfile, data))
    return 1;

  return 0;
}

/* Call OBJFILE_FUNC for any objfile found being referenced by EXP.
   OBJFILE_FUNC is never called with NULL OBJFILE.  OBJFILE_FUNC get
   passed an arbitrary caller supplied DATA pointer.  If OBJFILE_FUNC
   returns non-zero value then (any other) non-zero value is immediately
   returned to the caller.  Otherwise zero is returned after iterating
   through whole EXP.  */

static int
exp_iterate (struct expression *exp,
	     int (*objfile_func) (struct objfile *objfile, void *data),
	     void *data)
{
  int endpos;

  for (endpos = exp->nelts; endpos > 0; )
    {
      int pos, args, oplen = 0;

      operator_length (exp, endpos, &oplen, &args);
      gdb_assert (oplen > 0);

      pos = endpos - oplen;
      if (exp->language_defn->la_exp_desc->operator_check (exp, pos,
							   objfile_func, data))
	return 1;

      endpos = pos;
    }

  return 0;
}

/* Helper for exp_uses_objfile.  */

static int
exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
{
  struct objfile *objfile = (struct objfile *) objfile_voidp;

  if (exp_objfile->separate_debug_objfile_backlink)
    exp_objfile = exp_objfile->separate_debug_objfile_backlink;

  return exp_objfile == objfile;
}

/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
   is unloaded), otherwise return 0.  OBJFILE must not be a separate debug info
   file.  */

int
exp_uses_objfile (struct expression *exp, struct objfile *objfile)
{
  gdb_assert (objfile->separate_debug_objfile_backlink == NULL);

  return exp_iterate (exp, exp_uses_objfile_iter, objfile);
}

/* See definition in parser-defs.h.  */

void
increase_expout_size (struct parser_state *ps, size_t lenelt)
{
  if ((ps->expout_ptr + lenelt) >= ps->expout_size)
    {
      ps->expout_size = std::max (ps->expout_size * 2,
				  ps->expout_ptr + lenelt + 10);
      ps->expout.reset (XRESIZEVAR (expression,
				    ps->expout.release (),
				    (sizeof (struct expression)
				     + EXP_ELEM_TO_BYTES (ps->expout_size))));
    }
}

void
_initialize_parse (void)
{
  type_stack.size = 0;
  type_stack.depth = 0;
  type_stack.elements = NULL;

  add_setshow_zuinteger_cmd ("expression", class_maintenance,
			     &expressiondebug,
			     _("Set expression debugging."),
			     _("Show expression debugging."),
			     _("When non-zero, the internal representation "
			       "of expressions will be printed."),
			     NULL,
			     show_expressiondebug,
			     &setdebuglist, &showdebuglist);
  add_setshow_boolean_cmd ("parser", class_maintenance,
			    &parser_debug,
			   _("Set parser debugging."),
			   _("Show parser debugging."),
			   _("When non-zero, expression parser "
			     "tracing will be enabled."),
			    NULL,
			    show_parserdebug,
			    &setdebuglist, &showdebuglist);
}
