Removed superflous code.
[deliverable/binutils-gdb.git] / gdb / parse.c
index 214df03b6b5d8307e865b09001b06990e3a85e07..2d4a629a7723eeb34838de0ce34431185cc560f4 100644 (file)
@@ -1,5 +1,5 @@
 /* Parse expressions for GDB.
-   Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1986, 89, 90, 91, 94, 1998 Free Software Foundation, Inc.
    Modified from expread.y by the Department of Computer Science at the
    State University of New York at Buffalo, 1991.
 
@@ -17,7 +17,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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Parse an expression from text in a string,
    and return the result as a  struct expression  pointer.
@@ -28,21 +28,66 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    during the process of parsing; the lower levels of the tree always
    come first in the result.  */
    
-#include <stdio.h>
 #include "defs.h"
-#include "param.h"
+#include "gdb_string.h"
 #include "symtab.h"
+#include "gdbtypes.h"
 #include "frame.h"
 #include "expression.h"
 #include "value.h"
 #include "command.h"
 #include "language.h"
 #include "parser-defs.h"
+#include "gdbcmd.h"
+#include "symfile.h"   /* for overlay functions */
+\f
+/* Global variables declared in parser-defs.h (and commented there).  */
+struct expression *expout;
+int expout_size;
+int expout_ptr;
+struct block *expression_context_block;
+struct block *innermost_block;
+int arglist_len;
+union type_stack_elt *type_stack;
+int type_stack_depth, type_stack_size;
+char *lexptr;
+char *namecopy;
+int paren_depth;
+int comma_terminates;
+\f
+#ifdef MAINTENANCE_CMDS
+static int expressiondebug = 0;
+#endif
+
+static void
+free_funcalls PARAMS ((void));
+
+static void
+prefixify_expression PARAMS ((struct expression *));
+
+static void
+prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
+
+/* Data structure for saving values of arglist_len for function calls whose
+   arguments contain other function calls.  */
+
+struct funcall
+  {
+    struct funcall *next;
+    int arglist_len;
+  };
+
+static struct funcall *funcall_chain;
 
 /* Assign machine-independent names to certain registers 
    (unless overridden by the REGISTER_NAMES table) */
 
+#ifdef NO_STD_REGS
+unsigned num_std_regs = 0;
+struct std_regs std_regs[1];
+#else
 struct std_regs std_regs[] = {
+
 #ifdef PC_REGNUM
        { "pc", PC_REGNUM },
 #endif
@@ -55,10 +100,51 @@ struct std_regs std_regs[] = {
 #ifdef PS_REGNUM
        { "ps", PS_REGNUM },
 #endif
+
 };
 
 unsigned num_std_regs = (sizeof std_regs / sizeof std_regs[0]);
 
+#endif
+
+/* The generic method for targets to specify how their registers are named.
+   The mapping can be derived from three sources: reg_names; std_regs; or
+   a target specific alias hook. */
+
+int
+target_map_name_to_register (str, len)
+     char *str;
+     int len;
+{
+  int i;
+
+  /* First try target specific aliases. We try these first because on some 
+     systems standard names can be context dependent (eg. $pc on a 
+     multiprocessor can be could be any of several PCs).  */
+#ifdef REGISTER_NAME_ALIAS_HOOK
+  i =  REGISTER_NAME_ALIAS_HOOK (str, len);
+  if (i >= 0)
+    return i;
+#endif
+
+  /* Search architectural register name space. */
+  for (i = 0; i < NUM_REGS; i++)
+    if (reg_names[i] && len == strlen (reg_names[i])
+       && STREQN (str, reg_names[i], len))
+      {
+       return i;
+      }
+
+  /* Try standard aliases */
+  for (i = 0; i < num_std_regs; i++)
+    if (std_regs[i].name && len == strlen (std_regs[i].name)
+       && STREQN (str, std_regs[i].name, len))
+      {
+       return std_regs[i].regnum;
+      }
+
+  return -1;
+}
 
 /* Begin counting arguments for a function call,
    saving the data about any containing call.  */
@@ -66,8 +152,9 @@ unsigned num_std_regs = (sizeof std_regs / sizeof std_regs[0]);
 void
 start_arglist ()
 {
-  register struct funcall *new = (struct funcall *) xmalloc (sizeof (struct funcall));
+  register struct funcall *new;
 
+  new = (struct funcall *) xmalloc (sizeof (struct funcall));
   new->next = funcall_chain;
   new->arglist_len = arglist_len;
   arglist_len = 0;
@@ -84,14 +171,14 @@ end_arglist ()
   register struct funcall *call = funcall_chain;
   funcall_chain = call->next;
   arglist_len = call->arglist_len;
-  free (call);
+  free ((PTR)call);
   return val;
 }
 
 /* Free everything in the funcall chain.
    Used when there is an error inside parsing.  */
 
-void
+static void
 free_funcalls ()
 {
   register struct funcall *call, *next;
@@ -99,7 +186,7 @@ free_funcalls ()
   for (call = funcall_chain; call; call = next)
     {
       next = call->next;
-      free (call);
+      free ((PTR)call);
     }
 }
 \f
@@ -118,9 +205,9 @@ write_exp_elt (expelt)
   if (expout_ptr >= expout_size)
     {
       expout_size *= 2;
-      expout = (struct expression *) xrealloc (expout,
-                                              sizeof (struct expression)
-                                              + expout_size * sizeof (union exp_element));
+      expout = (struct expression *)
+       xrealloc ((char *) expout, sizeof (struct expression)
+                 + EXP_ELEM_TO_BYTES (expout_size));
     }
   expout->elts[expout_ptr++] = expelt;
 }
@@ -147,6 +234,15 @@ write_exp_elt_sym (expelt)
   write_exp_elt (tmp);
 }
 
+void
+write_exp_elt_block (b)
+     struct block *b;
+{
+  union exp_element tmp;
+  tmp.block = b;
+  write_exp_elt (tmp);
+}
+
 void
 write_exp_elt_longcst (expelt)
      LONGEST expelt;
@@ -160,7 +256,7 @@ write_exp_elt_longcst (expelt)
 
 void
 write_exp_elt_dblcst (expelt)
-     double expelt;
+     DOUBLEST expelt;
 {
   union exp_element tmp;
 
@@ -192,28 +288,244 @@ write_exp_elt_intern (expelt)
 }
 
 /* Add a string constant to the end of the expression.
-   Follow it by its length in bytes, as a separate exp_element.  */
+
+   String constants are stored by first writing an expression element
+   that contains the length of the string, then stuffing the string
+   constant itself into however many expression elements are needed
+   to hold it, and then writing another expression element that contains
+   the length of the string.  I.E. an expression element at each end of
+   the string records the string length, so you can skip over the 
+   expression elements containing the actual string bytes from either
+   end of the string.  Note that this also allows gdb to handle
+   strings with embedded null bytes, as is required for some languages.
+
+   Don't be fooled by the fact that the string is null byte terminated,
+   this is strictly for the convenience of debugging gdb itself.  Gdb
+   Gdb does not depend up the string being null terminated, since the
+   actual length is recorded in expression elements at each end of the
+   string.  The null byte is taken into consideration when computing how
+   many expression elements are required to hold the string constant, of
+   course. */
+
 
 void
 write_exp_string (str)
      struct stoken str;
 {
   register int len = str.length;
-  register int lenelt
-    = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+  register int lenelt;
+  register char *strdata;
 
-  expout_ptr += lenelt;
+  /* Compute the number of expression elements required to hold the string
+     (including a null byte terminator), along with one expression element
+     at each end to record the actual string length (not including the
+     null byte terminator). */
 
-  if (expout_ptr >= expout_size)
+  lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
+
+  /* Ensure that we have enough available expression elements to store
+     everything. */
+
+  if ((expout_ptr + lenelt) >= expout_size)
     {
-      expout_size = max (expout_size * 2, expout_ptr + 10);
+      expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
       expout = (struct expression *)
-       xrealloc (expout, (sizeof (struct expression)
-                          + (expout_size * sizeof (union exp_element))));
+       xrealloc ((char *) expout, (sizeof (struct expression)
+                                   + EXP_ELEM_TO_BYTES (expout_size)));
     }
-  bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len);
-  ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+
+  /* Write the leading length expression element (which advances the current
+     expression element index), then write the string constant followed by a
+     terminating null byte, and then write the trailing length expression
+     element. */
+
   write_exp_elt_longcst ((LONGEST) len);
+  strdata = (char *) &expout->elts[expout_ptr];
+  memcpy (strdata, str.ptr, len);
+  *(strdata + len) = '\0';
+  expout_ptr += lenelt - 2;
+  write_exp_elt_longcst ((LONGEST) len);
+}
+
+/* Add a bitstring constant to the end of the expression.
+
+   Bitstring constants are stored by first writing an expression element
+   that contains the length of the bitstring (in bits), then stuffing the
+   bitstring constant itself into however many expression elements are
+   needed to hold it, and then writing another expression element that
+   contains the length of the bitstring.  I.E. an expression element at
+   each end of the bitstring records the bitstring length, so you can skip
+   over the expression elements containing the actual bitstring bytes from
+   either end of the bitstring. */
+
+void
+write_exp_bitstring (str)
+     struct stoken str;
+{
+  register int bits = str.length;      /* length in bits */
+  register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+  register int lenelt;
+  register char *strdata;
+
+  /* Compute the number of expression elements required to hold the bitstring,
+     along with one expression element at each end to record the actual
+     bitstring length in bits. */
+
+  lenelt = 2 + BYTES_TO_EXP_ELEM (len);
+
+  /* Ensure that we have enough available expression elements to store
+     everything. */
+
+  if ((expout_ptr + lenelt) >= expout_size)
+    {
+      expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
+      expout = (struct expression *)
+       xrealloc ((char *) expout, (sizeof (struct expression)
+                                   + EXP_ELEM_TO_BYTES (expout_size)));
+    }
+
+  /* Write the leading length expression element (which advances the current
+     expression element index), then write the bitstring constant, and then
+     write the trailing length expression element. */
+
+  write_exp_elt_longcst ((LONGEST) bits);
+  strdata = (char *) &expout->elts[expout_ptr];
+  memcpy (strdata, str.ptr, len);
+  expout_ptr += lenelt - 2;
+  write_exp_elt_longcst ((LONGEST) bits);
+}
+
+/* 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;
+
+void
+write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
+     struct minimal_symbol *msymbol;
+     struct type *text_symbol_type;
+     struct type *data_symbol_type;
+{
+  CORE_ADDR addr;
+
+  write_exp_elt_opcode (OP_LONG);
+  write_exp_elt_type (lookup_pointer_type (builtin_type_void));
+
+  addr = SYMBOL_VALUE_ADDRESS (msymbol);
+  if (overlay_debugging)
+    addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
+  write_exp_elt_longcst ((LONGEST) addr);
+                                               
+  write_exp_elt_opcode (OP_LONG);
+
+  write_exp_elt_opcode (UNOP_MEMVAL);
+  switch (msymbol -> type)
+    {
+    case mst_text:
+    case mst_file_text:
+    case mst_solib_trampoline:
+      write_exp_elt_type (msym_text_symbol_type);
+      break;
+
+    case mst_data:
+    case mst_file_data:
+    case mst_bss:
+    case mst_file_bss:
+      write_exp_elt_type (msym_data_symbol_type);
+      break;
+
+    default:
+      write_exp_elt_type (msym_unknown_symbol_type);
+      break;
+    }
+  write_exp_elt_opcode (UNOP_MEMVAL);
+}
+\f
+/* Recognize tokens that start with '$'.  These include:
+
+       $regname        A native register name or a "standard
+                       register name".
+
+       $variable       A convenience variable with a name chosen
+                       by the user.
+
+       $digits         Value history with index <digits>, starting
+                       from the first value which has index 1.
+
+       $$digits        Value history with index <digits> relative
+                       to the last value.  I.E. $$0 is the last
+                       value, $$1 is the one previous to that, $$2
+                       is the one previous to $$1, etc.
+
+       $ | $0 | $$0    The last value in the value history.
+
+       $$              An abbreviation for the second to the last
+                       value in the value history, I.E. $$1
+
+   */
+
+void
+write_dollar_variable (str)
+     struct stoken str;
+{
+  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+     and $$digits (equivalent to $<-digits> if you could type that). */
+
+  int negate = 0;
+  int i = 1;
+  /* Double dollar means negate the number and add -1 as well.
+     Thus $$ alone means -1.  */
+  if (str.length >= 2 && str.ptr[1] == '$')
+    {
+      negate = 1;
+      i = 2;
+    }
+  if (i == str.length)
+    {
+      /* Just dollars (one or two) */
+      i = - negate;
+      goto handle_last;
+    }
+  /* Is the rest of the token digits?  */
+  for (; i < str.length; i++)
+    if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
+      break;
+  if (i == str.length)
+    {
+      i = atoi (str.ptr + 1 + negate);
+      if (negate)
+       i = - i;
+      goto handle_last;
+    }
+  
+  /* Handle tokens that refer to machine registers:
+     $ followed by a register name.  */
+  i = target_map_name_to_register( str.ptr + 1, str.length - 1 );
+  if( i >= 0 )
+    goto handle_register;
+
+  /* Any other names starting in $ are debugger internal variables.  */
+
+  write_exp_elt_opcode (OP_INTERNALVAR);
+  write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1));
+  write_exp_elt_opcode (OP_INTERNALVAR); 
+  return;
+ handle_last:
+  write_exp_elt_opcode (OP_LAST);
+  write_exp_elt_longcst ((LONGEST) i);
+  write_exp_elt_opcode (OP_LAST);
+  return;
+ handle_register:
+  write_exp_elt_opcode (OP_REGISTER);
+  write_exp_elt_longcst (i);
+  write_exp_elt_opcode (OP_REGISTER); 
+  return;
 }
 \f
 /* Return a null-terminated temporary copy of the name
@@ -223,7 +535,7 @@ char *
 copy_name (token)
      struct stoken token;
 {
-  bcopy (token.ptr, namecopy, token.length);
+  memcpy (namecopy, token.ptr, token.length);
   namecopy[token.length] = 0;
   return namecopy;
 }
@@ -231,21 +543,19 @@ copy_name (token)
 /* Reverse an expression from suffix form (in which it is constructed)
    to prefix form (in which we can conveniently print or execute it).  */
 
-static void prefixify_subexp ();
-
-void
+static void
 prefixify_expression (expr)
      register struct expression *expr;
 {
-  register int len = sizeof (struct expression) +
-                                   expr->nelts * sizeof (union exp_element);
+  register int len =
+    sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
   register struct expression *temp;
   register int inpos = expr->nelts, outpos = 0;
 
   temp = (struct expression *) alloca (len);
 
   /* Copy the original expression into temp.  */
-  bcopy (expr, temp, len);
+  memcpy (temp, expr, len);
 
   prefixify_subexp (temp, expr, inpos, outpos);
 }
@@ -262,7 +572,7 @@ length_of_subexp (expr, endpos)
   register int args = 0;
   register int i;
 
-  if (endpos < 0)
+  if (endpos < 1)
     error ("?error in length_of_subexp");
 
   i = (int) expr->elts[endpos - 1].opcode;
@@ -271,34 +581,38 @@ length_of_subexp (expr, endpos)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 4 + ((expr->elts[endpos - 2].longconst
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_VAR_VALUE:
       oplen = 4;
       break;
 
     case OP_TYPE:
     case OP_BOOL:
-    case OP_VAR_VALUE:
     case OP_LAST:
     case OP_REGISTER:
     case OP_INTERNALVAR:
       oplen = 3;
       break;
 
+    case OP_COMPLEX:
+      oplen = 1; 
+      args = 2;
+      break; 
+
     case OP_FUNCALL:
+    case OP_F77_UNDETERMINED_ARGLIST:
       oplen = 3;
-      args = 1 + expr->elts[endpos - 2].longconst;
+      args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
       break;
 
     case UNOP_MAX:
     case UNOP_MIN:
       oplen = 3;
-      args = 0;
       break;
 
    case BINOP_VAL:
@@ -320,24 +634,42 @@ length_of_subexp (expr, endpos)
       args = 1;
       break;
 
+    case OP_LABELED:
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       args = 1;
+      /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 3 + ((expr->elts[endpos - 2].longconst
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+    case OP_NAME:
+    case OP_EXPRSTRING:
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+      break;
+
+    case OP_BITSTRING:
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
+      break;
+
+    case OP_ARRAY:
+      oplen = 4;
+      args = longest_to_int (expr->elts[endpos - 2].longconst);
+      args -= longest_to_int (expr->elts[endpos - 3].longconst);
+      args += 1;
       break;
 
     case TERNOP_COND:
+    case TERNOP_SLICE:
+    case TERNOP_SLICE_COUNT:
       args = 3;
       break;
 
       /* Modula-2 */
-   case BINOP_MULTI_SUBSCRIPT:
-      oplen=3;
-      args = 1 + expr->elts[endpos- 2].longconst;
+   case MULTI_SUBSCRIPT:
+      oplen = 3;
+      args = 1 + longest_to_int (expr->elts[endpos- 2].longconst);
       break;
 
     case BINOP_ASSIGN_MODIFY:
@@ -389,34 +721,38 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 4 + ((inexpr->elts[inend - 2].longconst
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_VAR_VALUE:
       oplen = 4;
       break;
 
     case OP_TYPE:
     case OP_BOOL:
-    case OP_VAR_VALUE:
     case OP_LAST:
     case OP_REGISTER:
     case OP_INTERNALVAR:
       oplen = 3;
       break;
 
+    case OP_COMPLEX:
+      oplen = 1; 
+      args = 2; 
+      break; 
+
     case OP_FUNCALL:
+    case OP_F77_UNDETERMINED_ARGLIST:
       oplen = 3;
-      args = 1 + inexpr->elts[inend - 2].longconst;
+      args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
 
     case UNOP_MIN:
     case UNOP_MAX:
       oplen = 3;
-      args = 0;
       break;
 
     case UNOP_CAST:
@@ -437,18 +773,35 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       args=1;
       break;
 
-   case STRUCTOP_STRUCT:
+    case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
+    case OP_LABELED:
       args = 1;
+      /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 3 + ((inexpr->elts[inend - 2].longconst
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
-                  
+    case OP_NAME:
+    case OP_EXPRSTRING:
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+      break;
+
+    case OP_BITSTRING:
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
+      break;
+
+    case OP_ARRAY:
+      oplen = 4;
+      args = longest_to_int (inexpr->elts[inend - 2].longconst);
+      args -= longest_to_int (inexpr->elts[inend - 3].longconst);
+      args += 1;
       break;
 
     case TERNOP_COND:
+    case TERNOP_SLICE:
+    case TERNOP_SLICE_COUNT:
       args = 3;
       break;
 
@@ -458,9 +811,9 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       break;
 
       /* Modula-2 */
-   case BINOP_MULTI_SUBSCRIPT:
-      oplen=3;
-      args = 1 + inexpr->elts[inend - 2].longconst;
+   case MULTI_SUBSCRIPT:
+      oplen = 3;
+      args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
 
       /* C++ */
@@ -475,8 +828,8 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
   /* Copy the final operator itself, from the end of the input
      to the beginning of the output.  */
   inend -= oplen;
-  bcopy (&inexpr->elts[inend], &outexpr->elts[outbeg],
-        oplen * sizeof (union exp_element));
+  memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
+         EXP_ELEM_TO_BYTES (oplen));
   outbeg += oplen;
 
   /* Find the lengths of the arg subexpressions.  */
@@ -533,7 +886,7 @@ parse_exp_1 (stringptr, block, comma)
   if (lexptr == 0 || *lexptr == 0)
     error_no_arg ("expression to compute");
 
-  old_chain = make_cleanup (free_funcalls, 0);
+  old_chain = make_cleanup ((make_cleanup_func) free_funcalls, 0);
   funcall_chain = 0;
 
   expression_context_block = block ? block : get_selected_block ();
@@ -542,21 +895,41 @@ parse_exp_1 (stringptr, block, comma)
   expout_size = 10;
   expout_ptr = 0;
   expout = (struct expression *)
-    xmalloc (sizeof (struct expression)
-            + expout_size * sizeof (union exp_element));
+    xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
   expout->language_defn = current_language;
-  make_cleanup (free_current_contents, &expout);
+  make_cleanup ((make_cleanup_func) free_current_contents, &expout);
 
   if (current_language->la_parser ())
     current_language->la_error (NULL);
 
   discard_cleanups (old_chain);
+
+  /* Record the actual number of expression elements, and then
+     reallocate the expression memory so that we free up any
+     excess elements. */
+
   expout->nelts = expout_ptr;
   expout = (struct expression *)
-    xrealloc (expout,
-             sizeof (struct expression)
-             + expout_ptr * sizeof (union exp_element));
+    xrealloc ((char *) expout,
+             sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));;
+
+  /* Convert expression from postfix form as generated by yacc
+     parser, to a prefix form. */
+
+#ifdef MAINTENANCE_CMDS
+  if (expressiondebug)
+    dump_prefix_expression (expout, gdb_stdout,
+                           "before conversion to prefix form");
+#endif /* MAINTENANCE_CMDS */
+
   prefixify_expression (expout);
+
+#ifdef MAINTENANCE_CMDS
+  if (expressiondebug)
+    dump_postfix_expression (expout, gdb_stdout,
+                            "after conversion to prefix form");
+#endif /* MAINTENANCE_CMDS */
+
   *stringptr = lexptr;
   return expout;
 }
@@ -574,6 +947,9 @@ parse_expression (string)
     error ("Junk after end of expression.");
   return exp;
 }
+\f
+/* Stuff for maintaining a stack of types.  Currently just used by C, but
+   probably useful for any language which declares its types "backwards".  */
 
 void 
 push_type (tp)
@@ -583,7 +959,7 @@ push_type (tp)
     {
       type_stack_size *= 2;
       type_stack = (union type_stack_elt *)
-       xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
+       xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
     }
   type_stack[type_stack_depth++].piece = tp;
 }
@@ -596,7 +972,7 @@ push_type_int (n)
     {
       type_stack_size *= 2;
       type_stack = (union type_stack_elt *)
-       xrealloc (type_stack, type_stack_size * sizeof (*type_stack));
+       xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
     }
   type_stack[type_stack_depth++].int_val = n;
 }
@@ -618,6 +994,52 @@ pop_type_int ()
   return 0;
 }
 
+/* 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 (follow_type)
+     struct type *follow_type;
+{
+  int done = 0;
+  int array_size;
+  struct type *range_type;
+
+  while (!done)
+    switch (pop_type ())
+      {
+      case tp_end:
+       done = 1;
+       break;
+      case tp_pointer:
+       follow_type = lookup_pointer_type (follow_type);
+       break;
+      case tp_reference:
+       follow_type = lookup_reference_type (follow_type);
+       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.  */
+       range_type =
+         create_range_type ((struct type *) NULL,
+                            builtin_type_int, 0,
+                            array_size >= 0 ? array_size - 1 : 0);
+       follow_type =
+         create_array_type ((struct type *) NULL,
+                            follow_type, range_type);
+       if (array_size < 0)
+         TYPE_ARRAY_UPPER_BOUND_TYPE(follow_type)
+           = BOUND_CANNOT_BE_DETERMINED;
+       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;
+      }
+  return follow_type;
+}
+\f
 void
 _initialize_parse ()
 {
@@ -625,4 +1047,25 @@ _initialize_parse ()
   type_stack_depth = 0;
   type_stack = (union type_stack_elt *)
     xmalloc (type_stack_size * sizeof (*type_stack));
+
+  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);
+
+#ifdef MAINTENANCE_CMDS
+  add_show_from_set (
+     add_set_cmd ("expressiondebug", class_maintenance, var_zinteger,
+                 (char *)&expressiondebug,
+                "Set expression debugging.\n\
+When non-zero, the internal representation of expressions will be printed.",
+                 &setlist),
+     &showlist);
+#endif
 }
This page took 0.034507 seconds and 4 git commands to generate.