((type->is_unsigned () ? ax_zero_ext : ax_ext) (ax, bits));
}
+/* A helper that returns the target type if TYPE is a range type, or
+ otherwise just returns TYPE. */
+
+static struct type *
+strip_range_type (struct type *type)
+{
+ if (type->code () == TYPE_CODE_RANGE)
+ return type->target_type ();
+ return type;
+}
/* Assume that the top of the stack contains a value of type "pointer
to TYPE"; generate code to fetch its value. Note that TYPE is the
ax_trace_quick (ax, type->length ());
}
- if (type->code () == TYPE_CODE_RANGE)
- type = type->target_type ();
+ type = strip_range_type (type);
switch (type->code ())
{
gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1,
struct axs_value *value2)
{
+ struct type *type1 = strip_range_type (value1->type);
+ struct type *type2 = strip_range_type (value2->type);
+
/* Do the usual binary conversions. */
- if (value1->type->code () == TYPE_CODE_INT
- && value2->type->code () == TYPE_CODE_INT)
+ if (type1->code () == TYPE_CODE_INT
+ && type2->code () == TYPE_CODE_INT)
{
/* The ANSI integral promotions seem to work this way: Order the
integer types by size, and then by signedness: an n-bit
type. Promote to the "wider" of the two types, and always
promote at least to int. */
struct type *target = max_type (builtin_type (ax->gdbarch)->builtin_int,
- max_type (value1->type, value2->type));
+ max_type (type1, type2));
/* Deal with value2, on the top of the stack. */
- gen_conversion (ax, value2->type, target);
+ gen_conversion (ax, type2, target);
/* Deal with value1, not on the top of the stack. Don't
generate the `swap' instructions if we're not actually going
to do anything. */
- if (is_nontrivial_conversion (value1->type, target))
+ if (is_nontrivial_conversion (type1, target))
{
ax_simple (ax, aop_swap);
- gen_conversion (ax, value1->type, target);
+ gen_conversion (ax, type1, target);
ax_simple (ax, aop_swap);
}
require_rvalue (ax, value);
/* Dereference typedefs. */
type = check_typedef (type);
+ type = strip_range_type (type);
switch (type->code ())
{
struct axs_value *value1, struct axs_value *value2)
{
gdb_assert (value1->type->is_pointer_or_reference ());
- gdb_assert (value2->type->code () == TYPE_CODE_INT);
+ gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
gen_scale (ax, aop_mul, value1->type);
ax_simple (ax, aop_add);
struct axs_value *value1, struct axs_value *value2)
{
gdb_assert (value1->type->is_pointer_or_reference ());
- gdb_assert (value2->type->code () == TYPE_CODE_INT);
+ gdb_assert (strip_range_type (value2->type)->code () == TYPE_CODE_INT);
gen_scale (ax, aop_mul, value1->type);
ax_simple (ax, aop_sub);
int may_carry, const char *name)
{
/* We only handle INT op INT. */
- if ((value1->type->code () != TYPE_CODE_INT)
- || (value2->type->code () != TYPE_CODE_INT))
+ struct type *type1 = strip_range_type (value1->type);
+ if ((type1->code () != TYPE_CODE_INT)
+ || (strip_range_type (value2->type)->code () != TYPE_CODE_INT))
error (_("Invalid combination of types in %s."), name);
- ax_simple (ax, value1->type->is_unsigned () ? op_unsigned : op);
+ ax_simple (ax, type1->is_unsigned () ? op_unsigned : op);
if (may_carry)
- gen_extend (ax, value1->type); /* catch overflow */
- value->type = value1->type;
+ gen_extend (ax, type1); /* catch overflow */
+ value->type = type1;
value->kind = axs_rvalue;
}
gen_logical_not (struct agent_expr *ax, struct axs_value *value,
struct type *result_type)
{
- if (value->type->code () != TYPE_CODE_INT
- && value->type->code () != TYPE_CODE_PTR)
+ struct type *type = strip_range_type (value->type);
+ if (type->code () != TYPE_CODE_INT
+ && type->code () != TYPE_CODE_PTR)
error (_("Invalid type of operand to `!'."));
ax_simple (ax, aop_log_not);
static void
gen_complement (struct agent_expr *ax, struct axs_value *value)
{
- if (value->type->code () != TYPE_CODE_INT)
+ struct type *type = strip_range_type (value->type);
+ if (type->code () != TYPE_CODE_INT)
error (_("Invalid type of operand to `~'."));
ax_simple (ax, aop_bit_not);
- gen_extend (ax, value->type);
+ gen_extend (ax, type);
}
\f
switch (op)
{
case BINOP_ADD:
- if (value1->type->code () == TYPE_CODE_INT
+ if (strip_range_type (value1->type)->code () == TYPE_CODE_INT
&& value2->type->is_pointer_or_reference ())
{
/* Swap the values and proceed normally. */
gen_ptradd (ax, value, value2, value1);
}
else if (value1->type->is_pointer_or_reference ()
- && value2->type->code () == TYPE_CODE_INT)
+ && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
gen_ptradd (ax, value, value1, value2);
else
gen_binop (ax, value, value1, value2,
break;
case BINOP_SUB:
if (value1->type->is_pointer_or_reference ()
- && value2->type->code () == TYPE_CODE_INT)
+ && strip_range_type (value2->type)->code () == TYPE_CODE_INT)
gen_ptrsub (ax,value, value1, value2);
else if (value1->type->is_pointer_or_reference ()
&& value2->type->is_pointer_or_reference ())