aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog25
-rw-r--r--gdb/ax-gdb.c42
-rw-r--r--gdb/breakpoint.c4
-rw-r--r--gdb/c-exp.y36
-rw-r--r--gdb/eval.c47
-rw-r--r--gdb/expprint.c40
-rw-r--r--gdb/parse.c12
-rw-r--r--gdb/stack.c3
-rw-r--r--gdb/std-operator.def6
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 <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>
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. */