Document array indexing for Python gdb.Value
[binutils-gdb.git] / gdb / ada-exp.y
index 9b704968f909ea4686ef1dcce2a0b6492ca0aea3..3280a483a5ee3afa66ce2a661336a8b282d6c598 100644 (file)
@@ -42,9 +42,6 @@
 #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"
@@ -71,6 +68,11 @@ static struct parser_state *pstate = NULL;
 /* 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);
@@ -96,18 +98,8 @@ static const struct block *block_lookup (const struct block *, const char *);
 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 *);
@@ -423,15 +415,26 @@ make_tick_completer (struct stoken tok)
          (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;
@@ -446,7 +449,8 @@ make_tick_completer (struct stoken tok)
 %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
@@ -477,7 +481,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.  */
@@ -495,17 +499,25 @@ start   : exp1
 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));
                        }
        ;
 
@@ -605,6 +617,17 @@ primary :          aggregate
                        }
        ;        
 
+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
        ;
 
@@ -867,6 +890,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);
@@ -880,7 +915,7 @@ primary :   primary TICK_ACCESS
 tick_arglist :                 %prec '('
                        { $$ = 1; }
        |       '(' INT ')'
-                       { $$ = $2.val; }
+                       { $$ = $2.val->as_integer<LONGEST> (); }
        ;
 
 type_prefix :
@@ -901,7 +936,10 @@ opt_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
@@ -937,9 +975,15 @@ primary    :       STRING
        ;
 
 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
@@ -1144,13 +1188,15 @@ ada_parse (struct parser_state *par_state)
   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)
@@ -1271,7 +1317,7 @@ write_object_renaming (struct parser_state *par_state,
            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
          {
@@ -1844,30 +1890,6 @@ write_name_assoc (struct parser_state *par_state, struct stoken name)
   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)
 {
@@ -1883,12 +1905,6 @@ 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)
 {