/* Parse expressions for GDB.

   Copyright (C) 1986-2021 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 "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 "gdbsupport/gdb_optional.h"
#include "c-exp.h"

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


/* True if an expression parser should set yydebug.  */
bool 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 expression_up parse_exp_in_context (const char **, CORE_ADDR,
					   const struct block *, int,
					   bool, innermost_block_tracker *,
					   expr_completion_state *);

/* Documented at it's declaration.  */

void
innermost_block_tracker::update (const struct block *b,
				 innermost_block_tracker_types t)
{
  if ((m_types & t) != 0
      && (m_innermost_block == NULL
	  || contained_in (b, m_innermost_block)))
    m_innermost_block = b;
}



/* 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 obj_section *section = msymbol->obj_section (objfile);
  enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);

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

  /* The minimal symbol might point to a function descriptor;
     resolve it to the actual code address instead.  */
  CORE_ADDR addr;
  if (is_tls)
    {
      /* Addresses of TLS symbols are really offsets into a
	 per-objfile/per-thread storage block.  */
      addr = MSYMBOL_VALUE_RAW_ADDRESS (bound_msym.minsym);
    }
  else if (msymbol_is_function (objfile, msymbol, &addr))
    {
      if (addr != BMSYMBOL_VALUE_ADDRESS (bound_msym))
	{
	  /* This means we resolved a function descriptor, and we now
	     have an address for a code/text symbol instead of a data
	     symbol.  */
	  if (MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc)
	    type = mst_text_gnu_ifunc;
	  else
	    type = mst_text;
	  section = NULL;
	}
    }
  else
    addr = BMSYMBOL_VALUE_ADDRESS (bound_msym);

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

/* See parser-defs.h.  */

void
parser_state::mark_struct_expression (expr::structop_base_operation *op)
{
  gdb_assert (parse_completion
	      && (m_completion_state.expout_tag_completion_type
		  == TYPE_CODE_UNDEF));
  m_completion_state.expout_last_op = op;
}

/* 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
parser_state::mark_completion_tag (enum type_code tag, const char *ptr,
				   int length)
{
  gdb_assert (parse_completion
	      && (m_completion_state.expout_tag_completion_type
		  == TYPE_CODE_UNDEF)
	      && m_completion_state.expout_completion_name == NULL
	      && m_completion_state.expout_last_op == nullptr);
  gdb_assert (tag == TYPE_CODE_UNION
	      || tag == TYPE_CODE_STRUCT
	      || tag == TYPE_CODE_ENUM);
  m_completion_state.expout_tag_completion_type = tag;
  m_completion_state.expout_completion_name
    = make_unique_xstrndup (ptr, length);
}

/* See parser-defs.h.  */

void
parser_state::push_c_string (int kind, struct stoken_vector *vec)
{
  std::vector<std::string> data (vec->len);
  for (int i = 0; i < vec->len; ++i)
    data[i] = std::string (vec->tokens[i].ptr, vec->tokens[i].length);

  push_new<expr::c_string_operation> ((enum c_string_type_values) kind,
				      std::move (data));
}

/* See parser-defs.h.  */

void
parser_state::push_symbol (const char *name, block_symbol sym)
{
  if (sym.symbol != nullptr)
    {
      if (symbol_read_needs_frame (sym.symbol))
	block_tracker->update (sym);
      push_new<expr::var_value_operation> (sym);
    }
  else
    {
      struct bound_minimal_symbol msymbol = lookup_bound_minimal_symbol (name);
      if (msymbol.minsym != NULL)
	push_new<expr::var_msym_value_operation> (msymbol);
      else if (!have_full_symbols () && !have_partial_symbols ())
	error (_("No symbol table is loaded.  Use the \"file\" command."));
      else
	error (_("No symbol \"%s\" in current context."), name);
    }
}

/* See parser-defs.h.  */

void
parser_state::push_dollar (struct stoken str)
{
  struct block_symbol sym;
  struct bound_minimal_symbol msym;
  struct internalvar *isym = NULL;
  std::string copy;

  /* 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 (gdbarch (),
				   str.ptr + 1, str.length - 1);
  if (i >= 0)
    goto handle_register;

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

  copy = copy_name (str);
  isym = lookup_only_internalvar (copy.c_str () + 1);
  if (isym)
    {
      push_new<expr::internalvar_operation> (isym);
      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.c_str (), NULL, VAR_DOMAIN, NULL);
  if (sym.symbol)
    {
      push_new<expr::var_value_operation> (sym);
      return;
    }
  msym = lookup_bound_minimal_symbol (copy.c_str ());
  if (msym.minsym)
    {
      push_new<expr::var_msym_value_operation> (msym);
      return;
    }

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

  push_new<expr::internalvar_operation>
    (create_internalvar (copy.c_str () + 1));
  return;
handle_last:
  push_new<expr::last_operation> (i);
  return;
handle_register:
  str.length--;
  str.ptr++;
  push_new<expr::register_operation> (copy_name (str));
  block_tracker->update (expression_context_block,
			 INNERMOST_BLOCK_FOR_REGISTERS);
  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.  */

std::string
copy_name (struct stoken token)
{
  return std::string (token.ptr, token.length);
}


/* 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, innermost_block_tracker *tracker)
{
  return parse_exp_in_context (stringptr, pc, block, comma, false,
			       tracker, nullptr);
}

/* As for parse_exp_1, except that if VOID_CONTEXT_P, then
   no value is expected from the expression.  */

static expression_up
parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
		      const struct block *block,
		      int comma, bool void_context_p,
		      innermost_block_tracker *tracker,
		      expr_completion_state *cstate)
{
  const struct language_defn *lang = NULL;

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

  const struct block *expression_context_block = block;
  CORE_ADDR expression_context_pc = 0;

  innermost_block_tracker local_tracker;
  if (tracker == nullptr)
    tracker = &local_tracker;

  /* 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_ENTRY_PC (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_ENTRY_PC (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 (func->language ());
      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 (lang, get_current_arch (), expression_context_block,
		   expression_context_pc, comma, *stringptr,
		   cstate != nullptr, tracker, void_context_p);

  scoped_restore_current_language lang_saver;
  set_language (lang->la_language);

  try
    {
      lang->parser (&ps);
    }
  catch (const gdb_exception &except)
    {
      /* If parsing for completion, allow this to succeed; but if no
	 expression elements have been written, then there's nothing
	 to do, so fail.  */
      if (! ps.parse_completion || ps.expout->op == nullptr)
	throw;
    }

  expression_up result = ps.release ();
  result->op->set_outermost ();

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

  if (cstate != nullptr)
    *cstate = std::move (ps.m_completion_state);
  *stringptr = ps.lexptr;
  return result;
}

/* Parse STRING as an expression, and complain if this fails to use up
   all of the contents of STRING.  TRACKER, if non-null, will be
   updated by the parser.  VOID_CONTEXT_P should be true to indicate
   that the expression may be expected to return a value with void
   type.  Parsers are free to ignore this, or to use it to help with
   overload resolution decisions.  */

expression_up
parse_expression (const char *string, innermost_block_tracker *tracker,
		  bool void_context_p)
{
  expression_up exp = parse_exp_in_context (&string, 0, nullptr, 0,
					    void_context_p,
					    tracker, nullptr);
  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.  */

struct type *
parse_expression_for_completion (const char *string,
				 gdb::unique_xmalloc_ptr<char> *name,
				 enum type_code *code)
{
  expression_up exp;
  expr_completion_state cstate;

  try
    {
      exp = parse_exp_in_context (&string, 0, 0, 0, false, nullptr, &cstate);
    }
  catch (const gdb_exception_error &except)
    {
      /* Nothing, EXP remains NULL.  */
    }

  if (exp == NULL)
    return NULL;

  if (cstate.expout_tag_completion_type != TYPE_CODE_UNDEF)
    {
      *code = cstate.expout_tag_completion_type;
      *name = std::move (cstate.expout_completion_name);
      return NULL;
    }

  if (cstate.expout_last_op == nullptr)
    return nullptr;

  expr::structop_base_operation *op = cstate.expout_last_op;
  const std::string &fld = op->get_string ();
  *name = make_unique_xstrdup (fld.c_str ());
  return value_type (op->evaluate_lhs (exp.get ()));
}

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

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

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

  return exp->op->uses_objfile (objfile);
}

void _initialize_parse ();
void
_initialize_parse ()
{
  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);
}
