diff options
author | Tom Tromey <tom@tromey.com> | 2018-03-29 14:14:07 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-04-27 13:20:13 -0600 |
commit | 6873858b7e464e114f9a877e216949ad8350b4cf (patch) | |
tree | 8812199c58f09c14b00dc50805d9b066f02d28bd /gdb/rust-exp.y | |
parent | 632e107b32c0fe8aede62e070b00756e9fdd2c01 (diff) | |
download | gdb-6873858b7e464e114f9a877e216949ad8350b4cf.zip gdb-6873858b7e464e114f9a877e216949ad8350b4cf.tar.gz gdb-6873858b7e464e114f9a877e216949ad8350b4cf.tar.bz2 |
Add inclusive range support for Rust
This is version 2 of the patch to add inclusive range support for
Rust. I believe it addresses all review comments.
Rust recently stabilized the inclusive range feature:
https://github.com/rust-lang/rust/issues/28237
An inclusive range is an expression like "..= EXPR" or "EXPR ..=
EXPR". It is like an ordinary range, except the upper bound is
inclusive, not exclusive.
This patch adds support for this feature to gdb.
Regression tested on x86-64 Fedora 27.
2018-04-27 Tom Tromey <tom@tromey.com>
PR rust/22545:
* rust-lang.c (rust_inclusive_range_type_p): New function.
(rust_range): Handle inclusive ranges.
(rust_compute_range): Likewise.
* rust-exp.y (struct rust_op) <inclusive>: New field.
(DOTDOTEQ): New constant.
(range_expr): Add "..=" productions.
(operator_tokens): Add "..=" token.
(ast_range): Add "inclusive" parameter.
(convert_ast_to_expression) <case OP_RANGE>: Handle inclusive
ranges.
* parse.c (operator_length_standard) <case OP_RANGE>: Handle new
bounds values.
* expression.h (enum range_type) <NONE_BOUND_DEFAULT_EXCLUSIVE,
LOW_BOUND_DEFAULT_EXCLUSIVE>: New constants.
Update comments.
* expprint.c (print_subexp_standard): Handle new bounds values.
(dump_subexp_body_standard): Likewise.
2018-04-27 Tom Tromey <tom@tromey.com>
PR rust/22545:
* gdb.rust/simple.exp: Add inclusive range tests.
Diffstat (limited to 'gdb/rust-exp.y')
-rw-r--r-- | gdb/rust-exp.y | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y index b661a80..56aa689 100644 --- a/gdb/rust-exp.y +++ b/gdb/rust-exp.y @@ -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); @@ -300,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; @@ -333,6 +337,7 @@ struct rust_op /* Operator tokens. */ %token <voidval> DOTDOT +%token <voidval> DOTDOTEQ %token <voidval> OROR %token <voidval> ANDAND %token <voidval> EQEQ @@ -382,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 @@ -535,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: @@ -956,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 }, @@ -1841,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; @@ -2473,13 +2485,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); |