use remote-utils facilities for baud_rate
[deliverable/binutils-gdb.git] / gdb / eval.c
index 77ae90c4eb1823c3008867e368897c8195863a4f..4aba99f777b2abf207bed5ef3ca463f9532bad97 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
@@ -161,7 +162,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
      enum noside noside;
 {
   enum exp_opcode op;
-  int tem;
+  int tem, tem2, tem3;
   register int pc, pc2, oldpos;
   register value arg1, arg2, arg3;
   struct type *type;
@@ -175,8 +176,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
     {
     case OP_SCOPE:
       tem = longest_to_int (exp->elts[pc + 2].longconst);
-      (*pos) += 4 + ((tem + sizeof (union exp_element))
-                    / sizeof (union exp_element));
+      (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
       arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
                                             0,
                                             exp->elts[pc + 1].type,
@@ -197,7 +197,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
                                exp->elts[pc + 2].doubleconst);
 
     case OP_VAR_VALUE:
-      (*pos) += 2;
+      (*pos) += 3;
       if (noside == EVAL_SKIP)
        goto nosideret;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
@@ -226,7 +226,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
          return value_zero (SYMBOL_TYPE (sym), lv);
        }
       else
-       return value_of_variable (exp->elts[pc + 1].symbol);
+       return value_of_variable (exp->elts[pc + 2].symbol,
+                                 exp->elts[pc + 1].block);
 
     case OP_LAST:
       (*pos) += 2;
@@ -237,12 +238,10 @@ 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;
@@ -250,12 +249,31 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
     case OP_STRING:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + ((tem + sizeof (union exp_element))
-                    / sizeof (union exp_element));
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       if (noside == EVAL_SKIP)
        goto nosideret;
       return value_string (&exp->elts[pc + 2].string, tem);
 
+    case OP_BITSTRING:
+      error ("support for OP_BITSTRING unimplemented");
+      break;
+
+    case OP_ARRAY:
+      (*pos) += 3;
+      tem2 = longest_to_int (exp->elts[pc + 1].longconst);
+      tem3 = longest_to_int (exp->elts[pc + 2].longconst);
+      nargs = tem3 - tem2 + 1;
+      argvec = (value *) alloca (sizeof (value) * nargs);
+      for (tem = 0; tem < nargs; tem++)
+       {
+         /* Ensure that array expressions are coerced into pointer objects. */
+         argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+       }
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      return (value_array (tem2, tem3, argvec));
+      break;
+
     case TERNOP_COND:
       /* Skip third and second args to evaluate the first one.  */
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
@@ -350,12 +368,26 @@ evaluate_subexp (expect_type, exp, pos, noside)
          /* First, evaluate the structure into arg2 */
          pc2 = (*pos)++;
          tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
-         *pos += 3 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element);
+         *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
          if (noside == EVAL_SKIP)
            goto nosideret;
 
          if (op == STRUCTOP_STRUCT)
            {
+             /* If v is a variable in a register, and the user types
+                v.method (), this will produce an error, because v has
+                no address.
+
+                A possible way around this would be to allocate a
+                copy of the variable on the stack, copy in the
+                contents, call the function, and copy out the
+                contents.  I.e. convert this from call by reference
+                to call by copy-return (or whatever it's called).
+                However, this does not work because it is not the
+                same: the method being called could stash a copy of
+                the address, and then future uses through that address
+                (after the method returns) would be expected to
+                use the variable itself, not some copy of it.  */
              arg2 = evaluate_subexp_for_address (exp, pos, noside);
            }
          else
@@ -370,6 +402,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
          nargs = longest_to_int (exp->elts[pc + 1].longconst);
          tem = 0;
        }
+      /* Allocate arg vector, including space for the function to be
+        called in argvec[0] and a terminating NULL */
       argvec = (value *) alloca (sizeof (value) * (nargs + 2));
       for (; tem <= nargs; tem++)
        /* Ensure that array expressions are coerced into pointer objects. */
@@ -392,7 +426,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
          if (VALUE_OFFSET (temp))
            {
              arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (temp)),
-                                     value_as_long (arg2)+VALUE_OFFSET (temp));
+                                        VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
              argvec[1] = arg2;
            }
          if (static_memfuncp)
@@ -431,8 +465,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
     case STRUCTOP_STRUCT:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + ((tem + sizeof (union exp_element))
-                    / sizeof (union exp_element));
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
@@ -450,13 +483,12 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
     case STRUCTOP_PTR:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       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)),
+       return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
                                                   &exp->elts[pc + 2].string,
                                                   0),
                           lval_memory);
@@ -492,6 +524,16 @@ evaluate_subexp (expect_type, exp, pos, noside)
     bad_pointer_to_member:
       error("non-pointer-to-member value used in pointer-to-member construct");
 
+    case BINOP_CONCAT:
+      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+      arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+      if (binop_user_defined_p (op, arg1, arg2))
+       return value_x_binop (arg1, arg2, op, OP_NULL);
+      else
+       return value_concat (arg1, arg2);
+
     case BINOP_ASSIGN:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
@@ -542,6 +584,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:
@@ -555,7 +598,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);
@@ -858,7 +901,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
          if (op == OP_SCOPE)
            {
              int temm = longest_to_int (exp->elts[pc+3].longconst);
-             (*pos) += 3 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
+             (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1);
            }
          else
            evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
@@ -959,8 +1002,22 @@ evaluate_subexp (expect_type, exp, pos, noside)
       (*pos) += 1;
       return value_of_this (1);
 
+    case OP_TYPE:
+      error ("Attempt to use a type name as an expression");
+
     default:
-      error ("internal error: I do not know how to evaluate what you gave me");
+      /* Removing this case and compiling with gcc -Wall reveals that
+        a lot of cases are hitting this case.  Some of these should
+        probably be removed from expression.h (e.g. do we need a BINOP_SCOPE
+        and an OP_SCOPE?); others are legitimate expressions which are
+        (apparently) not fully implemented.
+
+        If there are any cases landing here which mean a user error,
+        then they should be separate cases, with more descriptive
+        error messages.  */
+
+      error ("\
+GDB does not (yet) know how to evaluated that kind of expression");
     }
 
  nosideret:
@@ -999,14 +1056,14 @@ evaluate_subexp_for_address (exp, pos, noside)
                         evaluate_subexp (NULL_TYPE, exp, pos, noside));
 
     case OP_VAR_VALUE:
-      var = exp->elts[pc + 1].symbol;
+      var = exp->elts[pc + 2].symbol;
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to. Let value_addr() deal with it. */
       if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
         goto default_case;
 
-      (*pos) += 3;
+      (*pos) += 4;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          struct type *type =
@@ -1023,7 +1080,10 @@ evaluate_subexp_for_address (exp, pos, noside)
          value_zero (type, not_lval);
        }
       else
-       return locate_var_value (var, (FRAME) 0);
+       return
+         locate_var_value
+           (var,
+            block_innermost_frame (exp->elts[pc + 1].block));
 
     default:
     default_case:
@@ -1041,9 +1101,17 @@ 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 (perhaps obsolete now that we have
+   VALUE_LAZY).
+
+   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)
@@ -1062,16 +1130,21 @@ evaluate_subexp_with_coercion (exp, pos, noside)
   switch (op)
     {
     case OP_VAR_VALUE:
-      var = exp->elts[pc + 1].symbol;
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY)
+      var = exp->elts[pc + 2].symbol;
+      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY
+         && CAST_IS_CONVERSION)
        {
-         (*pos) += 3;
-         val = locate_var_value (var, (FRAME) 0);
+         (*pos) += 4;
+         val =
+           locate_var_value
+             (var, block_innermost_frame (exp->elts[pc + 1].block));
          return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))),
                             val);
        }
-      default:
-       return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      /* FALLTHROUGH */
+
+    default:
+      return evaluate_subexp (NULL_TYPE, exp, pos, noside);
     }
 }
 
@@ -1109,9 +1182,11 @@ evaluate_subexp_for_sizeof (exp, pos)
                              (LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type));
 
     case OP_VAR_VALUE:
-      (*pos) += 3;
-      return value_from_longest (builtin_type_int,
-        (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol)));
+      (*pos) += 4;
+      return
+       value_from_longest
+         (builtin_type_int,
+          (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 2].symbol)));
 
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
This page took 0.027895 seconds and 4 git commands to generate.