aboutsummaryrefslogtreecommitdiff
path: root/gdb/eval.c
diff options
context:
space:
mode:
authorJohn Gilmore <gnu@cygnus>1990-09-05 17:54:31 +0000
committerJohn Gilmore <gnu@cygnus>1990-09-05 17:54:31 +0000
commit831c851165e112139af1265f294e198401814c1f (patch)
tree5f155fecb9b690be9c428e822d519c2710fefd47 /gdb/eval.c
parent7a67dd45ca1c191a0220697a3ec9fa92993caf8c (diff)
downloadgdb-831c851165e112139af1265f294e198401814c1f.zip
gdb-831c851165e112139af1265f294e198401814c1f.tar.gz
gdb-831c851165e112139af1265f294e198401814c1f.tar.bz2
Initial revision
Diffstat (limited to 'gdb/eval.c')
-rw-r--r--gdb/eval.c1021
1 files changed, 0 insertions, 1021 deletions
diff --git a/gdb/eval.c b/gdb/eval.c
deleted file mode 100644
index 8de5c84..0000000
--- a/gdb/eval.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/* Evaluate expressions for GDB.
- Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-GDB is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
-
-GDB is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GDB; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "value.h"
-#include "expression.h"
-
-
-/* Parse the string EXP as a C expression, evaluate it,
- and return the result as a number. */
-
-CORE_ADDR
-parse_and_eval_address (exp)
- char *exp;
-{
- struct expression *expr = parse_c_expression (exp);
- register CORE_ADDR addr;
- register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
-
- addr = (CORE_ADDR) value_as_long (evaluate_expression (expr));
- do_cleanups (old_chain);
- return addr;
-}
-
-/* Like parse_and_eval_address but takes a pointer to a char * variable
- and advanced that variable across the characters parsed. */
-
-CORE_ADDR
-parse_and_eval_address_1 (expptr)
- char **expptr;
-{
- struct expression *expr = parse_c_1 (expptr, 0, 0);
- register CORE_ADDR addr;
- register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
-
- addr = value_as_long (evaluate_expression (expr));
- do_cleanups (old_chain);
- return addr;
-}
-
-value
-parse_and_eval (exp)
- char *exp;
-{
- struct expression *expr = parse_c_expression (exp);
- register value val;
- register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
-
- val = evaluate_expression (expr);
- do_cleanups (old_chain);
- return val;
-}
-
-/* Parse up to a comma (or to a closeparen)
- in the string EXPP as an expression, evaluate it, and return the value.
- EXPP is advanced to point to the comma. */
-
-value
-parse_to_comma_and_eval (expp)
- char **expp;
-{
- struct expression *expr = parse_c_1 (expp, 0, 1);
- register value val;
- register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
-
- val = evaluate_expression (expr);
- do_cleanups (old_chain);
- return val;
-}
-
-/* Evaluate an expression in internal prefix form
- such as is constructed by expread.y.
-
- See expression.h for info on the format of an expression. */
-
-static value evaluate_subexp ();
-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;
-{
- int pc = 0;
- return evaluate_subexp (0, exp, &pc, EVAL_NORMAL);
-}
-
-/* Evaluate an expression, avoiding all memory references
- and getting a value whose type alone is correct. */
-
-value
-evaluate_type (exp)
- struct expression *exp;
-{
- int pc = 0;
- return evaluate_subexp (0, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
-}
-
-static value
-evaluate_subexp (expect_type, exp, pos, noside)
- struct type *expect_type;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
-{
- enum exp_opcode op;
- int tem;
- register int pc, pc2, oldpos;
- register value arg1, arg2, arg3;
- int nargs;
- value *argvec;
-
- pc = (*pos)++;
- op = exp->elts[pc].opcode;
-
- switch (op)
- {
- case OP_SCOPE:
- tem = strlen (&exp->elts[pc + 2].string);
- (*pos) += 3 + ((tem + sizeof (union exp_element))
- / sizeof (union exp_element));
- return value_static_field (exp->elts[pc + 1].type,
- &exp->elts[pc + 2].string, -1);
-
- case OP_LONG:
- (*pos) += 3;
- return value_from_long (exp->elts[pc + 1].type,
- exp->elts[pc + 2].longconst);
-
- case OP_DOUBLE:
- (*pos) += 3;
- return value_from_double (exp->elts[pc + 1].type,
- exp->elts[pc + 2].doubleconst);
-
- case OP_VAR_VALUE:
- (*pos) += 2;
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- struct symbol * sym = exp->elts[pc + 1].symbol;
- enum lval_type lv;
-
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_CONST:
- case LOC_LABEL:
- case LOC_CONST_BYTES:
- lv = not_lval;
- case LOC_REGISTER:
- case LOC_REGPARM:
- lv = lval_register;
- default:
- lv = lval_memory;
- }
-
- return value_zero (SYMBOL_TYPE (sym), lv);
- }
- else
- return value_of_variable (exp->elts[pc + 1].symbol);
-
- case OP_LAST:
- (*pos) += 2;
- return access_value_history ((int) exp->elts[pc + 1].longconst);
-
- case OP_REGISTER:
- (*pos) += 2;
- return value_of_register ((int) exp->elts[pc + 1].longconst);
-
- 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))
- / sizeof (union exp_element));
- if (noside == EVAL_SKIP)
- goto nosideret;
- return value_string (&exp->elts[pc + 1].string, tem);
-
- case TERNOP_COND:
- /* Skip third and second args to evaluate the first one. */
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (value_zerop (arg1))
- {
- evaluate_subexp (0, exp, pos, EVAL_SKIP);
- return evaluate_subexp (0, exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- evaluate_subexp (0, exp, pos, EVAL_SKIP);
- return arg2;
- }
-
- case OP_FUNCALL:
- (*pos) += 2;
- op = exp->elts[*pos].opcode;
- if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
- {
- int fnptr;
- int tem2;
-
- nargs = (int) exp->elts[pc + 1].longconst + 1;
- /* First, evaluate the structure into arg2 */
- pc2 = (*pos)++;
-
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- if (op == STRUCTOP_MEMBER)
- {
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- }
-
- /* If the function is a virtual function, then the
- aggregate value (providing the structure) plays
- its part by providing the vtable. Otherwise,
- it is just along for the ride: call the function
- directly. */
-
- arg1 = evaluate_subexp (0, exp, pos, noside);
-
- fnptr = (int) value_as_long (arg1);
- if (fnptr < 128)
- {
- struct type *basetype;
- int i, j;
- basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
- basetype = TYPE_VPTR_BASETYPE (basetype);
- for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)
- {
- struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i);
- /* If one is virtual, then all are virtual. */
- if (TYPE_FN_FIELD_VIRTUAL_P (f, 0))
- for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
- if (TYPE_FN_FIELD_VOFFSET (f, j) == fnptr)
- {
- value vtbl;
- value base = value_ind (arg2);
- struct type *fntype = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
-
- if (TYPE_VPTR_FIELDNO (basetype) < 0)
- TYPE_VPTR_FIELDNO (basetype)
- = fill_in_vptr_fieldno (basetype);
-
- VALUE_TYPE (base) = basetype;
- vtbl = value_field (base, TYPE_VPTR_FIELDNO (basetype));
- VALUE_TYPE (vtbl) = lookup_pointer_type (fntype);
- VALUE_TYPE (arg1) = builtin_type_int;
- arg1 = value_subscript (vtbl, arg1);
- VALUE_TYPE (arg1) = fntype;
- goto got_it;
- }
- }
- if (i < 0)
- error ("virtual function at index %d not found", fnptr);
- }
- else
- {
- VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));
- }
- got_it:
-
- /* Now, say which argument to start evaluating from */
- tem = 2;
- }
- else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
- {
- /* Hair for method invocations */
- int tem2;
-
- nargs = (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);
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- if (op == STRUCTOP_STRUCT)
- {
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- }
- /* Now, say which argument to start evaluating from */
- tem = 2;
- }
- else
- {
- nargs = (int) exp->elts[pc + 1].longconst;
- tem = 0;
- }
- argvec = (value *) alloca (sizeof (value) * (nargs + 2));
- for (; tem <= nargs; tem++)
- /* Ensure that array expressions are coerced into pointer objects. */
- argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
-
- /* signal end of arglist */
- argvec[tem] = 0;
-
- if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
- {
- int static_memfuncp;
-
- argvec[1] = arg2;
- argvec[0] =
- value_struct_elt (arg2, argvec+1, &exp->elts[pc2 + 1].string,
- &static_memfuncp,
- op == STRUCTOP_STRUCT
- ? "structure" : "structure pointer");
- if (static_memfuncp)
- {
- argvec[1] = argvec[0];
- nargs--;
- argvec++;
- }
- }
- else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
- {
- argvec[1] = arg2;
- argvec[0] = arg1;
- }
-
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the return type doesn't look like a function type, call an
- error. This can happen if somebody tries to turn a variable into
- a function call. This is here because people often want to
- call, eg, strcmp, which gdb doesn't know is a function. If
- gdb isn't asked for it's opinion (ie. through "whatis"),
- it won't offer it. */
-
- struct type *ftype =
- TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]));
-
- if (ftype)
- return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
- else
- error ("Expression of type other than \"Function returning ...\" used as function");
- }
- return call_function (argvec[0], nargs, argvec + 1);
-
- case STRUCTOP_STRUCT:
- tem = strlen (&exp->elts[pc + 1].string);
- (*pos) += 2 + ((tem + sizeof (union exp_element))
- / sizeof (union exp_element));
- arg1 = evaluate_subexp (0, 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),
- lval_memory);
- else
- return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, 0,
- "structure");
-
- case STRUCTOP_PTR:
- tem = strlen (&exp->elts[pc + 1].string);
- (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
- arg1 = evaluate_subexp (0, 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),
- lval_memory);
- else
- return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, 0,
- "structure pointer");
-
- case STRUCTOP_MEMBER:
- arg1 = evaluate_subexp_for_address (exp, pos, noside);
- arg2 = evaluate_subexp (0, 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_long (builtin_type_long,
- value_as_long (arg1) + value_as_long (arg2));
- VALUE_TYPE (arg3) =
- lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))));
- return value_ind (arg3);
-
- case STRUCTOP_MPTR:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (0, 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_long (builtin_type_long,
- value_as_long (arg1) + value_as_long (arg2));
- VALUE_TYPE (arg3) =
- lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))));
- return value_ind (arg3);
-
- case BINOP_ASSIGN:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, 0);
- else
- return value_assign (arg1, arg2);
-
- case BINOP_ASSIGN_MODIFY:
- (*pos) += 2;
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- op = exp->elts[pc + 1].opcode;
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op);
- else if (op == BINOP_ADD)
- arg2 = value_add (arg1, arg2);
- else if (op == BINOP_SUB)
- arg2 = value_sub (arg1, arg2);
- else
- arg2 = value_binop (arg1, arg2, op);
- return value_assign (arg1, arg2);
-
- case BINOP_ADD:
- 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, 0);
- else
- return value_add (arg1, arg2);
-
- case BINOP_SUB:
- 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, 0);
- else
- return value_sub (arg1, arg2);
-
- case BINOP_MUL:
- case BINOP_DIV:
- case BINOP_REM:
- case BINOP_LSH:
- case BINOP_RSH:
- case BINOP_LOGAND:
- case BINOP_LOGIOR:
- case BINOP_LOGXOR:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, 0);
- else
- if (noside == EVAL_AVOID_SIDE_EFFECTS
- && op == BINOP_DIV)
- return value_zero (VALUE_TYPE (arg1), not_lval);
- else
- return value_binop (arg1, arg2, op);
-
- case BINOP_SUBSCRIPT:
- arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
- VALUE_LVAL (arg1));
-
- if (binop_user_defined_p (op, arg1, arg2))
- return value_x_binop (arg1, arg2, op, 0);
- else
- return value_subscript (arg1, arg2);
-
- case BINOP_AND:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- goto nosideret;
- }
-
- oldpos = *pos;
- arg2 = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
- *pos = oldpos;
-
- if (binop_user_defined_p (op, arg1, arg2))
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_zerop (arg1);
- arg2 = evaluate_subexp (0, exp, pos,
- (tem ? EVAL_SKIP : noside));
- return value_from_long (builtin_type_int,
- (LONGEST) (!tem && !value_zerop (arg2)));
- }
-
- case BINOP_OR:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- goto nosideret;
- }
-
- oldpos = *pos;
- arg2 = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
- *pos = oldpos;
-
- if (binop_user_defined_p (op, arg1, arg2))
- {
- arg2 = evaluate_subexp (0, exp, pos, noside);
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_zerop (arg1);
- arg2 = evaluate_subexp (0, exp, pos,
- (!tem ? EVAL_SKIP : noside));
- return value_from_long (builtin_type_int,
- (LONGEST) (!tem || !value_zerop (arg2)));
- }
-
- case BINOP_EQUAL:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_equal (arg1, arg2);
- return value_from_long (builtin_type_int, (LONGEST) tem);
- }
-
- case BINOP_NOTEQUAL:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_equal (arg1, arg2);
- return value_from_long (builtin_type_int, (LONGEST) ! tem);
- }
-
- case BINOP_LESS:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_less (arg1, arg2);
- return value_from_long (builtin_type_int, (LONGEST) tem);
- }
-
- case BINOP_GTR:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_less (arg2, arg1);
- return value_from_long (builtin_type_int, (LONGEST) tem);
- }
-
- case BINOP_GEQ:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_less (arg1, arg2);
- return value_from_long (builtin_type_int, (LONGEST) ! tem);
- }
-
- case BINOP_LEQ:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (binop_user_defined_p (op, arg1, arg2))
- {
- return value_x_binop (arg1, arg2, op, 0);
- }
- else
- {
- tem = value_less (arg2, arg1);
- return value_from_long (builtin_type_int, (LONGEST) ! tem);
- }
-
- case BINOP_REPEAT:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- arg2 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT)
- error ("Non-integral right operand for \"@\" operator.");
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return allocate_repeat_value (VALUE_TYPE (arg1),
- (int) value_as_long (arg2));
- else
- return value_repeat (arg1, (int) value_as_long (arg2));
-
- case BINOP_COMMA:
- evaluate_subexp (0, exp, pos, noside);
- return evaluate_subexp (0, exp, pos, noside);
-
- case UNOP_NEG:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op);
- else
- return value_neg (arg1);
-
- case UNOP_LOGNOT:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op);
- else
- return value_lognot (arg1);
-
- case UNOP_ZEROP:
- arg1 = evaluate_subexp (0, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (unop_user_defined_p (op, arg1))
- return value_x_unop (arg1, op);
- else
- return value_from_long (builtin_type_int,
- (LONGEST) value_zerop (arg1));
-
- case UNOP_IND:
- if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
- expect_type = TYPE_TARGET_TYPE (expect_type);
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
- || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
- /* In C you can dereference an array to get the 1st elt. */
- || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY
- )
- return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
- lval_memory);
- else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT)
- /* GDB allows dereferencing an int. */
- return value_zero (builtin_type_int, lval_memory);
- else
- error ("Attempt to take contents of a non-pointer value.");
- }
- return value_ind (arg1);
-
- case UNOP_ADDR:
- /* C++: check for and handle pointer to members. */
-
- op = exp->elts[*pos].opcode;
-
- if (noside == EVAL_SKIP)
- {
- if (op == OP_SCOPE)
- {
- char *name = &exp->elts[pc+3].string;
- int tem = strlen (name);
- (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
- }
- else
- evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
- goto nosideret;
- }
-
- if (op == OP_SCOPE)
- {
- char *name = &exp->elts[pc+3].string;
- int tem = strlen (name);
- struct type *domain = exp->elts[pc+2].type;
- (*pos) += 2 + (tem + 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);
-
- case UNOP_SIZEOF:
- if (noside == EVAL_SKIP)
- {
- evaluate_subexp (0, exp, pos, EVAL_SKIP);
- goto nosideret;
- }
- return evaluate_subexp_for_sizeof (exp, pos);
-
- case UNOP_CAST:
- (*pos) += 2;
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- return value_cast (exp->elts[pc + 1].type, arg1);
-
- case UNOP_MEMVAL:
- (*pos) += 2;
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (exp->elts[pc + 1].type, lval_memory);
- else
- return value_at (exp->elts[pc + 1].type,
- (CORE_ADDR) value_as_long (arg1));
-
- case UNOP_PREINCREMENT:
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op);
- }
- else
- {
- arg2 = value_add (arg1, value_from_long (builtin_type_char,
- (LONGEST) 1));
- return value_assign (arg1, arg2);
- }
-
- case UNOP_PREDECREMENT:
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op);
- }
- else
- {
- arg2 = value_sub (arg1, value_from_long (builtin_type_char,
- (LONGEST) 1));
- return value_assign (arg1, arg2);
- }
-
- case UNOP_POSTINCREMENT:
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op);
- }
- else
- {
- arg2 = value_add (arg1, value_from_long (builtin_type_char,
- (LONGEST) 1));
- value_assign (arg1, arg2);
- return arg1;
- }
-
- case UNOP_POSTDECREMENT:
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
- return arg1;
- else if (unop_user_defined_p (op, arg1))
- {
- return value_x_unop (arg1, op);
- }
- else
- {
- arg2 = value_sub (arg1, value_from_long (builtin_type_char,
- (LONGEST) 1));
- value_assign (arg1, arg2);
- return arg1;
- }
-
- case OP_THIS:
- (*pos) += 1;
- return value_of_this (1);
-
- default:
- error ("internal error: I do not know how to evaluate what you gave me");
- }
-
- nosideret:
- return value_from_long (builtin_type_long, (LONGEST) 1);
-}
-
-/* Evaluate a subexpression of EXP, at index *POS,
- and return the address of that subexpression.
- Advance *POS over the subexpression.
- If the subexpression isn't an lvalue, get an error.
- NOSIDE may be EVAL_AVOID_SIDE_EFFECTS;
- then only the type of the result need be correct. */
-
-static value
-evaluate_subexp_for_address (exp, pos, noside)
- register struct expression *exp;
- register int *pos;
- enum noside noside;
-{
- enum exp_opcode op;
- register int pc;
-
- pc = (*pos);
- op = exp->elts[pc].opcode;
-
- switch (op)
- {
- case UNOP_IND:
- (*pos)++;
- return evaluate_subexp (0, exp, pos, noside);
-
- case UNOP_MEMVAL:
- (*pos) += 3;
- return value_cast (lookup_pointer_type (exp->elts[pc + 1].type),
- evaluate_subexp (0, exp, pos, noside));
-
- case OP_VAR_VALUE:
- (*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);
-
- if (sym_class == LOC_CONST
- || sym_class == LOC_CONST_BYTES
- || sym_class == LOC_REGISTER
- || sym_class == LOC_REGPARM)
- error ("Attempt to take address of register or constant.");
-
- return
- value_zero (type, not_lval);
- }
- else
- return locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0);
-
- default:
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- value x = evaluate_subexp (0, exp, pos, noside);
- if (VALUE_LVAL (x) == lval_memory)
- return value_zero (TYPE_POINTER_TYPE (VALUE_TYPE (x)),
- not_lval);
- else
- error ("Attempt to take address of non-lval");
- }
- return value_addr (evaluate_subexp (0, 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. */
-
-static value
-evaluate_subexp_with_coercion (exp, pos, noside)
- register struct expression *exp;
- register int *pos;
- enum noside noside;
-{
- register enum exp_opcode op;
- register int pc;
- register value val;
-
- pc = (*pos);
- op = exp->elts[pc].opcode;
-
- switch (op)
- {
- case OP_VAR_VALUE:
- if (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 1].symbol)) == TYPE_CODE_ARRAY)
- {
- (*pos) += 3;
- val = locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0);
- return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (exp->elts[pc + 1].symbol))),
- val);
- }
- }
-
- return evaluate_subexp (0, exp, pos, noside);
-}
-
-/* Evaluate a subexpression of EXP, at index *POS,
- and return a value for the size of that subexpression.
- Advance *POS over the subexpression. */
-
-static value
-evaluate_subexp_for_sizeof (exp, pos)
- register struct expression *exp;
- register int *pos;
-{
- enum exp_opcode op;
- register int pc;
- value val;
-
- pc = (*pos);
- op = exp->elts[pc].opcode;
-
- switch (op)
- {
- /* This case is handled specially
- so that we avoid creating a value for the result type.
- If the result type is very big, it's desirable not to
- create a value unnecessarily. */
- case UNOP_IND:
- (*pos)++;
- val = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
- return value_from_long (builtin_type_int, (LONGEST)
- TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (val))));
-
- case UNOP_MEMVAL:
- (*pos) += 3;
- return value_from_long (builtin_type_int,
- (LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type));
-
- case OP_VAR_VALUE:
- (*pos) += 3;
- return value_from_long (builtin_type_int,
- (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol)));
-
- default:
- val = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
- return value_from_long (builtin_type_int,
- (LONGEST) TYPE_LENGTH (VALUE_TYPE (val)));
- }
-}