/* The original expression string. */
static const char *original_expr;
+/* We don't have a good way to manage non-POD data in Yacc, so store
+ values here. The storage here is only valid for the duration of
+ the parse. */
+static std::vector<std::unique_ptr<gdb_mpz>> int_storage;
+
int yyparse (void);
static int yylex (void);
static void write_ambiguous_var (struct parser_state *,
const struct block *, const char *, int);
-static struct type *type_int (struct parser_state *);
-
-static struct type *type_long (struct parser_state *);
-
-static struct type *type_long_long (struct parser_state *);
-
-static struct type *type_long_double (struct parser_state *);
-
static struct type *type_for_char (struct parser_state *, ULONGEST);
-static struct type *type_boolean (struct parser_state *);
-
static struct type *type_system_address (struct parser_state *);
static std::string find_completion_bounds (struct parser_state *);
(new ada_tick_completer (std::string (tok.ptr, tok.length))));
}
+/* A convenience typedef. */
+typedef std::unique_ptr<ada_assign_operation> ada_assign_up;
+
+/* The stack of currently active assignment expressions. This is used
+ to implement '@', the target name symbol. */
+static std::vector<ada_assign_up> assignments;
+
%}
%union
{
LONGEST lval;
struct {
- LONGEST val;
+ const gdb_mpz *val;
struct type *type;
} typed_val;
+ struct {
+ LONGEST val;
+ struct type *type;
+ } typed_char;
struct {
gdb_byte val[16];
struct type *type;
%type <lval> aggregate_component_list
%type <tval> var_or_type type_prefix opt_type_prefix
-%token <typed_val> INT NULL_PTR CHARLIT
+%token <typed_val> INT NULL_PTR
+%token <typed_char> CHARLIT
%token <typed_val_float> FLOAT
%token TRUEKEYWORD FALSEKEYWORD
%token COLONCOLON
%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. */
exp1 : exp
| exp1 ';' exp
{ ada_wrap2<comma_operation> (BINOP_COMMA); }
- | primary ASSIGN exp /* Extension for convenience */
+ | primary ASSIGN
+ {
+ assignments.emplace_back
+ (new ada_assign_operation (ada_pop (), nullptr));
+ }
+ exp /* Extension for convenience */
{
+ ada_assign_up assign
+ = std::move (assignments.back ());
+ assignments.pop_back ();
+ value *lhs_val = (assign->eval_for_resolution
+ (pstate->expout.get ()));
+
operation_up rhs = pstate->pop ();
- operation_up lhs = ada_pop ();
- value *lhs_val
- = lhs->evaluate (nullptr, pstate->expout.get (),
- EVAL_AVOID_SIDE_EFFECTS);
rhs = resolve (std::move (rhs), true,
lhs_val->type ());
- pstate->push_new<ada_assign_operation>
- (std::move (lhs), std::move (rhs));
+
+ assign->set_rhs (std::move (rhs));
+ pstate->push (std::move (assign));
}
;
}
;
+primary : '@'
+ {
+ if (assignments.empty ())
+ error (_("the target name symbol ('@') may only "
+ "appear in an assignment context"));
+ ada_assign_operation *current
+ = assignments.back ().get ();
+ pstate->push_new<ada_target_operation> (current);
+ }
+ ;
+
simple_exp : primary
;
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);
tick_arglist : %prec '('
{ $$ = 1; }
| '(' INT ')'
- { $$ = $2.val; }
+ { $$ = $2.val->as_integer<LONGEST> (); }
;
type_prefix :
primary : INT
- { write_int (pstate, (LONGEST) $1.val, $1.type); }
+ {
+ pstate->push_new<long_const_operation> ($1.type, *$1.val);
+ ada_wrap<ada_wrapped_operation> ();
+ }
;
primary : CHARLIT
;
primary : TRUEKEYWORD
- { write_int (pstate, 1, type_boolean (pstate)); }
+ {
+ write_int (pstate, 1,
+ parse_type (pstate)->builtin_bool);
+ }
| FALSEKEYWORD
- { write_int (pstate, 0, type_boolean (pstate)); }
+ {
+ write_int (pstate, 0,
+ parse_type (pstate)->builtin_bool);
+ }
;
primary : NEW NAME
original_expr = par_state->lexptr;
scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
- parser_debug);
+ par_state->debug);
lexer_init (yyin); /* (Re-)initialize lexer. */
obstack_free (&temp_parse_space, NULL);
obstack_init (&temp_parse_space);
components.clear ();
associations.clear ();
+ int_storage.clear ();
+ assignments.clear ();
int result = yyparse ();
if (!result)
if (next == renaming_expr)
goto BadEncoding;
renaming_expr = next;
- write_int (par_state, val, type_int (par_state));
+ write_int (par_state, val, parse_type (par_state)->builtin_int);
}
else
{
push_association<ada_name_association> (ada_pop ());
}
-static struct type *
-type_int (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_int;
-}
-
-static struct type *
-type_long (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long;
-}
-
-static struct type *
-type_long_long (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long_long;
-}
-
-static struct type *
-type_long_double (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_long_double;
-}
-
static struct type *
type_for_char (struct parser_state *par_state, ULONGEST value)
{
"wide_wide_character");
}
-static struct type *
-type_boolean (struct parser_state *par_state)
-{
- return parse_type (par_state)->builtin_bool;
-}
-
static struct type *
type_system_address (struct parser_state *par_state)
{