diff options
author | Tom Tromey <tom@tromey.com> | 2021-03-08 07:27:57 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-03-08 07:28:37 -0700 |
commit | 413403fc34156cf695b09553fca91e0990520787 (patch) | |
tree | bf463e2ea8f074b198caca43014951dca5253d5c /gdb/tracepoint.c | |
parent | b0f9164cc6d738db3a71c1ea83aa6567f0387bca (diff) | |
download | fsf-binutils-gdb-413403fc34156cf695b09553fca91e0990520787.zip fsf-binutils-gdb-413403fc34156cf695b09553fca91e0990520787.tar.gz fsf-binutils-gdb-413403fc34156cf695b09553fca91e0990520787.tar.bz2 |
Add an expr::operation_up to struct expression
This adds an expr::operation_up to struct expression, and then
modifies various parts of GDB to use this member when it is non-null.
The list of such spots was a bit surprising to me, and found only
after writing most of the code and then noticing what no longer
compiled.
In a few spots, new accessor methods are added to operation
subclasses, so that code that dissects an expression will work with
the new scheme.
After this change, code that constructs an expression can be switched
to the new form without breaking.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;
now in superclass.
* value.h (fetch_subexp_value): Add "op" parameter.
* value.c (init_if_undefined_command): Update.
* tracepoint.c (validate_actionline, encode_actions_1): Update.
* stap-probe.c (stap_probe::compile_to_ax): Update.
* printcmd.c (set_command): Update.
* ppc-linux-nat.c (ppc_linux_nat_target::check_condition):
Update.
* parser-defs.h (struct expr_builder) <set_operation>: New
method.
* parse.c (parse_exp_in_context, exp_uses_objfile): Update.
* expression.h (struct expression) <first_opcode>: Update.
<op>: New member.
* expprint.c (dump_raw_expression, dump_prefix_expression):
Update.
* expop.h (class var_value_operation) <get_symbol>: New method.
(class register_operation) <get_name>: New method.
(class equal_operation): No longer a typedef, now a subclass.
(class unop_memval_operation) <get_type>: New method.
(class assign_operation) <get_lhs>: New method.
(class unop_cast_operation) <get_type>: New method.
* eval.c (evaluate_expression, evaluate_type)
(evaluate_subexpression_type): Update.
(fetch_subexp_value): Add "op" parameter.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.c (gen_trace_for_expr, gen_eval_for_expr, gen_printf):
Update.
Diffstat (limited to 'gdb/tracepoint.c')
-rw-r--r-- | gdb/tracepoint.c | 82 |
1 files changed, 62 insertions, 20 deletions
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 0cbd2c6..101c526 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -57,6 +57,7 @@ #include "location.h" #include <algorithm> #include "cli/cli-style.h" +#include "expop.h" #include <unistd.h> @@ -689,19 +690,29 @@ validate_actionline (const char *line, struct breakpoint *b) if (exp->first_opcode () == OP_VAR_VALUE) { - if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST) + symbol *sym; + if (exp->op != nullptr) + { + expr::var_value_operation *vvop + = (dynamic_cast<expr::var_value_operation *> + (exp->op.get ())); + sym = vvop->get_symbol (); + } + else + sym = exp->elts[2].symbol; + + if (SYMBOL_CLASS (sym) == LOC_CONST) { error (_("constant `%s' (value %s) " "will not be collected."), - exp->elts[2].symbol->print_name (), - plongest (SYMBOL_VALUE (exp->elts[2].symbol))); + sym->print_name (), + plongest (SYMBOL_VALUE (sym))); } - else if (SYMBOL_CLASS (exp->elts[2].symbol) - == LOC_OPTIMIZED_OUT) + else if (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT) { error (_("`%s' is optimized away " "and cannot be collected."), - exp->elts[2].symbol->print_name ()); + sym->print_name ()); } } @@ -1384,7 +1395,16 @@ encode_actions_1 (struct command_line *action, { case OP_REGISTER: { - const char *name = &exp->elts[2].string; + const char *name; + if (exp->op != nullptr) + { + expr::register_operation *regop + = (dynamic_cast<expr::register_operation *> + (exp->op.get ())); + name = regop->get_name (); + } + else + name = &exp->elts[2].string; i = user_reg_map_name_to_regnum (target_gdbarch (), name, strlen (name)); @@ -1400,25 +1420,47 @@ encode_actions_1 (struct command_line *action, } case UNOP_MEMVAL: - /* Safe because we know it's a simple expression. */ - tempval = evaluate_expression (exp.get ()); - addr = value_address (tempval); - /* Initialize the TYPE_LENGTH if it is a typedef. */ - check_typedef (exp->elts[1].type); - collect->add_memrange (target_gdbarch (), - memrange_absolute, addr, - TYPE_LENGTH (exp->elts[1].type), - tloc->address); - collect->append_exp (std::string (exp_start, - action_exp)); + { + /* Safe because we know it's a simple expression. */ + tempval = evaluate_expression (exp.get ()); + addr = value_address (tempval); + struct type *type; + if (exp->op != nullptr) + { + expr::unop_memval_operation *memop + = (dynamic_cast<expr::unop_memval_operation *> + (exp->op.get ())); + type = memop->get_type (); + } + else + type = exp->elts[1].type; + /* Initialize the TYPE_LENGTH if it is a typedef. */ + check_typedef (type); + collect->add_memrange (target_gdbarch (), + memrange_absolute, addr, + TYPE_LENGTH (type), + tloc->address); + collect->append_exp (std::string (exp_start, + action_exp)); + } break; case OP_VAR_VALUE: { - struct symbol *sym = exp->elts[2].symbol; + struct symbol *sym; + + if (exp->op != nullptr) + { + expr::var_value_operation *vvo + = (dynamic_cast<expr::var_value_operation *> + (exp->op.get ())); + sym = vvo->get_symbol (); + } + else + sym = exp->elts[2].symbol; const char *name = sym->natural_name (); - collect->collect_symbol (exp->elts[2].symbol, + collect->collect_symbol (sym, target_gdbarch (), frame_reg, frame_offset, |