#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
case BINOP_MUL:
case BINOP_DIV:
case BINOP_REM:
+ case BINOP_MOD:
case BINOP_LSH:
case BINOP_RSH:
case BINOP_BITWISE_AND:
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);
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)
}
/* 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)
{
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);