* ada-lang.c (ada_coerce_to_simple_array_type): Use builtin_type_int32
[deliverable/binutils-gdb.git] / gdb / parse.c
index e0b5b70b7c73dc89b0c6ba5078a444208f5f1245..75853ff2e238803f034bf06fb7b0c6daf8b6933b 100644 (file)
@@ -1,7 +1,8 @@
 /* Parse expressions for GDB.
 
-   Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2004, 2005, 2007, 2008
+   Free Software Foundation, Inc.
 
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
@@ -10,7 +11,7 @@
 
    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 2 of the License, or
+   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,
@@ -19,9 +20,7 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   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.
 #include "parser-defs.h"
 #include "gdbcmd.h"
 #include "symfile.h"           /* for overlay functions */
-#include "inferior.h"          /* for NUM_PSEUDO_REGS.  NOTE: replace 
-                                  with "gdbarch.h" when appropriate.  */
+#include "inferior.h"
 #include "doublest.h"
 #include "gdb_assert.h"
 #include "block.h"
 #include "source.h"
+#include "objfiles.h"
+#include "exceptions.h"
+#include "user-regs.h"
 
 /* Standard set of definitions for printing, dumping, prefixifying,
  * and evaluating expressions.  */
@@ -81,6 +82,15 @@ char *prev_lexptr;
 int paren_depth;
 int comma_terminates;
 
+/* True if parsing an expression to find a field reference.  This is
+   only used by completion.  */
+int in_parse_field;
+
+/* 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;
+
 /* A temporary buffer for identifiers, so we can null-terminate them.
 
    We allocate this with xrealloc.  parse_exp_1 used to allocate with
@@ -101,13 +111,13 @@ show_expressiondebug (struct ui_file *file, int from_tty,
 
 static void free_funcalls (void *ignore);
 
-static void prefixify_expression (struct expression *);
+static int prefixify_expression (struct expression *);
 
-static void prefixify_subexp (struct expression *, struct expression *, int,
-                             int);
+static int prefixify_subexp (struct expression *, struct expression *, int,
+                            int);
 
 static struct expression *parse_exp_in_context (char **, struct block *, int, 
-                                               int);
+                                               int, int *);
 
 void _initialize_parse (void);
 
@@ -191,6 +201,7 @@ void
 write_exp_elt_opcode (enum exp_opcode expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.opcode = expelt;
 
@@ -201,6 +212,7 @@ void
 write_exp_elt_sym (struct symbol *expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.symbol = expelt;
 
@@ -211,14 +223,25 @@ void
 write_exp_elt_block (struct block *b)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
   tmp.block = b;
   write_exp_elt (tmp);
 }
 
+void
+write_exp_elt_objfile (struct objfile *objfile)
+{
+  union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
+  tmp.objfile = objfile;
+  write_exp_elt (tmp);
+}
+
 void
 write_exp_elt_longcst (LONGEST expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.longconst = expelt;
 
@@ -229,16 +252,30 @@ void
 write_exp_elt_dblcst (DOUBLEST expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.doubleconst = expelt;
 
   write_exp_elt (tmp);
 }
 
+void
+write_exp_elt_decfloatcst (gdb_byte expelt[16])
+{
+  union exp_element tmp;
+  int index;
+
+  for (index = 0; index < 16; index++)
+    tmp.decfloatconst[index] = expelt[index];
+
+  write_exp_elt (tmp);
+}
+
 void
 write_exp_elt_type (struct type *expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.type = expelt;
 
@@ -249,6 +286,7 @@ void
 write_exp_elt_intern (struct internalvar *expelt)
 {
   union exp_element tmp;
+  memset (&tmp, 0, sizeof (union exp_element));
 
   tmp.internalvar = expelt;
 
@@ -362,56 +400,81 @@ write_exp_bitstring (struct stoken str)
 }
 
 /* Add the appropriate elements for a minimal symbol to the end of
-   the expression.  The rationale behind passing in text_symbol_type and
-   data_symbol_type was so that Modula-2 could pass in WORD for
-   data_symbol_type.  Perhaps it still is useful to have those types vary
-   based on the language, but they no longer have names like "int", so
-   the initial rationale is gone.  */
-
-static struct type *msym_text_symbol_type;
-static struct type *msym_data_symbol_type;
-static struct type *msym_unknown_symbol_type;
+   the expression.  */
 
 void
-write_exp_msymbol (struct minimal_symbol *msymbol, 
-                  struct type *text_symbol_type, 
-                  struct type *data_symbol_type)
+write_exp_msymbol (struct minimal_symbol *msymbol)
 {
-  CORE_ADDR addr;
+  struct objfile *objfile = msymbol_objfile (msymbol);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+  CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (msymbol);
+  struct obj_section *section = SYMBOL_OBJ_SECTION (msymbol);
+  enum minimal_symbol_type type = msymbol->type;
+  CORE_ADDR pc;
+
+  /* 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)
+    {
+      /* In this case, assume we have a code symbol instead of
+        a data symbol.  */
+      type = mst_text;
+      section = NULL;
+      addr = pc;
+    }
+
+  if (overlay_debugging)
+    addr = symbol_overlayed_address (addr, section);
 
   write_exp_elt_opcode (OP_LONG);
   /* Let's make the type big enough to hold a 64-bit address.  */
-  write_exp_elt_type (builtin_type_CORE_ADDR);
-
-  addr = SYMBOL_VALUE_ADDRESS (msymbol);
-  if (overlay_debugging)
-    addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
+  write_exp_elt_type (builtin_type (gdbarch)->builtin_core_addr);
   write_exp_elt_longcst ((LONGEST) addr);
-
   write_exp_elt_opcode (OP_LONG);
 
+  if (section && section->the_bfd_section->flags & SEC_THREAD_LOCAL)
+    {
+      write_exp_elt_opcode (UNOP_MEMVAL_TLS);
+      write_exp_elt_objfile (objfile);
+      write_exp_elt_type (builtin_type (gdbarch)->nodebug_tls_symbol);
+      write_exp_elt_opcode (UNOP_MEMVAL_TLS);
+      return;
+    }
+
   write_exp_elt_opcode (UNOP_MEMVAL);
-  switch (msymbol->type)
+  switch (type)
     {
     case mst_text:
     case mst_file_text:
     case mst_solib_trampoline:
-      write_exp_elt_type (msym_text_symbol_type);
+      write_exp_elt_type (builtin_type (gdbarch)->nodebug_text_symbol);
       break;
 
     case mst_data:
     case mst_file_data:
     case mst_bss:
     case mst_file_bss:
-      write_exp_elt_type (msym_data_symbol_type);
+      write_exp_elt_type (builtin_type (gdbarch)->nodebug_data_symbol);
       break;
 
     default:
-      write_exp_elt_type (msym_unknown_symbol_type);
+      write_exp_elt_type (builtin_type (gdbarch)->nodebug_unknown_symbol);
       break;
     }
   write_exp_elt_opcode (UNOP_MEMVAL);
 }
+
+/* Mark the current index as the starting location of a structure
+   expression.  This is used when completing on field names.  */
+
+void
+mark_struct_expression (void)
+{
+  expout_last_struct = expout_ptr;
+}
+
 \f
 /* Recognize tokens that start with '$'.  These include:
 
@@ -441,6 +504,7 @@ write_dollar_variable (struct stoken str)
 {
   struct symbol *sym = NULL;
   struct minimal_symbol *msym = NULL;
+  struct internalvar *isym = NULL;
 
   /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
      and $$digits (equivalent to $<-digits> if you could type that). */
@@ -474,16 +538,27 @@ write_dollar_variable (struct stoken str)
 
   /* Handle tokens that refer to machine registers:
      $ followed by a register name.  */
-  i = frame_map_name_to_regnum (deprecated_selected_frame,
-                               str.ptr + 1, str.length - 1);
+  i = user_reg_map_name_to_regnum (current_gdbarch,
+                                  str.ptr + 1, str.length - 1);
   if (i >= 0)
     goto handle_register;
 
+  /* Any names starting with $ are probably debugger internal variables.  */
+
+  isym = lookup_only_internalvar (copy_name (str) + 1);
+  if (isym)
+    {
+      write_exp_elt_opcode (OP_INTERNALVAR);
+      write_exp_elt_intern (isym);
+      write_exp_elt_opcode (OP_INTERNALVAR);
+      return;
+    }
+
   /* On some systems, such as HP-UX and hppa-linux, certain system routines 
      have names beginning with $ or $$.  Check for those, first. */
 
   sym = lookup_symbol (copy_name (str), (struct block *) NULL,
-                      VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL);
+                      VAR_DOMAIN, (int *) NULL);
   if (sym)
     {
       write_exp_elt_opcode (OP_VAR_VALUE);
@@ -495,16 +570,14 @@ write_dollar_variable (struct stoken str)
   msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
   if (msym)
     {
-      write_exp_msymbol (msym,
-                        lookup_function_type (builtin_type_int),
-                        builtin_type_int);
+      write_exp_msymbol (msym);
       return;
     }
 
-  /* Any other names starting in $ are debugger internal variables.  */
+  /* Any other names are assumed to be debugger internal variables.  */
 
   write_exp_elt_opcode (OP_INTERNALVAR);
-  write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1));
+  write_exp_elt_intern (create_internalvar (copy_name (str) + 1));
   write_exp_elt_opcode (OP_INTERNALVAR);
   return;
 handle_last:
@@ -514,193 +587,14 @@ handle_last:
   return;
 handle_register:
   write_exp_elt_opcode (OP_REGISTER);
-  write_exp_elt_longcst (i);
+  str.length--;
+  str.ptr++;
+  write_exp_string (str);
   write_exp_elt_opcode (OP_REGISTER);
   return;
 }
 
 
-/* Parse a string that is possibly a namespace / nested class
-   specification, i.e., something of the form A::B::C::x.  Input
-   (NAME) is the entire string; LEN is the current valid length; the
-   output is a string, TOKEN, which points to the largest recognized
-   prefix which is a series of namespaces or classes.  CLASS_PREFIX is
-   another output, which records whether a nested class spec was
-   recognized (= 1) or a fully qualified variable name was found (=
-   0).  ARGPTR is side-effected (if non-NULL) to point to beyond the
-   string recognized and consumed by this routine.
-
-   The return value is a pointer to the symbol for the base class or
-   variable if found, or NULL if not found.  Callers must check this
-   first -- if NULL, the outputs may not be correct. 
-
-   This function is used c-exp.y.  This is used specifically to get
-   around HP aCC (and possibly other compilers), which insists on
-   generating names with embedded colons for namespace or nested class
-   members.
-
-   (Argument LEN is currently unused. 1997-08-27)
-
-   Callers must free memory allocated for the output string TOKEN.  */
-
-static const char coloncolon[2] =
-{':', ':'};
-
-struct symbol *
-parse_nested_classes_for_hpacc (char *name, int len, char **token,
-                               int *class_prefix, char **argptr)
-{
-  /* Comment below comes from decode_line_1 which has very similar
-     code, which is called for "break" command parsing. */
-
-  /* We have what looks like a class or namespace
-     scope specification (A::B), possibly with many
-     levels of namespaces or classes (A::B::C::D).
-
-     Some versions of the HP ANSI C++ compiler (as also possibly
-     other compilers) generate class/function/member names with
-     embedded double-colons if they are inside namespaces. To
-     handle this, we loop a few times, considering larger and
-     larger prefixes of the string as though they were single
-     symbols.  So, if the initially supplied string is
-     A::B::C::D::foo, we have to look up "A", then "A::B",
-     then "A::B::C", then "A::B::C::D", and finally
-     "A::B::C::D::foo" as single, monolithic symbols, because
-     A, B, C or D may be namespaces.
-
-     Note that namespaces can nest only inside other
-     namespaces, and not inside classes.  So we need only
-     consider *prefixes* of the string; there is no need to look up
-     "B::C" separately as a symbol in the previous example. */
-
-  char *p;
-  char *start, *end;
-  char *prefix = NULL;
-  char *tmp;
-  struct symbol *sym_class = NULL;
-  struct symbol *sym_var = NULL;
-  struct type *t;
-  int prefix_len = 0;
-  int done = 0;
-  char *q;
-
-  /* Check for HP-compiled executable -- in other cases
-     return NULL, and caller must default to standard GDB
-     behaviour. */
-
-  if (!deprecated_hp_som_som_object_present)
-    return (struct symbol *) NULL;
-
-  p = name;
-
-  /* Skip over whitespace and possible global "::" */
-  while (*p && (*p == ' ' || *p == '\t'))
-    p++;
-  if (p[0] == ':' && p[1] == ':')
-    p += 2;
-  while (*p && (*p == ' ' || *p == '\t'))
-    p++;
-
-  while (1)
-    {
-      /* Get to the end of the next namespace or class spec. */
-      /* If we're looking at some non-token, fail immediately */
-      start = p;
-      if (!(isalpha (*p) || *p == '$' || *p == '_'))
-       return (struct symbol *) NULL;
-      p++;
-      while (*p && (isalnum (*p) || *p == '$' || *p == '_'))
-       p++;
-
-      if (*p == '<')
-       {
-         /* If we have the start of a template specification,
-            scan right ahead to its end */
-         q = find_template_name_end (p);
-         if (q)
-           p = q;
-       }
-
-      end = p;
-
-      /* Skip over "::" and whitespace for next time around */
-      while (*p && (*p == ' ' || *p == '\t'))
-       p++;
-      if (p[0] == ':' && p[1] == ':')
-       p += 2;
-      while (*p && (*p == ' ' || *p == '\t'))
-       p++;
-
-      /* Done with tokens? */
-      if (!*p || !(isalpha (*p) || *p == '$' || *p == '_'))
-       done = 1;
-
-      tmp = (char *) alloca (prefix_len + end - start + 3);
-      if (prefix)
-       {
-         memcpy (tmp, prefix, prefix_len);
-         memcpy (tmp + prefix_len, coloncolon, 2);
-         memcpy (tmp + prefix_len + 2, start, end - start);
-         tmp[prefix_len + 2 + end - start] = '\000';
-       }
-      else
-       {
-         memcpy (tmp, start, end - start);
-         tmp[end - start] = '\000';
-       }
-
-      prefix = tmp;
-      prefix_len = strlen (prefix);
-
-      /* See if the prefix we have now is something we know about */
-
-      if (!done)
-       {
-         /* More tokens to process, so this must be a class/namespace */
-         sym_class = lookup_symbol (prefix, 0, STRUCT_DOMAIN,
-                                    0, (struct symtab **) NULL);
-       }
-      else
-       {
-         /* No more tokens, so try as a variable first */
-         sym_var = lookup_symbol (prefix, 0, VAR_DOMAIN,
-                                  0, (struct symtab **) NULL);
-         /* If failed, try as class/namespace */
-         if (!sym_var)
-           sym_class = lookup_symbol (prefix, 0, STRUCT_DOMAIN,
-                                      0, (struct symtab **) NULL);
-       }
-
-      if (sym_var ||
-         (sym_class &&
-          (t = check_typedef (SYMBOL_TYPE (sym_class)),
-           (TYPE_CODE (t) == TYPE_CODE_STRUCT
-            || TYPE_CODE (t) == TYPE_CODE_UNION))))
-       {
-         /* We found a valid token */
-         *token = (char *) xmalloc (prefix_len + 1);
-         memcpy (*token, prefix, prefix_len);
-         (*token)[prefix_len] = '\000';
-         break;
-       }
-
-      /* No variable or class/namespace found, no more tokens */
-      if (done)
-       return (struct symbol *) NULL;
-    }
-
-  /* Out of loop, so we must have found a valid token */
-  if (sym_var)
-    *class_prefix = 0;
-  else
-    *class_prefix = 1;
-
-  if (argptr)
-    *argptr = done ? p : end;
-
-  return sym_var ? sym_var : sym_class;                /* found */
-}
-
 char *
 find_template_name_end (char *p)
 {
@@ -783,13 +677,16 @@ copy_name (struct stoken token)
 }
 \f
 /* Reverse an expression from suffix form (in which it is constructed)
-   to prefix form (in which we can conveniently print or execute it).  */
+   to prefix form (in which we can conveniently print or execute it).
+   Ordinarily this always returns -1.  However, if EXPOUT_LAST_STRUCT
+   is not -1 (i.e., we are trying to complete a field name), it will
+   return the index of the subexpression which is the left-hand-side
+   of the struct operation at EXPOUT_LAST_STRUCT.  */
 
-static void
+static int
 prefixify_expression (struct expression *expr)
 {
-  int len =
-  sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
+  int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
   struct expression *temp;
   int inpos = expr->nelts, outpos = 0;
 
@@ -798,7 +695,7 @@ prefixify_expression (struct expression *expr)
   /* Copy the original expression into temp.  */
   memcpy (temp, expr, len);
 
-  prefixify_subexp (temp, expr, inpos, outpos);
+  return prefixify_subexp (temp, expr, inpos, outpos);
 }
 
 /* Return the number of exp_elements in the postfix subexpression 
@@ -857,6 +754,7 @@ operator_length_standard (struct expression *expr, int endpos,
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_DECFLOAT:
     case OP_VAR_VALUE:
       oplen = 4;
       break;
@@ -864,13 +762,12 @@ operator_length_standard (struct expression *expr, int endpos,
     case OP_TYPE:
     case OP_BOOL:
     case OP_LAST:
-    case OP_REGISTER:
     case OP_INTERNALVAR:
       oplen = 3;
       break;
 
     case OP_COMPLEX:
-      oplen = 1;
+      oplen = 3;
       args = 2;
       break;
 
@@ -897,6 +794,11 @@ operator_length_standard (struct expression *expr, int endpos,
       args = 1;
       break;
 
+    case UNOP_MEMVAL_TLS:
+      oplen = 4;
+      args = 1;
+      break;
+
     case UNOP_ABS:
     case UNOP_CAP:
     case UNOP_CHR:
@@ -914,12 +816,12 @@ operator_length_standard (struct expression *expr, int endpos,
     case STRUCTOP_PTR:
       args = 1;
       /* fall through */
+    case OP_REGISTER:
     case OP_M2_STRING:
     case OP_STRING:
     case OP_OBJC_NSSTRING:     /* Objective C Foundation Class NSString constant */
     case OP_OBJC_SELECTOR:     /* Objective C "@selector" pseudo-op */
     case OP_NAME:
-    case OP_EXPRSTRING:
       oplen = longest_to_int (expr->elts[endpos - 2].longconst);
       oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
@@ -990,9 +892,12 @@ operator_length_standard (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.  */
+   In the process, convert it from suffix to prefix form.
+   If EXPOUT_LAST_STRUCT is -1, then this function always returns -1.
+   Otherwise, it returns the index of the subexpression which is the
+   left-hand-side of the expression at EXPOUT_LAST_STRUCT.  */
 
-static void
+static int
 prefixify_subexp (struct expression *inexpr,
                  struct expression *outexpr, int inend, int outbeg)
 {
@@ -1001,6 +906,7 @@ prefixify_subexp (struct expression *inexpr,
   int i;
   int *arglens;
   enum exp_opcode opcode;
+  int result = -1;
 
   operator_length (inexpr, inend, &oplen, &args);
 
@@ -1011,6 +917,9 @@ prefixify_subexp (struct expression *inexpr,
          EXP_ELEM_TO_BYTES (oplen));
   outbeg += oplen;
 
+  if (expout_last_struct == inend)
+    result = outbeg - oplen;
+
   /* Find the lengths of the arg subexpressions.  */
   arglens = (int *) alloca (args * sizeof (int));
   for (i = args - 1; i >= 0; i--)
@@ -1028,11 +937,21 @@ prefixify_subexp (struct expression *inexpr,
      outbeg does similarly in the output.  */
   for (i = 0; i < args; i++)
     {
+      int r;
       oplen = arglens[i];
       inend += oplen;
-      prefixify_subexp (inexpr, outexpr, inend, outbeg);
+      r = prefixify_subexp (inexpr, outexpr, inend, outbeg);
+      if (r != -1)
+       {
+         /* Return immediately.  We probably have only parsed a
+            partial expression, so we don't want to try to reverse
+            the other operands.  */
+         return r;
+       }
       outbeg += oplen;
     }
+
+  return result;
 }
 \f
 /* This page contains the two entry points to this file.  */
@@ -1050,23 +969,30 @@ prefixify_subexp (struct expression *inexpr,
 struct expression *
 parse_exp_1 (char **stringptr, struct block *block, int comma)
 {
-  return parse_exp_in_context (stringptr, block, comma, 0);
+  return parse_exp_in_context (stringptr, block, comma, 0, NULL);
 }
 
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
-   no value is expected from the expression.  */
+   no value is expected from the expression.
+   OUT_SUBEXP is set when attempting to complete a field name; in this
+   case it is set to the index of the subexpression on the
+   left-hand-side of the struct op.  If not doing such completion, it
+   is left untouched.  */
 
 static struct expression *
 parse_exp_in_context (char **stringptr, struct block *block, int comma, 
-                     int void_context_p)
+                     int void_context_p, int *out_subexp)
 {
+  volatile struct gdb_exception except;
   struct cleanup *old_chain;
+  int subexp;
 
   lexptr = *stringptr;
   prev_lexptr = NULL;
 
   paren_depth = 0;
   type_stack_depth = 0;
+  expout_last_struct = -1;
 
   comma_terminates = comma;
 
@@ -1076,26 +1002,24 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
   old_chain = make_cleanup (free_funcalls, 0 /*ignore*/);
   funcall_chain = 0;
 
-  /* If no context specified, try using the current frame, if any. */
+  expression_context_block = block;
 
-  if (!block)
-    block = get_selected_block (&expression_context_pc);
+  /* 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
+    expression_context_pc = BLOCK_START (expression_context_block);
 
-  /* Fall back to using the current source static context, if any. */
+  /* Fall back to using the current source static context, if any.  */
 
-  if (!block)
+  if (!expression_context_block)
     {
       struct symtab_and_line cursal = get_current_source_symtab_and_line ();
       if (cursal.symtab)
-       block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK);
-    }
-
-  /* Save the context, if specified by caller, or found above. */
-
-  if (block)
-    {
-      expression_context_block = block;
-      expression_context_pc = BLOCK_START (block);
+       expression_context_block
+         = BLOCKVECTOR_BLOCK (BLOCKVECTOR (cursal.symtab), STATIC_BLOCK);
+      if (expression_context_block)
+       expression_context_pc = BLOCK_START (expression_context_block);
     }
 
   expout_size = 10;
@@ -1103,10 +1027,21 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
   expout = (struct expression *)
     xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
   expout->language_defn = current_language;
-  make_cleanup (free_current_contents, &expout);
+  expout->gdbarch = current_gdbarch;
 
-  if (current_language->la_parser ())
-    current_language->la_error (NULL);
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (current_language->la_parser ())
+       current_language->la_error (NULL);
+    }
+  if (except.reason < 0)
+    {
+      if (! in_parse_field)
+       {
+         xfree (expout);
+         throw_exception (except);
+       }
+    }
 
   discard_cleanups (old_chain);
 
@@ -1126,7 +1061,9 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
     dump_raw_expression (expout, gdb_stdlog,
                         "before conversion to prefix form");
 
-  prefixify_expression (expout);
+  subexp = prefixify_expression (expout);
+  if (out_subexp)
+    *out_subexp = subexp;
 
   current_language->la_post_parser (&expout, void_context_p);
 
@@ -1150,18 +1087,43 @@ parse_expression (char *string)
   return exp;
 }
 
+/* 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.  In all other cases, return NULL.  */
 
-/* As for parse_expression, except that if VOID_CONTEXT_P, then
-   no value is expected from the expression.  */
-
-struct expression *
-parse_expression_in_context (char *string, int void_context_p)
+struct type *
+parse_field_expression (char *string, char **name)
 {
-  struct expression *exp;
-  exp = parse_exp_in_context (&string, 0, 0, void_context_p);
-  if (*string != '\000')
-    error (_("Junk after end of expression."));
-  return exp;
+  struct expression *exp = NULL;
+  struct value *val;
+  int subexp;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      in_parse_field = 1;
+      exp = parse_exp_in_context (&string, 0, 0, 0, &subexp);
+    }
+  in_parse_field = 0;
+  if (except.reason < 0 || ! exp)
+    return NULL;
+  if (expout_last_struct == -1)
+    {
+      xfree (exp);
+      return NULL;
+    }
+
+  *name = extract_field_op (exp, &subexp);
+  if (!*name)
+    {
+      xfree (exp);
+      return NULL;
+    }
+  val = evaluate_subexpression_type (exp, subexp);
+  xfree (exp);
+
+  return value_type (val);
 }
 
 /* A post-parser that does nothing */
@@ -1300,7 +1262,7 @@ follow_types (struct type *follow_type)
           done with it.  */
        range_type =
          create_range_type ((struct type *) NULL,
-                            builtin_type_int, 0,
+                            builtin_type_int32, 0,
                             array_size >= 0 ? array_size - 1 : 0);
        follow_type =
          create_array_type ((struct type *) NULL,
@@ -1318,24 +1280,6 @@ follow_types (struct type *follow_type)
   return follow_type;
 }
 \f
-static void build_parse (void);
-static void
-build_parse (void)
-{
-  int i;
-
-  msym_text_symbol_type =
-    init_type (TYPE_CODE_FUNC, 1, 0, "<text variable, no debug info>", NULL);
-  TYPE_TARGET_TYPE (msym_text_symbol_type) = builtin_type_int;
-  msym_data_symbol_type =
-    init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
-              "<data variable, no debug info>", NULL);
-  msym_unknown_symbol_type =
-    init_type (TYPE_CODE_INT, 1, 0,
-              "<variable (not text or data), no debug info>",
-              NULL);
-}
-
 /* This function avoids direct calls to fprintf 
    in the parser generated debug code.  */
 void
@@ -1361,16 +1305,6 @@ _initialize_parse (void)
   type_stack = (union type_stack_elt *)
     xmalloc (type_stack_size * sizeof (*type_stack));
 
-  build_parse ();
-
-  /* FIXME - For the moment, handle types by swapping them in and out.
-     Should be using the per-architecture data-pointer and a large
-     struct. */
-  DEPRECATED_REGISTER_GDBARCH_SWAP (msym_text_symbol_type);
-  DEPRECATED_REGISTER_GDBARCH_SWAP (msym_data_symbol_type);
-  DEPRECATED_REGISTER_GDBARCH_SWAP (msym_unknown_symbol_type);
-  deprecated_register_gdbarch_swap (NULL, 0, build_parse);
-
   add_setshow_zinteger_cmd ("expression", class_maintenance,
                            &expressiondebug, _("\
 Set expression debugging."), _("\
This page took 0.0574480000000001 seconds and 4 git commands to generate.