diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2008-09-11 14:15:39 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2008-09-11 14:15:39 +0000 |
commit | f7c79c4197b4e8003d9c9828b2e22df6444c5860 (patch) | |
tree | de5d42a6e7408f5b6908d23598a0bf49f5a2e8ea | |
parent | f44316fa94c208d45b37782734469d178d31b273 (diff) | |
download | gdb-f7c79c4197b4e8003d9c9828b2e22df6444c5860.zip gdb-f7c79c4197b4e8003d9c9828b2e22df6444c5860.tar.gz gdb-f7c79c4197b4e8003d9c9828b2e22df6444c5860.tar.bz2 |
* ax-gdb.c: Include "language.h".
(gen_frame_args_address): Add GDBARCH parameter; use it
instead of current_gdbarch.
(gen_frame_locals_address): Likewise.
(gen_var_ref): Add GDBARCH parameter. Update calls to
gen_frame_args_address and gen_frame_locals_address. Use
pointer type from gdbarch.
(gen_usual_unary): Add EXP parameter. Use integer type
from exp->gdbarch.
(gen_usual_arithmetic): Likewise.
(gen_integral_promotions): Likewise.
(gen_add, gen_sub): Remove.
(gen_ptradd, gen_ptrsub, gen_ptrdiff): New functions.
(gen_logical_not): Use passed-in boolean result type
instead of builtin_type_int.
(gen_complement): Do not call gen_usual_unary or
gen_integral_promotions.
(gen_struct_ref): Call require_rvalue instead of gen_usual_unary.
(gen_repeat): Add EXP parameter. Update call to gen_expr.
Use builtin_type_int32 as internal range type.
(gen_sizeof): Add EXP and SIZE_TYPE parameters. Use SIZE_TYPE
as result type. Update call to gen_expr.
(gen_expr): Add EXP parameter. Update calls to gen_expr,
gen_repeat, gen_var_ref, gen_usual_unary, gen_usual_arithmetic,
and gen_integral_promotions. Call gen_ptradd, gen_ptrsub,
gen_ptrdiff, or gen_binop instead of gen_add or gen_sub.
Use exp->gdbarch instead of current_gdbarch.
Call language_bool_type to determine result type of UNOP_LOGICAL_NOT.
-rw-r--r-- | gdb/ChangeLog | 31 | ||||
-rw-r--r-- | gdb/ax-gdb.c | 331 |
2 files changed, 192 insertions, 170 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bb72d9d..c6761ab 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,36 @@ 2008-09-11 Ulrich Weigand <uweigand@de.ibm.com> + * ax-gdb.c: Include "language.h". + (gen_frame_args_address): Add GDBARCH parameter; use it + instead of current_gdbarch. + (gen_frame_locals_address): Likewise. + (gen_var_ref): Add GDBARCH parameter. Update calls to + gen_frame_args_address and gen_frame_locals_address. Use + pointer type from gdbarch. + (gen_usual_unary): Add EXP parameter. Use integer type + from exp->gdbarch. + (gen_usual_arithmetic): Likewise. + (gen_integral_promotions): Likewise. + (gen_add, gen_sub): Remove. + (gen_ptradd, gen_ptrsub, gen_ptrdiff): New functions. + (gen_logical_not): Use passed-in boolean result type + instead of builtin_type_int. + (gen_complement): Do not call gen_usual_unary or + gen_integral_promotions. + (gen_struct_ref): Call require_rvalue instead of gen_usual_unary. + (gen_repeat): Add EXP parameter. Update call to gen_expr. + Use builtin_type_int32 as internal range type. + (gen_sizeof): Add EXP and SIZE_TYPE parameters. Use SIZE_TYPE + as result type. Update call to gen_expr. + (gen_expr): Add EXP parameter. Update calls to gen_expr, + gen_repeat, gen_var_ref, gen_usual_unary, gen_usual_arithmetic, + and gen_integral_promotions. Call gen_ptradd, gen_ptrsub, + gen_ptrdiff, or gen_binop instead of gen_add or gen_sub. + Use exp->gdbarch instead of current_gdbarch. + Call language_bool_type to determine result type of UNOP_LOGICAL_NOT. + +2008-09-11 Ulrich Weigand <uweigand@de.ibm.com> + * eval.c (evaluate_subexp_standard): Add calls to binop_promote and unop_promote before calling value_binop et. al. * ada-lang.c (ada_evaluate_subexp): Add calls to binop_promote diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 1a1ecda..5d1332a 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -34,6 +34,7 @@ #include "block.h" #include "regcache.h" #include "user-regs.h" +#include "language.h" /* To make sense of this file, you should read doc/agentexpr.texi. Then look at the types and enums in ax-gdb.h. For the code itself, @@ -72,11 +73,11 @@ static void gen_fetch (struct agent_expr *, struct type *); static void gen_left_shift (struct agent_expr *, int); -static void gen_frame_args_address (struct agent_expr *); -static void gen_frame_locals_address (struct agent_expr *); +static void gen_frame_args_address (struct gdbarch *, struct agent_expr *); +static void gen_frame_locals_address (struct gdbarch *, struct agent_expr *); static void gen_offset (struct agent_expr *ax, int offset); static void gen_sym_offset (struct agent_expr *, struct symbol *); -static void gen_var_ref (struct agent_expr *ax, +static void gen_var_ref (struct gdbarch *, struct agent_expr *ax, struct axs_value *value, struct symbol *var); @@ -86,35 +87,39 @@ static void gen_int_literal (struct agent_expr *ax, static void require_rvalue (struct agent_expr *ax, struct axs_value *value); -static void gen_usual_unary (struct agent_expr *ax, struct axs_value *value); +static void gen_usual_unary (struct expression *exp, struct agent_expr *ax, + struct axs_value *value); static int type_wider_than (struct type *type1, struct type *type2); static struct type *max_type (struct type *type1, struct type *type2); static void gen_conversion (struct agent_expr *ax, struct type *from, struct type *to); static int is_nontrivial_conversion (struct type *from, struct type *to); -static void gen_usual_arithmetic (struct agent_expr *ax, +static void gen_usual_arithmetic (struct expression *exp, + struct agent_expr *ax, struct axs_value *value1, struct axs_value *value2); -static void gen_integral_promotions (struct agent_expr *ax, +static void gen_integral_promotions (struct expression *exp, + struct agent_expr *ax, struct axs_value *value); static void gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type); static void gen_scale (struct agent_expr *ax, enum agent_op op, struct type *type); -static void gen_add (struct agent_expr *ax, - struct axs_value *value, - struct axs_value *value1, - struct axs_value *value2, char *name); -static void gen_sub (struct agent_expr *ax, - struct axs_value *value, - struct axs_value *value1, struct axs_value *value2); +static void gen_ptradd (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2); +static void gen_ptrsub (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2); +static void gen_ptrdiff (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2, + struct type *result_type); static void gen_binop (struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2, enum agent_op op, enum agent_op op_unsigned, int may_carry, char *name); -static void gen_logical_not (struct agent_expr *ax, struct axs_value *value); +static void gen_logical_not (struct agent_expr *ax, struct axs_value *value, + struct type *result_type); static void gen_complement (struct agent_expr *ax, struct axs_value *value); static void gen_deref (struct agent_expr *, struct axs_value *); static void gen_address_of (struct agent_expr *, struct axs_value *); @@ -126,11 +131,12 @@ static void gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field, char *operator_name, char *operand_name); -static void gen_repeat (union exp_element **pc, +static void gen_repeat (struct expression *exp, union exp_element **pc, struct agent_expr *ax, struct axs_value *value); -static void gen_sizeof (union exp_element **pc, - struct agent_expr *ax, struct axs_value *value); -static void gen_expr (union exp_element **pc, +static void gen_sizeof (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value, + struct type *size_type); +static void gen_expr (struct expression *exp, union exp_element **pc, struct agent_expr *ax, struct axs_value *value); static void agent_command (char *exp, int from_tty); @@ -455,12 +461,12 @@ gen_left_shift (struct agent_expr *ax, int distance) /* Generate code to push the base address of the argument portion of the top stack frame. */ static void -gen_frame_args_address (struct agent_expr *ax) +gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (current_gdbarch, + gdbarch_virtual_frame_pointer (gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -470,12 +476,12 @@ gen_frame_args_address (struct agent_expr *ax) /* Generate code to push the base address of the locals portion of the top stack frame. */ static void -gen_frame_locals_address (struct agent_expr *ax) +gen_frame_locals_address (struct gdbarch *gdbarch, struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (current_gdbarch, + gdbarch_virtual_frame_pointer (gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -520,7 +526,8 @@ gen_sym_offset (struct agent_expr *ax, struct symbol *var) symbol VAR. Set VALUE to describe the result. */ static void -gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) +gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, + struct axs_value *value, struct symbol *var) { /* Dereference any typedefs. */ value->type = check_typedef (SYMBOL_TYPE (var)); @@ -550,22 +557,22 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) break; case LOC_ARG: /* var lives in argument area of frame */ - gen_frame_args_address (ax); + gen_frame_args_address (gdbarch, ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; case LOC_REF_ARG: /* As above, but the frame slot really holds the address of the variable. */ - gen_frame_args_address (ax); + gen_frame_args_address (gdbarch, ax); gen_sym_offset (ax, var); /* Don't assume any particular pointer size. */ - gen_fetch (ax, lookup_pointer_type (builtin_type_void)); + gen_fetch (ax, builtin_type (gdbarch)->builtin_data_ptr); value->kind = axs_lvalue_memory; break; case LOC_LOCAL: /* var lives in locals area of frame */ - gen_frame_locals_address (ax); + gen_frame_locals_address (gdbarch, ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; @@ -697,7 +704,8 @@ require_rvalue (struct agent_expr *ax, struct axs_value *value) lvalue through unchanged, and let `+' raise an error. */ static void -gen_usual_unary (struct agent_expr *ax, struct axs_value *value) +gen_usual_unary (struct expression *exp, struct agent_expr *ax, + struct axs_value *value) { /* We don't have to generate any code for the usual integral conversions, since values are always represented as full-width on @@ -732,7 +740,7 @@ gen_usual_unary (struct agent_expr *ax, struct axs_value *value) /* If the value is an enum, call it an integer. */ case TYPE_CODE_ENUM: - value->type = builtin_type_int; + value->type = builtin_type (exp->gdbarch)->builtin_int; break; } @@ -817,8 +825,8 @@ is_nontrivial_conversion (struct type *from, struct type *to) and promotes each argument to that type. *VALUE1 and *VALUE2 describe the values as they are passed in, and as they are left. */ static void -gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, - struct axs_value *value2) +gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, + struct axs_value *value1, struct axs_value *value2) { /* Do the usual binary conversions. */ if (TYPE_CODE (value1->type) == TYPE_CODE_INT @@ -829,7 +837,7 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, unsigned type is considered "wider" than an n-bit signed type. Promote to the "wider" of the two types, and always promote at least to int. */ - struct type *target = max_type (builtin_type_int, + struct type *target = max_type (builtin_type (exp->gdbarch)->builtin_int, max_type (value1->type, value2->type)); /* Deal with value2, on the top of the stack. */ @@ -854,17 +862,20 @@ gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, the value on the top of the stack, as described by VALUE. Assume the value has integral type. */ static void -gen_integral_promotions (struct agent_expr *ax, struct axs_value *value) +gen_integral_promotions (struct expression *exp, struct agent_expr *ax, + struct axs_value *value) { - if (!type_wider_than (value->type, builtin_type_int)) + const struct builtin_type *builtin = builtin_type (exp->gdbarch); + + if (!type_wider_than (value->type, builtin->builtin_int)) { - gen_conversion (ax, value->type, builtin_type_int); - value->type = builtin_type_int; + gen_conversion (ax, value->type, builtin->builtin_int); + value->type = builtin->builtin_int; } - else if (!type_wider_than (value->type, builtin_type_unsigned_int)) + else if (!type_wider_than (value->type, builtin->builtin_unsigned_int)) { - gen_conversion (ax, value->type, builtin_type_unsigned_int); - value->type = builtin_type_unsigned_int; + gen_conversion (ax, value->type, builtin->builtin_unsigned_int); + value->type = builtin->builtin_unsigned_int; } } @@ -937,105 +948,60 @@ gen_scale (struct agent_expr *ax, enum agent_op op, struct type *type) } -/* Generate code for an addition; non-trivial because we deal with - pointer arithmetic. We set VALUE to describe the result value; we - assume VALUE1 and VALUE2 describe the two operands, and that - they've undergone the usual binary conversions. Used by both - BINOP_ADD and BINOP_SUBSCRIPT. NAME is used in error messages. */ +/* Generate code for pointer arithmetic PTR + INT. */ static void -gen_add (struct agent_expr *ax, struct axs_value *value, - struct axs_value *value1, struct axs_value *value2, char *name) +gen_ptradd (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2) { - /* Is it INT+PTR? */ - if (TYPE_CODE (value1->type) == TYPE_CODE_INT - && TYPE_CODE (value2->type) == TYPE_CODE_PTR) - { - /* Swap the values and proceed normally. */ - ax_simple (ax, aop_swap); - gen_scale (ax, aop_mul, value2->type); - ax_simple (ax, aop_add); - gen_extend (ax, value2->type); /* Catch overflow. */ - value->type = value2->type; - } + gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR); + gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT); - /* Is it PTR+INT? */ - else if (TYPE_CODE (value1->type) == TYPE_CODE_PTR - && TYPE_CODE (value2->type) == TYPE_CODE_INT) - { - gen_scale (ax, aop_mul, value1->type); - ax_simple (ax, aop_add); - gen_extend (ax, value1->type); /* Catch overflow. */ - value->type = value1->type; - } + gen_scale (ax, aop_mul, value1->type); + ax_simple (ax, aop_add); + gen_extend (ax, value1->type); /* Catch overflow. */ + value->type = value1->type; + value->kind = axs_rvalue; +} - /* Must be number + number; the usual binary conversions will have - brought them both to the same width. */ - else if (TYPE_CODE (value1->type) == TYPE_CODE_INT - && TYPE_CODE (value2->type) == TYPE_CODE_INT) - { - ax_simple (ax, aop_add); - gen_extend (ax, value1->type); /* Catch overflow. */ - value->type = value1->type; - } - else - error (_("Invalid combination of types in %s."), name); +/* Generate code for pointer arithmetic PTR - INT. */ +static void +gen_ptrsub (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2) +{ + gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR); + gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_INT); + gen_scale (ax, aop_mul, value1->type); + ax_simple (ax, aop_sub); + gen_extend (ax, value1->type); /* Catch overflow. */ + value->type = value1->type; value->kind = axs_rvalue; } -/* Generate code for an addition; non-trivial because we have to deal - with pointer arithmetic. We set VALUE to describe the result - value; we assume VALUE1 and VALUE2 describe the two operands, and - that they've undergone the usual binary conversions. */ +/* Generate code for pointer arithmetic PTR - PTR. */ static void -gen_sub (struct agent_expr *ax, struct axs_value *value, - struct axs_value *value1, struct axs_value *value2) +gen_ptrdiff (struct agent_expr *ax, struct axs_value *value, + struct axs_value *value1, struct axs_value *value2, + struct type *result_type) { - if (TYPE_CODE (value1->type) == TYPE_CODE_PTR) - { - /* Is it PTR - INT? */ - if (TYPE_CODE (value2->type) == TYPE_CODE_INT) - { - gen_scale (ax, aop_mul, value1->type); - ax_simple (ax, aop_sub); - gen_extend (ax, value1->type); /* Catch overflow. */ - value->type = value1->type; - } + gdb_assert (TYPE_CODE (value1->type) == TYPE_CODE_PTR); + gdb_assert (TYPE_CODE (value2->type) == TYPE_CODE_PTR); - /* Is it PTR - PTR? Strictly speaking, the types ought to - match, but this is what the normal GDB expression evaluator - tests for. */ - else if (TYPE_CODE (value2->type) == TYPE_CODE_PTR - && (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type)) - == TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type)))) - { - ax_simple (ax, aop_sub); - gen_scale (ax, aop_div_unsigned, value1->type); - value->type = builtin_type_long; /* FIXME --- should be ptrdiff_t */ - } - else - error (_("\ + if (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type)) + != TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type))) + error (_("\ First argument of `-' is a pointer, but second argument is neither\n\ an integer nor a pointer of the same type.")); - } - - /* Must be number + number. */ - else if (TYPE_CODE (value1->type) == TYPE_CODE_INT - && TYPE_CODE (value2->type) == TYPE_CODE_INT) - { - ax_simple (ax, aop_sub); - gen_extend (ax, value1->type); /* Catch overflow. */ - value->type = value1->type; - } - - else - error (_("Invalid combination of types in subtraction.")); + ax_simple (ax, aop_sub); + gen_scale (ax, aop_div_unsigned, value1->type); + value->type = result_type; value->kind = axs_rvalue; } + /* Generate code for a binary operator that doesn't do pointer magic. We set VALUE to describe the result value; we assume VALUE1 and VALUE2 describe the two operands, and that they've undergone the @@ -1062,15 +1028,15 @@ gen_binop (struct agent_expr *ax, struct axs_value *value, static void -gen_logical_not (struct agent_expr *ax, struct axs_value *value) +gen_logical_not (struct agent_expr *ax, struct axs_value *value, + struct type *result_type) { if (TYPE_CODE (value->type) != TYPE_CODE_INT && TYPE_CODE (value->type) != TYPE_CODE_PTR) error (_("Invalid type of operand to `!'.")); - gen_usual_unary (ax, value); ax_simple (ax, aop_log_not); - value->type = builtin_type_int; + value->type = result_type; } @@ -1080,8 +1046,6 @@ gen_complement (struct agent_expr *ax, struct axs_value *value) if (TYPE_CODE (value->type) != TYPE_CODE_INT) error (_("Invalid type of operand to `~'.")); - gen_usual_unary (ax, value); - gen_integral_promotions (ax, value); ax_simple (ax, aop_bit_not); gen_extend (ax, value->type); } @@ -1355,7 +1319,7 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field, should at least be consistent. */ while (TYPE_CODE (value->type) == TYPE_CODE_PTR) { - gen_usual_unary (ax, value); + require_rvalue (ax, value); gen_deref (ax, value); } type = check_typedef (value->type); @@ -1400,13 +1364,13 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, char *field, stack slots, doing weird things with sizeof, etc. So we require the right operand to be a constant expression. */ static void -gen_repeat (union exp_element **pc, struct agent_expr *ax, - struct axs_value *value) +gen_repeat (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value) { struct axs_value value1; /* We don't want to turn this into an rvalue, so no conversions here. */ - gen_expr (pc, ax, &value1); + gen_expr (exp, pc, ax, &value1); if (value1.kind != axs_lvalue_memory) error (_("Left operand of `@' must be an object in memory.")); @@ -1429,7 +1393,7 @@ gen_repeat (union exp_element **pc, struct agent_expr *ax, /* FIXME-type-allocation: need a way to free this type when we are done with it. */ struct type *range - = create_range_type (0, builtin_type_int, 0, length - 1); + = create_range_type (0, builtin_type_int32, 0, length - 1); struct type *array = create_array_type (0, value1.type, range); value->kind = axs_lvalue_memory; @@ -1443,8 +1407,9 @@ gen_repeat (union exp_element **pc, struct agent_expr *ax, *PC should point at the start of the operand expression; we advance it to the first instruction after the operand. */ static void -gen_sizeof (union exp_element **pc, struct agent_expr *ax, - struct axs_value *value) +gen_sizeof (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value, + struct type *size_type) { /* We don't care about the value of the operand expression; we only care about its type. However, in the current arrangement, the @@ -1452,14 +1417,14 @@ gen_sizeof (union exp_element **pc, struct agent_expr *ax, So we generate code for the operand, and then throw it away, replacing it with code that simply pushes its size. */ int start = ax->len; - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); /* Throw away the code we just generated. */ ax->len = start; ax_const_l (ax, TYPE_LENGTH (value->type)); value->kind = axs_rvalue; - value->type = builtin_type_int; + value->type = size_type; } @@ -1469,8 +1434,8 @@ gen_sizeof (union exp_element **pc, struct agent_expr *ax, /* A gen_expr function written by a Gen-X'er guy. Append code for the subexpression of EXPR starting at *POS_P to AX. */ static void -gen_expr (union exp_element **pc, struct agent_expr *ax, - struct axs_value *value) +gen_expr (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value) { /* Used to hold the descriptions of operand expressions. */ struct axs_value value1, value2; @@ -1503,18 +1468,40 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, case BINOP_BITWISE_IOR: case BINOP_BITWISE_XOR: (*pc)++; - gen_expr (pc, ax, &value1); - gen_usual_unary (ax, &value1); - gen_expr (pc, ax, &value2); - gen_usual_unary (ax, &value2); - gen_usual_arithmetic (ax, &value1, &value2); + gen_expr (exp, pc, ax, &value1); + gen_usual_unary (exp, ax, &value1); + gen_expr (exp, pc, ax, &value2); + gen_usual_unary (exp, ax, &value2); + gen_usual_arithmetic (exp, ax, &value1, &value2); switch (op) { case BINOP_ADD: - gen_add (ax, value, &value1, &value2, "addition"); + if (TYPE_CODE (value1.type) == TYPE_CODE_INT + && TYPE_CODE (value2.type) == TYPE_CODE_PTR) + { + /* Swap the values and proceed normally. */ + ax_simple (ax, aop_swap); + gen_ptradd (ax, value, &value2, &value1); + } + else if (TYPE_CODE (value1.type) == TYPE_CODE_PTR + && TYPE_CODE (value2.type) == TYPE_CODE_INT) + gen_ptradd (ax, value, &value1, &value2); + else + gen_binop (ax, value, &value1, &value2, + aop_add, aop_add, 1, "addition"); break; case BINOP_SUB: - gen_sub (ax, value, &value1, &value2); + if (TYPE_CODE (value1.type) == TYPE_CODE_PTR + && TYPE_CODE (value2.type) == TYPE_CODE_INT) + gen_ptrsub (ax,value, &value1, &value2); + else if (TYPE_CODE (value1.type) == TYPE_CODE_PTR + && TYPE_CODE (value2.type) == TYPE_CODE_PTR) + /* FIXME --- result type should be ptrdiff_t */ + gen_ptrdiff (ax, value, &value1, &value2, + builtin_type (exp->gdbarch)->builtin_long); + else + gen_binop (ax, value, &value1, &value2, + aop_sub, aop_sub, 1, "subtraction"); break; case BINOP_MUL: gen_binop (ax, value, &value1, &value2, @@ -1529,7 +1516,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, aop_rem_signed, aop_rem_unsigned, 1, "remainder"); break; case BINOP_SUBSCRIPT: - gen_add (ax, value, &value1, &value2, "array subscripting"); + gen_ptradd (ax, value, &value1, &value2); if (TYPE_CODE (value->type) != TYPE_CODE_PTR) error (_("Invalid combination of types in array subscripting.")); gen_deref (ax, value); @@ -1565,12 +1552,12 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, variables it mentions get traced. */ case BINOP_COMMA: (*pc)++; - gen_expr (pc, ax, &value1); + gen_expr (exp, pc, ax, &value1); /* Don't just dispose of the left operand. We might be tracing, in which case we want to emit code to trace it if it's an lvalue. */ gen_traced_pop (ax, &value1); - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); /* It's the consumer's responsibility to trace the right operand. */ break; @@ -1584,7 +1571,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, break; case OP_VAR_VALUE: - gen_var_ref (ax, value, (*pc)[2].symbol); + gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol); (*pc) += 4; break; @@ -1593,18 +1580,17 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, const char *name = &(*pc)[2].string; int reg; (*pc) += 4 + BYTES_TO_EXP_ELEM ((*pc)[1].longconst + 1); - reg = user_reg_map_name_to_regnum (current_gdbarch, - name, strlen (name)); + reg = user_reg_map_name_to_regnum (exp->gdbarch, name, strlen (name)); if (reg == -1) internal_error (__FILE__, __LINE__, _("Register $%s not available"), name); - if (reg >= gdbarch_num_regs (current_gdbarch)) + if (reg >= gdbarch_num_regs (exp->gdbarch)) error (_("'%s' is a pseudo-register; " "GDB cannot yet trace pseudoregister contents."), name); value->kind = axs_lvalue_register; value->u.reg = reg; - value->type = register_type (current_gdbarch, reg); + value->type = register_type (exp->gdbarch, reg); } break; @@ -1615,14 +1601,14 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, case BINOP_REPEAT: /* Note that gen_repeat handles its own argument evaluation. */ (*pc)++; - gen_repeat (pc, ax, value); + gen_repeat (exp, pc, ax, value); break; case UNOP_CAST: { struct type *type = (*pc)[1].type; (*pc) += 3; - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); gen_cast (ax, value, type); } break; @@ -1631,7 +1617,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, { struct type *type = check_typedef ((*pc)[1].type); (*pc) += 3; - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); /* I'm not sure I understand UNOP_MEMVAL entirely. I think it's just a hack for dealing with minsyms; you take some integer constant, pretend it's the address of an lvalue of @@ -1648,37 +1634,41 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, case UNOP_PLUS: (*pc)++; /* + FOO is equivalent to 0 + FOO, which can be optimized. */ - gen_expr (pc, ax, value); - gen_usual_unary (ax, value); + gen_expr (exp, pc, ax, value); + gen_usual_unary (exp, ax, value); break; case UNOP_NEG: (*pc)++; /* -FOO is equivalent to 0 - FOO. */ - gen_int_literal (ax, &value1, (LONGEST) 0, builtin_type_int); - gen_usual_unary (ax, &value1); /* shouldn't do much */ - gen_expr (pc, ax, &value2); - gen_usual_unary (ax, &value2); - gen_usual_arithmetic (ax, &value1, &value2); - gen_sub (ax, value, &value1, &value2); + gen_int_literal (ax, &value1, (LONGEST) 0, builtin_type_int8); + gen_usual_unary (exp, ax, &value1); /* shouldn't do much */ + gen_expr (exp, pc, ax, &value2); + gen_usual_unary (exp, ax, &value2); + gen_usual_arithmetic (exp, ax, &value1, &value2); + gen_binop (ax, value, &value1, &value2, aop_sub, aop_sub, 1, "negation"); break; case UNOP_LOGICAL_NOT: (*pc)++; - gen_expr (pc, ax, value); - gen_logical_not (ax, value); + gen_expr (exp, pc, ax, value); + gen_usual_unary (exp, ax, value); + gen_logical_not (ax, value, + language_bool_type (exp->language_defn, exp->gdbarch)); break; case UNOP_COMPLEMENT: (*pc)++; - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); + gen_usual_unary (exp, ax, value); + gen_integral_promotions (exp, ax, value); gen_complement (ax, value); break; case UNOP_IND: (*pc)++; - gen_expr (pc, ax, value); - gen_usual_unary (ax, value); + gen_expr (exp, pc, ax, value); + gen_usual_unary (exp, ax, value); if (TYPE_CODE (value->type) != TYPE_CODE_PTR) error (_("Argument of unary `*' is not a pointer.")); gen_deref (ax, value); @@ -1686,7 +1676,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, case UNOP_ADDR: (*pc)++; - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); gen_address_of (ax, value); break; @@ -1695,7 +1685,8 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, /* Notice that gen_sizeof handles its own operand, unlike most of the other unary operator functions. This is because we have to throw away the code we generate. */ - gen_sizeof (pc, ax, value); + gen_sizeof (exp, pc, ax, value, + builtin_type (exp->gdbarch)->builtin_int); break; case STRUCTOP_STRUCT: @@ -1705,7 +1696,7 @@ gen_expr (union exp_element **pc, struct agent_expr *ax, char *name = &(*pc)[2].string; (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1); - gen_expr (pc, ax, value); + gen_expr (exp, pc, ax, value); if (op == STRUCTOP_STRUCT) gen_struct_ref (ax, value, name, ".", "structure or union"); else if (op == STRUCTOP_PTR) @@ -1748,7 +1739,7 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr) pc = expr->elts; trace_kludge = 1; - gen_expr (&pc, ax, &value); + gen_expr (expr, &pc, ax, &value); /* Make sure we record the final object, and get rid of it. */ gen_traced_pop (ax, &value); |