forked from Imagelibrary/binutils-gdb
Implement 'Enum_Val and 'Enum_Rep
This patch implements the Ada 2022 attributes 'Enum_Val and 'Enum_Rep. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
This commit is contained in:
2
gdb/NEWS
2
gdb/NEWS
@@ -84,6 +84,8 @@
|
||||
is 64k. To print longer strings you should increase
|
||||
'max-value-size'.
|
||||
|
||||
* The Ada 2022 Enum_Rep and Enum_Val attributes are now supported.
|
||||
|
||||
* New commands
|
||||
|
||||
maintenance print record-instruction [ N ]
|
||||
|
||||
@@ -69,7 +69,14 @@ extern struct value *ada_pos_atr (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside, enum exp_opcode op,
|
||||
struct value *arg);
|
||||
extern struct value *ada_val_atr (enum noside noside, struct type *type,
|
||||
extern struct value *ada_atr_enum_rep (struct expression *exp,
|
||||
enum noside noside, struct type *type,
|
||||
struct value *arg);
|
||||
extern struct value *ada_atr_enum_val (struct expression *exp,
|
||||
enum noside noside, struct type *type,
|
||||
struct value *arg);
|
||||
extern struct value *ada_val_atr (struct expression *exp,
|
||||
enum noside noside, struct type *type,
|
||||
struct value *arg);
|
||||
extern struct value *ada_binop_exp (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
@@ -424,8 +431,14 @@ protected:
|
||||
using operation::do_generate_ax;
|
||||
};
|
||||
|
||||
/* Implement the Ada 'val attribute. */
|
||||
class ada_atr_val_operation
|
||||
typedef struct value *ada_atr_ftype (struct expression *exp,
|
||||
enum noside noside,
|
||||
struct type *type,
|
||||
struct value *arg);
|
||||
|
||||
/* Implement several Ada attributes. */
|
||||
template<ada_atr_ftype FUNC>
|
||||
class ada_atr_operation
|
||||
: public tuple_holding_operation<struct type *, operation_up>
|
||||
{
|
||||
public:
|
||||
@@ -434,12 +447,23 @@ public:
|
||||
|
||||
value *evaluate (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside) override;
|
||||
enum noside noside) override
|
||||
{
|
||||
value *arg = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
|
||||
return FUNC (exp, noside, std::get<0> (m_storage), arg);
|
||||
}
|
||||
|
||||
enum exp_opcode opcode () const override
|
||||
{ return OP_ATR_VAL; }
|
||||
{
|
||||
/* The value here generally doesn't matter. */
|
||||
return OP_ATR_VAL;
|
||||
}
|
||||
};
|
||||
|
||||
using ada_atr_val_operation = ada_atr_operation<ada_val_atr>;
|
||||
using ada_atr_enum_rep_operation = ada_atr_operation<ada_atr_enum_rep>;
|
||||
using ada_atr_enum_val_operation = ada_atr_operation<ada_atr_enum_val>;
|
||||
|
||||
/* The indirection operator for Ada. */
|
||||
class ada_unop_ind_operation
|
||||
: public unop_ind_base_operation
|
||||
|
||||
@@ -474,7 +474,7 @@ make_tick_completer (struct stoken tok)
|
||||
%right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH
|
||||
%right TICK_MAX TICK_MIN TICK_MODULUS
|
||||
%right TICK_POS TICK_RANGE TICK_SIZE TICK_TAG TICK_VAL
|
||||
%right TICK_COMPLETE
|
||||
%right TICK_COMPLETE TICK_ENUM_REP TICK_ENUM_VAL
|
||||
/* The following are right-associative only so that reductions at this
|
||||
precedence have lower precedence than '.' and '('. The syntax still
|
||||
forces a.b.c, e.g., to be LEFT-associated. */
|
||||
@@ -864,6 +864,18 @@ primary : primary TICK_ACCESS
|
||||
pstate->push_new<ada_atr_val_operation>
|
||||
($1, std::move (arg));
|
||||
}
|
||||
| type_prefix TICK_ENUM_REP '(' exp ')'
|
||||
{
|
||||
operation_up arg = ada_pop (true, $1);
|
||||
pstate->push_new<ada_atr_enum_rep_operation>
|
||||
($1, std::move (arg));
|
||||
}
|
||||
| type_prefix TICK_ENUM_VAL '(' exp ')'
|
||||
{
|
||||
operation_up arg = ada_pop (true, $1);
|
||||
pstate->push_new<ada_atr_enum_val_operation>
|
||||
($1, std::move (arg));
|
||||
}
|
||||
| type_prefix TICK_MODULUS
|
||||
{
|
||||
struct type *type_arg = check_typedef ($1);
|
||||
|
||||
@@ -8815,7 +8815,8 @@ val_atr (struct type *type, LONGEST val)
|
||||
}
|
||||
|
||||
struct value *
|
||||
ada_val_atr (enum noside noside, struct type *type, struct value *arg)
|
||||
ada_val_atr (struct expression *exp, enum noside noside, struct type *type,
|
||||
struct value *arg)
|
||||
{
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return value::zero (type, not_lval);
|
||||
@@ -8827,6 +8828,52 @@ ada_val_atr (enum noside noside, struct type *type, struct value *arg)
|
||||
|
||||
return val_atr (type, value_as_long (arg));
|
||||
}
|
||||
|
||||
/* Implementation of the enum_rep attribute. */
|
||||
struct value *
|
||||
ada_atr_enum_rep (struct expression *exp, enum noside noside, struct type *type,
|
||||
struct value *arg)
|
||||
{
|
||||
struct type *inttype = builtin_type (exp->gdbarch)->builtin_int;
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return value::zero (inttype, not_lval);
|
||||
|
||||
if (type->code () == TYPE_CODE_RANGE)
|
||||
type = type->target_type ();
|
||||
if (type->code () != TYPE_CODE_ENUM)
|
||||
error (_("'Enum_Rep only defined on enum types"));
|
||||
if (!types_equal (type, arg->type ()))
|
||||
error (_("'Enum_Rep requires argument to have same type as enum"));
|
||||
|
||||
return value_cast (inttype, arg);
|
||||
}
|
||||
|
||||
/* Implementation of the enum_val attribute. */
|
||||
struct value *
|
||||
ada_atr_enum_val (struct expression *exp, enum noside noside, struct type *type,
|
||||
struct value *arg)
|
||||
{
|
||||
struct type *original_type = type;
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return value::zero (original_type, not_lval);
|
||||
|
||||
if (type->code () == TYPE_CODE_RANGE)
|
||||
type = type->target_type ();
|
||||
if (type->code () != TYPE_CODE_ENUM)
|
||||
error (_("'Enum_Val only defined on enum types"));
|
||||
if (!integer_type_p (arg->type ()))
|
||||
error (_("'Enum_Val requires integral argument"));
|
||||
|
||||
LONGEST value = value_as_long (arg);
|
||||
for (int i = 0; i < type->num_fields (); ++i)
|
||||
{
|
||||
if (type->field (i).loc_enumval () == value)
|
||||
return value_from_longest (original_type, value);
|
||||
}
|
||||
|
||||
error (_("value %s not found in enum"), plongest (value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Evaluation */
|
||||
@@ -10919,15 +10966,6 @@ ada_var_value_operation::do_generate_ax (struct expression *exp,
|
||||
var_value_operation::do_generate_ax (exp, ax, value, cast_type);
|
||||
}
|
||||
|
||||
value *
|
||||
ada_atr_val_operation::evaluate (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
enum noside noside)
|
||||
{
|
||||
value *arg = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
|
||||
return ada_val_atr (noside, std::get<0> (m_storage), arg);
|
||||
}
|
||||
|
||||
value *
|
||||
ada_unop_ind_operation::evaluate (struct type *expect_type,
|
||||
struct expression *exp,
|
||||
|
||||
@@ -684,6 +684,8 @@ attributes[] = {
|
||||
{ "size", TICK_SIZE },
|
||||
{ "tag", TICK_TAG },
|
||||
{ "val", TICK_VAL },
|
||||
{ "enum_rep", TICK_ENUM_REP },
|
||||
{ "enum_val", TICK_ENUM_VAL },
|
||||
};
|
||||
|
||||
/* Return the syntactic code corresponding to the attribute name or
|
||||
|
||||
@@ -61,3 +61,8 @@ gdb_test "print enum_subrange'val(3)" " = lit3"
|
||||
|
||||
gdb_test "print indexed_by_enum(lit2)" "43"
|
||||
gdb_test "print s(2)" "101 'e'"
|
||||
|
||||
gdb_test "print enum_with_gaps'enum_rep(lit3)" " = 13" \
|
||||
"enum_rep"
|
||||
gdb_test "print enum_with_gaps'enum_val(21)" " = lit4" \
|
||||
"enum_val"
|
||||
|
||||
Reference in New Issue
Block a user