* 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) <UNOP_CAST_TYPE>: New case. <UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update. <UNOP_MEMVAL_TYPE>: New case. (evaluate_subexp_for_address) <UNOP_MEMVAL_TYPE>: New case. (evaluate_subexp_for_sizeof) <UNOP_MEMVAL_TYPE>: New case. * expprint.c (print_subexp_standard) <UNOP_CAST_TYPE>: New case. <UNOP_MEMVAL_TYPE>: New case. (dump_subexp_body_standard) <UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update. <UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases. * parse.c (operator_length_standard) <UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update. <UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases. * stack.c (return_command): Also check for UNOP_CAST_TYPE. * std-operator.def (UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE): New constants.
This commit is contained in:
parent
b1e0c0fa45
commit
9eaf670568
@ -1,3 +1,28 @@
|
||||
2012-07-19 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* 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) <UNOP_CAST_TYPE>: New case.
|
||||
<UNOP_DYNAMIC_CAST, UNOP_REINTERPRET_CAST>: Update.
|
||||
<UNOP_MEMVAL_TYPE>: New case.
|
||||
(evaluate_subexp_for_address) <UNOP_MEMVAL_TYPE>: New case.
|
||||
(evaluate_subexp_for_sizeof) <UNOP_MEMVAL_TYPE>: New case.
|
||||
* expprint.c (print_subexp_standard) <UNOP_CAST_TYPE>: New case.
|
||||
<UNOP_MEMVAL_TYPE>: New case.
|
||||
(dump_subexp_body_standard) <UNOP_DYNAMIC_CAST,
|
||||
UNOP_REINTERPRET_CAST>: Update.
|
||||
<UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: New cases.
|
||||
* parse.c (operator_length_standard) <UNOP_DYNAMIC_CAST,
|
||||
UNOP_REINTERPRET_CAST>: Update.
|
||||
<UNOP_CAST_TYPE, UNOP_MEMVAL_TYPE>: 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 <yao@codesourcery.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
|
42
gdb/ax-gdb.c
42
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. */
|
||||
|
@ -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
|
||||
|
36
gdb/c-exp.y
36
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:
|
||||
|
47
gdb/eval.c
47
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));
|
||||
|
@ -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, " (");
|
||||
|
12
gdb/parse.c
12
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:
|
||||
|
@ -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."));
|
||||
|
@ -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. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user