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
|
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 ]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user