Handle var_zuinteger and var_zuinteger_unlimited from Python
[deliverable/binutils-gdb.git] / gdb / rust-exp.y
index 88c6623de138df83a742ff42072ba5ee9ad243bf..9f21498d4c9aa5d5584189ac2ba76f349b8caabf 100644 (file)
@@ -1,5 +1,5 @@
 /* Bison parser for Rust expressions, for GDB.
-   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -54,7 +54,7 @@ struct typed_val_int
 
 struct typed_val_float
 {
-  DOUBLEST dval;
+  gdb_byte val[16];
   struct type *type;
 };
 
@@ -111,7 +111,8 @@ static const struct rust_op *ast_string (struct stoken str);
 static const struct rust_op *ast_struct (const struct rust_op *name,
                                         rust_set_vector *fields);
 static const struct rust_op *ast_range (const struct rust_op *lhs,
-                                       const struct rust_op *rhs);
+                                       const struct rust_op *rhs,
+                                       bool inclusive);
 static const struct rust_op *ast_array_type (const struct rust_op *lhs,
                                             struct typed_val_int val);
 static const struct rust_op *ast_slice_type (const struct rust_op *type);
@@ -173,10 +174,6 @@ static const char *number_regex_text =
 
 static regex_t number_regex;
 
-/* True if we're running unit tests.  */
-
-static int unit_testing;
-
 /* Obstack for data temporarily allocated during parsing.  Points to
    the obstack in the rust_parser, or to a temporary obstack during
    unit testing.  */
@@ -304,6 +301,9 @@ struct rust_op
      name occurred at the end of the expression and is eligible for
      completion.  */
   unsigned int completing : 1;
+  /* For OP_RANGE, indicates whether the range is inclusive or
+     exclusive.  */
+  unsigned int inclusive : 1;
   /* Operands of expression.  Which one is used and how depends on the
      particular opcode.  */
   RUSTSTYPE left;
@@ -337,6 +337,7 @@ struct rust_op
 
 /* Operator tokens.  */
 %token <voidval> DOTDOT
+%token <voidval> DOTDOTEQ
 %token <voidval> OROR
 %token <voidval> ANDAND
 %token <voidval> EQEQ
@@ -386,7 +387,7 @@ struct rust_op
 %type <one_field_init> struct_expr_tail
 
 /* Precedence.  */
-%nonassoc DOTDOT
+%nonassoc DOTDOT DOTDOTEQ
 %right '=' COMPOUND_ASSIGN
 %left OROR
 %left ANDAND
@@ -429,7 +430,8 @@ expr:
 |      array_expr
 |      idx_expr
 |      range_expr
-|      unop_expr /* Must precede call_expr because of ambiguity with sizeof.  */
+|      unop_expr /* Must precede call_expr because of ambiguity with
+                    sizeof.  */
 |      binop_expr
 |      paren_expr
 |      call_expr
@@ -449,9 +451,9 @@ unit_expr:
                  struct typed_val_int val;
 
                  val.type
-                   = language_lookup_primitive_type (current_parser->language (),
-                                                     current_parser->arch (),
-                                                     "()");
+                   = (language_lookup_primitive_type
+                      (current_parser->language (), current_parser->arch (),
+                       "()"));
                  val.val = 0;
                  $$ = ast_literal (val);
                }
@@ -484,6 +486,14 @@ struct_expr_tail:
                  sf.init = $3;
                  $$ = sf;
                }
+|      IDENT
+               {
+                 struct set_field sf;
+
+                 sf.name = $1;
+                 sf.init = ast_path ($1, NULL);
+                 $$ = sf;
+               }
 ;
 
 struct_expr_list:
@@ -506,6 +516,15 @@ struct_expr_list:
                  $5->push_back (sf);
                  $$ = $5;
                }
+|      IDENT ',' struct_expr_list
+               {
+                 struct set_field sf;
+
+                 sf.name = $1;
+                 sf.init = ast_path ($1, NULL);
+                 $3->push_back (sf);
+                 $$ = $3;
+               }
 ;
 
 array_expr:
@@ -521,13 +540,17 @@ array_expr:
 
 range_expr:
        expr DOTDOT
-               { $$ = ast_range ($1, NULL); }
+               { $$ = ast_range ($1, NULL, false); }
 |      expr DOTDOT expr
-               { $$ = ast_range ($1, $3); }
+               { $$ = ast_range ($1, $3, false); }
+|      expr DOTDOTEQ expr
+               { $$ = ast_range ($1, $3, true); }
 |      DOTDOT expr
-               { $$ = ast_range (NULL, $2); }
+               { $$ = ast_range (NULL, $2, false); }
+|      DOTDOTEQ expr
+               { $$ = ast_range (NULL, $2, true); }
 |      DOTDOT
-               { $$ = ast_range (NULL, NULL); }
+               { $$ = ast_range (NULL, NULL, false); }
 ;
 
 literal:
@@ -627,8 +650,8 @@ unop_expr:
 
 |      '&' KW_MUT expr %prec UNARY
                { $$ = ast_unary (UNOP_ADDR, $3); }
-|   KW_SIZEOF '(' expr ')' %prec UNARY
-        { $$ = ast_unary (UNOP_SIZEOF, $3); }
+|      KW_SIZEOF '(' expr ')' %prec UNARY
+               { $$ = ast_unary (UNOP_SIZEOF, $3); }
 ;
 
 binop_expr:
@@ -742,9 +765,7 @@ maybe_expr_list:
 ;
 
 paren_expr_list:
-       '('
-       maybe_expr_list
-       ')'
+       '(' maybe_expr_list ')'
                { $$ = $2; }
 ;
 
@@ -832,7 +853,7 @@ path_for_type:
 
 just_identifiers_for_type:
        IDENT
-               { $$ = ast_path ($1, NULL); }
+               { $$ = ast_path ($1, NULL); }
 |      just_identifiers_for_type COLONCOLON IDENT
                {
                  $$ = ast_path (rust_concat3 ($1->left.sval.ptr, "::",
@@ -944,6 +965,7 @@ static const struct token_info operator_tokens[] =
   { "&=", COMPOUND_ASSIGN, BINOP_BITWISE_AND },
   { "|=", COMPOUND_ASSIGN, BINOP_BITWISE_IOR },
   { "^=", COMPOUND_ASSIGN, BINOP_BITWISE_XOR },
+  { "..=", DOTDOTEQ, OP_NULL },
 
   { "::", COLONCOLON, OP_NULL },
   { "..", DOTDOT, OP_NULL },
@@ -1015,7 +1037,6 @@ super_name (const struct rust_op *ident, unsigned int n_supers)
 
   if (n_supers > 0)
     {
-      int i;
       int len;
       std::vector<int> offsets;
       unsigned int current_len;
@@ -1049,15 +1070,13 @@ super_name (const struct rust_op *ident, unsigned int n_supers)
                   ident->right.params);
 }
 
-/* A helper that updates innermost_block as appropriate.  */
+/* A helper that updates the innermost block as appropriate.  */
 
 static void
 update_innermost_block (struct block_symbol sym)
 {
-  if (symbol_read_needs_frame (sym.symbol)
-      && (innermost_block == NULL
-         || contained_in (sym.block, innermost_block)))
-    innermost_block = sym.block;
+  if (symbol_read_needs_frame (sym.symbol))
+    innermost_block.update (sym);
 }
 
 /* A helper to look up a Rust type, or fail.  This only works for
@@ -1068,11 +1087,6 @@ rust_type (const char *name)
 {
   struct type *type;
 
-  /* When unit testing, we don't bother checking the types, so avoid a
-     possibly-failing lookup here.  */
-  if (unit_testing)
-    return NULL;
-
   type = language_lookup_primitive_type (current_parser->language (),
                                         current_parser->arch (),
                                         name);
@@ -1260,7 +1274,6 @@ lex_string (void)
 {
   int is_byte = lexptr[0] == 'b';
   int raw_length;
-  int len_in_chars = 0;
 
   if (is_byte)
     ++lexptr;
@@ -1586,8 +1599,11 @@ lex_number (void)
     }
   else
     {
-      rustyylval.typed_val_float.dval = strtod (number.c_str (), NULL);
       rustyylval.typed_val_float.type = type;
+      bool parsed = parse_float (number.c_str (), number.length (),
+                                rustyylval.typed_val_float.type,
+                                rustyylval.typed_val_float.val);
+      gdb_assert (parsed);
     }
 
   return is_integer ? (could_be_decimal ? DECIMAL_INTEGER : INTEGER) : FLOAT;
@@ -1716,7 +1732,7 @@ ast_dliteral (struct typed_val_float val)
 {
   struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op);
 
-  result->opcode = OP_DOUBLE;
+  result->opcode = OP_FLOAT;
   result->left.typed_val_float = val;
 
   return result;
@@ -1835,11 +1851,13 @@ ast_structop_anonymous (const struct rust_op *left,
 /* Make a range operation.  */
 
 static const struct rust_op *
-ast_range (const struct rust_op *lhs, const struct rust_op *rhs)
+ast_range (const struct rust_op *lhs, const struct rust_op *rhs,
+          bool inclusive)
 {
   struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op);
 
   result->opcode = OP_RANGE;
+  result->inclusive = inclusive;
   result->left.op = lhs;
   result->right.op = rhs;
 
@@ -2001,8 +2019,11 @@ convert_params_to_types (struct parser_state *state, rust_op_vector *params)
 {
   std::vector<struct type *> result;
 
-  for (const rust_op *op : *params)
-    result.push_back (convert_ast_to_type (state, op));
+  if (params != nullptr)
+    {
+      for (const rust_op *op : *params)
+        result.push_back (convert_ast_to_type (state, op));
+    }
 
   return result;
 }
@@ -2075,7 +2096,6 @@ convert_ast_to_type (struct parser_state *state,
        std::vector<struct type *> args
          (convert_params_to_types (state, operation->left.params));
        int i;
-       struct type *type;
        const char *name;
 
        obstack_1grow (work_obstack, '(');
@@ -2181,11 +2201,11 @@ convert_ast_to_expression (struct parser_state *state,
       write_exp_elt_opcode (state, OP_LONG);
       break;
 
-    case OP_DOUBLE:
-      write_exp_elt_opcode (state, OP_DOUBLE);
+    case OP_FLOAT:
+      write_exp_elt_opcode (state, OP_FLOAT);
       write_exp_elt_type (state, operation->left.typed_val_float.type);
-      write_exp_elt_dblcst (state, operation->left.typed_val_float.dval);
-      write_exp_elt_opcode (state, OP_DOUBLE);
+      write_exp_elt_floatcst (state, operation->left.typed_val_float.val);
+      write_exp_elt_opcode (state, OP_FLOAT);
       break;
 
     case STRUCTOP_STRUCT:
@@ -2403,7 +2423,6 @@ convert_ast_to_expression (struct parser_state *state,
 
     case OP_AGGREGATE:
       {
-       int i;
        int length;
        rust_set_vector *fields = operation->right.field_inits;
        struct type *type;
@@ -2469,13 +2488,22 @@ convert_ast_to_expression (struct parser_state *state,
          {
            convert_ast_to_expression (state, operation->right.op, top);
            if (kind == BOTH_BOUND_DEFAULT)
-             kind = LOW_BOUND_DEFAULT;
+             kind = (operation->inclusive
+                     ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE);
            else
              {
                gdb_assert (kind == HIGH_BOUND_DEFAULT);
-               kind = NONE_BOUND_DEFAULT;
+               kind = (operation->inclusive
+                       ? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE);
              }
          }
+       else
+         {
+           /* Nothing should make an inclusive range without an upper
+              bound.  */
+           gdb_assert (!operation->inclusive);
+         }
+
        write_exp_elt_opcode (state, OP_RANGE);
        write_exp_elt_longcst (state, kind);
        write_exp_elt_opcode (state, OP_RANGE);
@@ -2675,7 +2703,9 @@ rust_lex_tests (void)
   scoped_restore obstack_holder = make_scoped_restore (&work_obstack,
                                                       &test_obstack);
 
-  unit_testing = 1;
+  // Set up dummy "parser", so that rust_type works.
+  struct parser_state ps (0, &rust_language_defn, target_gdbarch ());
+  rust_parser parser (&ps);
 
   rust_lex_test_one ("", 0);
   rust_lex_test_one ("    \t  \n \r  ", 0);
@@ -2764,8 +2794,6 @@ rust_lex_tests (void)
 
   rust_lex_test_completion ();
   rust_lex_test_push_back ();
-
-  unit_testing = 0;
 }
 
 #endif /* GDB_SELF_TEST */
@@ -2779,6 +2807,6 @@ _initialize_rust_exp (void)
   gdb_assert (code == 0);
 
 #if GDB_SELF_TEST
-  selftests::register_test (rust_lex_tests);
+  selftests::register_test ("rust-lex", rust_lex_tests);
 #endif
 }
This page took 0.03234 seconds and 4 git commands to generate.