* test-build.mk (HOLES): Add "xargs" for gdb.
[deliverable/binutils-gdb.git] / gdb / parse.c
index ca9bcc8c9b011fd36689b640eedad801c5095ff9..e4ff571f1b7cec7fd2a02b47589d84086e6dc043 100644 (file)
@@ -1,5 +1,5 @@
 /* Parse expressions for GDB.
-   Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1989, 1990, 1991, 1994 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.
@@ -29,6 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    come first in the result.  */
    
 #include "defs.h"
+#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "frame.h"
@@ -37,7 +38,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "command.h"
 #include "language.h"
 #include "parser-defs.h"
-
+\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
 static void
 free_funcalls PARAMS ((void));
 
@@ -200,7 +215,7 @@ write_exp_elt_longcst (expelt)
 
 void
 write_exp_elt_dblcst (expelt)
-     double expelt;
+     DOUBLEST expelt;
 {
   union exp_element tmp;
 
@@ -340,7 +355,15 @@ write_exp_bitstring (str)
 }
 
 /* Add the appropriate elements for a minimal symbol to the end of
-   the expression.  */
+   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)
@@ -349,7 +372,7 @@ write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
      struct type *data_symbol_type;
 {
   write_exp_elt_opcode (OP_LONG);
-  write_exp_elt_type (builtin_type_long);
+  write_exp_elt_type (lookup_pointer_type (builtin_type_void));
   write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
   write_exp_elt_opcode (OP_LONG);
 
@@ -358,23 +381,115 @@ write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
     {
     case mst_text:
     case mst_file_text:
-      write_exp_elt_type (text_symbol_type);
+    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 (data_symbol_type);
+      write_exp_elt_type (msym_data_symbol_type);
       break;
 
     default:
-      write_exp_elt_type (builtin_type_char);
+      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.  */
+  for (i = 0; i < NUM_REGS; i++)
+    if (reg_names[i] && str.length - 1 == strlen (reg_names[i])
+       && STREQN (str.ptr + 1, reg_names[i], str.length - 1))
+      {
+       goto handle_register;
+      }
+  for (i = 0; i < num_std_regs; i++)
+    if (std_regs[i].name && str.length - 1 == strlen (std_regs[i].name)
+       && STREQN (str.ptr + 1, std_regs[i].name, str.length - 1))
+      {
+       i = std_regs[i].regnum;
+       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
    of a string token.  */
 
@@ -446,7 +561,13 @@ length_of_subexp (expr, endpos)
       oplen = 3;
       break;
 
+    case OP_COMPLEX:
+      oplen = 1; 
+      args = 2;
+      break; 
+
     case OP_FUNCALL:
+    case OP_F77_UNDETERMINED_ARGLIST:
       oplen = 3;
       args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
       break;
@@ -475,12 +596,20 @@ length_of_subexp (expr, endpos)
       args = 1;
       break;
 
+    case OP_LABELED:
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC
+    case STRUCTOP_FIELD:
+#endif /* GENERAL_MAGIC */
+/* end-sanitize-gm */
       args = 1;
       /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
+    case OP_NAME:
+    case OP_EXPRSTRING:
       oplen = longest_to_int (expr->elts[endpos - 2].longconst);
       oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
@@ -499,12 +628,14 @@ length_of_subexp (expr, endpos)
       break;
 
     case TERNOP_COND:
+    case TERNOP_SLICE:
+    case TERNOP_SLICE_COUNT:
       args = 3;
       break;
 
       /* Modula-2 */
    case MULTI_SUBSCRIPT:
-      oplen=3;
+      oplen = 3;
       args = 1 + longest_to_int (expr->elts[endpos- 2].longconst);
       break;
 
@@ -575,7 +706,13 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       oplen = 3;
       break;
 
+    case OP_COMPLEX:
+      oplen = 1; 
+      args = 2; 
+      break; 
+
     case OP_FUNCALL:
+    case OP_F77_UNDETERMINED_ARGLIST:
       oplen = 3;
       args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
@@ -605,10 +742,13 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
 
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
+    case OP_LABELED:
       args = 1;
       /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
+    case OP_NAME:
+    case OP_EXPRSTRING:
       oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
       oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
@@ -627,6 +767,8 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       break;
 
     case TERNOP_COND:
+    case TERNOP_SLICE:
+    case TERNOP_SLICE_COUNT:
       args = 3;
       break;
 
@@ -637,7 +779,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
 
       /* Modula-2 */
    case MULTI_SUBSCRIPT:
-      oplen=3;
+      oplen = 3;
       args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
 
@@ -833,20 +975,22 @@ follow_types (follow_type)
        break;
       case tp_array:
        array_size = pop_type_int ();
-       if (array_size != -1)
-         {
-           range_type =
-             create_range_type ((struct type *) NULL,
-                                builtin_type_int, 0,
-                                array_size - 1);
-           follow_type =
-             create_array_type ((struct type *) NULL,
-                                follow_type, range_type);
-         }
-       else
-         follow_type = lookup_pointer_type (follow_type);
+       /* 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;
       }
@@ -860,4 +1004,15 @@ _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);
 }
This page took 0.027411 seconds and 4 git commands to generate.