From 9eaf670568f57fc78fe40d30fc89ac5b442693fb Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 19 Jul 2012 15:33:25 +0000 Subject: [PATCH] * ax-gdb.c (gen_expr): Handle UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE. * breakpoint.c (watchpoint_exp_is_const): Handle UNOP_CAST_TYPE, UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST. * c-exp.y (exp): Emit UNOP_MEMVAL_TYPE, UNOP_CAST_TYPE. Update for changes to UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST. Use type_exp production where appropriate. * eval.c (evaluate_subexp_standard) : New case. : Update. : New case. (evaluate_subexp_for_address) : New case. (evaluate_subexp_for_sizeof) : New case. * expprint.c (print_subexp_standard) : New case. : New case. (dump_subexp_body_standard) : Update. : New cases. * parse.c (operator_length_standard) : Update. : New cases. * stack.c (return_command): Also check for UNOP_CAST_TYPE. * std-operator.def (UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE): New constants. --- gdb/ChangeLog | 25 +++++++++++++++++++++++++ gdb/ax-gdb.c | 42 ++++++++++++++++++++++++++++++++++++++++++ gdb/breakpoint.c | 4 ++++ gdb/c-exp.y | 36 ++++++++++++------------------------ gdb/eval.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- gdb/expprint.c | 40 ++++++++++++++++++++++++++++++++++++---- gdb/parse.c | 12 ++++++++---- gdb/stack.c | 3 ++- gdb/std-operator.def | 6 ++++++ 9 files changed, 178 insertions(+), 37 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ffaeb22..7fa9780 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2012-07-19 Tom Tromey + + * ax-gdb.c (gen_expr): Handle UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE. + * breakpoint.c (watchpoint_exp_is_const): Handle UNOP_CAST_TYPE, + UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST. + * c-exp.y (exp): Emit UNOP_MEMVAL_TYPE, UNOP_CAST_TYPE. Update + for changes to UNOP_REINTERPRET_CAST, UNOP_DYNAMIC_CAST. Use + type_exp production where appropriate. + * eval.c (evaluate_subexp_standard) : New case. + : Update. + : New case. + (evaluate_subexp_for_address) : New case. + (evaluate_subexp_for_sizeof) : New case. + * expprint.c (print_subexp_standard) : New case. + : New case. + (dump_subexp_body_standard) : Update. + : New cases. + * parse.c (operator_length_standard) : Update. + : New cases. + * stack.c (return_command): Also check for UNOP_CAST_TYPE. + * std-operator.def (UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE): New + constants. + 2012-07-19 Yao Qi Jan Kratochvil diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 845153d..2db56bf 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -2076,6 +2076,23 @@ gen_expr (struct expression *exp, union exp_element **pc, } break; + case UNOP_CAST_TYPE: + { + int offset; + struct value *val; + struct type *type; + + ++*pc; + offset = *pc - exp->elts; + val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (val); + *pc = &exp->elts[offset]; + + gen_expr (exp, pc, ax, value); + gen_cast (ax, value, type); + } + break; + case UNOP_MEMVAL: { struct type *type = check_typedef ((*pc)[1].type); @@ -2094,6 +2111,31 @@ gen_expr (struct expression *exp, union exp_element **pc, } break; + case UNOP_MEMVAL_TYPE: + { + int offset; + struct value *val; + struct type *type; + + ++*pc; + offset = *pc - exp->elts; + val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (val); + *pc = &exp->elts[offset]; + + gen_expr (exp, pc, ax, value); + + /* If we have an axs_rvalue or an axs_lvalue_memory, then we + already have the right value on the stack. For + axs_lvalue_register, we must convert. */ + if (value->kind == axs_lvalue_register) + require_rvalue (ax, value); + + value->type = type; + value->kind = axs_lvalue_memory; + } + break; + case UNOP_PLUS: (*pc)++; /* + FOO is equivalent to 0 + FOO, which can be optimized. */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 63cd8de..a122f6f 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -10171,6 +10171,10 @@ watchpoint_exp_is_const (const struct expression *exp) case UNOP_ADDR: case UNOP_HIGH: case UNOP_CAST: + + case UNOP_CAST_TYPE: + case UNOP_REINTERPRET_CAST: + case UNOP_DYNAMIC_CAST: /* Unary, binary and ternary operators: We have to check their operands. If they are constant, then so is the result of that operation. For instance, if A and B are diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 0613799..e36a0fb 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -471,16 +471,12 @@ exp : lcurly arglist rcurly %prec ARROW write_exp_elt_opcode (OP_ARRAY); } ; -exp : lcurly type rcurly exp %prec UNARY - { write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_MEMVAL); } +exp : lcurly type_exp rcurly exp %prec UNARY + { write_exp_elt_opcode (UNOP_MEMVAL_TYPE); } ; -exp : '(' type ')' exp %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_CAST); } +exp : '(' type_exp ')' exp %prec UNARY + { write_exp_elt_opcode (UNOP_CAST_TYPE); } ; exp : '(' exp1 ')' @@ -639,30 +635,22 @@ exp : SIZEOF '(' type ')' %prec UNARY write_exp_elt_opcode (OP_LONG); } ; -exp : REINTERPRET_CAST '<' type '>' '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_REINTERPRET_CAST); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_REINTERPRET_CAST); } +exp : REINTERPRET_CAST '<' type_exp '>' '(' exp ')' %prec UNARY + { write_exp_elt_opcode (UNOP_REINTERPRET_CAST); } ; -exp : STATIC_CAST '<' type '>' '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_CAST); } +exp : STATIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY + { write_exp_elt_opcode (UNOP_CAST_TYPE); } ; -exp : DYNAMIC_CAST '<' type '>' '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_DYNAMIC_CAST); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_DYNAMIC_CAST); } +exp : DYNAMIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY + { write_exp_elt_opcode (UNOP_DYNAMIC_CAST); } ; -exp : CONST_CAST '<' type '>' '(' exp ')' %prec UNARY +exp : CONST_CAST '<' type_exp '>' '(' exp ')' %prec UNARY { /* We could do more error checking here, but it doesn't seem worthwhile. */ - write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_CAST); } + write_exp_elt_opcode (UNOP_CAST_TYPE); } ; string_exp: diff --git a/gdb/eval.c b/gdb/eval.c index 7d3a8b9..a012873 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -2707,17 +2707,27 @@ evaluate_subexp_standard (struct type *expect_type, arg1 = value_cast (type, arg1); return arg1; + case UNOP_CAST_TYPE: + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (arg1); + arg1 = evaluate_subexp (type, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (type != value_type (arg1)) + arg1 = value_cast (type, arg1); + return arg1; + case UNOP_DYNAMIC_CAST: - (*pos) += 2; - type = exp->elts[pc + 1].type; + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (arg1); arg1 = evaluate_subexp (type, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; return value_dynamic_cast (type, arg1); case UNOP_REINTERPRET_CAST: - (*pos) += 2; - type = exp->elts[pc + 1].type; + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (arg1); arg1 = evaluate_subexp (type, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; @@ -2734,6 +2744,18 @@ evaluate_subexp_standard (struct type *expect_type, return value_at_lazy (exp->elts[pc + 1].type, value_as_address (arg1)); + case UNOP_MEMVAL_TYPE: + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (arg1); + 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_lazy (exp->elts[pc + 1].type, + value_as_address (arg1)); + case UNOP_MEMVAL_TLS: (*pos) += 3; arg1 = evaluate_subexp (expect_type, exp, pos, noside); @@ -2936,6 +2958,17 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), evaluate_subexp (NULL_TYPE, exp, pos, noside)); + case UNOP_MEMVAL_TYPE: + { + struct type *type; + + (*pos) += 1; + x = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (x); + return value_cast (lookup_pointer_type (type), + evaluate_subexp (NULL_TYPE, exp, pos, noside)); + } + case OP_VAR_VALUE: var = exp->elts[pc + 2].symbol; @@ -3078,6 +3111,12 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos) type = check_typedef (exp->elts[pc + 1].type); return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + case UNOP_MEMVAL_TYPE: + (*pos) += 1; + val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = check_typedef (value_type (val)); + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + case OP_VAR_VALUE: (*pos) += 4; type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); diff --git a/gdb/expprint.c b/gdb/expprint.c index 6915d43..c3f6697 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -429,13 +429,25 @@ print_subexp_standard (struct expression *exp, int *pos, fputs_filtered (")", stream); return; + case UNOP_CAST_TYPE: + (*pos) += 1; + if ((int) prec > (int) PREC_PREFIX) + fputs_filtered ("(", stream); + fputs_filtered ("(", stream); + print_subexp (exp, pos, stream, PREC_PREFIX); + fputs_filtered (") ", stream); + print_subexp (exp, pos, stream, PREC_PREFIX); + if ((int) prec > (int) PREC_PREFIX) + fputs_filtered (")", stream); + return; + case UNOP_DYNAMIC_CAST: case UNOP_REINTERPRET_CAST: fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast" : "reinterpret_cast", stream); fputs_filtered ("<", stream); - (*pos) += 2; - type_print (exp->elts[pc + 1].type, "", stream, 0); + (*pos) += 1; + print_subexp (exp, pos, stream, PREC_PREFIX); fputs_filtered ("> (", stream); print_subexp (exp, pos, stream, PREC_PREFIX); fputs_filtered (")", stream); @@ -471,6 +483,18 @@ print_subexp_standard (struct expression *exp, int *pos, fputs_filtered (")", stream); return; + case UNOP_MEMVAL_TYPE: + (*pos) += 1; + if ((int) prec > (int) PREC_PREFIX) + fputs_filtered ("(", stream); + fputs_filtered ("{", stream); + print_subexp (exp, pos, stream, PREC_PREFIX); + fputs_filtered ("} ", stream); + print_subexp (exp, pos, stream, PREC_PREFIX); + if ((int) prec > (int) PREC_PREFIX) + fputs_filtered (")", stream); + return; + case UNOP_MEMVAL_TLS: (*pos) += 3; if ((int) prec > (int) PREC_PREFIX) @@ -910,10 +934,18 @@ dump_subexp_body_standard (struct expression *exp, elt = dump_subexp (exp, stream, elt); } break; - case UNOP_MEMVAL: - case UNOP_CAST: case UNOP_DYNAMIC_CAST: case UNOP_REINTERPRET_CAST: + case UNOP_CAST_TYPE: + case UNOP_MEMVAL_TYPE: + ++elt; + fprintf_filtered (stream, " ("); + elt = dump_subexp (exp, stream, elt); + fprintf_filtered (stream, ")"); + elt = dump_subexp (exp, stream, elt); + break; + case UNOP_MEMVAL: + case UNOP_CAST: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); diff --git a/gdb/parse.c b/gdb/parse.c index 529c517..1f9addf 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -910,10 +910,16 @@ operator_length_standard (const struct expression *expr, int endpos, oplen = 3; break; - case BINOP_VAL: - case UNOP_CAST: + case UNOP_CAST_TYPE: case UNOP_DYNAMIC_CAST: case UNOP_REINTERPRET_CAST: + case UNOP_MEMVAL_TYPE: + oplen = 1; + args = 2; + break; + + case BINOP_VAL: + case UNOP_CAST: case UNOP_MEMVAL: oplen = 3; args = 1; @@ -1732,8 +1738,6 @@ operator_check_standard (struct expression *exp, int pos, case OP_SCOPE: case OP_TYPE: case UNOP_CAST: - case UNOP_DYNAMIC_CAST: - case UNOP_REINTERPRET_CAST: case UNOP_MAX: case UNOP_MEMVAL: case UNOP_MIN: diff --git a/gdb/stack.c b/gdb/stack.c index 35d379d..51747ea 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2308,7 +2308,8 @@ return_command (char *retval_exp, int from_tty) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) { - if (retval_expr->elts[0].opcode != UNOP_CAST) + if (retval_expr->elts[0].opcode != UNOP_CAST + && retval_expr->elts[0].opcode != UNOP_CAST_TYPE) error (_("Return value type not available for selected " "stack frame.\n" "Please use an explicit cast of the value to return.")); diff --git a/gdb/std-operator.def b/gdb/std-operator.def index f2f650b..9c6a01b 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -216,6 +216,9 @@ OP (OP_ARRAY) It casts the value of the following subexpression. */ OP (UNOP_CAST) +/* Like UNOP_CAST, but the type is a subexpression. */ +OP (UNOP_CAST_TYPE) + /* The C++ dynamic_cast operator. */ OP (UNOP_DYNAMIC_CAST) @@ -235,6 +238,9 @@ OP (UNOP_MEMVAL) following subexpression from the TLS specified by `struct objfile'. */ OP (UNOP_MEMVAL_TLS) +/* Like UNOP_MEMVAL, but the type is supplied as a subexpression. */ +OP (UNOP_MEMVAL_TYPE) + /* UNOP_... operate on one value from a following subexpression and replace it with a result. They take no immediate arguments. */ -- 2.7.4