* Rename remote-es1800.c to remote-es.c
[deliverable/binutils-gdb.git] / gdb / eval.c
index 82e02cee09dabe7fd4594a3aedaede3c22879377..971ad9a32d4abcbe2deb45adad11bd22a2cd2da6 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "expression.h"
 #include "target.h"
 #include "frame.h"
+#include "language.h"  /* For CAST_IS_CONVERSION */
 
 /* Values of NOSIDE argument to eval_subexp.  */
 enum noside
@@ -174,22 +175,22 @@ evaluate_subexp (expect_type, exp, pos, noside)
   switch (op)
     {
     case OP_SCOPE:
-      tem = strlen (&exp->elts[pc + 2].string);
-      (*pos) += 3 + ((tem + sizeof (union exp_element))
+      tem = longest_to_int (exp->elts[pc + 2].longconst);
+      (*pos) += 4 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
       arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
                                             0,
                                             exp->elts[pc + 1].type,
-                                            &exp->elts[pc + 2].string,
+                                            &exp->elts[pc + 3].string,
                                             expect_type);
       if (arg1 == NULL)
-       error ("There is no field named %s", &exp->elts[pc + 2].string);
+       error ("There is no field named %s", &exp->elts[pc + 3].string);
       return arg1;
 
     case OP_LONG:
       (*pos) += 3;
       return value_from_longest (exp->elts[pc + 1].type,
-                             exp->elts[pc + 2].longconst);
+                                exp->elts[pc + 2].longconst);
 
     case OP_DOUBLE:
       (*pos) += 3;
@@ -237,22 +238,24 @@ evaluate_subexp (expect_type, exp, pos, noside)
       (*pos) += 2;
       return value_of_register (longest_to_int (exp->elts[pc + 1].longconst));
 
+    /* start-sanitize-chill */
     case OP_BOOL:
       (*pos) += 2;
       return value_from_longest (builtin_type_chill_bool,
                                 exp->elts[pc + 1].longconst);
+    /* end-sanitize-chill */
 
     case OP_INTERNALVAR:
       (*pos) += 2;
       return value_of_internalvar (exp->elts[pc + 1].internalvar);
 
     case OP_STRING:
-      tem = strlen (&exp->elts[pc + 1].string);
-      (*pos) += 2 + ((tem + sizeof (union exp_element))
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
       if (noside == EVAL_SKIP)
        goto nosideret;
-      return value_string (&exp->elts[pc + 1].string, tem);
+      return value_string (&exp->elts[pc + 2].string, tem);
 
     case TERNOP_COND:
       /* Skip third and second args to evaluate the first one.  */
@@ -347,8 +350,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
          nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1;
          /* First, evaluate the structure into arg2 */
          pc2 = (*pos)++;
-         tem2 = strlen (&exp->elts[pc2 + 1].string);
-         *pos += 2 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element);
+         tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
+         *pos += 3 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element);
          if (noside == EVAL_SKIP)
            goto nosideret;
 
@@ -383,7 +386,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
          argvec[1] = arg2;
          argvec[0] =
-           value_struct_elt (&temp, argvec+1, &exp->elts[pc2 + 1].string,
+           value_struct_elt (&temp, argvec+1, &exp->elts[pc2 + 2].string,
                              &static_memfuncp,
                              op == STRUCTOP_STRUCT
                              ? "structure" : "structure pointer");
@@ -428,40 +431,40 @@ evaluate_subexp (expect_type, exp, pos, noside)
       return call_function_by_hand (argvec[0], nargs, argvec + 1);
 
     case STRUCTOP_STRUCT:
-      tem = strlen (&exp->elts[pc + 1].string);
-      (*pos) += 2 + ((tem + sizeof (union exp_element))
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
-                                                  &exp->elts[pc + 1].string,
+                                                  &exp->elts[pc + 2].string,
                                                   0),
                           lval_memory);
       else
        {
          value temp = arg1;
-         return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].string,
+         return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string,
                                   (int *) 0, "structure");
        }
 
     case STRUCTOP_PTR:
-      tem = strlen (&exp->elts[pc + 1].string);
-      (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        return value_zero (lookup_struct_elt_type (TYPE_TARGET_TYPE
                                                   (VALUE_TYPE (arg1)),
-                                                  &exp->elts[pc + 1].string,
+                                                  &exp->elts[pc + 2].string,
                                                   0),
                           lval_memory);
       else
        {
          value temp = arg1;
-         return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].string,
+         return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string,
                                   (int *) 0, "structure pointer");
        }
 
@@ -540,6 +543,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
     case BINOP_MUL:
     case BINOP_DIV:
     case BINOP_REM:
+    case BINOP_MOD:
     case BINOP_LSH:
     case BINOP_RSH:
     case BINOP_BITWISE_AND:
@@ -553,7 +557,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
        return value_x_binop (arg1, arg2, op, OP_NULL);
       else
        if (noside == EVAL_AVOID_SIDE_EFFECTS
-           && (op == BINOP_DIV || op == BINOP_REM))
+           && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD))
          return value_zero (VALUE_TYPE (arg1), not_lval);
       else
        return value_binop (arg1, arg2, op);
@@ -582,6 +586,57 @@ evaluate_subexp (expect_type, exp, pos, noside)
       else
        return value_subscript (arg1, arg2);
       
+    case MULTI_SUBSCRIPT:
+      (*pos) += 2;
+      nargs = longest_to_int (exp->elts[pc + 1].longconst);
+      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+      while (nargs-- > 0)
+       {
+         arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+         /* FIXME:  EVAL_SKIP handling may not be correct. */
+         if (noside == EVAL_SKIP)
+           {
+             if (nargs > 0)
+               {
+                 continue;
+               }
+             else
+               {
+                 goto nosideret;
+               }
+           }
+         /* FIXME:  EVAL_AVOID_SIDE_EFFECTS handling may not be correct. */
+         if (noside == EVAL_AVOID_SIDE_EFFECTS)
+           {
+             /* If the user attempts to subscript something that has no target
+                type (like a plain int variable for example), then report this
+                as an error. */
+             
+             type = TYPE_TARGET_TYPE (VALUE_TYPE (arg1));
+             if (type != NULL)
+               {
+                 arg1 = value_zero (type, VALUE_LVAL (arg1));
+                 noside = EVAL_SKIP;
+                 continue;
+               }
+             else
+               {
+                 error ("cannot subscript something of type `%s'",
+                        TYPE_NAME (VALUE_TYPE (arg1)));
+               }
+           }
+         
+         if (binop_user_defined_p (op, arg1, arg2))
+           {
+             arg1 = value_x_binop (arg1, arg2, op, OP_NULL);
+           }
+         else
+           {
+             arg1 = value_subscript (arg1, arg2);
+           }
+       }
+      return (arg1);
+
     case BINOP_LOGICAL_AND:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
@@ -804,9 +859,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
        {
          if (op == OP_SCOPE)
            {
-             char *name = &exp->elts[pc+3].string;
-             int temm = strlen (name);
-             (*pos) += 2 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
+             int temm = longest_to_int (exp->elts[pc+3].longconst);
+             (*pos) += 3 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
            }
          else
            evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
@@ -989,9 +1043,16 @@ evaluate_subexp_for_address (exp, pos, noside)
 }
 
 /* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
-   When used in contexts where arrays will be coerced anyway,
-   this is equivalent to `evaluate_subexp'
-   but much faster because it avoids actually fetching array contents.  */
+   When used in contexts where arrays will be coerced anyway, this is
+   equivalent to `evaluate_subexp' but much faster because it avoids
+   actually fetching array contents.
+
+   Note that we currently only do the coercion for C expressions, where
+   arrays are zero based and the coercion is correct.  For other languages,
+   with nonzero based arrays, coercion loses.  Use CAST_IS_CONVERSION
+   to decide if coercion is appropriate.
+
+  */
 
 static value
 evaluate_subexp_with_coercion (exp, pos, noside)
@@ -1011,7 +1072,8 @@ evaluate_subexp_with_coercion (exp, pos, noside)
     {
     case OP_VAR_VALUE:
       var = exp->elts[pc + 1].symbol;
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY)
+      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY
+         && CAST_IS_CONVERSION)
        {
          (*pos) += 3;
          val = locate_var_value (var, (FRAME) 0);
This page took 0.026276 seconds and 4 git commands to generate.