* configure.in (*-*-sunos*): Use trailing * to match all
[deliverable/binutils-gdb.git] / gdb / eval.c
index 110a129fea5ab41a4c64c7b1f1377641ac85bbd2..2b70c4bb6fd4faf5b75cd158c91ef7203c8f3d25 100644 (file)
@@ -1,5 +1,5 @@
 /* Evaluate expressions for GDB.
-   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,15 +17,45 @@ 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.  */
 
-#include <stdio.h>
 #include "defs.h"
 #include "symtab.h"
+#include "gdbtypes.h"
 #include "value.h"
 #include "expression.h"
 #include "target.h"
 #include "frame.h"
 
-#define        NULL_TYPE       ((struct type *)0)
+/* Values of NOSIDE argument to eval_subexp.  */
+enum noside
+{ EVAL_NORMAL,
+  EVAL_SKIP,                   /* Only effect is to increment pos.  */
+  EVAL_AVOID_SIDE_EFFECTS      /* Don't modify any variables or
+                                  call any functions.  The value
+                                  returned will have the correct
+                                  type, and will have an
+                                  approximately correct lvalue
+                                  type (inaccuracy: anything that is
+                                  listed as being in a register in
+                                  the function in which it was
+                                  declared will be lval_register).  */
+};
+
+/* Prototypes for local functions. */
+
+static value
+evaluate_subexp_for_sizeof PARAMS ((struct expression *, int *));
+
+static value
+evaluate_subexp_with_coercion PARAMS ((struct expression *, int *,
+                                      enum noside));
+
+static value
+evaluate_subexp_for_address PARAMS ((struct expression *, int *,
+                                    enum noside));
+
+static value
+evaluate_subexp PARAMS ((struct type *, struct expression *, int *,
+                        enum noside));
 
 \f
 /* Parse the string EXP as a C expression, evaluate it,
@@ -37,8 +67,8 @@ parse_and_eval_address (exp)
 {
   struct expression *expr = parse_expression (exp);
   register CORE_ADDR addr;
-  register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+  register struct cleanup *old_chain = 
+      make_cleanup (free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -54,8 +84,8 @@ parse_and_eval_address_1 (expptr)
 {
   struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);
   register CORE_ADDR addr;
-  register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+  register struct cleanup *old_chain =
+      make_cleanup (free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -104,21 +134,6 @@ static value evaluate_subexp_for_address ();
 static value evaluate_subexp_for_sizeof ();
 static value evaluate_subexp_with_coercion ();
 
-/* Values of NOSIDE argument to eval_subexp.  */
-enum noside
-{ EVAL_NORMAL,
-  EVAL_SKIP,                   /* Only effect is to increment pos.  */
-  EVAL_AVOID_SIDE_EFFECTS      /* Don't modify any variables or
-                                  call any functions.  The value
-                                  returned will have the correct
-                                  type, and will have an
-                                  approximately correct lvalue
-                                  type (inaccuracy: anything that is
-                                  listed as being in a register in
-                                  the function in which it was
-                                  declared will be lval_register).  */
-};
-
 value
 evaluate_expression (exp)
      struct expression *exp;
@@ -149,6 +164,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
   int tem;
   register int pc, pc2, oldpos;
   register value arg1, arg2, arg3;
+  struct type *type;
   int nargs;
   value *argvec;
 
@@ -161,8 +177,11 @@ evaluate_subexp (expect_type, exp, pos, noside)
       tem = strlen (&exp->elts[pc + 2].string);
       (*pos) += 3 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
-      arg1 = value_static_field (exp->elts[pc + 1].type,
-                                &exp->elts[pc + 2].string, -1);
+      arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
+                                            0,
+                                            exp->elts[pc + 1].type,
+                                            &exp->elts[pc + 2].string,
+                                            expect_type);
       if (arg1 == NULL)
        error ("There is no field named %s", &exp->elts[pc + 2].string);
       return arg1;
@@ -406,7 +425,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
          else
            error ("Expression of type other than \"Function returning ...\" used as function");
        }
-      return target_call_function (argvec[0], nargs, argvec + 1);
+      return call_function_by_hand (argvec[0], nargs, argvec + 1);
 
     case STRUCTOP_STRUCT:
       tem = strlen (&exp->elts[pc + 1].string);
@@ -448,35 +467,28 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
     case STRUCTOP_MEMBER:
       arg1 = evaluate_subexp_for_address (exp, pos, noside);
-      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-      if (noside == EVAL_SKIP)
-       goto nosideret;
-      /* Now, convert these values to an address.  */
-      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
-         || ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
-              != TYPE_CODE_MEMBER)
-             && (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
-                 != TYPE_CODE_METHOD)))
-       error ("non-pointer-to-member value used in pointer-to-member construct");
-      arg3 = value_from_longest (
-       lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
-                             value_as_long (arg1) + value_as_long (arg2));
-      return value_ind (arg3);
-
+      goto handle_pointer_to_member;
     case STRUCTOP_MPTR:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+    handle_pointer_to_member:
       arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
+      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR)
+       goto bad_pointer_to_member;
+      type = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
+      if (TYPE_CODE (type) == TYPE_CODE_METHOD)
+       error ("not implemented: pointer-to-method in pointer-to-member construct");
+      if (TYPE_CODE (type) != TYPE_CODE_MEMBER)
+       goto bad_pointer_to_member;
       /* Now, convert these values to an address.  */
-      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
-         || (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
-             && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
-       error ("non-pointer-to-member value used in pointer-to-member construct");
-      arg3 = value_from_longest (
-       lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
-                             value_as_long (arg1) + value_as_long (arg2));
+      arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
+                        arg1);
+      arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+                                value_as_long (arg1) + value_as_long (arg2));
       return value_ind (arg3);
+    bad_pointer_to_member:
+      error("non-pointer-to-member value used in pointer-to-member construct");
 
     case BINOP_ASSIGN:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
@@ -541,7 +553,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_DIV || op == BINOP_REM))
          return value_zero (VALUE_TYPE (arg1), not_lval);
       else
        return value_binop (arg1, arg2, op);
@@ -683,8 +695,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
        }
       else
        {
-         tem = value_less (arg1, arg2);
-         return value_from_longest (builtin_type_int, (LONGEST) tem);
+         tem = value_less (arg2, arg1) || value_equal (arg1, arg2);
+         return value_from_longest (builtin_type_int, (LONGEST) tem);
        }
 
     case BINOP_LEQ:
@@ -698,8 +710,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
        }
       else 
        {
-         tem = value_less (arg2, arg1);
-         return value_from_longest (builtin_type_int, (LONGEST) tem);
+         tem = value_less (arg1, arg2) || value_equal (arg1, arg2);
+         return value_from_longest (builtin_type_int, (LONGEST) tem);
        }
 
     case BINOP_REPEAT:
@@ -732,10 +744,6 @@ evaluate_subexp (expect_type, exp, pos, noside)
       /* C++: check for and handle destructor names.  */
       op = exp->elts[*pos].opcode;
 
-      /* FIXME-tiemann: this is a cop-out.  */
-      if (op == OP_SCOPE)
-       error ("destructor in eval");
-
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
@@ -795,19 +803,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
          goto nosideret;
        }
 
-      if (op == OP_SCOPE)
-       {
-         char *name = &exp->elts[pc+3].string;
-         int temm = strlen (name);
-         struct type *domain = exp->elts[pc+2].type;
-         (*pos) += 2 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
-         arg1 = value_struct_elt_for_address (domain, expect_type, name);
-         if (arg1)
-           return arg1;
-         error ("no field `%s' in structure", name);
-       }
-      else
-       return evaluate_subexp_for_address (exp, pos, noside);
+      return evaluate_subexp_for_address (exp, pos, noside);
 
     case UNOP_SIZEOF:
       if (noside == EVAL_SKIP)
@@ -924,6 +920,7 @@ evaluate_subexp_for_address (exp, pos, noside)
 {
   enum exp_opcode op;
   register int pc;
+  struct symbol *var;
 
   pc = (*pos);
   op = exp->elts[pc].opcode;
@@ -940,13 +937,19 @@ evaluate_subexp_for_address (exp, pos, noside)
                         evaluate_subexp (NULL_TYPE, exp, pos, noside));
 
     case OP_VAR_VALUE:
+      var = exp->elts[pc + 1].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;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          struct type *type =
-           lookup_pointer_type (SYMBOL_TYPE (exp->elts[pc + 1].symbol));
-         enum address_class sym_class =
-           SYMBOL_CLASS (exp->elts[pc + 1].symbol);
+           lookup_pointer_type (SYMBOL_TYPE (var));
+         enum address_class sym_class = SYMBOL_CLASS (var);
 
          if (sym_class == LOC_CONST
              || sym_class == LOC_CONST_BYTES
@@ -958,9 +961,10 @@ evaluate_subexp_for_address (exp, pos, noside)
          value_zero (type, not_lval);
        }
       else
-       return locate_var_value (exp->elts[pc + 1].symbol, (FRAME) 0);
+       return locate_var_value (var, (FRAME) 0);
 
     default:
+    default_case:
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          value x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
@@ -988,6 +992,7 @@ evaluate_subexp_with_coercion (exp, pos, noside)
   register enum exp_opcode op;
   register int pc;
   register value val;
+  struct symbol *var;
 
   pc = (*pos);
   op = exp->elts[pc].opcode;
@@ -995,11 +1000,12 @@ evaluate_subexp_with_coercion (exp, pos, noside)
   switch (op)
     {
     case OP_VAR_VALUE:
-      if (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 1].symbol)) == TYPE_CODE_ARRAY)
+      var = exp->elts[pc + 1].symbol;
+      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY)
        {
          (*pos) += 3;
-         val = locate_var_value (exp->elts[pc + 1].symbol, (FRAME) 0);
-         return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (exp->elts[pc + 1].symbol))),
+         val = locate_var_value (var, (FRAME) 0);
+         return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))),
                             val);
        }
       default:
@@ -1062,7 +1068,7 @@ parse_and_eval_type (p, length)
     char *tmp = (char *)alloca (length + 4);
     struct expression *expr;
     tmp[0] = '(';
-    bcopy (p, tmp+1, length);
+    (void) memcpy (tmp+1, p, length);
     tmp[length+1] = ')';
     tmp[length+2] = '0';
     tmp[length+3] = '\0';
This page took 0.02796 seconds and 4 git commands to generate.