+ {
+ if (ada_is_fixed_point_type (value_type (arg1)))
+ arg1 = cast_from_fixed_to_double (arg1);
+ if (ada_is_fixed_point_type (value_type (arg2)))
+ arg2 = cast_from_fixed_to_double (arg2);
+ return ada_value_binop (arg1, arg2, op);
+ }
+
+ case BINOP_REM:
+ case BINOP_MOD:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS
+ && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD))
+ return value_zero (value_type (arg1), not_lval);
+ else
+ return ada_value_binop (arg1, arg2, op);
+
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ tem = 0;
+ else
+ tem = ada_value_equal (arg1, arg2);
+ if (op == BINOP_NOTEQUAL)
+ tem = !tem;
+ return value_from_longest (LA_BOOL_TYPE, (LONGEST) tem);
+
+ case UNOP_NEG:
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ else if (ada_is_fixed_point_type (value_type (arg1)))
+ return value_cast (value_type (arg1), value_neg (arg1));
+ else
+ return value_neg (arg1);
+
+ case OP_VAR_VALUE:
+ *pos -= 1;
+ if (noside == EVAL_SKIP)
+ {
+ *pos += 4;
+ goto nosideret;
+ }
+ else if (SYMBOL_DOMAIN (exp->elts[pc + 2].symbol) == UNDEF_DOMAIN)
+ /* Only encountered when an unresolved symbol occurs in a
+ context other than a function call, in which case, it is
+ illegal. */
+ error (_("Unexpected unresolved symbol, %s, during evaluation"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ *pos += 4;
+ return value_zero
+ (to_static_fixed_type
+ (static_unwrap_type (SYMBOL_TYPE (exp->elts[pc + 2].symbol))),
+ not_lval);
+ }
+ else
+ {
+ arg1 =
+ unwrap_value (evaluate_subexp_standard
+ (expect_type, exp, pos, noside));
+ return ada_to_fixed_value (arg1);
+ }
+
+ case OP_FUNCALL:
+ (*pos) += 2;
+
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0] and a terminating NULL. */
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ argvec =
+ (struct value **) alloca (sizeof (struct value *) * (nargs + 2));
+
+ if (exp->elts[*pos].opcode == OP_VAR_VALUE
+ && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
+ error (_("Unexpected unresolved symbol, %s, during evaluation"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 5].symbol));
+ else
+ {
+ for (tem = 0; tem <= nargs; tem += 1)
+ argvec[tem] = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ argvec[tem] = 0;
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ }
+
+ if (ada_is_packed_array_type (desc_base_type (value_type (argvec[0]))))
+ argvec[0] = ada_coerce_to_simple_array (argvec[0]);
+ else if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_REF
+ || (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_ARRAY
+ && VALUE_LVAL (argvec[0]) == lval_memory))
+ argvec[0] = value_addr (argvec[0]);
+
+ type = ada_check_typedef (value_type (argvec[0]));
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ switch (TYPE_CODE (ada_check_typedef (TYPE_TARGET_TYPE (type))))
+ {
+ case TYPE_CODE_FUNC:
+ type = ada_check_typedef (TYPE_TARGET_TYPE (type));
+ break;
+ case TYPE_CODE_ARRAY:
+ break;
+ case TYPE_CODE_STRUCT:
+ if (noside != EVAL_AVOID_SIDE_EFFECTS)
+ argvec[0] = ada_value_ind (argvec[0]);
+ type = ada_check_typedef (TYPE_TARGET_TYPE (type));
+ break;
+ default:
+ error (_("cannot subscript or call something of type `%s'"),
+ ada_type_name (value_type (argvec[0])));
+ break;
+ }
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_FUNC:
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return allocate_value (TYPE_TARGET_TYPE (type));
+ return call_function_by_hand (argvec[0], nargs, argvec + 1);
+ case TYPE_CODE_STRUCT:
+ {
+ int arity;
+
+ arity = ada_array_arity (type);
+ type = ada_array_element_type (type, nargs);
+ if (type == NULL)
+ error (_("cannot subscript or call a record"));
+ if (arity != nargs)
+ error (_("wrong number of subscripts; expecting %d"), arity);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return allocate_value (ada_aligned_type (type));
+ return
+ unwrap_value (ada_value_subscript
+ (argvec[0], nargs, argvec + 1));
+ }
+ case TYPE_CODE_ARRAY:
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ type = ada_array_element_type (type, nargs);
+ if (type == NULL)
+ error (_("element type of array unknown"));
+ else
+ return allocate_value (ada_aligned_type (type));
+ }
+ return
+ unwrap_value (ada_value_subscript
+ (ada_coerce_to_simple_array (argvec[0]),
+ nargs, argvec + 1));
+ case TYPE_CODE_PTR: /* Pointer to array */
+ type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ type = ada_array_element_type (type, nargs);
+ if (type == NULL)
+ error (_("element type of array unknown"));
+ else
+ return allocate_value (ada_aligned_type (type));
+ }
+ return
+ unwrap_value (ada_value_ptr_subscript (argvec[0], type,
+ nargs, argvec + 1));
+
+ default:
+ error (_("Attempt to index or call something other than an \
+array or function"));
+ }
+
+ case TERNOP_SLICE:
+ {
+ struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct value *low_bound_val =
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct value *high_bound_val =
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ LONGEST low_bound;
+ LONGEST high_bound;
+ low_bound_val = coerce_ref (low_bound_val);
+ high_bound_val = coerce_ref (high_bound_val);
+ low_bound = pos_atr (low_bound_val);
+ high_bound = pos_atr (high_bound_val);
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ /* If this is a reference to an aligner type, then remove all
+ the aligners. */
+ if (TYPE_CODE (value_type (array)) == TYPE_CODE_REF
+ && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array))))
+ TYPE_TARGET_TYPE (value_type (array)) =
+ ada_aligned_type (TYPE_TARGET_TYPE (value_type (array)));
+
+ if (ada_is_packed_array_type (value_type (array)))
+ error (_("cannot slice a packed array"));
+
+ /* If this is a reference to an array or an array lvalue,
+ convert to a pointer. */
+ if (TYPE_CODE (value_type (array)) == TYPE_CODE_REF
+ || (TYPE_CODE (value_type (array)) == TYPE_CODE_ARRAY
+ && VALUE_LVAL (array) == lval_memory))
+ array = value_addr (array);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS
+ && ada_is_array_descriptor_type (ada_check_typedef
+ (value_type (array))))
+ return empty_array (ada_type_of_array (array, 0), low_bound);
+
+ array = ada_coerce_to_simple_array_ptr (array);
+
+ /* If we have more than one level of pointer indirection,
+ dereference the value until we get only one level. */
+ while (TYPE_CODE (value_type (array)) == TYPE_CODE_PTR
+ && (TYPE_CODE (TYPE_TARGET_TYPE (value_type (array)))
+ == TYPE_CODE_PTR))
+ array = value_ind (array);
+
+ /* Make sure we really do have an array type before going further,
+ to avoid a SEGV when trying to get the index type or the target
+ type later down the road if the debug info generated by
+ the compiler is incorrect or incomplete. */
+ if (!ada_is_simple_array_type (value_type (array)))
+ error (_("cannot take slice of non-array"));
+
+ if (TYPE_CODE (value_type (array)) == TYPE_CODE_PTR)
+ {
+ if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
+ return empty_array (TYPE_TARGET_TYPE (value_type (array)),
+ low_bound);
+ else
+ {
+ struct type *arr_type0 =
+ to_fixed_array_type (TYPE_TARGET_TYPE (value_type (array)),
+ NULL, 1);
+ return ada_value_slice_ptr (array, arr_type0,
+ (int) low_bound,
+ (int) high_bound);
+ }
+ }
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return array;
+ else if (high_bound < low_bound)
+ return empty_array (value_type (array), low_bound);
+ else
+ return ada_value_slice (array, (int) low_bound, (int) high_bound);
+ }
+
+ case UNOP_IN_RANGE:
+ (*pos) += 2;
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ type = exp->elts[pc + 1].type;
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ switch (TYPE_CODE (type))
+ {
+ default:
+ lim_warning (_("Membership test incompletely implemented; \
+always returns true"));
+ return value_from_longest (builtin_type_int, (LONGEST) 1);
+
+ case TYPE_CODE_RANGE:
+ arg2 = value_from_longest (builtin_type_int, TYPE_LOW_BOUND (type));
+ arg3 = value_from_longest (builtin_type_int,
+ TYPE_HIGH_BOUND (type));
+ return
+ value_from_longest (builtin_type_int,
+ (value_less (arg1, arg3)
+ || value_equal (arg1, arg3))
+ && (value_less (arg2, arg1)
+ || value_equal (arg2, arg1)));
+ }
+
+ case BINOP_IN_BOUNDS:
+ (*pos) += 2;
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (builtin_type_int, not_lval);
+
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+
+ if (tem < 1 || tem > ada_array_arity (value_type (arg2)))
+ error (_("invalid dimension number to 'range"));
+
+ arg3 = ada_array_bound (arg2, tem, 1);
+ arg2 = ada_array_bound (arg2, tem, 0);
+
+ return
+ value_from_longest (builtin_type_int,
+ (value_less (arg1, arg3)
+ || value_equal (arg1, arg3))
+ && (value_less (arg2, arg1)
+ || value_equal (arg2, arg1)));