/* Parse expressions for GDB.

   Copyright (C) 1986-2023 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)
{
  gdb_printf (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)
{
  gdb_printf (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 *,
      std::unique_ptr<expr_completion_base> *);

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

  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 = bound_msym.minsym->value_raw_address ();
    }
  else if (msymbol_is_function (objfile, msymbol, &addr))
    {
      if (addr != bound_msym.value_address ())
	{
	  /* 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 () == mst_data_gnu_ifunc)
	    type = mst_text_gnu_ifunc;
	  else
	    type = mst_text;
	  section = NULL;
	}
    }
  else
    addr = bound_msym.value_address ();

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

bool
expr_complete_tag::complete (struct expression *exp,
			     completion_tracker &tracker)
{
  collect_symbol_completion_matches_type (tracker, m_name.get (),
					  m_name.get (), m_code);
  return true;
}

/* See parser-defs.h.  */

void
parser_state::mark_struct_expression (expr::structop_base_operation *op)
{
  gdb_assert (parse_completion && m_completion_state == nullptr);
  m_completion_state.reset (new expr_complete_structop (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 == nullptr);
  gdb_assert (tag == TYPE_CODE_UNION
	      || tag == TYPE_CODE_STRUCT
	      || tag == TYPE_CODE_ENUM);
  m_completion_state.reset
    (new expr_complete_tag (tag, 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,
		      std::unique_ptr<expr_completion_base> *completer)
{
  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 = expression_context_block->entry_pc ();
  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
	  = cursal.symtab->compunit ()->blockvector ()->static_block ();

      if (expression_context_block)
	expression_context_pc = expression_context_block->entry_pc ();
    }

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

      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,
		   completer != nullptr, tracker, void_context_p);

  scoped_restore_current_language lang_saver;
  set_language (lang->la_language);

  try
    {
      lang->parser (&ps);
    }
  catch (const gdb_exception_error &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)
    result->dump (gdb_stdlog);

  if (completer != nullptr)
    *completer = 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 the parse is marked for
   completion, set COMPLETER and return the expression.  In all other
   cases, return NULL.  */

expression_up
parse_expression_for_completion
     (const char *string,
      std::unique_ptr<expr_completion_base> *completer)
{
  expression_up exp;

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

  /* If we didn't get a completion result, be sure to also not return
     an expression to our caller.  */
  if (*completer == nullptr)
    return nullptr;

  return exp;
}

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

/* Return true if the number N_SIGN * N fits in a type with TYPE_BITS and
   TYPE_SIGNED_P.  N_SIGNED is either 1 or -1.  */

bool
fits_in_type (int n_sign, ULONGEST n, int type_bits, bool type_signed_p)
{
  /* Normalize -0.  */
  if (n == 0 && n_sign == -1)
    n_sign = 1;

  if (n_sign == -1 && !type_signed_p)
    /* Can't fit a negative number in an unsigned type.  */
    return false;

  if (type_bits > sizeof (ULONGEST) * 8)
    return true;

  ULONGEST smax = (ULONGEST)1 << (type_bits - 1);
  if (n_sign == -1)
    {
      /* Negative number, signed type.  */
      return (n <= smax);
    }
  else if (n_sign == 1 && type_signed_p)
    {
      /* Positive number, signed type.  */
      return (n < smax);
    }
  else if (n_sign == 1 && !type_signed_p)
    {
      /* Positive number, unsigned type.  */
      return ((n >> 1) >> (type_bits - 1)) == 0;
    }
  else
    gdb_assert_not_reached ("");
}

/* 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)
    gdb_vprintf (gdb_stderr, y, args); 
  else
    {
      gdb_printf (gdb_stderr, " Unknown FILE used.\n");
      gdb_vprintf (gdb_stderr, y, args);
    }
  va_end (args);
}

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