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:
Tom Tromey
2023-06-23 09:59:38 -06:00
parent 1e5ae3d17f
commit 22f6f7979c
6 changed files with 99 additions and 16 deletions

View File

@@ -84,6 +84,8 @@
is 64k. To print longer strings you should increase is 64k. To print longer strings you should increase
'max-value-size'. 'max-value-size'.
* The Ada 2022 Enum_Rep and Enum_Val attributes are now supported.
* New commands * New commands
maintenance print record-instruction [ N ] maintenance print record-instruction [ N ]

View File

@@ -69,7 +69,14 @@ extern struct value *ada_pos_atr (struct type *expect_type,
struct expression *exp, struct expression *exp,
enum noside noside, enum exp_opcode op, enum noside noside, enum exp_opcode op,
struct value *arg); 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); struct value *arg);
extern struct value *ada_binop_exp (struct type *expect_type, extern struct value *ada_binop_exp (struct type *expect_type,
struct expression *exp, struct expression *exp,
@@ -424,8 +431,14 @@ protected:
using operation::do_generate_ax; using operation::do_generate_ax;
}; };
/* Implement the Ada 'val attribute. */ typedef struct value *ada_atr_ftype (struct expression *exp,
class ada_atr_val_operation 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 tuple_holding_operation<struct type *, operation_up>
{ {
public: public:
@@ -434,12 +447,23 @@ public:
value *evaluate (struct type *expect_type, value *evaluate (struct type *expect_type,
struct expression *exp, 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 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. */ /* The indirection operator for Ada. */
class ada_unop_ind_operation class ada_unop_ind_operation
: public unop_ind_base_operation : public unop_ind_base_operation

View File

@@ -474,7 +474,7 @@ make_tick_completer (struct stoken tok)
%right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH %right TICK_ACCESS TICK_ADDRESS TICK_FIRST TICK_LAST TICK_LENGTH
%right TICK_MAX TICK_MIN TICK_MODULUS %right TICK_MAX TICK_MIN TICK_MODULUS
%right TICK_POS TICK_RANGE TICK_SIZE TICK_TAG TICK_VAL %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 /* The following are right-associative only so that reductions at this
precedence have lower precedence than '.' and '('. The syntax still precedence have lower precedence than '.' and '('. The syntax still
forces a.b.c, e.g., to be LEFT-associated. */ 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> pstate->push_new<ada_atr_val_operation>
($1, std::move (arg)); ($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 | type_prefix TICK_MODULUS
{ {
struct type *type_arg = check_typedef ($1); struct type *type_arg = check_typedef ($1);

View File

@@ -8815,7 +8815,8 @@ val_atr (struct type *type, LONGEST val)
} }
struct value * 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) if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (type, not_lval); 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)); 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 */ /* 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); 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 * value *
ada_unop_ind_operation::evaluate (struct type *expect_type, ada_unop_ind_operation::evaluate (struct type *expect_type,
struct expression *exp, struct expression *exp,

View File

@@ -684,6 +684,8 @@ attributes[] = {
{ "size", TICK_SIZE }, { "size", TICK_SIZE },
{ "tag", TICK_TAG }, { "tag", TICK_TAG },
{ "val", TICK_VAL }, { "val", TICK_VAL },
{ "enum_rep", TICK_ENUM_REP },
{ "enum_val", TICK_ENUM_VAL },
}; };
/* Return the syntactic code corresponding to the attribute name or /* Return the syntactic code corresponding to the attribute name or

View File

@@ -61,3 +61,8 @@ gdb_test "print enum_subrange'val(3)" " = lit3"
gdb_test "print indexed_by_enum(lit2)" "43" gdb_test "print indexed_by_enum(lit2)" "43"
gdb_test "print s(2)" "101 'e'" 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"