Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / gdb / parse.c
index d161776cf9cd4eac2580112ec4648cfd6e05f179..65e3c6008cdf626aebc040cc4015cf3b1629e251 100644 (file)
@@ -1,6 +1,6 @@
 /* Parse expressions for GDB.
 
 /* Parse expressions for GDB.
 
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
 
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
 #include "gdbcmd.h"
 #include "symfile.h"           /* for overlay functions */
 #include "inferior.h"
 #include "gdbcmd.h"
 #include "symfile.h"           /* for overlay functions */
 #include "inferior.h"
-#include "doublest.h"
+#include "target-float.h"
 #include "block.h"
 #include "source.h"
 #include "objfiles.h"
 #include "user-regs.h"
 #include "block.h"
 #include "source.h"
 #include "objfiles.h"
 #include "user-regs.h"
+#include <algorithm>
+#include "gdbsupport/gdb_optional.h"
 
 /* Standard set of definitions for printing, dumping, prefixifying,
  * and evaluating expressions.  */
 
 /* Standard set of definitions for printing, dumping, prefixifying,
  * and evaluating expressions.  */
@@ -62,32 +64,6 @@ const struct exp_descriptor exp_descriptor_standard =
     dump_subexp_body_standard,
     evaluate_subexp_standard
   };
     dump_subexp_body_standard,
     evaluate_subexp_standard
   };
-\f
-/* 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;
-
 \f
 static unsigned int expressiondebug = 0;
 static void
 \f
 static unsigned int expressiondebug = 0;
 static void
@@ -98,8 +74,8 @@ show_expressiondebug (struct ui_file *file, int from_tty,
 }
 
 
 }
 
 
-/* Non-zero if an expression parser should set yydebug.  */
-int parser_debug;
+/* True if an expression parser should set yydebug.  */
+bool parser_debug;
 
 static void
 show_parserdebug (struct ui_file *file, int from_tty,
 
 static void
 show_parserdebug (struct ui_file *file, int from_tty,
@@ -109,106 +85,59 @@ show_parserdebug (struct ui_file *file, int from_tty,
 }
 
 
 }
 
 
-static void free_funcalls (void *ignore);
-
 static int prefixify_subexp (struct expression *, struct expression *, int,
 static int prefixify_subexp (struct expression *, struct expression *, int,
-                            int);
-
-static struct expression *parse_exp_in_context (const char **, CORE_ADDR,
-                                               const struct block *, int, 
-                                               int, int *);
-static struct expression *parse_exp_in_context_1 (const char **, CORE_ADDR,
-                                                 const struct block *, int,
-                                                 int, int *);
+                            int, int);
 
 
-void _initialize_parse (void);
+static expression_up parse_exp_in_context (const char **, CORE_ADDR,
+                                          const struct block *, int,
+                                          int, int *,
+                                          innermost_block_tracker *,
+                                          expr_completion_state *);
 
 
-/* Data structure for saving values of arglist_len for function calls whose
-   arguments contain other function calls.  */
+static void increase_expout_size (struct expr_builder *ps, size_t lenelt);
 
 
-struct funcall
-  {
-    struct funcall *next;
-    int arglist_len;
-  };
 
 
-static struct funcall *funcall_chain;
-
-/* Begin counting arguments for a function call,
-   saving the data about any containing call.  */
+/* Documented at it's declaration.  */
 
 void
 
 void
-start_arglist (void)
+innermost_block_tracker::update (const struct block *b,
+                                innermost_block_tracker_types t)
 {
 {
-  struct funcall *new;
-
-  new = (struct funcall *) xmalloc (sizeof (struct funcall));
-  new->next = funcall_chain;
-  new->arglist_len = arglist_len;
-  arglist_len = 0;
-  funcall_chain = new;
+  if ((m_types & t) != 0
+      && (m_innermost_block == NULL
+         || contained_in (b, m_innermost_block)))
+    m_innermost_block = b;
 }
 
 }
 
-/* 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;
-  struct funcall *call = funcall_chain;
-
-  funcall_chain = call->next;
-  arglist_len = call->arglist_len;
-  xfree (call);
-  return val;
-}
-
-/* Free everything in the funcall chain.
-   Used when there is an error inside parsing.  */
-
-static void
-free_funcalls (void *ignore)
-{
-  struct funcall *call, *next;
-
-  for (call = funcall_chain; call; call = next)
-    {
-      next = call->next;
-      xfree (call);
-    }
-}
 \f
 
 /* See definition in parser-defs.h.  */
 
 \f
 
 /* See definition in parser-defs.h.  */
 
-void
-initialize_expout (struct parser_state *ps, size_t initial_size,
-                  const struct language_defn *lang,
-                  struct gdbarch *gdbarch)
+expr_builder::expr_builder (const struct language_defn *lang,
+                           struct gdbarch *gdbarch)
+  : expout_size (10),
+    expout (XNEWVAR (expression,
+                    (sizeof (expression)
+                     + EXP_ELEM_TO_BYTES (expout_size)))),
+    expout_ptr (0)
 {
 {
-  ps->expout_size = initial_size;
-  ps->expout_ptr = 0;
-  ps->expout = xmalloc (sizeof (struct expression)
-                       + EXP_ELEM_TO_BYTES (ps->expout_size));
-  ps->expout->language_defn = lang;
-  ps->expout->gdbarch = gdbarch;
+  expout->language_defn = lang;
+  expout->gdbarch = gdbarch;
 }
 
 }
 
-/* See definition in parser-defs.h.  */
-
-void
-reallocate_expout (struct parser_state *ps)
+expression_up
+expr_builder::release ()
 {
   /* Record the actual number of expression elements, and then
      reallocate the expression memory so that we free up any
      excess elements.  */
 
 {
   /* Record the actual number of expression elements, and then
      reallocate the expression memory so that we free up any
      excess elements.  */
 
-  ps->expout->nelts = ps->expout_ptr;
-  ps->expout = (struct expression *)
-     xrealloc (ps->expout,
-              sizeof (struct expression)
-              + EXP_ELEM_TO_BYTES (ps->expout_ptr));
+  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
 }
 
 /* This page contains the functions for adding data to the struct expression
@@ -220,20 +149,20 @@ reallocate_expout (struct parser_state *ps)
    a register through here.  */
 
 static void
    a register through here.  */
 
 static void
-write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
+write_exp_elt (struct expr_builder *ps, const union exp_element *expelt)
 {
   if (ps->expout_ptr >= ps->expout_size)
     {
       ps->expout_size *= 2;
 {
   if (ps->expout_ptr >= ps->expout_size)
     {
       ps->expout_size *= 2;
-      ps->expout = (struct expression *)
-       xrealloc (ps->expout, sizeof (struct expression)
-                 + EXP_ELEM_TO_BYTES (ps->expout_size));
+      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
     }
   ps->expout->elts[ps->expout_ptr++] = *expelt;
 }
 
 void
-write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
+write_exp_elt_opcode (struct expr_builder *ps, enum exp_opcode expelt)
 {
   union exp_element tmp;
 
 {
   union exp_element tmp;
 
@@ -243,7 +172,7 @@ write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
 }
 
 void
 }
 
 void
-write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
+write_exp_elt_sym (struct expr_builder *ps, struct symbol *expelt)
 {
   union exp_element tmp;
 
 {
   union exp_element tmp;
 
@@ -252,60 +181,60 @@ write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
   write_exp_elt (ps, &tmp);
 }
 
   write_exp_elt (ps, &tmp);
 }
 
-void
-write_exp_elt_block (struct parser_state *ps, const struct block *b)
+static void
+write_exp_elt_msym (struct expr_builder *ps, minimal_symbol *expelt)
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
-  tmp.block = b;
+  tmp.msymbol = expelt;
   write_exp_elt (ps, &tmp);
 }
 
 void
   write_exp_elt (ps, &tmp);
 }
 
 void
-write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
+write_exp_elt_block (struct expr_builder *ps, const struct block *b)
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
-  tmp.objfile = objfile;
+  tmp.block = b;
   write_exp_elt (ps, &tmp);
 }
 
 void
   write_exp_elt (ps, &tmp);
 }
 
 void
-write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
+write_exp_elt_objfile (struct expr_builder *ps, struct objfile *objfile)
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
-  tmp.longconst = expelt;
+  tmp.objfile = objfile;
   write_exp_elt (ps, &tmp);
 }
 
 void
   write_exp_elt (ps, &tmp);
 }
 
 void
-write_exp_elt_dblcst (struct parser_state *ps, DOUBLEST expelt)
+write_exp_elt_longcst (struct expr_builder *ps, LONGEST expelt)
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
 {
   union exp_element tmp;
 
   memset (&tmp, 0, sizeof (union exp_element));
-  tmp.doubleconst = expelt;
+  tmp.longconst = expelt;
   write_exp_elt (ps, &tmp);
 }
 
 void
   write_exp_elt (ps, &tmp);
 }
 
 void
-write_exp_elt_decfloatcst (struct parser_state *ps, gdb_byte expelt[16])
+write_exp_elt_floatcst (struct expr_builder *ps, const gdb_byte expelt[16])
 {
   union exp_element tmp;
   int index;
 
   for (index = 0; index < 16; index++)
 {
   union exp_element tmp;
   int index;
 
   for (index = 0; index < 16; index++)
-    tmp.decfloatconst[index] = expelt[index];
+    tmp.floatconst[index] = expelt[index];
 
   write_exp_elt (ps, &tmp);
 }
 
 void
 
   write_exp_elt (ps, &tmp);
 }
 
 void
-write_exp_elt_type (struct parser_state *ps, struct type *expelt)
+write_exp_elt_type (struct expr_builder *ps, struct type *expelt)
 {
   union exp_element tmp;
 
 {
   union exp_element tmp;
 
@@ -315,7 +244,7 @@ write_exp_elt_type (struct parser_state *ps, struct type *expelt)
 }
 
 void
 }
 
 void
-write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
+write_exp_elt_intern (struct expr_builder *ps, struct internalvar *expelt)
 {
   union exp_element tmp;
 
 {
   union exp_element tmp;
 
@@ -346,7 +275,7 @@ write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
 
 
 void
 
 
 void
-write_exp_string (struct parser_state *ps, struct stoken str)
+write_exp_string (struct expr_builder *ps, struct stoken str)
 {
   int len = str.length;
   size_t lenelt;
 {
   int len = str.length;
   size_t lenelt;
@@ -388,7 +317,7 @@ write_exp_string (struct parser_state *ps, struct stoken str)
    long constant, followed by the contents of the string.  */
 
 void
    long constant, followed by the contents of the string.  */
 
 void
-write_exp_string_vector (struct parser_state *ps, int type,
+write_exp_string_vector (struct expr_builder *ps, int type,
                         struct stoken_vector *vec)
 {
   int i, len;
                         struct stoken_vector *vec)
 {
   int i, len;
@@ -441,7 +370,7 @@ write_exp_string_vector (struct parser_state *ps, int type,
    either end of the bitstring.  */
 
 void
    either end of the bitstring.  */
 
 void
-write_exp_bitstring (struct parser_state *ps, struct stoken str)
+write_exp_bitstring (struct expr_builder *ps, struct stoken str)
 {
   int bits = str.length;       /* length in bits */
   int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
 {
   int bits = str.length;       /* length in bits */
   int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
@@ -467,107 +396,108 @@ write_exp_bitstring (struct parser_state *ps, struct stoken str)
   write_exp_elt_longcst (ps, (LONGEST) bits);
 }
 
   write_exp_elt_longcst (ps, (LONGEST) bits);
 }
 
-/* Add the appropriate elements for a minimal symbol to the end of
-   the expression.  */
+/* Return the type of MSYMBOL, a minimal symbol of OBJFILE.  If
+   ADDRESS_P is not NULL, set it to the MSYMBOL's resolved
+   address.  */
 
 
-void
-write_exp_msymbol (struct parser_state *ps,
-                  struct bound_minimal_symbol bound_msym)
+type *
+find_minsym_type_and_address (minimal_symbol *msymbol,
+                             struct objfile *objfile,
+                             CORE_ADDR *address_p)
 {
 {
-  struct minimal_symbol *msymbol = bound_msym.minsym;
-  struct objfile *objfile = bound_msym.objfile;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
-
-  CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (bound_msym);
+  bound_minimal_symbol bound_msym = {msymbol, objfile};
   struct obj_section *section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
   enum minimal_symbol_type type = MSYMBOL_TYPE (msymbol);
   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);
 
   /* The minimal symbol might point to a function descriptor;
      resolve it to the actual code address instead.  */
 
   /* 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)
+  CORE_ADDR addr;
+  if (is_tls)
     {
     {
-      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)
+      /* 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))
        {
        {
-         /* 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;
+         /* 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
-       type = mst_text;
-      section = NULL;
-      addr = pc;
     }
     }
+  else
+    addr = BMSYMBOL_VALUE_ADDRESS (bound_msym);
 
   if (overlay_debugging)
     addr = symbol_overlayed_address (addr, section);
 
 
   if (overlay_debugging)
     addr = symbol_overlayed_address (addr, section);
 
-  write_exp_elt_opcode (ps, OP_LONG);
-  /* Let's make the type big enough to hold a 64-bit address.  */
-  write_exp_elt_type (ps, objfile_type (objfile)->builtin_core_addr);
-  write_exp_elt_longcst (ps, (LONGEST) addr);
-  write_exp_elt_opcode (ps, OP_LONG);
-
-  if (section && section->the_bfd_section->flags & SEC_THREAD_LOCAL)
+  if (is_tls)
     {
     {
-      write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
-      write_exp_elt_objfile (ps, objfile);
-      write_exp_elt_type (ps, objfile_type (objfile)->nodebug_tls_symbol);
-      write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
-      return;
+      /* 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;
     }
 
     }
 
-  write_exp_elt_opcode (ps, UNOP_MEMVAL);
+  if (address_p != NULL)
+    *address_p = addr;
+
   switch (type)
     {
     case mst_text:
     case mst_file_text:
     case mst_solib_trampoline:
   switch (type)
     {
     case mst_text:
     case mst_file_text:
     case mst_solib_trampoline:
-      write_exp_elt_type (ps, objfile_type (objfile)->nodebug_text_symbol);
-      break;
+      return objfile_type (objfile)->nodebug_text_symbol;
 
     case mst_text_gnu_ifunc:
 
     case mst_text_gnu_ifunc:
-      write_exp_elt_type (ps, objfile_type (objfile)
-                         ->nodebug_text_gnu_ifunc_symbol);
-      break;
+      return objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
 
     case mst_data:
     case mst_file_data:
     case mst_bss:
     case mst_file_bss:
 
     case mst_data:
     case mst_file_data:
     case mst_bss:
     case mst_file_bss:
-      write_exp_elt_type (ps, objfile_type (objfile)->nodebug_data_symbol);
-      break;
+      return objfile_type (objfile)->nodebug_data_symbol;
 
     case mst_slot_got_plt:
 
     case mst_slot_got_plt:
-      write_exp_elt_type (ps, objfile_type (objfile)->nodebug_got_plt_symbol);
-      break;
+      return objfile_type (objfile)->nodebug_got_plt_symbol;
 
     default:
 
     default:
-      write_exp_elt_type (ps, objfile_type (objfile)->nodebug_unknown_symbol);
-      break;
+      return objfile_type (objfile)->nodebug_unknown_symbol;
     }
     }
-  write_exp_elt_opcode (ps, UNOP_MEMVAL);
 }
 
 }
 
-/* Mark the current index as the starting location of a structure
-   expression.  This is used when completing on field names.  */
+/* Add the appropriate elements for a minimal symbol to the end of
+   the expression.  */
 
 void
 
 void
-mark_struct_expression (struct parser_state *ps)
+write_exp_msymbol (struct expr_builder *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);
+}
+
+/* See parser-defs.h.  */
+
+void
+parser_state::mark_struct_expression ()
 {
   gdb_assert (parse_completion
 {
   gdb_assert (parse_completion
-             && expout_tag_completion_type == TYPE_CODE_UNDEF);
-  expout_last_struct = ps->expout_ptr;
+             && (m_completion_state.expout_tag_completion_type
+                 == TYPE_CODE_UNDEF));
+  m_completion_state.expout_last_struct = expout_ptr;
 }
 
 /* Indicate that the current parser invocation is completing a tag.
 }
 
 /* Indicate that the current parser invocation is completing a tag.
@@ -575,19 +505,19 @@ mark_struct_expression (struct parser_state *ps)
    start of the tag name.  */
 
 void
    start of the tag name.  */
 
 void
-mark_completion_tag (enum type_code tag, const char *ptr, int length)
+parser_state::mark_completion_tag (enum type_code tag, const char *ptr,
+                                  int length)
 {
   gdb_assert (parse_completion
 {
   gdb_assert (parse_completion
-             && expout_tag_completion_type == TYPE_CODE_UNDEF
-             && expout_completion_name == NULL
-             && expout_last_struct == -1);
+             && (m_completion_state.expout_tag_completion_type
+                 == TYPE_CODE_UNDEF)
+             && m_completion_state.expout_completion_name == NULL
+             && m_completion_state.expout_last_struct == -1);
   gdb_assert (tag == TYPE_CODE_UNION
              || tag == TYPE_CODE_STRUCT
              || tag == TYPE_CODE_ENUM);
   gdb_assert (tag == TYPE_CODE_UNION
              || tag == TYPE_CODE_STRUCT
              || tag == TYPE_CODE_ENUM);
-  expout_tag_completion_type = tag;
-  expout_completion_name = xmalloc (length + 1);
-  memcpy (expout_completion_name, ptr, length);
-  expout_completion_name[length] = '\0';
+  m_completion_state.expout_tag_completion_type = tag;
+  m_completion_state.expout_completion_name.reset (xstrndup (ptr, length));
 }
 
 \f
 }
 
 \f
@@ -615,9 +545,10 @@ mark_completion_tag (enum type_code tag, const char *ptr, int length)
 void
 write_dollar_variable (struct parser_state *ps, struct stoken str)
 {
 void
 write_dollar_variable (struct parser_state *ps, struct stoken str)
 {
-  struct symbol *sym = NULL;
+  struct block_symbol sym;
   struct bound_minimal_symbol msym;
   struct internalvar *isym = NULL;
   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).  */
 
   /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
      and $$digits (equivalent to $<-digits> if you could type that).  */
@@ -651,14 +582,15 @@ write_dollar_variable (struct parser_state *ps, struct stoken str)
 
   /* Handle tokens that refer to machine registers:
      $ followed by a register name.  */
 
   /* Handle tokens that refer to machine registers:
      $ followed by a register name.  */
-  i = user_reg_map_name_to_regnum (parse_gdbarch (ps),
+  i = user_reg_map_name_to_regnum (ps->gdbarch (),
                                   str.ptr + 1, str.length - 1);
   if (i >= 0)
     goto handle_register;
 
   /* Any names starting with $ are probably debugger internal variables.  */
 
                                   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);
+  copy = copy_name (str);
+  isym = lookup_only_internalvar (copy.c_str () + 1);
   if (isym)
     {
       write_exp_elt_opcode (ps, OP_INTERNALVAR);
   if (isym)
     {
       write_exp_elt_opcode (ps, OP_INTERNALVAR);
@@ -670,17 +602,16 @@ write_dollar_variable (struct parser_state *ps, struct stoken str)
   /* On some systems, such as HP-UX and hppa-linux, certain system routines 
      have names beginning with $ or $$.  Check for those, first.  */
 
   /* 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)
+  sym = lookup_symbol (copy.c_str (), NULL, VAR_DOMAIN, NULL);
+  if (sym.symbol)
     {
       write_exp_elt_opcode (ps, OP_VAR_VALUE);
     {
       write_exp_elt_opcode (ps, OP_VAR_VALUE);
-      write_exp_elt_block (ps, block_found);   /* set by lookup_symbol */
-      write_exp_elt_sym (ps, sym);
+      write_exp_elt_block (ps, sym.block);
+      write_exp_elt_sym (ps, sym.symbol);
       write_exp_elt_opcode (ps, OP_VAR_VALUE);
       return;
     }
       write_exp_elt_opcode (ps, OP_VAR_VALUE);
       return;
     }
-  msym = lookup_bound_minimal_symbol (copy_name (str));
+  msym = lookup_bound_minimal_symbol (copy.c_str ());
   if (msym.minsym)
     {
       write_exp_msymbol (ps, msym);
   if (msym.minsym)
     {
       write_exp_msymbol (ps, msym);
@@ -690,7 +621,7 @@ write_dollar_variable (struct parser_state *ps, struct stoken str)
   /* Any other names are assumed to be debugger internal variables.  */
 
   write_exp_elt_opcode (ps, OP_INTERNALVAR);
   /* 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_intern (ps, create_internalvar (copy.c_str () + 1));
   write_exp_elt_opcode (ps, OP_INTERNALVAR);
   return;
 handle_last:
   write_exp_elt_opcode (ps, OP_INTERNALVAR);
   return;
 handle_last:
@@ -704,6 +635,8 @@ handle_register:
   str.ptr++;
   write_exp_string (ps, str);
   write_exp_elt_opcode (ps, OP_REGISTER);
   str.ptr++;
   write_exp_string (ps, str);
   write_exp_elt_opcode (ps, OP_REGISTER);
+  ps->block_tracker->update (ps->expression_context_block,
+                            INNERMOST_BLOCK_FOR_REGISTERS);
   return;
 }
 
   return;
 }
 
@@ -775,41 +708,21 @@ find_template_name_end (const char *p)
    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
    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.
+   into a separate block of storage.  */
 
 
-   N.B. A single buffer is reused on each call.  */
-
-char *
+std::string
 copy_name (struct stoken token)
 {
 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 = xrealloc (namecopy, token.length + 1);
-    }
-      
-  memcpy (namecopy, token.ptr, token.length);
-  namecopy[token.length] = 0;
-
-  return namecopy;
+  return std::string (token.ptr, token.length);
 }
 \f
 
 /* See comments on parser-defs.h.  */
 
 int
 }
 \f
 
 /* See comments on parser-defs.h.  */
 
 int
-prefixify_expression (struct expression *expr)
+prefixify_expression (struct expression *expr, int last_struct)
 {
 {
+  gdb_assert (expr->nelts > 0);
   int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
   struct expression *temp;
   int inpos = expr->nelts, outpos = 0;
   int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
   struct expression *temp;
   int inpos = expr->nelts, outpos = 0;
@@ -819,13 +732,13 @@ prefixify_expression (struct expression *expr)
   /* Copy the original expression into temp.  */
   memcpy (temp, expr, len);
 
   /* Copy the original expression into temp.  */
   memcpy (temp, expr, len);
 
-  return prefixify_subexp (temp, expr, inpos, outpos);
+  return prefixify_subexp (temp, expr, inpos, outpos, last_struct);
 }
 
 /* Return the number of exp_elements in the postfix subexpression 
    of EXPR whose operator is at index ENDPOS - 1 in EXPR.  */
 
 }
 
 /* Return the number of exp_elements in the postfix subexpression 
    of EXPR whose operator is at index ENDPOS - 1 in EXPR.  */
 
-int
+static int
 length_of_subexp (struct expression *expr, int endpos)
 {
   int oplen, args;
 length_of_subexp (struct expression *expr, int endpos)
 {
   int oplen, args;
@@ -861,7 +774,7 @@ operator_length_standard (const struct expression *expr, int endpos,
 {
   int oplen = 1;
   int args = 0;
 {
   int oplen = 1;
   int args = 0;
-  enum f90_range_type range_type;
+  enum range_type range_type;
   int i;
 
   if (endpos < 1)
   int i;
 
   if (endpos < 1)
@@ -878,12 +791,18 @@ operator_length_standard (const struct expression *expr, int endpos,
       break;
 
     case OP_LONG:
       break;
 
     case OP_LONG:
-    case OP_DOUBLE:
-    case OP_DECFLOAT:
+    case OP_FLOAT:
     case OP_VAR_VALUE:
     case OP_VAR_VALUE:
+    case OP_VAR_MSYM_VALUE:
       oplen = 4;
       break;
 
       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_TYPE:
     case OP_BOOL:
     case OP_LAST:
@@ -904,7 +823,7 @@ operator_length_standard (const struct expression *expr, int endpos,
       break;
 
     case TYPE_INSTANCE:
       break;
 
     case TYPE_INSTANCE:
-      oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 5 + longest_to_int (expr->elts[endpos - 2].longconst);
       args = 1;
       break;
 
       args = 1;
       break;
 
@@ -933,11 +852,6 @@ operator_length_standard (const struct expression *expr, int endpos,
       args = 1;
       break;
 
       args = 1;
       break;
 
-    case UNOP_MEMVAL_TLS:
-      oplen = 4;
-      args = 1;
-      break;
-
     case UNOP_ABS:
     case UNOP_CAP:
     case UNOP_CHR:
     case UNOP_ABS:
     case UNOP_CAP:
     case UNOP_CHR:
@@ -1003,13 +917,15 @@ operator_length_standard (const struct expression *expr, int endpos,
       oplen = 2;
       break;
 
       oplen = 2;
       break;
 
-    case OP_F90_RANGE:
+    case OP_RANGE:
       oplen = 3;
       oplen = 3;
+      range_type = (enum range_type)
+       longest_to_int (expr->elts[endpos - 2].longconst);
 
 
-      range_type = longest_to_int (expr->elts[endpos - 2].longconst);
       switch (range_type)
        {
        case LOW_BOUND_DEFAULT:
       switch (range_type)
        {
        case LOW_BOUND_DEFAULT:
+       case LOW_BOUND_DEFAULT_EXCLUSIVE:
        case HIGH_BOUND_DEFAULT:
          args = 1;
          break;
        case HIGH_BOUND_DEFAULT:
          args = 1;
          break;
@@ -1017,6 +933,7 @@ operator_length_standard (const struct expression *expr, int endpos,
          args = 0;
          break;
        case NONE_BOUND_DEFAULT:
          args = 0;
          break;
        case NONE_BOUND_DEFAULT:
+       case NONE_BOUND_DEFAULT_EXCLUSIVE:
          args = 2;
          break;
        }
          args = 2;
          break;
        }
@@ -1034,13 +951,14 @@ operator_length_standard (const struct expression *expr, int endpos,
 /* 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.
 /* 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.
+   If LAST_STRUCT is -1, then this function always returns -1.
    Otherwise, it returns the index of the subexpression which is the
    Otherwise, it returns the index of the subexpression which is the
-   left-hand-side of the expression at EXPOUT_LAST_STRUCT.  */
+   left-hand-side of the expression at LAST_STRUCT.  */
 
 static int
 prefixify_subexp (struct expression *inexpr,
 
 static int
 prefixify_subexp (struct expression *inexpr,
-                 struct expression *outexpr, int inend, int outbeg)
+                 struct expression *outexpr, int inend, int outbeg,
+                 int last_struct)
 {
   int oplen;
   int args;
 {
   int oplen;
   int args;
@@ -1057,7 +975,7 @@ prefixify_subexp (struct expression *inexpr,
          EXP_ELEM_TO_BYTES (oplen));
   outbeg += oplen;
 
          EXP_ELEM_TO_BYTES (oplen));
   outbeg += oplen;
 
-  if (expout_last_struct == inend)
+  if (last_struct == inend)
     result = outbeg - oplen;
 
   /* Find the lengths of the arg subexpressions.  */
     result = outbeg - oplen;
 
   /* Find the lengths of the arg subexpressions.  */
@@ -1081,7 +999,7 @@ prefixify_subexp (struct expression *inexpr,
 
       oplen = arglens[i];
       inend += oplen;
 
       oplen = arglens[i];
       inend += oplen;
-      r = prefixify_subexp (inexpr, outexpr, inend, outbeg);
+      r = prefixify_subexp (inexpr, outexpr, inend, outbeg, last_struct);
       if (r != -1)
        {
          /* Return immediately.  We probably have only parsed a
       if (r != -1)
        {
          /* Return immediately.  We probably have only parsed a
@@ -1105,20 +1023,12 @@ prefixify_subexp (struct expression *inexpr,
 
    If COMMA is nonzero, stop if a comma is reached.  */
 
 
    If COMMA is nonzero, stop if a comma is reached.  */
 
-struct expression *
+expression_up
 parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
 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 struct expression *
-parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
-                     const struct block *block,
-                     int comma, int void_context_p, int *out_subexp)
+            int comma, innermost_block_tracker *tracker)
 {
 {
-  return parse_exp_in_context_1 (stringptr, pc, block, comma,
-                                void_context_p, out_subexp);
+  return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL,
+                              tracker, nullptr);
 }
 
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
 }
 
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
@@ -1128,42 +1038,31 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
    left-hand-side of the struct op.  If not doing such completion, it
    is left untouched.  */
 
    left-hand-side of the struct op.  If not doing such completion, it
    is left untouched.  */
 
-static struct expression *
-parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
-                       const struct block *block,
-                       int comma, int void_context_p, int *out_subexp)
+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,
+                     innermost_block_tracker *tracker,
+                     expr_completion_state *cstate)
 {
 {
-  volatile struct gdb_exception except;
-  struct cleanup *old_chain, *inner_chain;
   const struct language_defn *lang = NULL;
   const struct language_defn *lang = NULL;
-  struct parser_state ps;
   int subexp;
 
   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)
+  if (*stringptr == 0 || **stringptr == 0)
     error_no_arg (_("expression to compute"));
 
     error_no_arg (_("expression to compute"));
 
-  old_chain = make_cleanup (free_funcalls, 0 /*ignore*/);
-  funcall_chain = 0;
+  const struct block *expression_context_block = block;
+  CORE_ADDR expression_context_pc = 0;
 
 
-  expression_context_block = block;
+  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)
 
   /* 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);
+    expression_context_pc = BLOCK_ENTRY_PC (expression_context_block);
   else
     expression_context_pc = pc;
 
   else
     expression_context_pc = pc;
 
@@ -1177,7 +1076,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
          = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (cursal.symtab),
                               STATIC_BLOCK);
       if (expression_context_block)
          = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (cursal.symtab),
                               STATIC_BLOCK);
       if (expression_context_block)
-       expression_context_pc = BLOCK_START (expression_context_block);
+       expression_context_pc = BLOCK_ENTRY_PC (expression_context_block);
     }
 
   if (language_mode == language_mode_auto && block != NULL)
     }
 
   if (language_mode == language_mode_auto && block != NULL)
@@ -1199,7 +1098,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
       struct symbol *func = block_linkage_function (block);
 
       if (func != NULL)
       struct symbol *func = block_linkage_function (block);
 
       if (func != NULL)
-        lang = language_def (SYMBOL_LANGUAGE (func));
+        lang = language_def (func->language ());
       if (lang == NULL || lang->la_language == language_unknown)
         lang = current_language;
     }
       if (lang == NULL || lang->la_language == language_unknown)
         lang = current_language;
     }
@@ -1211,116 +1110,133 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
      and others called from *.y) ensure CURRENT_LANGUAGE gets restored
      to the value matching SELECTED_FRAME as set by get_current_arch.  */
 
      and others called from *.y) ensure CURRENT_LANGUAGE gets restored
      to the value matching SELECTED_FRAME as set by get_current_arch.  */
 
-  initialize_expout (&ps, 10, lang, get_current_arch ());
-  inner_chain = make_cleanup_restore_current_language ();
+  parser_state ps (lang, get_current_arch (), expression_context_block,
+                  expression_context_pc, comma, *stringptr,
+                  cstate != nullptr, tracker);
+
+  scoped_restore_current_language lang_saver;
   set_language (lang->la_language);
 
   set_language (lang->la_language);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  try
     {
     {
-      if (lang->la_parser (&ps))
-        lang->la_error (NULL);
+      lang->la_parser (&ps);
     }
     }
-  if (except.reason < 0)
+  catch (const gdb_exception &except)
     {
     {
-      if (! parse_completion)
-       {
-         xfree (ps.expout);
-         throw_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_ptr == 0)
+       throw;
     }
 
     }
 
-  reallocate_expout (&ps);
+  /* 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)
 
   /* Convert expression from postfix form as generated by yacc
      parser, to a prefix form.  */
 
   if (expressiondebug)
-    dump_raw_expression (ps.expout, gdb_stdlog,
+    dump_raw_expression (result.get (), gdb_stdlog,
                         "before conversion to prefix form");
 
                         "before conversion to prefix form");
 
-  subexp = prefixify_expression (ps.expout);
+  subexp = prefixify_expression (result.get (),
+                                ps.m_completion_state.expout_last_struct);
   if (out_subexp)
     *out_subexp = subexp;
 
   if (out_subexp)
     *out_subexp = subexp;
 
-  lang->la_post_parser (&ps.expout, void_context_p);
+  lang->la_post_parser (&result, void_context_p, ps.parse_completion,
+                       tracker);
 
   if (expressiondebug)
 
   if (expressiondebug)
-    dump_prefix_expression (ps.expout, gdb_stdlog);
+    dump_prefix_expression (result.get (), gdb_stdlog);
 
 
-  do_cleanups (inner_chain);
-  discard_cleanups (old_chain);
-
-  *stringptr = lexptr;
-  return ps.expout;
+  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.  */
 
 }
 
 /* Parse STRING as an expression, and complain if this fails
    to use up all of the contents of STRING.  */
 
-struct expression *
-parse_expression (const char *string)
+expression_up
+parse_expression (const char *string, innermost_block_tracker *tracker)
 {
 {
-  struct expression *exp;
-
-  exp = parse_exp_1 (&string, 0, 0, 0);
+  expression_up exp = parse_exp_1 (&string, 0, 0, 0, tracker);
   if (*string)
     error (_("Junk after end of expression."));
   return exp;
 }
 
   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
 /* 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.  */
+   an exception.  In all other cases, return NULL.  */
 
 struct type *
 
 struct type *
-parse_expression_for_completion (const char *string, char **name,
+parse_expression_for_completion (const char *string,
+                                gdb::unique_xmalloc_ptr<char> *name,
                                 enum type_code *code)
 {
                                 enum type_code *code)
 {
-  struct expression *exp = NULL;
+  expression_up exp;
   struct value *val;
   int subexp;
   struct value *val;
   int subexp;
-  volatile struct gdb_exception except;
+  expr_completion_state cstate;
 
 
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  try
     {
     {
-      parse_completion = 1;
-      exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
+      exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp,
+                                 nullptr, &cstate);
     }
     }
-  parse_completion = 0;
-  if (except.reason < 0 || ! exp)
-    return NULL;
-
-  if (expout_tag_completion_type != TYPE_CODE_UNDEF)
+  catch (const gdb_exception_error &except)
     {
     {
-      *code = expout_tag_completion_type;
-      *name = expout_completion_name;
-      expout_completion_name = NULL;
-      return NULL;
+      /* Nothing, EXP remains NULL.  */
     }
 
     }
 
-  if (expout_last_struct == -1)
+  if (exp == NULL)
+    return NULL;
+
+  if (cstate.expout_tag_completion_type != TYPE_CODE_UNDEF)
     {
     {
-      xfree (exp);
+      *code = cstate.expout_tag_completion_type;
+      *name = std::move (cstate.expout_completion_name);
       return NULL;
     }
 
       return NULL;
     }
 
-  *name = extract_field_op (exp, &subexp);
-  if (!*name)
+  if (cstate.expout_last_struct == -1)
+    return NULL;
+
+  const char *fieldname = extract_field_op (exp.get (), &subexp);
+  if (fieldname == NULL)
     {
     {
-      xfree (exp);
+      name->reset ();
       return NULL;
     }
 
       return NULL;
     }
 
+  name->reset (xstrdup (fieldname));
   /* This might throw an exception.  If so, we want to let it
      propagate.  */
   /* This might throw an exception.  If so, we want to let it
      propagate.  */
-  val = evaluate_subexpression_type (exp, subexp);
-  /* (*NAME) is a part of the EXP memory block freed below.  */
-  *name = xstrdup (*name);
-  xfree (exp);
+  val = evaluate_subexpression_type (exp.get (), subexp);
 
   return value_type (val);
 }
 
   return value_type (val);
 }
@@ -1328,407 +1244,23 @@ parse_expression_for_completion (const char *string, char **name,
 /* A post-parser that does nothing.  */
 
 void
 /* A post-parser that does nothing.  */
 
 void
-null_post_parser (struct expression **exp, int void_context_p)
+null_post_parser (expression_up *exp, int void_context_p, int completin,
+                 innermost_block_tracker *tracker)
 {
 }
 
 /* Parse floating point value P of length LEN.
 {
 }
 
 /* Parse floating point value P of length LEN.
-   Return 0 (false) if invalid, 1 (true) if valid.
-   The successfully parsed number is stored in D.
-   *SUFFIX points to the suffix of the number in P.
+   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.  */
 
 
    NOTE: This accepts the floating point syntax that sscanf accepts.  */
 
-int
-parse_float (const char *p, int len, DOUBLEST *d, const char **suffix)
+bool
+parse_float (const char *p, int len,
+            const struct type *type, gdb_byte *data)
 {
 {
-  char *copy;
-  int n, num;
-
-  copy = xmalloc (len + 1);
-  memcpy (copy, p, len);
-  copy[len] = 0;
-
-  num = sscanf (copy, "%" DOUBLEST_SCAN_FORMAT "%n", d, &n);
-  xfree (copy);
-
-  /* The sscanf man page suggests not making any assumptions on the effect
-     of %n on the result, so we don't.
-     That is why we simply test num == 0.  */
-  if (num == 0)
-    return 0;
-
-  *suffix = p + n;
-  return 1;
-}
-
-/* Parse floating point value P of length LEN, using the C syntax for floats.
-   Return 0 (false) if invalid, 1 (true) if valid.
-   The successfully parsed number is stored in *D.
-   Its type is taken from builtin_type (gdbarch) and is stored in *T.  */
-
-int
-parse_c_float (struct gdbarch *gdbarch, const char *p, int len,
-              DOUBLEST *d, struct type **t)
-{
-  const char *suffix;
-  int suffix_len;
-  const struct builtin_type *builtin_types = builtin_type (gdbarch);
-
-  if (! parse_float (p, len, d, &suffix))
-    return 0;
-
-  suffix_len = p + len - suffix;
-
-  if (suffix_len == 0)
-    *t = builtin_types->builtin_double;
-  else if (suffix_len == 1)
-    {
-      /* Handle suffixes: 'f' for float, 'l' for long double.  */
-      if (tolower (*suffix) == 'f')
-       *t = builtin_types->builtin_float;
-      else if (tolower (*suffix) == 'l')
-       *t = builtin_types->builtin_long_double;
-      else
-       return 0;
-    }
-  else
-    return 0;
-
-  return 1;
-}
-\f
-/* 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 = xrealloc (stack->elements,
-                                 stack->size * sizeof (union type_stack_elt));
-    }
-}
-
-/* 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 or tp_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_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 = 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 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_reference_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_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;
+  return target_float_from_string (data, type, std::string (p, len));
 }
 \f
 /* This function avoids direct calls to fprintf 
 }
 \f
 /* This function avoids direct calls to fprintf 
@@ -1771,8 +1303,7 @@ operator_check_standard (struct expression *exp, int pos,
     {
     case BINOP_VAL:
     case OP_COMPLEX:
     {
     case BINOP_VAL:
     case OP_COMPLEX:
-    case OP_DECFLOAT:
-    case OP_DOUBLE:
+    case OP_FLOAT:
     case OP_LONG:
     case OP_SCOPE:
     case OP_TYPE:
     case OP_LONG:
     case OP_SCOPE:
     case OP_TYPE:
@@ -1785,24 +1316,19 @@ operator_check_standard (struct expression *exp, int pos,
 
     case TYPE_INSTANCE:
       {
 
     case TYPE_INSTANCE:
       {
-       LONGEST arg, nargs = elts[pos + 1].longconst;
+       LONGEST arg, nargs = elts[pos + 2].longconst;
 
        for (arg = 0; arg < nargs; arg++)
          {
 
        for (arg = 0; arg < nargs; arg++)
          {
-           struct type *type = elts[pos + 2 + arg].type;
-           struct objfile *objfile = TYPE_OBJFILE (type);
+           struct type *inst_type = elts[pos + 3 + arg].type;
+           struct objfile *inst_objfile = TYPE_OBJFILE (inst_type);
 
 
-           if (objfile && (*objfile_func) (objfile, data))
+           if (inst_objfile && (*objfile_func) (inst_objfile, data))
              return 1;
          }
       }
       break;
 
              return 1;
          }
       }
       break;
 
-    case UNOP_MEMVAL_TLS:
-      objfile = elts[pos + 1].objfile;
-      type = elts[pos + 2].type;
-      break;
-
     case OP_VAR_VALUE:
       {
        const struct block *const block = elts[pos + 1].block;
     case OP_VAR_VALUE:
       {
        const struct block *const block = elts[pos + 1].block;
@@ -1810,7 +1336,7 @@ operator_check_standard (struct expression *exp, int pos,
 
        /* Check objfile where the variable itself is placed.
           SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
 
        /* Check objfile where the variable itself is placed.
           SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
-       if ((*objfile_func) (SYMBOL_OBJFILE (symbol), data))
+       if ((*objfile_func) (symbol_objfile (symbol), data))
          return 1;
 
        /* Check objfile where is placed the code touching the variable.  */
          return 1;
 
        /* Check objfile where is placed the code touching the variable.  */
@@ -1819,6 +1345,9 @@ operator_check_standard (struct expression *exp, int pos,
        type = SYMBOL_TYPE (symbol);
       }
       break;
        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.  */
     }
 
   /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
@@ -1869,7 +1398,7 @@ exp_iterate (struct expression *exp,
 static int
 exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
 {
 static int
 exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
 {
-  struct objfile *objfile = objfile_voidp;
+  struct objfile *objfile = (struct objfile *) objfile_voidp;
 
   if (exp_objfile->separate_debug_objfile_backlink)
     exp_objfile = exp_objfile->separate_debug_objfile_backlink;
 
   if (exp_objfile->separate_debug_objfile_backlink)
     exp_objfile = exp_objfile->separate_debug_objfile_backlink;
@@ -1889,28 +1418,27 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
   return exp_iterate (exp, exp_uses_objfile_iter, objfile);
 }
 
   return exp_iterate (exp, exp_uses_objfile_iter, objfile);
 }
 
-/* See definition in parser-defs.h.  */
+/* Reallocate the `expout' pointer inside PS so that it can accommodate
+   at least LENELT expression elements.  This function does nothing if
+   there is enough room for the elements.  */
 
 
-void
-increase_expout_size (struct parser_state *ps, size_t lenelt)
+static void
+increase_expout_size (struct expr_builder *ps, size_t lenelt)
 {
   if ((ps->expout_ptr + lenelt) >= ps->expout_size)
     {
 {
   if ((ps->expout_ptr + lenelt) >= ps->expout_size)
     {
-      ps->expout_size = max (ps->expout_size * 2,
-                            ps->expout_ptr + lenelt + 10);
-      ps->expout = (struct expression *)
-       xrealloc (ps->expout, (sizeof (struct expression)
-                              + EXP_ELEM_TO_BYTES (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)
 {
     }
 }
 
 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."),
   add_setshow_zuinteger_cmd ("expression", class_maintenance,
                             &expressiondebug,
                             _("Set expression debugging."),
This page took 0.067318 seconds and 4 git commands to generate.