/* YACC parser for Ada expressions, for GDB.
- Copyright (C) 1986-2022 Free Software Foundation, Inc.
+ Copyright (C) 1986-2023 Free Software Foundation, Inc.
This file is part of GDB.
#include "parser-defs.h"
#include "language.h"
#include "ada-lang.h"
-#include "bfd.h" /* Required by objfiles.h. */
-#include "symfile.h" /* Required by objfiles.h. */
-#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "frame.h"
#include "block.h"
#include "ada-exp.h"
/* 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 *);
struct value *callee_v = callee->evaluate (nullptr,
pstate->expout.get (),
EVAL_AVOID_SIDE_EFFECTS);
- callee_t = ada_check_typedef (value_type (callee_v));
+ callee_t = ada_check_typedef (callee_v->type ());
array_arity = ada_array_arity (callee_t);
}
choice_component ()
{
ada_component *last = components.back ().get ();
- ada_choices_component *result = dynamic_cast<ada_choices_component *> (last);
- gdb_assert (result != nullptr);
- return result;
+ return gdb::checked_static_cast<ada_choices_component *> (last);
}
/* Pop the most recent component from the global stack, and return
(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,
- value_type (lhs_val));
- pstate->push_new<ada_assign_operation>
- (std::move (lhs), std::move (rhs));
+ lhs_val->type ());
+
+ 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);
if (!ada_is_modular_type (type_arg))
error (_("'modulus must be applied to modular type"));
write_int (pstate, ada_modulus (type_arg),
- TYPE_TARGET_TYPE (type_arg));
+ type_arg->target_type ());
}
;
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
{
symtab = NULL;
if (symtab != NULL)
- result = BLOCKVECTOR_BLOCK (symtab->compunit ()->blockvector (),
- STATIC_BLOCK);
+ result = symtab->compunit ()->blockvector ()->static_block ();
else if (syms.empty () || syms[0].symbol->aclass () != LOC_BLOCK)
{
if (context == NULL)
{
if (syms.size () > 1)
warning (_("Function name \"%s\" ambiguous here"), raw_name);
- result = SYMBOL_BLOCK_VALUE (syms[0].symbol);
+ result = syms[0].symbol->value_block ();
}
return result;
write_selectors (par_state, encoded_name + tail_index);
return NULL;
default:
- internal_error (__FILE__, __LINE__,
- _("impossible value from ada_parse_renaming"));
+ internal_error (_("impossible value from ada_parse_renaming"));
}
if (type_sym != NULL)
}
else if (syms.empty ())
{
+ struct objfile *objfile = nullptr;
+ if (block != nullptr)
+ objfile = block->objfile ();
+
struct bound_minimal_symbol msym
- = ada_lookup_simple_minsym (decoded_name.c_str ());
+ = ada_lookup_simple_minsym (decoded_name.c_str (), objfile);
if (msym.minsym != NULL)
{
par_state->push_new<ada_var_msym_value_operation> (msym);
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)
{