aboutsummaryrefslogtreecommitdiff
path: root/gdb/rust-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/rust-parse.c')
-rw-r--r--gdb/rust-parse.c131
1 files changed, 67 insertions, 64 deletions
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c
index 9300e17..b428b97 100644
--- a/gdb/rust-parse.c
+++ b/gdb/rust-parse.c
@@ -1,6 +1,6 @@
/* Rust expression parsing for GDB, the GNU debugger.
- Copyright (C) 2016-2024 Free Software Foundation, Inc.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -235,27 +235,31 @@ struct rust_parser
std::string super_name (const std::string &ident, unsigned int n_supers);
int lex_character ();
+ int lex_decimal_integer ();
int lex_number ();
int lex_string ();
int lex_identifier ();
uint32_t lex_hex (int min, int max);
- uint32_t lex_escape (int is_byte);
+ uint32_t lex_escape (bool is_byte);
int lex_operator ();
- int lex_one_token ();
+ int lex_one_token (bool decimal_only);
void push_back (char c);
/* The main interface to lexing. Lexes one token and updates the
- internal state. */
- void lex ()
+ internal state. DECIMAL_ONLY is true in the special case where
+ we want to tell the lexer not to parse a number as a float, but
+ instead only as a decimal integer. See parse_field. */
+ void lex (bool decimal_only = false)
{
- current_token = lex_one_token ();
+ current_token = lex_one_token (decimal_only);
}
- /* Assuming the current token is TYPE, lex the next token. */
- void assume (int type)
+ /* Assuming the current token is TYPE, lex the next token.
+ DECIMAL_ONLY is passed to 'lex', which see. */
+ void assume (int type, bool decimal_only = false)
{
gdb_assert (current_token == type);
- lex ();
+ lex (decimal_only);
}
/* Require the single-character token C, and lex the next token; or
@@ -519,7 +523,7 @@ rust_parser::lex_hex (int min, int max)
otherwise we're lexing a character escape. */
uint32_t
-rust_parser::lex_escape (int is_byte)
+rust_parser::lex_escape (bool is_byte)
{
uint32_t result;
@@ -617,12 +621,12 @@ lex_multibyte_char (const char *text, int *len)
int
rust_parser::lex_character ()
{
- int is_byte = 0;
+ bool is_byte = false;
uint32_t value;
if (pstate->lexptr[0] == 'b')
{
- is_byte = 1;
+ is_byte = true;
++pstate->lexptr;
}
gdb_assert (pstate->lexptr[0] == '\'');
@@ -672,10 +676,8 @@ starts_raw_string (const char *str)
static bool
ends_raw_string (const char *str, int n)
{
- int i;
-
gdb_assert (str[0] == '"');
- for (i = 0; i < n; ++i)
+ for (int i = 0; i < n; ++i)
if (str[i + 1] != '#')
return false;
return true;
@@ -900,6 +902,26 @@ rust_parser::lex_operator ()
return *pstate->lexptr++;
}
+/* Lex a decimal integer. */
+
+int
+rust_parser::lex_decimal_integer ()
+{
+ gdb_assert (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9');
+
+ std::string copy;
+ while (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')
+ {
+ copy.push_back (pstate->lexptr[0]);
+ ++pstate->lexptr;
+ }
+
+ /* No need to set the value's type in this situation. */
+ current_int_val.val.set (copy.c_str (), 10);
+
+ return DECIMAL_INTEGER;
+}
+
/* Lex a number. */
int
@@ -907,14 +929,12 @@ rust_parser::lex_number ()
{
regmatch_t subexps[NUM_SUBEXPRESSIONS];
int match;
- int is_integer = 0;
- int could_be_decimal = 1;
- int implicit_i32 = 0;
+ bool is_integer = false;
+ bool implicit_i32 = false;
const char *type_name = NULL;
struct type *type;
int end_index;
int type_index = -1;
- int i;
match = regexec (&number_regex, pstate->lexptr, ARRAY_SIZE (subexps),
subexps, 0);
@@ -924,18 +944,15 @@ rust_parser::lex_number ()
if (subexps[INT_TEXT].rm_so != -1)
{
/* Integer part matched. */
- is_integer = 1;
+ is_integer = true;
end_index = subexps[INT_TEXT].rm_eo;
if (subexps[INT_TYPE].rm_so == -1)
{
type_name = "i32";
- implicit_i32 = 1;
+ implicit_i32 = true;
}
else
- {
- type_index = INT_TYPE;
- could_be_decimal = 0;
- }
+ type_index = INT_TYPE;
}
else if (subexps[FLOAT_TYPE1].rm_so != -1)
{
@@ -968,11 +985,10 @@ rust_parser::lex_number ()
if (rust_identifier_start_p (*next) || *next == '.')
{
--subexps[0].rm_eo;
- is_integer = 1;
+ is_integer = true;
end_index = subexps[0].rm_eo;
type_name = "i32";
- could_be_decimal = 1;
- implicit_i32 = 1;
+ implicit_i32 = true;
}
}
@@ -993,11 +1009,9 @@ rust_parser::lex_number ()
/* Copy the text of the number and remove the "_"s. */
std::string number;
- for (i = 0; i < end_index && pstate->lexptr[i]; ++i)
+ for (int i = 0; i < end_index && pstate->lexptr[i]; ++i)
{
- if (pstate->lexptr[i] == '_')
- could_be_decimal = 0;
- else
+ if (pstate->lexptr[i] != '_')
number.push_back (pstate->lexptr[i]);
}
@@ -1019,10 +1033,7 @@ rust_parser::lex_number ()
else if (number[1] == 'b')
radix = 2;
if (radix != 10)
- {
- offset = 2;
- could_be_decimal = 0;
- }
+ offset = 2;
}
if (!current_int_val.val.set (number.c_str () + offset, radix))
@@ -1052,13 +1063,13 @@ rust_parser::lex_number ()
gdb_assert (parsed);
}
- return is_integer ? (could_be_decimal ? DECIMAL_INTEGER : INTEGER) : FLOAT;
+ return is_integer ? INTEGER : FLOAT;
}
/* The lexer. */
int
-rust_parser::lex_one_token ()
+rust_parser::lex_one_token (bool decimal_only)
{
/* Skip all leading whitespace. */
while (pstate->lexptr[0] == ' '
@@ -1085,7 +1096,7 @@ rust_parser::lex_one_token ()
}
if (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')
- return lex_number ();
+ return decimal_only ? lex_decimal_integer () : lex_number ();
else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '\'')
return lex_character ();
else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '"')
@@ -1540,7 +1551,7 @@ rust_parser::parse_addr ()
operation_up
rust_parser::parse_field (operation_up &&lhs)
{
- assume ('.');
+ assume ('.', true);
operation_up result;
switch (current_token)
@@ -1570,9 +1581,6 @@ rust_parser::parse_field (operation_up &&lhs)
}
break;
- case INTEGER:
- error (_("'_' not allowed in integers in anonymous field references"));
-
default:
error (_("field name expected"));
}
@@ -1666,7 +1674,7 @@ rust_parser::parse_array_type ()
struct type *elt_type = parse_type ();
require (';');
- if (current_token != INTEGER && current_token != DECIMAL_INTEGER)
+ if (current_token != INTEGER)
error (_("integer expected"));
ULONGEST val = current_int_val.val.as_integer<ULONGEST> ();
lex ();
@@ -1765,7 +1773,7 @@ rust_parser::parse_tuple_type ()
std::string type_name = type_to_string (types[i]);
if (i > 0)
- obstack_1grow (&obstack, ',');
+ obstack_grow_str (&obstack, ", ");
obstack_grow_str (&obstack, type_name.c_str ());
}
@@ -2039,7 +2047,6 @@ rust_parser::parse_atom (bool required)
break;
case INTEGER:
- case DECIMAL_INTEGER:
result = make_operation<long_const_operation> (current_int_val.type,
current_int_val.val);
lex ();
@@ -2180,12 +2187,12 @@ rust_lex_test_one (rust_parser *parser, const char *input, int expected)
parser->reset (input);
- token = parser->lex_one_token ();
+ token = parser->lex_one_token (false);
SELF_CHECK (token == expected);
if (token)
{
- token = parser->lex_one_token ();
+ token = parser->lex_one_token (false);
SELF_CHECK (token == 0);
}
}
@@ -2235,13 +2242,11 @@ static void
rust_lex_test_sequence (rust_parser *parser, const char *input, int len,
const int expected[])
{
- int i;
-
parser->reset (input);
- for (i = 0; i < len; ++i)
+ for (int i = 0; i < len; ++i)
{
- int token = parser->lex_one_token ();
+ int token = parser->lex_one_token (false);
SELF_CHECK (token == expected[i]);
}
}
@@ -2251,10 +2256,10 @@ rust_lex_test_sequence (rust_parser *parser, const char *input, int len,
static void
rust_lex_test_trailing_dot (rust_parser *parser)
{
- const int expected1[] = { DECIMAL_INTEGER, '.', IDENT, '(', ')', 0 };
+ const int expected1[] = { INTEGER, '.', IDENT, '(', ')', 0 };
const int expected2[] = { INTEGER, '.', IDENT, '(', ')', 0 };
const int expected3[] = { FLOAT, EQEQ, '(', ')', 0 };
- const int expected4[] = { DECIMAL_INTEGER, DOTDOT, DECIMAL_INTEGER, 0 };
+ const int expected4[] = { INTEGER, DOTDOT, INTEGER, 0 };
rust_lex_test_sequence (parser, "23.g()", ARRAY_SIZE (expected1), expected1);
rust_lex_test_sequence (parser, "23_0.g()", ARRAY_SIZE (expected2),
@@ -2271,14 +2276,14 @@ rust_lex_test_completion (rust_parser *parser)
{
const int expected[] = { IDENT, '.', COMPLETE, 0 };
- parser->pstate->parse_completion = 1;
+ parser->pstate->parse_completion = true;
rust_lex_test_sequence (parser, "something.wha", ARRAY_SIZE (expected),
expected);
rust_lex_test_sequence (parser, "something.", ARRAY_SIZE (expected),
expected);
- parser->pstate->parse_completion = 0;
+ parser->pstate->parse_completion = false;
}
/* Test pushback. */
@@ -2290,16 +2295,16 @@ rust_lex_test_push_back (rust_parser *parser)
parser->reset (">>=");
- token = parser->lex_one_token ();
+ token = parser->lex_one_token (false);
SELF_CHECK (token == COMPOUND_ASSIGN);
SELF_CHECK (parser->current_opcode == BINOP_RSH);
parser->push_back ('=');
- token = parser->lex_one_token ();
+ token = parser->lex_one_token (false);
SELF_CHECK (token == '=');
- token = parser->lex_one_token ();
+ token = parser->lex_one_token (false);
SELF_CHECK (token == 0);
}
@@ -2357,7 +2362,7 @@ rust_lex_tests (void)
rust_lex_exception_test (&parser, "'\\Q'", "Invalid escape \\Q in literal");
rust_lex_exception_test (&parser, "b'\\Q'", "Invalid escape \\Q in literal");
- rust_lex_int_test (&parser, "23", 23, DECIMAL_INTEGER);
+ rust_lex_int_test (&parser, "23", 23, INTEGER);
rust_lex_int_test (&parser, "2_344__29", 234429, INTEGER);
rust_lex_int_test (&parser, "0x1f", 0x1f, INTEGER);
rust_lex_int_test (&parser, "23usize", 23, INTEGER);
@@ -2382,7 +2387,7 @@ rust_lex_tests (void)
rust_lex_stringish_test (&parser, "thread", "thread", IDENT);
rust_lex_stringish_test (&parser, "r#true", "true", IDENT);
- const int expected1[] = { IDENT, DECIMAL_INTEGER, 0 };
+ const int expected1[] = { IDENT, INTEGER, 0 };
rust_lex_test_sequence (&parser, "r#thread 23", ARRAY_SIZE (expected1),
expected1);
const int expected2[] = { IDENT, '#', 0 };
@@ -2416,9 +2421,7 @@ rust_lex_tests (void)
-void _initialize_rust_exp ();
-void
-_initialize_rust_exp ()
+INIT_GDB_FILE (rust_exp)
{
int code = regcomp (&number_regex, number_regex_text, REG_EXTENDED);
/* If the regular expression was incorrect, it was a programming