Message ID | 20240822154730.1595141-2-nt8r@protonmail.com |
---|---|
State | New |
Headers | |
Series | Tab complete convenience variables | |
Checks
Context | Check | Description |
---|---|---|
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 | success | Build passed |
linaro-tcwg-bot/tcwg_gdb_build--master-arm | success | Build passed |
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 | fail | Test failed |
Commit Message
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 3d619012b..7853aa444 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1668,6 +1668,31 @@ register_operation::do_generate_ax (struct expression *exp, value->type = register_type (ax->gdbarch, reg); } +void +uninit_internalvar_operation::do_generate_ax (struct expression *exp, + struct agent_expr *ax, + struct axs_value *value, + struct type *cast_type) +{ + const char *name = get_name (); + struct internalvar *var = lookup_only_internalvar(name); + struct trace_state_variable *tsv; + + tsv = find_trace_state_variable (name); + if (tsv) + { + ax_tsv (ax, aop_getv, tsv->number); + if (ax->tracing) + ax_tsv (ax, aop_tracev, tsv->number); + /* Trace state variables are always 64-bit integers. */ + value->kind = axs_rvalue; + value->type = builtin_type (ax->gdbarch)->builtin_long_long; + } + else if (! compile_internalvar_to_ax (var, ax, value)) + error (_("$%s is not a trace state variable; GDB agent " + "expressions cannot use convenience variables."), name); +} + void internalvar_operation::do_generate_ax (struct expression *exp, struct agent_expr *ax, diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c index 45b30842e..7dedb3829 100644 --- a/gdb/cli/cli-utils.c +++ b/gdb/cli/cli-utils.c @@ -49,7 +49,7 @@ get_ulongest (const char **pp, int trailer) while (isalnum (*p) || *p == '_') p++; std::string varname (start, p - start); - if (!get_internalvar_integer (lookup_internalvar (varname.c_str ()), + if (!get_internalvar_integer (lookup_only_internalvar (varname.c_str ()), &retval)) error (_("Convenience variable $%s does not have integer value."), varname.c_str ()); diff --git a/gdb/expop.h b/gdb/expop.h index 2d46a9dad..f0cc8dbb1 100644 --- a/gdb/expop.h +++ b/gdb/expop.h @@ -878,6 +878,42 @@ class bool_operation { return true; } }; +/* Reference to a variable that had not been defined at parse time. */ +class uninit_internalvar_operation + : public tuple_holding_operation<std::string> +{ +public: + + using tuple_holding_operation::tuple_holding_operation; + + value *evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) override + { + internalvar* iv = lookup_only_internalvar(std::get<0> (m_storage).c_str ()); + if (!iv) { + return value::allocate (builtin_type (exp->gdbarch)->builtin_void); + } + return value_of_internalvar (exp->gdbarch, iv); + } + + const char *get_name () const + { + return std::get<0> (m_storage).c_str (); + } + + enum exp_opcode opcode () const override + { return OP_INTERNALVAR; } + +protected: + + void do_generate_ax (struct expression *exp, + struct agent_expr *ax, + struct axs_value *value, + struct type *cast_type) + override; +}; + class internalvar_operation : public tuple_holding_operation<internalvar *> { @@ -1891,7 +1927,17 @@ class assign_operation struct expression *exp, enum noside noside) override { - value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + operation *lhs_op = std::get<0> (m_storage).get(); + + /* If the operation is an internalvar that was not initialized at + parse time, ensure that it exists. */ + auto *uninit_var_op = dynamic_cast<uninit_internalvar_operation *> (lhs_op); + if (uninit_var_op) { + lookup_internalvar (uninit_var_op->get_name()); + } + + value *lhs = lhs_op->evaluate (nullptr, exp, noside); + /* Special-case assignments where the left-hand-side is a convenience variable -- in these, don't bother setting an expected type. This avoids a weird case where re-assigning a diff --git a/gdb/parse.c b/gdb/parse.c index e0837de7b..19e2504f9 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -242,8 +242,7 @@ parser_state::push_dollar (struct stoken str) /* Any other names are assumed to be debugger internal variables. */ - push_new<expr::internalvar_operation> - (create_internalvar (copy.c_str () + 1)); + push_new<expr::uninit_internalvar_operation> (copy.c_str () + 1); } /* See parser-defs.h. */