mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
Introduce and use operation::type_p
There's currently code in gdb that checks if an expression evaluates to a type. In some spots this is done by comparing the opcode against OP_TYPE, but other spots more correctly also compare with OP_TYPEOF and OP_DECLTYPE. This patch cleans up this area, replacing opcode-checking with a new method on 'operation'. Generally, checking the opcode should be considered deprecated, although it's unfortunately difficult to get rid of opcodes entirely. I also took advantage of this change to turn eval_op_type into a method, removing a bit of indirection. Reviewed-by: Keith Seitz <keiths@redhat.com>
This commit is contained in:
parent
c5c8598743
commit
1ce2312391
@ -10772,7 +10772,7 @@ ada_unop_atr_operation::evaluate (struct type *expect_type,
|
||||
struct type *type_arg = nullptr;
|
||||
value *val = nullptr;
|
||||
|
||||
if (std::get<0> (m_storage)->opcode () == OP_TYPE)
|
||||
if (std::get<0> (m_storage)->type_p ())
|
||||
{
|
||||
value *tem = std::get<0> (m_storage)->evaluate (nullptr, exp,
|
||||
EVAL_AVOID_SIDE_EFFECTS);
|
||||
|
@ -493,7 +493,7 @@ dtrace_process_dof_probe (struct objfile *objfile,
|
||||
{
|
||||
}
|
||||
|
||||
if (expr != NULL && expr->first_opcode () == OP_TYPE)
|
||||
if (expr != NULL && expr->type_p ())
|
||||
type = expr->evaluate_type ()->type ();
|
||||
|
||||
args.emplace_back (type, std::move (type_str), std::move (expr));
|
||||
|
11
gdb/eval.c
11
gdb/eval.c
@ -1872,18 +1872,21 @@ eval_op_postdec (struct type *expect_type, struct expression *exp,
|
||||
}
|
||||
}
|
||||
|
||||
/* A helper function for OP_TYPE. */
|
||||
namespace expr
|
||||
{
|
||||
|
||||
struct value *
|
||||
eval_op_type (struct type *expect_type, struct expression *exp,
|
||||
enum noside noside, struct type *type)
|
||||
type_operation::evaluate (struct type *expect_type, struct expression *exp,
|
||||
enum noside noside)
|
||||
{
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return value::allocate (type);
|
||||
return value::allocate (std::get<0> (m_storage));
|
||||
else
|
||||
error (_("Attempt to use a type name as an expression"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* A helper function for BINOP_ASSIGN_MODIFY. */
|
||||
|
||||
struct value *
|
||||
|
20
gdb/expop.h
20
gdb/expop.h
@ -172,9 +172,6 @@ extern struct value *eval_op_ind (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside,
|
||||
struct value *arg1);
|
||||
extern struct value *eval_op_type (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside, struct type *type);
|
||||
extern struct value *eval_op_alignof (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside,
|
||||
@ -1560,16 +1557,16 @@ class type_operation
|
||||
|
||||
value *evaluate (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside) override
|
||||
{
|
||||
return eval_op_type (expect_type, exp, noside, std::get<0> (m_storage));
|
||||
}
|
||||
enum noside noside) override;
|
||||
|
||||
enum exp_opcode opcode () const override
|
||||
{ return OP_TYPE; }
|
||||
|
||||
bool constant_p () const override
|
||||
{ return true; }
|
||||
|
||||
bool type_p () const override
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
/* Implement the "typeof" operation. */
|
||||
@ -1593,6 +1590,9 @@ class typeof_operation
|
||||
|
||||
enum exp_opcode opcode () const override
|
||||
{ return OP_TYPEOF; }
|
||||
|
||||
bool type_p () const override
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
/* Implement 'decltype'. */
|
||||
@ -1638,6 +1638,9 @@ class decltype_operation
|
||||
|
||||
enum exp_opcode opcode () const override
|
||||
{ return OP_DECLTYPE; }
|
||||
|
||||
bool type_p () const override
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
/* Implement 'typeid'. */
|
||||
@ -1652,9 +1655,8 @@ class typeid_operation
|
||||
struct expression *exp,
|
||||
enum noside noside) override
|
||||
{
|
||||
enum exp_opcode sub_op = std::get<0> (m_storage)->opcode ();
|
||||
enum noside sub_noside
|
||||
= ((sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF)
|
||||
= (std::get<0> (m_storage)->type_p ()
|
||||
? EVAL_AVOID_SIDE_EFFECTS
|
||||
: noside);
|
||||
|
||||
|
@ -147,6 +147,11 @@ class operation
|
||||
virtual bool uses_objfile (struct objfile *objfile) const
|
||||
{ return false; }
|
||||
|
||||
/* Some expression nodes represent a type, not a value. This method
|
||||
should be overridden to return 'true' in these situations. */
|
||||
virtual bool type_p () const
|
||||
{ return false; }
|
||||
|
||||
/* Generate agent expression bytecodes for this operation. */
|
||||
void generate_ax (struct expression *exp, struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
@ -215,6 +220,11 @@ struct expression
|
||||
op->dump (stream, 0);
|
||||
}
|
||||
|
||||
/* Call the type_p method on the outermost sub-expression of this
|
||||
expression, and return the result. */
|
||||
bool type_p () const
|
||||
{ return op->type_p (); }
|
||||
|
||||
/* Return true if this expression uses OBJFILE (and will become
|
||||
dangling when OBJFILE is unloaded), otherwise return false.
|
||||
OBJFILE must not be a separate debug info file. */
|
||||
|
@ -513,7 +513,7 @@ whatis_exp (const char *exp, int show)
|
||||
val = expr->evaluate_type ();
|
||||
type = val->type ();
|
||||
|
||||
if (show == -1 && expr->first_opcode () == OP_TYPE)
|
||||
if (show == -1 && expr->type_p ())
|
||||
{
|
||||
/* The user expression names a type directly. */
|
||||
|
||||
|
@ -323,10 +323,7 @@ varobj_create (const char *objname,
|
||||
}
|
||||
|
||||
/* Don't allow variables to be created for types. */
|
||||
enum exp_opcode opcode = var->root->exp->first_opcode ();
|
||||
if (opcode == OP_TYPE
|
||||
|| opcode == OP_TYPEOF
|
||||
|| opcode == OP_DECLTYPE)
|
||||
if (var->root->exp->type_p ())
|
||||
{
|
||||
gdb_printf (gdb_stderr, "Attempt to use a type name"
|
||||
" as an expression.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user