1 /* Bison parser for Rust expressions, for GDB.
2 Copyright (C) 2016-2019 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* The Bison manual says that %pure-parser is deprecated, but we use
20 it anyway because it also works with Byacc. That is also why
21 this uses %lex-param and %parse-param rather than the simpler
22 %param -- Byacc does not support the latter. */
24 %lex
-param
{struct rust_parser
*parser
}
25 %parse
-param
{struct rust_parser
*parser
}
27 /* Removing the last conflict seems difficult. */
36 #include "cp-support.h"
37 #include "gdb_obstack.h"
38 #include "gdb_regex.h"
39 #include "rust-lang.h"
40 #include "parser-defs.h"
41 #include "common/selftest.h"
43 #include "common/vec.h"
45 #define GDB_YY_REMAP_PREFIX rust
48 #define RUSTSTYPE YYSTYPE
51 typedef std
::vector
<const struct rust_op
*> rust_op_vector
;
53 /* A typed integer constant. */
61 /* A typed floating point constant. */
63 struct typed_val_float
69 /* An identifier and an expression. This is used to represent one
70 element of a struct initializer. */
75 const struct rust_op
*init
;
78 typedef std
::vector
<set_field
> rust_set_vector
;
84 /* A typed integer constant. */
85 struct typed_val_int typed_val_int
;
87 /* A typed floating point constant. */
88 struct typed_val_float typed_val_float
;
90 /* An identifier or string. */
93 /* A token representing an opcode, like "==". */
94 enum exp_opcode opcode
;
96 /* A list of expressions; for example, the arguments to a function
98 rust_op_vector
*params
;
100 /* A list of field initializers. */
101 rust_set_vector
*field_inits
;
103 /* A single field initializer. */
104 struct set_field one_field_init
;
107 const struct rust_op
*op
;
109 /* A plain integer, for example used to count the number of
110 "super::" prefixes on a path. */
117 static int rustyylex
(YYSTYPE *, rust_parser
*);
118 static void rustyyerror
(rust_parser
*parser
, const char *msg
);
120 static struct stoken make_stoken
(const char *);
122 /* A regular expression for matching Rust numbers. This is split up
123 since it is very long and this gives us a way to comment the
126 static const char *number_regex_text
=
127 /* subexpression 1: allows use of alternation, otherwise uninteresting */
129 /* First comes floating point. */
130 /* Recognize number after the decimal point, with optional
131 exponent and optional type suffix.
132 subexpression 2: allows "?", otherwise uninteresting
133 subexpression 3: if present, type suffix
135 "[0-9][0-9_]*\\.[0-9][0-9_]*([eE][-+]?[0-9][0-9_]*)?(f32|f64)?"
136 #define FLOAT_TYPE1 3
138 /* Recognize exponent without decimal point, with optional type
140 subexpression 4: if present, type suffix
142 #define FLOAT_TYPE2 4
143 "[0-9][0-9_]*[eE][-+]?[0-9][0-9_]*(f32|f64)?"
145 /* "23." is a valid floating point number, but "23.e5" and
146 "23.f32" are not. So, handle the trailing-. case
150 /* Finally come integers.
151 subexpression 5: text of integer
152 subexpression 6: if present, type suffix
153 subexpression 7: allows use of alternation, otherwise uninteresting
157 "(0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*)"
158 "([iu](size|8|16|32|64))?"
160 /* The number of subexpressions to allocate space for, including the
161 "0th" whole match subexpression. */
162 #define NUM_SUBEXPRESSIONS 8
164 /* The compiled number-matching regex. */
166 static regex_t number_regex
;
168 /* An instance of this is created before parsing, and destroyed when
169 parsing is finished. */
173 rust_parser
(struct parser_state
*state
)
174 : rust_ast
(nullptr
),
183 /* Create a new rust_set_vector. The storage for the new vector is
184 managed by this class. */
185 rust_set_vector
*new_set_vector
()
187 rust_set_vector
*result
= new rust_set_vector
;
188 set_vectors.push_back
(std
::unique_ptr
<rust_set_vector
> (result
));
192 /* Create a new rust_ops_vector. The storage for the new vector is
193 managed by this class. */
194 rust_op_vector
*new_op_vector
()
196 rust_op_vector
*result
= new rust_op_vector
;
197 op_vectors.push_back
(std
::unique_ptr
<rust_op_vector
> (result
));
201 /* Return the parser's language. */
202 const struct language_defn
*language
() const
204 return pstate
->language
();
207 /* Return the parser's gdbarch. */
208 struct gdbarch
*arch
() const
210 return pstate
->gdbarch
();
213 /* A helper to look up a Rust type, or fail. This only works for
214 types defined by rust_language_arch_info. */
216 struct type
*get_type
(const char *name
)
220 type
= language_lookup_primitive_type
(language
(), arch
(), name
);
222 error (_
("Could not find Rust type %s"), name
);
226 const char *copy_name
(const char *name
, int len
);
227 struct stoken concat3
(const char *s1
, const char *s2
, const char *s3
);
228 const struct rust_op
*crate_name
(const struct rust_op
*name
);
229 const struct rust_op
*super_name
(const struct rust_op
*ident
,
230 unsigned int n_supers
);
232 int lex_character
(YYSTYPE *lvalp
);
233 int lex_number
(YYSTYPE *lvalp
);
234 int lex_string
(YYSTYPE *lvalp
);
235 int lex_identifier
(YYSTYPE *lvalp
);
236 uint32_t lex_hex
(int min
, int max
);
237 uint32_t lex_escape
(int is_byte
);
238 int lex_operator
(YYSTYPE *lvalp
);
239 void push_back
(char c
);
241 void update_innermost_block
(struct block_symbol sym
);
242 struct block_symbol lookup_symbol
(const char *name
,
243 const struct block
*block
,
244 const domain_enum domain
);
245 struct type
*rust_lookup_type
(const char *name
, const struct block
*block
);
246 std
::vector
<struct type
*> convert_params_to_types
(rust_op_vector
*params
);
247 struct type
*convert_ast_to_type
(const struct rust_op
*operation
);
248 const char *convert_name
(const struct rust_op
*operation
);
249 void convert_params_to_expression
(rust_op_vector
*params
,
250 const struct rust_op
*top
);
251 void convert_ast_to_expression
(const struct rust_op
*operation
,
252 const struct rust_op
*top
,
253 bool want_type
= false
);
255 struct rust_op
*ast_basic_type
(enum type_code typecode
);
256 const struct rust_op
*ast_operation
(enum exp_opcode opcode
,
257 const struct rust_op
*left
,
258 const struct rust_op
*right
);
259 const struct rust_op
*ast_compound_assignment
260 (enum exp_opcode opcode
, const struct rust_op
*left
,
261 const struct rust_op
*rust_op
);
262 const struct rust_op
*ast_literal
(struct typed_val_int val
);
263 const struct rust_op
*ast_dliteral
(struct typed_val_float val
);
264 const struct rust_op
*ast_structop
(const struct rust_op
*left
,
267 const struct rust_op
*ast_structop_anonymous
268 (const struct rust_op
*left
, struct typed_val_int number
);
269 const struct rust_op
*ast_unary
(enum exp_opcode opcode
,
270 const struct rust_op
*expr
);
271 const struct rust_op
*ast_cast
(const struct rust_op
*expr
,
272 const struct rust_op
*type
);
273 const struct rust_op
*ast_call_ish
(enum exp_opcode opcode
,
274 const struct rust_op
*expr
,
275 rust_op_vector
*params
);
276 const struct rust_op
*ast_path
(struct stoken name
,
277 rust_op_vector
*params
);
278 const struct rust_op
*ast_string
(struct stoken str
);
279 const struct rust_op
*ast_struct
(const struct rust_op
*name
,
280 rust_set_vector
*fields
);
281 const struct rust_op
*ast_range
(const struct rust_op
*lhs
,
282 const struct rust_op
*rhs
,
284 const struct rust_op
*ast_array_type
(const struct rust_op
*lhs
,
285 struct typed_val_int val
);
286 const struct rust_op
*ast_slice_type
(const struct rust_op
*type
);
287 const struct rust_op
*ast_reference_type
(const struct rust_op
*type
);
288 const struct rust_op
*ast_pointer_type
(const struct rust_op
*type
,
290 const struct rust_op
*ast_function_type
(const struct rust_op
*result
,
291 rust_op_vector
*params
);
292 const struct rust_op
*ast_tuple_type
(rust_op_vector
*params
);
295 /* A pointer to this is installed globally. */
296 auto_obstack obstack
;
298 /* Result of parsing. Points into obstack. */
299 const struct rust_op
*rust_ast
;
301 /* This keeps track of the various vectors we allocate. */
302 std
::vector
<std
::unique_ptr
<rust_set_vector
>> set_vectors
;
303 std
::vector
<std
::unique_ptr
<rust_op_vector
>> op_vectors
;
305 /* The parser state gdb gave us. */
306 struct parser_state
*pstate
;
308 /* Depth of parentheses. */
312 /* Rust AST operations. We build a tree of these; then lower them to
313 gdb expressions when parsing has completed. */
318 enum exp_opcode opcode
;
319 /* If OPCODE is OP_TYPE, then this holds information about what type
320 is described by this node. */
321 enum type_code typecode
;
322 /* Indicates whether OPCODE actually represents a compound
323 assignment. For example, if OPCODE is GTGT and this is false,
324 then this rust_op represents an ordinary ">>"; but if this is
325 true, then this rust_op represents ">>=". Unused in other
327 unsigned int compound_assignment
: 1;
328 /* Only used by a field expression; if set, indicates that the field
329 name occurred at the end of the expression and is eligible for
331 unsigned int completing
: 1;
332 /* For OP_RANGE, indicates whether the range is inclusive or
334 unsigned int inclusive
: 1;
335 /* Operands of expression. Which one is used and how depends on the
336 particular opcode. */
345 %token
<sval
> COMPLETE
346 %token
<typed_val_int
> INTEGER
347 %token
<typed_val_int
> DECIMAL_INTEGER
349 %token
<sval
> BYTESTRING
350 %token
<typed_val_float
> FLOAT
351 %token
<opcode
> COMPOUND_ASSIGN
353 /* Keyword tokens. */
354 %token
<voidval
> KW_AS
355 %token
<voidval
> KW_IF
356 %token
<voidval
> KW_TRUE
357 %token
<voidval
> KW_FALSE
358 %token
<voidval
> KW_SUPER
359 %token
<voidval
> KW_SELF
360 %token
<voidval
> KW_MUT
361 %token
<voidval
> KW_EXTERN
362 %token
<voidval
> KW_CONST
363 %token
<voidval
> KW_FN
364 %token
<voidval
> KW_SIZEOF
366 /* Operator tokens. */
367 %token
<voidval
> DOTDOT
368 %token
<voidval
> DOTDOTEQ
369 %token
<voidval
> OROR
370 %token
<voidval
> ANDAND
371 %token
<voidval
> EQEQ
372 %token
<voidval
> NOTEQ
373 %token
<voidval
> LTEQ
374 %token
<voidval
> GTEQ
375 %token
<voidval
> LSH RSH
376 %token
<voidval
> COLONCOLON
377 %token
<voidval
> ARROW
380 %type
<op
> path_for_expr
381 %type
<op
> identifier_path_for_expr
382 %type
<op
> path_for_type
383 %type
<op
> identifier_path_for_type
384 %type
<op
> just_identifiers_for_type
386 %type
<params
> maybe_type_list
387 %type
<params
> type_list
389 %type
<depth
> super_path
393 %type
<op
> field_expr
396 %type
<op
> binop_expr
397 %type
<op
> binop_expr_expr
398 %type
<op
> type_cast_expr
399 %type
<op
> assignment_expr
400 %type
<op
> compound_assignment_expr
401 %type
<op
> paren_expr
404 %type
<op
> tuple_expr
406 %type
<op
> struct_expr
407 %type
<op
> array_expr
408 %type
<op
> range_expr
410 %type
<params
> expr_list
411 %type
<params
> maybe_expr_list
412 %type
<params
> paren_expr_list
414 %type
<field_inits
> struct_expr_list
415 %type
<one_field_init
> struct_expr_tail
418 %nonassoc DOTDOT DOTDOTEQ
419 %right
'=' COMPOUND_ASSIGN
422 %nonassoc EQEQ NOTEQ
'<' '>' LTEQ GTEQ
430 /* These could be %precedence in Bison, but that isn't a yacc
441 /* If we are completing and see a valid parse,
442 rust_ast will already have been set. */
443 if
(parser
->rust_ast
== NULL
)
444 parser
->rust_ast
= $1;
448 /* Note that the Rust grammar includes a method_call_expr, but we
449 handle this differently, to avoid a shift/reduce conflict with
461 | unop_expr
/* Must precede call_expr because of ambiguity with
469 '(' expr
',' maybe_expr_list
')'
472 error (_
("Tuple expressions not supported yet"));
479 struct typed_val_int val
;
482 = (language_lookup_primitive_type
483 (parser
->language
(), parser
->arch
(),
486 $$
= parser
->ast_literal
(val
);
490 /* To avoid a shift/reduce conflict with call_expr, we don't handle
491 tuple struct expressions here, but instead when examining the
494 path_for_expr
'{' struct_expr_list
'}'
495 { $$
= parser
->ast_struct
($1, $3); }
522 sf.init
= parser
->ast_path
($1, NULL
);
530 $$
= parser
->new_set_vector
();
534 rust_set_vector
*result
= parser
->new_set_vector
();
535 result
->push_back
($1);
538 | IDENT
':' expr
',' struct_expr_list
547 | IDENT
',' struct_expr_list
552 sf.init
= parser
->ast_path
($1, NULL
);
559 '[' KW_MUT expr_list
']'
560 { $$
= parser
->ast_call_ish
(OP_ARRAY
, NULL
, $3); }
562 { $$
= parser
->ast_call_ish
(OP_ARRAY
, NULL
, $2); }
563 |
'[' KW_MUT expr
';' expr
']'
564 { $$
= parser
->ast_operation
(OP_RUST_ARRAY
, $3, $5); }
565 |
'[' expr
';' expr
']'
566 { $$
= parser
->ast_operation
(OP_RUST_ARRAY
, $2, $4); }
571 { $$
= parser
->ast_range
($1, NULL
, false
); }
573 { $$
= parser
->ast_range
($1, $3, false
); }
575 { $$
= parser
->ast_range
($1, $3, true
); }
577 { $$
= parser
->ast_range
(NULL
, $2, false
); }
579 { $$
= parser
->ast_range
(NULL
, $2, true
); }
581 { $$
= parser
->ast_range
(NULL
, NULL
, false
); }
586 { $$
= parser
->ast_literal
($1); }
588 { $$
= parser
->ast_literal
($1); }
590 { $$
= parser
->ast_dliteral
($1); }
593 struct set_field field
;
594 struct typed_val_int val
;
597 rust_set_vector
*fields
= parser
->new_set_vector
();
599 /* Wrap the raw string in the &str struct. */
600 field.name.ptr
= "data_ptr";
601 field.name.length
= strlen
(field.name.ptr
);
602 field.init
= parser
->ast_unary
(UNOP_ADDR
,
603 parser
->ast_string
($1));
604 fields
->push_back
(field
);
606 val.type
= parser
->get_type
("usize");
609 field.name.ptr
= "length";
610 field.name.length
= strlen
(field.name.ptr
);
611 field.init
= parser
->ast_literal
(val
);
612 fields
->push_back
(field
);
615 token.length
= strlen
(token.ptr
);
616 $$
= parser
->ast_struct
(parser
->ast_path
(token
, NULL
),
620 { $$
= parser
->ast_string
($1); }
623 struct typed_val_int val
;
625 val.type
= language_bool_type
(parser
->language
(),
628 $$
= parser
->ast_literal
(val
);
632 struct typed_val_int val
;
634 val.type
= language_bool_type
(parser
->language
(),
637 $$
= parser
->ast_literal
(val
);
643 { $$
= parser
->ast_structop
($1, $3.ptr
, 0); }
646 $$
= parser
->ast_structop
($1, $3.ptr
, 1);
647 parser
->rust_ast
= $$
;
649 | expr
'.' DECIMAL_INTEGER
650 { $$
= parser
->ast_structop_anonymous
($1, $3); }
655 { $$
= parser
->ast_operation
(BINOP_SUBSCRIPT
, $1, $3); }
660 { $$
= parser
->ast_unary
(UNOP_PLUS
, $2); }
662 |
'-' expr %prec UNARY
663 { $$
= parser
->ast_unary
(UNOP_NEG
, $2); }
665 |
'!' expr %prec UNARY
667 /* Note that we provide a Rust-specific evaluator
668 override for UNOP_COMPLEMENT, so it can do the
669 right thing for both bool and integral
671 $$
= parser
->ast_unary
(UNOP_COMPLEMENT
, $2);
674 |
'*' expr %prec UNARY
675 { $$
= parser
->ast_unary
(UNOP_IND
, $2); }
677 |
'&' expr %prec UNARY
678 { $$
= parser
->ast_unary
(UNOP_ADDR
, $2); }
680 |
'&' KW_MUT expr %prec UNARY
681 { $$
= parser
->ast_unary
(UNOP_ADDR
, $3); }
682 | KW_SIZEOF
'(' expr
')' %prec UNARY
683 { $$
= parser
->ast_unary
(UNOP_SIZEOF
, $3); }
690 | compound_assignment_expr
695 { $$
= parser
->ast_operation
(BINOP_MUL
, $1, $3); }
698 { $$
= parser
->ast_operation
(BINOP_REPEAT
, $1, $3); }
701 { $$
= parser
->ast_operation
(BINOP_DIV
, $1, $3); }
704 { $$
= parser
->ast_operation
(BINOP_REM
, $1, $3); }
707 { $$
= parser
->ast_operation
(BINOP_LESS
, $1, $3); }
710 { $$
= parser
->ast_operation
(BINOP_GTR
, $1, $3); }
713 { $$
= parser
->ast_operation
(BINOP_BITWISE_AND
, $1, $3); }
716 { $$
= parser
->ast_operation
(BINOP_BITWISE_IOR
, $1, $3); }
719 { $$
= parser
->ast_operation
(BINOP_BITWISE_XOR
, $1, $3); }
722 { $$
= parser
->ast_operation
(BINOP_ADD
, $1, $3); }
725 { $$
= parser
->ast_operation
(BINOP_SUB
, $1, $3); }
728 { $$
= parser
->ast_operation
(BINOP_LOGICAL_OR
, $1, $3); }
731 { $$
= parser
->ast_operation
(BINOP_LOGICAL_AND
, $1, $3); }
734 { $$
= parser
->ast_operation
(BINOP_EQUAL
, $1, $3); }
737 { $$
= parser
->ast_operation
(BINOP_NOTEQUAL
, $1, $3); }
740 { $$
= parser
->ast_operation
(BINOP_LEQ
, $1, $3); }
743 { $$
= parser
->ast_operation
(BINOP_GEQ
, $1, $3); }
746 { $$
= parser
->ast_operation
(BINOP_LSH
, $1, $3); }
749 { $$
= parser
->ast_operation
(BINOP_RSH
, $1, $3); }
754 { $$
= parser
->ast_cast
($1, $3); }
759 { $$
= parser
->ast_operation
(BINOP_ASSIGN
, $1, $3); }
762 compound_assignment_expr:
763 expr COMPOUND_ASSIGN expr
764 { $$
= parser
->ast_compound_assignment
($2, $1, $3); }
776 $$
= parser
->new_op_vector
();
789 /* The result can't be NULL. */
790 $$
= parser
->new_op_vector
();
797 '(' maybe_expr_list
')'
803 { $$
= parser
->ast_call_ish
(OP_FUNCALL
, $1, $2); }
814 | super_path KW_SUPER COLONCOLON
822 { $$
= parser
->ast_path
($1, NULL
); }
824 { $$
= parser
->ast_path
(make_stoken
("self"), NULL
); }
828 identifier_path_for_expr
829 | KW_SELF COLONCOLON identifier_path_for_expr
830 { $$
= parser
->super_name
($3, 0); }
831 | maybe_self_path super_path identifier_path_for_expr
832 { $$
= parser
->super_name
($3, $2); }
833 | COLONCOLON identifier_path_for_expr
834 { $$
= parser
->crate_name
($2); }
835 | KW_EXTERN identifier_path_for_expr
837 /* This is a gdb extension to make it possible to
838 refer to items in other crates. It just bypasses
839 adding the current crate to the front of the
841 $$
= parser
->ast_path
(parser
->concat3
("::",
848 identifier_path_for_expr:
850 { $$
= parser
->ast_path
($1, NULL
); }
851 | identifier_path_for_expr COLONCOLON IDENT
853 $$
= parser
->ast_path
(parser
->concat3
($1->left.sval.ptr
,
857 | identifier_path_for_expr COLONCOLON
'<' type_list
'>'
858 { $$
= parser
->ast_path
($1->left.sval
, $4); }
859 | identifier_path_for_expr COLONCOLON
'<' type_list RSH
861 $$
= parser
->ast_path
($1->left.sval
, $4);
862 parser
->push_back
('>');
867 identifier_path_for_type
868 | KW_SELF COLONCOLON identifier_path_for_type
869 { $$
= parser
->super_name
($3, 0); }
870 | maybe_self_path super_path identifier_path_for_type
871 { $$
= parser
->super_name
($3, $2); }
872 | COLONCOLON identifier_path_for_type
873 { $$
= parser
->crate_name
($2); }
874 | KW_EXTERN identifier_path_for_type
876 /* This is a gdb extension to make it possible to
877 refer to items in other crates. It just bypasses
878 adding the current crate to the front of the
880 $$
= parser
->ast_path
(parser
->concat3
("::",
887 just_identifiers_for_type:
889 { $$
= parser
->ast_path
($1, NULL
); }
890 | just_identifiers_for_type COLONCOLON IDENT
892 $$
= parser
->ast_path
(parser
->concat3
($1->left.sval.ptr
,
898 identifier_path_for_type:
899 just_identifiers_for_type
900 | just_identifiers_for_type
'<' type_list
'>'
901 { $$
= parser
->ast_path
($1->left.sval
, $3); }
902 | just_identifiers_for_type
'<' type_list RSH
904 $$
= parser
->ast_path
($1->left.sval
, $3);
905 parser
->push_back
('>');
911 |
'[' type
';' INTEGER
']'
912 { $$
= parser
->ast_array_type
($2, $4); }
913 |
'[' type
';' DECIMAL_INTEGER
']'
914 { $$
= parser
->ast_array_type
($2, $4); }
916 { $$
= parser
->ast_slice_type
($3); }
918 { $$
= parser
->ast_reference_type
($2); }
920 { $$
= parser
->ast_pointer_type
($3, 1); }
922 { $$
= parser
->ast_pointer_type
($3, 0); }
923 | KW_FN
'(' maybe_type_list
')' ARROW type
924 { $$
= parser
->ast_function_type
($6, $3); }
925 |
'(' maybe_type_list
')'
926 { $$
= parser
->ast_tuple_type
($2); }
939 rust_op_vector
*result
= parser
->new_op_vector
();
940 result
->push_back
($1);
952 /* A struct of this type is used to describe a token. */
958 enum exp_opcode opcode
;
961 /* Identifier tokens. */
963 static const struct token_info identifier_tokens
[] =
965 { "as", KW_AS
, OP_NULL
},
966 { "false", KW_FALSE
, OP_NULL
},
967 { "if", 0, OP_NULL
},
968 { "mut", KW_MUT
, OP_NULL
},
969 { "const", KW_CONST
, OP_NULL
},
970 { "self", KW_SELF
, OP_NULL
},
971 { "super", KW_SUPER
, OP_NULL
},
972 { "true", KW_TRUE
, OP_NULL
},
973 { "extern", KW_EXTERN
, OP_NULL
},
974 { "fn", KW_FN
, OP_NULL
},
975 { "sizeof", KW_SIZEOF
, OP_NULL
},
978 /* Operator tokens, sorted longest first. */
980 static const struct token_info operator_tokens
[] =
982 { ">>=", COMPOUND_ASSIGN
, BINOP_RSH
},
983 { "<<=", COMPOUND_ASSIGN
, BINOP_LSH
},
985 { "<<", LSH
, OP_NULL
},
986 { ">>", RSH
, OP_NULL
},
987 { "&&", ANDAND
, OP_NULL
},
988 { "||", OROR
, OP_NULL
},
989 { "==", EQEQ
, OP_NULL
},
990 { "!=", NOTEQ
, OP_NULL
},
991 { "<=", LTEQ
, OP_NULL
},
992 { ">=", GTEQ
, OP_NULL
},
993 { "+=", COMPOUND_ASSIGN
, BINOP_ADD
},
994 { "-=", COMPOUND_ASSIGN
, BINOP_SUB
},
995 { "*=", COMPOUND_ASSIGN
, BINOP_MUL
},
996 { "/=", COMPOUND_ASSIGN
, BINOP_DIV
},
997 { "%=", COMPOUND_ASSIGN
, BINOP_REM
},
998 { "&=", COMPOUND_ASSIGN
, BINOP_BITWISE_AND
},
999 { "|=", COMPOUND_ASSIGN
, BINOP_BITWISE_IOR
},
1000 { "^=", COMPOUND_ASSIGN
, BINOP_BITWISE_XOR
},
1001 { "..=", DOTDOTEQ
, OP_NULL
},
1003 { "::", COLONCOLON
, OP_NULL
},
1004 { "..", DOTDOT
, OP_NULL
},
1005 { "->", ARROW
, OP_NULL
}
1008 /* Helper function to copy to the name obstack. */
1011 rust_parser::copy_name
(const char *name
, int len
)
1013 return
(const char *) obstack_copy0
(&obstack
, name
, len
);
1016 /* Helper function to make an stoken from a C string. */
1018 static struct stoken
1019 make_stoken
(const char *p
)
1021 struct stoken result
;
1024 result.length
= strlen
(result.ptr
);
1028 /* Helper function to concatenate three strings on the name
1032 rust_parser::concat3
(const char *s1
, const char *s2
, const char *s3
)
1034 return make_stoken
(obconcat
(&obstack
, s1
, s2
, s3
, (char *) NULL
));
1037 /* Return an AST node referring to NAME, but relative to the crate's
1040 const struct rust_op
*
1041 rust_parser::crate_name
(const struct rust_op
*name
)
1043 std
::string crate
= rust_crate_for_block
(pstate
->expression_context_block
);
1044 struct stoken result
;
1046 gdb_assert
(name
->opcode
== OP_VAR_VALUE
);
1049 error (_
("Could not find crate for current location"));
1050 result
= make_stoken
(obconcat
(&obstack
, "::", crate.c_str
(), "::",
1051 name
->left.sval.ptr
, (char *) NULL
));
1053 return ast_path
(result
, name
->right.params
);
1056 /* Create an AST node referring to a "super::" qualified name. IDENT
1057 is the base name and N_SUPERS is how many "super::"s were
1058 provided. N_SUPERS can be zero. */
1060 const struct rust_op
*
1061 rust_parser::super_name
(const struct rust_op
*ident
, unsigned int n_supers
)
1063 const char *scope
= block_scope
(pstate
->expression_context_block
);
1066 gdb_assert
(ident
->opcode
== OP_VAR_VALUE
);
1068 if
(scope
[0] == '\0')
1069 error (_
("Couldn't find namespace scope for self::"));
1074 std
::vector
<int> offsets
;
1075 unsigned int current_len
;
1077 current_len
= cp_find_first_component
(scope
);
1078 while
(scope
[current_len
] != '\0')
1080 offsets.push_back
(current_len
);
1081 gdb_assert
(scope
[current_len
] == ':');
1084 current_len
+= cp_find_first_component
(scope
1088 len
= offsets.size
();
1089 if
(n_supers
>= len
)
1090 error (_
("Too many super:: uses from '%s'"), scope
);
1092 offset
= offsets
[len
- n_supers
];
1095 offset
= strlen
(scope
);
1097 obstack_grow
(&obstack
, "::", 2);
1098 obstack_grow
(&obstack
, scope
, offset
);
1099 obstack_grow
(&obstack
, "::", 2);
1100 obstack_grow0
(&obstack
, ident
->left.sval.ptr
, ident
->left.sval.length
);
1102 return ast_path
(make_stoken
((const char *) obstack_finish
(&obstack
)),
1103 ident
->right.params
);
1106 /* A helper that updates the innermost block as appropriate. */
1109 rust_parser::update_innermost_block
(struct block_symbol sym
)
1111 if
(symbol_read_needs_frame
(sym.symbol
))
1112 pstate
->block_tracker
->update
(sym
);
1115 /* Lex a hex number with at least MIN digits and at most MAX
1119 rust_parser::lex_hex
(int min
, int max
)
1121 uint32_t result
= 0;
1123 /* We only want to stop at MAX if we're lexing a byte escape. */
1124 int check_max
= min
== max
;
1126 while
((check_max ? len
<= max
: 1)
1127 && ((pstate
->lexptr
[0] >= 'a' && pstate
->lexptr
[0] <= 'f')
1128 ||
(pstate
->lexptr
[0] >= 'A' && pstate
->lexptr
[0] <= 'F')
1129 ||
(pstate
->lexptr
[0] >= '0' && pstate
->lexptr
[0] <= '9')))
1132 if
(pstate
->lexptr
[0] >= 'a' && pstate
->lexptr
[0] <= 'f')
1133 result
= result
+ 10 + pstate
->lexptr
[0] - 'a';
1134 else if
(pstate
->lexptr
[0] >= 'A' && pstate
->lexptr
[0] <= 'F')
1135 result
= result
+ 10 + pstate
->lexptr
[0] - 'A';
1137 result
= result
+ pstate
->lexptr
[0] - '0';
1143 error (_
("Not enough hex digits seen"));
1146 gdb_assert
(min
!= max
);
1147 error (_
("Overlong hex escape"));
1153 /* Lex an escape. IS_BYTE is true if we're lexing a byte escape;
1154 otherwise we're lexing a character escape. */
1157 rust_parser::lex_escape
(int is_byte
)
1161 gdb_assert
(pstate
->lexptr
[0] == '\\');
1163 switch
(pstate
->lexptr
[0])
1167 result
= lex_hex
(2, 2);
1172 error (_
("Unicode escape in byte literal"));
1174 if
(pstate
->lexptr
[0] != '{')
1175 error (_
("Missing '{' in Unicode escape"));
1177 result
= lex_hex
(1, 6);
1178 /* Could do range checks here. */
1179 if
(pstate
->lexptr
[0] != '}')
1180 error (_
("Missing '}' in Unicode escape"));
1214 error (_
("Invalid escape \\%c in literal"), pstate
->lexptr
[0]);
1220 /* Lex a character constant. */
1223 rust_parser::lex_character
(YYSTYPE *lvalp
)
1228 if
(pstate
->lexptr
[0] == 'b')
1233 gdb_assert
(pstate
->lexptr
[0] == '\'');
1235 /* This should handle UTF-8 here. */
1236 if
(pstate
->lexptr
[0] == '\\')
1237 value
= lex_escape
(is_byte
);
1240 value
= pstate
->lexptr
[0] & 0xff;
1244 if
(pstate
->lexptr
[0] != '\'')
1245 error (_
("Unterminated character literal"));
1248 lvalp
->typed_val_int.val
= value
;
1249 lvalp
->typed_val_int.type
= get_type
(is_byte ?
"u8" : "char");
1254 /* Return the offset of the double quote if STR looks like the start
1255 of a raw string, or 0 if STR does not start a raw string. */
1258 starts_raw_string
(const char *str
)
1260 const char *save
= str
;
1265 while
(str
[0] == '#')
1272 /* Return true if STR looks like the end of a raw string that had N
1273 hashes at the start. */
1276 ends_raw_string
(const char *str
, int n
)
1280 gdb_assert
(str
[0] == '"');
1281 for
(i
= 0; i
< n
; ++i
)
1282 if
(str
[i
+ 1] != '#')
1287 /* Lex a string constant. */
1290 rust_parser::lex_string
(YYSTYPE *lvalp
)
1292 int is_byte
= pstate
->lexptr
[0] == 'b';
1297 raw_length
= starts_raw_string
(pstate
->lexptr
);
1298 pstate
->lexptr
+= raw_length
;
1299 gdb_assert
(pstate
->lexptr
[0] == '"');
1308 if
(pstate
->lexptr
[0] == '"' && ends_raw_string
(pstate
->lexptr
,
1311 /* Exit with lexptr pointing after the final "#". */
1312 pstate
->lexptr
+= raw_length
;
1315 else if
(pstate
->lexptr
[0] == '\0')
1316 error (_
("Unexpected EOF in string"));
1318 value
= pstate
->lexptr
[0] & 0xff;
1319 if
(is_byte
&& value
> 127)
1320 error (_
("Non-ASCII value in raw byte string"));
1321 obstack_1grow
(&obstack
, value
);
1325 else if
(pstate
->lexptr
[0] == '"')
1327 /* Make sure to skip the quote. */
1331 else if
(pstate
->lexptr
[0] == '\\')
1333 value
= lex_escape
(is_byte
);
1336 obstack_1grow
(&obstack
, value
);
1338 convert_between_encodings
("UTF-32", "UTF-8", (gdb_byte
*) &value
,
1339 sizeof
(value
), sizeof
(value
),
1340 &obstack
, translit_none
);
1342 else if
(pstate
->lexptr
[0] == '\0')
1343 error (_
("Unexpected EOF in string"));
1346 value
= pstate
->lexptr
[0] & 0xff;
1347 if
(is_byte
&& value
> 127)
1348 error (_
("Non-ASCII value in byte string"));
1349 obstack_1grow
(&obstack
, value
);
1354 lvalp
->sval.length
= obstack_object_size
(&obstack
);
1355 lvalp
->sval.ptr
= (const char *) obstack_finish
(&obstack
);
1356 return is_byte ? BYTESTRING
: STRING
;
1359 /* Return true if STRING starts with whitespace followed by a digit. */
1362 space_then_number
(const char *string)
1364 const char *p
= string;
1366 while
(p
[0] == ' ' || p
[0] == '\t')
1371 return
*p
>= '0' && *p
<= '9';
1374 /* Return true if C can start an identifier. */
1377 rust_identifier_start_p
(char c
)
1379 return
((c
>= 'a' && c
<= 'z')
1380 ||
(c
>= 'A' && c
<= 'Z')
1385 /* Lex an identifier. */
1388 rust_parser::lex_identifier
(YYSTYPE *lvalp
)
1390 const char *start
= pstate
->lexptr
;
1391 unsigned int length
;
1392 const struct token_info
*token
;
1394 int is_gdb_var
= pstate
->lexptr
[0] == '$';
1396 gdb_assert
(rust_identifier_start_p
(pstate
->lexptr
[0]));
1400 /* For the time being this doesn't handle Unicode rules. Non-ASCII
1401 identifiers are gated anyway. */
1402 while
((pstate
->lexptr
[0] >= 'a' && pstate
->lexptr
[0] <= 'z')
1403 ||
(pstate
->lexptr
[0] >= 'A' && pstate
->lexptr
[0] <= 'Z')
1404 || pstate
->lexptr
[0] == '_'
1405 ||
(is_gdb_var
&& pstate
->lexptr
[0] == '$')
1406 ||
(pstate
->lexptr
[0] >= '0' && pstate
->lexptr
[0] <= '9'))
1410 length
= pstate
->lexptr
- start
;
1412 for
(i
= 0; i
< ARRAY_SIZE
(identifier_tokens
); ++i
)
1414 if
(length
== strlen
(identifier_tokens
[i
].name
)
1415 && strncmp
(identifier_tokens
[i
].name
, start
, length
) == 0)
1417 token
= &identifier_tokens
[i
];
1424 if
(token
->value
== 0)
1426 /* Leave the terminating token alone. */
1427 pstate
->lexptr
= start
;
1431 else if
(token
== NULL
1432 && (strncmp
(start
, "thread", length
) == 0
1433 || strncmp
(start
, "task", length
) == 0)
1434 && space_then_number
(pstate
->lexptr
))
1436 /* "task" or "thread" followed by a number terminates the
1437 parse, per gdb rules. */
1438 pstate
->lexptr
= start
;
1442 if
(token
== NULL ||
(pstate
->parse_completion
&& pstate
->lexptr
[0] == '\0'))
1443 lvalp
->sval
= make_stoken
(copy_name
(start
, length
));
1445 if
(pstate
->parse_completion
&& pstate
->lexptr
[0] == '\0')
1447 /* Prevent rustyylex from returning two COMPLETE tokens. */
1448 pstate
->prev_lexptr
= pstate
->lexptr
;
1453 return token
->value
;
1459 /* Lex an operator. */
1462 rust_parser::lex_operator
(YYSTYPE *lvalp
)
1464 const struct token_info
*token
= NULL
;
1467 for
(i
= 0; i
< ARRAY_SIZE
(operator_tokens
); ++i
)
1469 if
(strncmp
(operator_tokens
[i
].name
, pstate
->lexptr
,
1470 strlen
(operator_tokens
[i
].name
)) == 0)
1472 pstate
->lexptr
+= strlen
(operator_tokens
[i
].name
);
1473 token
= &operator_tokens
[i
];
1480 lvalp
->opcode
= token
->opcode
;
1481 return token
->value
;
1484 return
*pstate
->lexptr
++;
1490 rust_parser::lex_number
(YYSTYPE *lvalp
)
1492 regmatch_t subexps
[NUM_SUBEXPRESSIONS
];
1495 int could_be_decimal
= 1;
1496 int implicit_i32
= 0;
1497 const char *type_name
= NULL
;
1500 int type_index
= -1;
1503 match
= regexec
(&number_regex
, pstate
->lexptr
, ARRAY_SIZE
(subexps
),
1505 /* Failure means the regexp is broken. */
1506 gdb_assert
(match
== 0);
1508 if
(subexps
[INT_TEXT
].rm_so
!= -1)
1510 /* Integer part matched. */
1512 end_index
= subexps
[INT_TEXT
].rm_eo
;
1513 if
(subexps
[INT_TYPE
].rm_so
== -1)
1520 type_index
= INT_TYPE
;
1521 could_be_decimal
= 0;
1524 else if
(subexps
[FLOAT_TYPE1
].rm_so
!= -1)
1526 /* Found floating point type suffix. */
1527 end_index
= subexps
[FLOAT_TYPE1
].rm_so
;
1528 type_index
= FLOAT_TYPE1
;
1530 else if
(subexps
[FLOAT_TYPE2
].rm_so
!= -1)
1532 /* Found floating point type suffix. */
1533 end_index
= subexps
[FLOAT_TYPE2
].rm_so
;
1534 type_index
= FLOAT_TYPE2
;
1538 /* Any other floating point match. */
1539 end_index
= subexps
[0].rm_eo
;
1543 /* We need a special case if the final character is ".". In this
1544 case we might need to parse an integer. For example, "23.f()" is
1545 a request for a trait method call, not a syntax error involving
1546 the floating point number "23.". */
1547 gdb_assert
(subexps
[0].rm_eo
> 0);
1548 if
(pstate
->lexptr
[subexps
[0].rm_eo
- 1] == '.')
1550 const char *next
= skip_spaces
(&pstate
->lexptr
[subexps
[0].rm_eo
]);
1552 if
(rust_identifier_start_p
(*next
) ||
*next
== '.')
1556 end_index
= subexps
[0].rm_eo
;
1558 could_be_decimal
= 1;
1563 /* Compute the type name if we haven't already. */
1564 std
::string type_name_holder
;
1565 if
(type_name
== NULL
)
1567 gdb_assert
(type_index
!= -1);
1568 type_name_holder
= std
::string ((pstate
->lexptr
1569 + subexps
[type_index
].rm_so
),
1570 (subexps
[type_index
].rm_eo
1571 - subexps
[type_index
].rm_so
));
1572 type_name
= type_name_holder.c_str
();
1575 /* Look up the type. */
1576 type
= get_type
(type_name
);
1578 /* Copy the text of the number and remove the "_"s. */
1580 for
(i
= 0; i
< end_index
&& pstate
->lexptr
[i
]; ++i
)
1582 if
(pstate
->lexptr
[i
] == '_')
1583 could_be_decimal
= 0;
1585 number.push_back
(pstate
->lexptr
[i
]);
1588 /* Advance past the match. */
1589 pstate
->lexptr
+= subexps
[0].rm_eo
;
1591 /* Parse the number. */
1598 if
(number
[0] == '0')
1600 if
(number
[1] == 'x')
1602 else if
(number
[1] == 'o')
1604 else if
(number
[1] == 'b')
1609 could_be_decimal
= 0;
1613 value
= strtoulst
(number.c_str
() + offset
, NULL
, radix
);
1614 if
(implicit_i32
&& value
>= ((uint64_t) 1) << 31)
1615 type
= get_type
("i64");
1617 lvalp
->typed_val_int.val
= value
;
1618 lvalp
->typed_val_int.type
= type
;
1622 lvalp
->typed_val_float.type
= type
;
1623 bool parsed
= parse_float
(number.c_str
(), number.length
(),
1624 lvalp
->typed_val_float.type
,
1625 lvalp
->typed_val_float.val
);
1626 gdb_assert
(parsed
);
1629 return is_integer ?
(could_be_decimal ? DECIMAL_INTEGER
: INTEGER
) : FLOAT
;
1635 rustyylex
(YYSTYPE *lvalp
, rust_parser
*parser
)
1637 struct parser_state
*pstate
= parser
->pstate
;
1639 /* Skip all leading whitespace. */
1640 while
(pstate
->lexptr
[0] == ' '
1641 || pstate
->lexptr
[0] == '\t'
1642 || pstate
->lexptr
[0] == '\r'
1643 || pstate
->lexptr
[0] == '\n')
1646 /* If we hit EOF and we're completing, then return COMPLETE -- maybe
1647 we're completing an empty string at the end of a field_expr.
1648 But, we don't want to return two COMPLETE tokens in a row. */
1649 if
(pstate
->lexptr
[0] == '\0' && pstate
->lexptr
== pstate
->prev_lexptr
)
1651 pstate
->prev_lexptr
= pstate
->lexptr
;
1652 if
(pstate
->lexptr
[0] == '\0')
1654 if
(pstate
->parse_completion
)
1656 lvalp
->sval
= make_stoken
("");
1662 if
(pstate
->lexptr
[0] >= '0' && pstate
->lexptr
[0] <= '9')
1663 return parser
->lex_number
(lvalp
);
1664 else if
(pstate
->lexptr
[0] == 'b' && pstate
->lexptr
[1] == '\'')
1665 return parser
->lex_character
(lvalp
);
1666 else if
(pstate
->lexptr
[0] == 'b' && pstate
->lexptr
[1] == '"')
1667 return parser
->lex_string
(lvalp
);
1668 else if
(pstate
->lexptr
[0] == 'b' && starts_raw_string
(pstate
->lexptr
+ 1))
1669 return parser
->lex_string
(lvalp
);
1670 else if
(starts_raw_string
(pstate
->lexptr
))
1671 return parser
->lex_string
(lvalp
);
1672 else if
(rust_identifier_start_p
(pstate
->lexptr
[0]))
1673 return parser
->lex_identifier
(lvalp
);
1674 else if
(pstate
->lexptr
[0] == '"')
1675 return parser
->lex_string
(lvalp
);
1676 else if
(pstate
->lexptr
[0] == '\'')
1677 return parser
->lex_character
(lvalp
);
1678 else if
(pstate
->lexptr
[0] == '}' || pstate
->lexptr
[0] == ']')
1680 /* Falls through to lex_operator. */
1681 --parser
->paren_depth
;
1683 else if
(pstate
->lexptr
[0] == '(' || pstate
->lexptr
[0] == '{')
1685 /* Falls through to lex_operator. */
1686 ++parser
->paren_depth
;
1688 else if
(pstate
->lexptr
[0] == ',' && pstate
->comma_terminates
1689 && parser
->paren_depth
== 0)
1692 return parser
->lex_operator
(lvalp
);
1695 /* Push back a single character to be re-lexed. */
1698 rust_parser::push_back
(char c
)
1700 /* Can't be called before any lexing. */
1701 gdb_assert
(pstate
->prev_lexptr
!= NULL
);
1704 gdb_assert
(*pstate
->lexptr
== c
);
1709 /* Make an arbitrary operation and fill in the fields. */
1711 const struct rust_op
*
1712 rust_parser::ast_operation
(enum exp_opcode opcode
, const struct rust_op
*left
,
1713 const struct rust_op
*right
)
1715 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1717 result
->opcode
= opcode
;
1718 result
->left.op
= left
;
1719 result
->right.op
= right
;
1724 /* Make a compound assignment operation. */
1726 const struct rust_op
*
1727 rust_parser::ast_compound_assignment
(enum exp_opcode opcode
,
1728 const struct rust_op
*left
,
1729 const struct rust_op
*right
)
1731 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1733 result
->opcode
= opcode
;
1734 result
->compound_assignment
= 1;
1735 result
->left.op
= left
;
1736 result
->right.op
= right
;
1741 /* Make a typed integer literal operation. */
1743 const struct rust_op
*
1744 rust_parser::ast_literal
(struct typed_val_int val
)
1746 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1748 result
->opcode
= OP_LONG
;
1749 result
->left.typed_val_int
= val
;
1754 /* Make a typed floating point literal operation. */
1756 const struct rust_op
*
1757 rust_parser::ast_dliteral
(struct typed_val_float val
)
1759 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1761 result
->opcode
= OP_FLOAT
;
1762 result
->left.typed_val_float
= val
;
1767 /* Make a unary operation. */
1769 const struct rust_op
*
1770 rust_parser::ast_unary
(enum exp_opcode opcode
, const struct rust_op
*expr
)
1772 return ast_operation
(opcode
, expr
, NULL
);
1775 /* Make a cast operation. */
1777 const struct rust_op
*
1778 rust_parser::ast_cast
(const struct rust_op
*expr
, const struct rust_op
*type
)
1780 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1782 result
->opcode
= UNOP_CAST
;
1783 result
->left.op
= expr
;
1784 result
->right.op
= type
;
1789 /* Make a call-like operation. This is nominally a function call, but
1790 when lowering we may discover that it actually represents the
1791 creation of a tuple struct. */
1793 const struct rust_op
*
1794 rust_parser::ast_call_ish
(enum exp_opcode opcode
, const struct rust_op
*expr
,
1795 rust_op_vector
*params
)
1797 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1799 result
->opcode
= opcode
;
1800 result
->left.op
= expr
;
1801 result
->right.params
= params
;
1806 /* Make a structure creation operation. */
1808 const struct rust_op
*
1809 rust_parser::ast_struct
(const struct rust_op
*name
, rust_set_vector
*fields
)
1811 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1813 result
->opcode
= OP_AGGREGATE
;
1814 result
->left.op
= name
;
1815 result
->right.field_inits
= fields
;
1820 /* Make an identifier path. */
1822 const struct rust_op
*
1823 rust_parser::ast_path
(struct stoken path
, rust_op_vector
*params
)
1825 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1827 result
->opcode
= OP_VAR_VALUE
;
1828 result
->left.sval
= path
;
1829 result
->right.params
= params
;
1834 /* Make a string constant operation. */
1836 const struct rust_op
*
1837 rust_parser::ast_string
(struct stoken str
)
1839 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1841 result
->opcode
= OP_STRING
;
1842 result
->left.sval
= str
;
1847 /* Make a field expression. */
1849 const struct rust_op
*
1850 rust_parser::ast_structop
(const struct rust_op
*left
, const char *name
,
1853 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1855 result
->opcode
= STRUCTOP_STRUCT
;
1856 result
->completing
= completing
;
1857 result
->left.op
= left
;
1858 result
->right.sval
= make_stoken
(name
);
1863 /* Make an anonymous struct operation, like 'x.0'. */
1865 const struct rust_op
*
1866 rust_parser::ast_structop_anonymous
(const struct rust_op
*left
,
1867 struct typed_val_int number
)
1869 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1871 result
->opcode
= STRUCTOP_ANONYMOUS
;
1872 result
->left.op
= left
;
1873 result
->right.typed_val_int
= number
;
1878 /* Make a range operation. */
1880 const struct rust_op
*
1881 rust_parser::ast_range
(const struct rust_op
*lhs
, const struct rust_op
*rhs
,
1884 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1886 result
->opcode
= OP_RANGE
;
1887 result
->inclusive
= inclusive
;
1888 result
->left.op
= lhs
;
1889 result
->right.op
= rhs
;
1894 /* A helper function to make a type-related AST node. */
1897 rust_parser::ast_basic_type
(enum type_code typecode
)
1899 struct rust_op
*result
= OBSTACK_ZALLOC
(&obstack
, struct rust_op
);
1901 result
->opcode
= OP_TYPE
;
1902 result
->typecode
= typecode
;
1906 /* Create an AST node describing an array type. */
1908 const struct rust_op
*
1909 rust_parser::ast_array_type
(const struct rust_op
*lhs
,
1910 struct typed_val_int val
)
1912 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_ARRAY
);
1914 result
->left.op
= lhs
;
1915 result
->right.typed_val_int
= val
;
1919 /* Create an AST node describing a reference type. */
1921 const struct rust_op
*
1922 rust_parser::ast_slice_type
(const struct rust_op
*type
)
1924 /* Use TYPE_CODE_COMPLEX just because it is handy. */
1925 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_COMPLEX
);
1927 result
->left.op
= type
;
1931 /* Create an AST node describing a reference type. */
1933 const struct rust_op
*
1934 rust_parser::ast_reference_type
(const struct rust_op
*type
)
1936 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_REF
);
1938 result
->left.op
= type
;
1942 /* Create an AST node describing a pointer type. */
1944 const struct rust_op
*
1945 rust_parser::ast_pointer_type
(const struct rust_op
*type
, int is_mut
)
1947 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_PTR
);
1949 result
->left.op
= type
;
1950 /* For the time being we ignore is_mut. */
1954 /* Create an AST node describing a function type. */
1956 const struct rust_op
*
1957 rust_parser::ast_function_type
(const struct rust_op
*rtype
,
1958 rust_op_vector
*params
)
1960 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_FUNC
);
1962 result
->left.op
= rtype
;
1963 result
->right.params
= params
;
1967 /* Create an AST node describing a tuple type. */
1969 const struct rust_op
*
1970 rust_parser::ast_tuple_type
(rust_op_vector
*params
)
1972 struct rust_op
*result
= ast_basic_type
(TYPE_CODE_STRUCT
);
1974 result
->left.params
= params
;
1978 /* A helper to appropriately munge NAME and BLOCK depending on the
1979 presence of a leading "::". */
1982 munge_name_and_block
(const char **name
, const struct block
**block
)
1984 /* If it is a global reference, skip the current block in favor of
1985 the static block. */
1986 if
(strncmp
(*name
, "::", 2) == 0)
1989 *block
= block_static_block
(*block
);
1993 /* Like lookup_symbol, but handles Rust namespace conventions, and
1994 doesn't require field_of_this_result. */
1997 rust_parser::lookup_symbol
(const char *name
, const struct block
*block
,
1998 const domain_enum domain
)
2000 struct block_symbol result
;
2002 munge_name_and_block
(&name
, &block
);
2004 result
= ::lookup_symbol
(name
, block
, domain
, NULL
);
2005 if
(result.symbol
!= NULL
)
2006 update_innermost_block
(result
);
2010 /* Look up a type, following Rust namespace conventions. */
2013 rust_parser::rust_lookup_type
(const char *name
, const struct block
*block
)
2015 struct block_symbol result
;
2018 munge_name_and_block
(&name
, &block
);
2020 result
= ::lookup_symbol
(name
, block
, STRUCT_DOMAIN
, NULL
);
2021 if
(result.symbol
!= NULL
)
2023 update_innermost_block
(result
);
2024 return SYMBOL_TYPE
(result.symbol
);
2027 type
= lookup_typename
(language
(), arch
(), name
, NULL
, 1);
2031 /* Last chance, try a built-in type. */
2032 return language_lookup_primitive_type
(language
(), arch
(), name
);
2035 /* Convert a vector of rust_ops representing types to a vector of
2038 std::vector
<struct type
*>
2039 rust_parser::convert_params_to_types
(rust_op_vector
*params
)
2041 std
::vector
<struct type
*> result
;
2043 if
(params
!= nullptr
)
2045 for
(const rust_op
*op
: *params
)
2046 result.push_back
(convert_ast_to_type
(op
));
2052 /* Convert a rust_op representing a type to a struct type *. */
2055 rust_parser::convert_ast_to_type
(const struct rust_op
*operation
)
2057 struct type
*type
, *result
= NULL
;
2059 if
(operation
->opcode
== OP_VAR_VALUE
)
2061 const char *varname
= convert_name
(operation
);
2063 result
= rust_lookup_type
(varname
, pstate
->expression_context_block
);
2065 error (_
("No typed name '%s' in current context"), varname
);
2069 gdb_assert
(operation
->opcode
== OP_TYPE
);
2071 switch
(operation
->typecode
)
2073 case TYPE_CODE_ARRAY
:
2074 type
= convert_ast_to_type
(operation
->left.op
);
2075 if
(operation
->right.typed_val_int.val
< 0)
2076 error (_
("Negative array length"));
2077 result
= lookup_array_range_type
(type
, 0,
2078 operation
->right.typed_val_int.val
- 1);
2081 case TYPE_CODE_COMPLEX
:
2083 struct type
*usize
= get_type
("usize");
2085 type
= convert_ast_to_type
(operation
->left.op
);
2086 result
= rust_slice_type
("&[*gdb*]", type
, usize
);
2092 /* For now we treat &x and *x identically. */
2093 type
= convert_ast_to_type
(operation
->left.op
);
2094 result
= lookup_pointer_type
(type
);
2097 case TYPE_CODE_FUNC
:
2099 std
::vector
<struct type
*> args
2100 (convert_params_to_types
(operation
->right.params
));
2101 struct type
**argtypes
= NULL
;
2103 type
= convert_ast_to_type
(operation
->left.op
);
2105 argtypes
= args.data
();
2108 = lookup_function_type_with_arguments
(type
, args.size
(),
2110 result
= lookup_pointer_type
(result
);
2114 case TYPE_CODE_STRUCT
:
2116 std
::vector
<struct type
*> args
2117 (convert_params_to_types
(operation
->left.params
));
2121 obstack_1grow
(&obstack
, '(');
2122 for
(i
= 0; i
< args.size
(); ++i
)
2124 std
::string type_name
= type_to_string
(args
[i
]);
2127 obstack_1grow
(&obstack
, ',');
2128 obstack_grow_str
(&obstack
, type_name.c_str
());
2131 obstack_grow_str0
(&obstack
, ")");
2132 name
= (const char *) obstack_finish
(&obstack
);
2134 /* We don't allow creating new tuple types (yet), but we do
2135 allow looking up existing tuple types. */
2136 result
= rust_lookup_type
(name
, pstate
->expression_context_block
);
2138 error (_
("could not find tuple type '%s'"), name
);
2143 gdb_assert_not_reached
("unhandled opcode in convert_ast_to_type");
2146 gdb_assert
(result
!= NULL
);
2150 /* A helper function to turn a rust_op representing a name into a full
2151 name. This applies generic arguments as needed. The returned name
2152 is allocated on the work obstack. */
2155 rust_parser::convert_name
(const struct rust_op
*operation
)
2159 gdb_assert
(operation
->opcode
== OP_VAR_VALUE
);
2161 if
(operation
->right.params
== NULL
)
2162 return operation
->left.sval.ptr
;
2164 std
::vector
<struct type
*> types
2165 (convert_params_to_types
(operation
->right.params
));
2167 obstack_grow_str
(&obstack
, operation
->left.sval.ptr
);
2168 obstack_1grow
(&obstack
, '<');
2169 for
(i
= 0; i
< types.size
(); ++i
)
2171 std
::string type_name
= type_to_string
(types
[i
]);
2174 obstack_1grow
(&obstack
, ',');
2176 obstack_grow_str
(&obstack
, type_name.c_str
());
2178 obstack_grow_str0
(&obstack
, ">");
2180 return
(const char *) obstack_finish
(&obstack
);
2183 /* A helper function that converts a vec of rust_ops to a gdb
2187 rust_parser::convert_params_to_expression
(rust_op_vector
*params
,
2188 const struct rust_op
*top
)
2190 for
(const rust_op
*elem
: *params
)
2191 convert_ast_to_expression
(elem
, top
);
2194 /* Lower a rust_op to a gdb expression. STATE is the parser state.
2195 OPERATION is the operation to lower. TOP is a pointer to the
2196 top-most operation; it is used to handle the special case where the
2197 top-most expression is an identifier and can be optionally lowered
2198 to OP_TYPE. WANT_TYPE is a flag indicating that, if the expression
2199 is the name of a type, then emit an OP_TYPE for it (rather than
2200 erroring). If WANT_TYPE is set, then the similar TOP handling is
2204 rust_parser::convert_ast_to_expression
(const struct rust_op
*operation
,
2205 const struct rust_op
*top
,
2208 switch
(operation
->opcode
)
2211 write_exp_elt_opcode
(pstate
, OP_LONG
);
2212 write_exp_elt_type
(pstate
, operation
->left.typed_val_int.type
);
2213 write_exp_elt_longcst
(pstate
, operation
->left.typed_val_int.val
);
2214 write_exp_elt_opcode
(pstate
, OP_LONG
);
2218 write_exp_elt_opcode
(pstate
, OP_FLOAT
);
2219 write_exp_elt_type
(pstate
, operation
->left.typed_val_float.type
);
2220 write_exp_elt_floatcst
(pstate
, operation
->left.typed_val_float.val
);
2221 write_exp_elt_opcode
(pstate
, OP_FLOAT
);
2224 case STRUCTOP_STRUCT
:
2226 convert_ast_to_expression
(operation
->left.op
, top
);
2228 if
(operation
->completing
)
2229 pstate
->mark_struct_expression
();
2230 write_exp_elt_opcode
(pstate
, STRUCTOP_STRUCT
);
2231 write_exp_string
(pstate
, operation
->right.sval
);
2232 write_exp_elt_opcode
(pstate
, STRUCTOP_STRUCT
);
2236 case STRUCTOP_ANONYMOUS
:
2238 convert_ast_to_expression
(operation
->left.op
, top
);
2240 write_exp_elt_opcode
(pstate
, STRUCTOP_ANONYMOUS
);
2241 write_exp_elt_longcst
(pstate
, operation
->right.typed_val_int.val
);
2242 write_exp_elt_opcode
(pstate
, STRUCTOP_ANONYMOUS
);
2247 convert_ast_to_expression
(operation
->left.op
, top
, true
);
2248 write_exp_elt_opcode
(pstate
, UNOP_SIZEOF
);
2253 case UNOP_COMPLEMENT
:
2256 convert_ast_to_expression
(operation
->left.op
, top
);
2257 write_exp_elt_opcode
(pstate
, operation
->opcode
);
2260 case BINOP_SUBSCRIPT
:
2267 case BINOP_BITWISE_AND
:
2268 case BINOP_BITWISE_IOR
:
2269 case BINOP_BITWISE_XOR
:
2272 case BINOP_LOGICAL_OR
:
2273 case BINOP_LOGICAL_AND
:
2275 case BINOP_NOTEQUAL
:
2282 convert_ast_to_expression
(operation
->left.op
, top
);
2283 convert_ast_to_expression
(operation
->right.op
, top
);
2284 if
(operation
->compound_assignment
)
2286 write_exp_elt_opcode
(pstate
, BINOP_ASSIGN_MODIFY
);
2287 write_exp_elt_opcode
(pstate
, operation
->opcode
);
2288 write_exp_elt_opcode
(pstate
, BINOP_ASSIGN_MODIFY
);
2291 write_exp_elt_opcode
(pstate
, operation
->opcode
);
2293 if
(operation
->compound_assignment
2294 || operation
->opcode
== BINOP_ASSIGN
)
2298 type
= language_lookup_primitive_type
(pstate
->language
(),
2302 write_exp_elt_opcode
(pstate
, OP_LONG
);
2303 write_exp_elt_type
(pstate
, type
);
2304 write_exp_elt_longcst
(pstate
, 0);
2305 write_exp_elt_opcode
(pstate
, OP_LONG
);
2307 write_exp_elt_opcode
(pstate
, BINOP_COMMA
);
2313 struct type
*type
= convert_ast_to_type
(operation
->right.op
);
2315 convert_ast_to_expression
(operation
->left.op
, top
);
2316 write_exp_elt_opcode
(pstate
, UNOP_CAST
);
2317 write_exp_elt_type
(pstate
, type
);
2318 write_exp_elt_opcode
(pstate
, UNOP_CAST
);
2324 if
(operation
->left.op
->opcode
== OP_VAR_VALUE
)
2327 const char *varname
= convert_name
(operation
->left.op
);
2329 type
= rust_lookup_type
(varname
,
2330 pstate
->expression_context_block
);
2333 /* This is actually a tuple struct expression, not a
2335 rust_op_vector
*params
= operation
->right.params
;
2337 if
(TYPE_CODE
(type
) != TYPE_CODE_NAMESPACE
)
2339 if
(!rust_tuple_struct_type_p
(type
))
2340 error (_
("Type %s is not a tuple struct"), varname
);
2342 for
(int i
= 0; i
< params
->size
(); ++i
)
2344 char *cell
= get_print_cell
();
2346 xsnprintf
(cell
, PRINT_CELL_SIZE
, "__%d", i
);
2347 write_exp_elt_opcode
(pstate
, OP_NAME
);
2348 write_exp_string
(pstate
, make_stoken
(cell
));
2349 write_exp_elt_opcode
(pstate
, OP_NAME
);
2351 convert_ast_to_expression
((*params
)[i
], top
);
2354 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2355 write_exp_elt_type
(pstate
, type
);
2356 write_exp_elt_longcst
(pstate
, 2 * params
->size
());
2357 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2362 convert_ast_to_expression
(operation
->left.op
, top
);
2363 convert_params_to_expression
(operation
->right.params
, top
);
2364 write_exp_elt_opcode
(pstate
, OP_FUNCALL
);
2365 write_exp_elt_longcst
(pstate
, operation
->right.params
->size
());
2366 write_exp_elt_longcst
(pstate
, OP_FUNCALL
);
2371 gdb_assert
(operation
->left.op
== NULL
);
2372 convert_params_to_expression
(operation
->right.params
, top
);
2373 write_exp_elt_opcode
(pstate
, OP_ARRAY
);
2374 write_exp_elt_longcst
(pstate
, 0);
2375 write_exp_elt_longcst
(pstate
, operation
->right.params
->size
() - 1);
2376 write_exp_elt_longcst
(pstate
, OP_ARRAY
);
2381 struct block_symbol sym
;
2382 const char *varname
;
2384 if
(operation
->left.sval.ptr
[0] == '$')
2386 write_dollar_variable
(pstate
, operation
->left.sval
);
2390 varname
= convert_name
(operation
);
2391 sym
= lookup_symbol
(varname
, pstate
->expression_context_block
,
2393 if
(sym.symbol
!= NULL
&& SYMBOL_CLASS
(sym.symbol
) != LOC_TYPEDEF
)
2395 write_exp_elt_opcode
(pstate
, OP_VAR_VALUE
);
2396 write_exp_elt_block
(pstate
, sym.block
);
2397 write_exp_elt_sym
(pstate
, sym.symbol
);
2398 write_exp_elt_opcode
(pstate
, OP_VAR_VALUE
);
2402 struct type
*type
= NULL
;
2404 if
(sym.symbol
!= NULL
)
2406 gdb_assert
(SYMBOL_CLASS
(sym.symbol
) == LOC_TYPEDEF
);
2407 type
= SYMBOL_TYPE
(sym.symbol
);
2410 type
= rust_lookup_type
(varname
,
2411 pstate
->expression_context_block
);
2413 error (_
("No symbol '%s' in current context"), varname
);
2416 && TYPE_CODE
(type
) == TYPE_CODE_STRUCT
2417 && TYPE_NFIELDS
(type
) == 0)
2419 /* A unit-like struct. */
2420 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2421 write_exp_elt_type
(pstate
, type
);
2422 write_exp_elt_longcst
(pstate
, 0);
2423 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2425 else if
(want_type || operation
== top
)
2427 write_exp_elt_opcode
(pstate
, OP_TYPE
);
2428 write_exp_elt_type
(pstate
, type
);
2429 write_exp_elt_opcode
(pstate
, OP_TYPE
);
2432 error (_
("Found type '%s', which can't be "
2433 "evaluated in this context"),
2442 rust_set_vector
*fields
= operation
->right.field_inits
;
2447 for
(const set_field
&init
: *fields
)
2449 if
(init.name.ptr
!= NULL
)
2451 write_exp_elt_opcode
(pstate
, OP_NAME
);
2452 write_exp_string
(pstate
, init.name
);
2453 write_exp_elt_opcode
(pstate
, OP_NAME
);
2457 convert_ast_to_expression
(init.init
, top
);
2460 if
(init.name.ptr
== NULL
)
2462 /* This is handled differently from Ada in our
2464 write_exp_elt_opcode
(pstate
, OP_OTHERS
);
2468 name
= convert_name
(operation
->left.op
);
2469 type
= rust_lookup_type
(name
, pstate
->expression_context_block
);
2471 error (_
("Could not find type '%s'"), operation
->left.sval.ptr
);
2473 if
(TYPE_CODE
(type
) != TYPE_CODE_STRUCT
2474 || rust_tuple_type_p
(type
)
2475 || rust_tuple_struct_type_p
(type
))
2476 error (_
("Struct expression applied to non-struct type"));
2478 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2479 write_exp_elt_type
(pstate
, type
);
2480 write_exp_elt_longcst
(pstate
, length
);
2481 write_exp_elt_opcode
(pstate
, OP_AGGREGATE
);
2487 write_exp_elt_opcode
(pstate
, OP_STRING
);
2488 write_exp_string
(pstate
, operation
->left.sval
);
2489 write_exp_elt_opcode
(pstate
, OP_STRING
);
2495 enum range_type kind
= BOTH_BOUND_DEFAULT
;
2497 if
(operation
->left.op
!= NULL
)
2499 convert_ast_to_expression
(operation
->left.op
, top
);
2500 kind
= HIGH_BOUND_DEFAULT
;
2502 if
(operation
->right.op
!= NULL
)
2504 convert_ast_to_expression
(operation
->right.op
, top
);
2505 if
(kind
== BOTH_BOUND_DEFAULT
)
2506 kind
= (operation
->inclusive
2507 ? LOW_BOUND_DEFAULT
: LOW_BOUND_DEFAULT_EXCLUSIVE
);
2510 gdb_assert
(kind
== HIGH_BOUND_DEFAULT
);
2511 kind
= (operation
->inclusive
2512 ? NONE_BOUND_DEFAULT
: NONE_BOUND_DEFAULT_EXCLUSIVE
);
2517 /* Nothing should make an inclusive range without an upper
2519 gdb_assert
(!operation
->inclusive
);
2522 write_exp_elt_opcode
(pstate
, OP_RANGE
);
2523 write_exp_elt_longcst
(pstate
, kind
);
2524 write_exp_elt_opcode
(pstate
, OP_RANGE
);
2529 gdb_assert_not_reached
("unhandled opcode in convert_ast_to_expression");
2535 /* The parser as exposed to gdb. */
2538 rust_parse
(struct parser_state
*state
)
2542 /* This sets various globals and also clears them on
2544 rust_parser parser
(state
);
2546 result
= rustyyparse
(&parser
);
2548 if
(!result ||
(state
->parse_completion
&& parser.rust_ast
!= NULL
))
2549 parser.convert_ast_to_expression
(parser.rust_ast
, parser.rust_ast
);
2554 /* The parser error handler. */
2557 rustyyerror
(rust_parser
*parser
, const char *msg
)
2559 const char *where
= (parser
->pstate
->prev_lexptr
2560 ? parser
->pstate
->prev_lexptr
2561 : parser
->pstate
->lexptr
);
2562 error (_
("%s in expression, near `%s'."), msg
, where
);
2569 /* Initialize the lexer for testing. */
2572 rust_lex_test_init
(rust_parser
*parser
, const char *input
)
2574 parser
->pstate
->prev_lexptr
= NULL
;
2575 parser
->pstate
->lexptr
= input
;
2576 parser
->paren_depth
= 0;
2579 /* A test helper that lexes a string, expecting a single token. It
2580 returns the lexer data for this token. */
2583 rust_lex_test_one
(rust_parser
*parser
, const char *input
, int expected
)
2588 rust_lex_test_init
(parser
, input
);
2590 token
= rustyylex
(&result
, parser
);
2591 SELF_CHECK
(token
== expected
);
2596 token
= rustyylex
(&ignore
, parser
);
2597 SELF_CHECK
(token
== 0);
2603 /* Test that INPUT lexes as the integer VALUE. */
2606 rust_lex_int_test
(rust_parser
*parser
, const char *input
,
2607 LONGEST value
, int kind
)
2609 RUSTSTYPE result
= rust_lex_test_one
(parser
, input
, kind
);
2610 SELF_CHECK
(result.typed_val_int.val
== value
);
2613 /* Test that INPUT throws an exception with text ERR. */
2616 rust_lex_exception_test
(rust_parser
*parser
, const char *input
,
2621 /* The "kind" doesn't matter. */
2622 rust_lex_test_one
(parser
, input
, DECIMAL_INTEGER
);
2625 catch
(const gdb_exception_error
&except
)
2627 SELF_CHECK
(strcmp
(except.what
(), err
) == 0);
2631 /* Test that INPUT lexes as the identifier, string, or byte-string
2632 VALUE. KIND holds the expected token kind. */
2635 rust_lex_stringish_test
(rust_parser
*parser
, const char *input
,
2636 const char *value
, int kind
)
2638 RUSTSTYPE result
= rust_lex_test_one
(parser
, input
, kind
);
2639 SELF_CHECK
(result.sval.length
== strlen
(value
));
2640 SELF_CHECK
(strncmp
(result.sval.ptr
, value
, result.sval.length
) == 0);
2643 /* Helper to test that a string parses as a given token sequence. */
2646 rust_lex_test_sequence
(rust_parser
*parser
, const char *input
, int len
,
2647 const int expected
[])
2651 parser
->pstate
->lexptr
= input
;
2652 parser
->paren_depth
= 0;
2654 for
(i
= 0; i
< len
; ++i
)
2657 int token
= rustyylex
(&ignore
, parser
);
2659 SELF_CHECK
(token
== expected
[i
]);
2663 /* Tests for an integer-parsing corner case. */
2666 rust_lex_test_trailing_dot
(rust_parser
*parser
)
2668 const int expected1
[] = { DECIMAL_INTEGER
, '.', IDENT
, '(', ')', 0 };
2669 const int expected2
[] = { INTEGER
, '.', IDENT
, '(', ')', 0 };
2670 const int expected3
[] = { FLOAT
, EQEQ
, '(', ')', 0 };
2671 const int expected4
[] = { DECIMAL_INTEGER
, DOTDOT
, DECIMAL_INTEGER
, 0 };
2673 rust_lex_test_sequence
(parser
, "23.g()", ARRAY_SIZE
(expected1
), expected1
);
2674 rust_lex_test_sequence
(parser
, "23_0.g()", ARRAY_SIZE
(expected2
),
2676 rust_lex_test_sequence
(parser
, "23.==()", ARRAY_SIZE
(expected3
),
2678 rust_lex_test_sequence
(parser
, "23..25", ARRAY_SIZE
(expected4
), expected4
);
2681 /* Tests of completion. */
2684 rust_lex_test_completion
(rust_parser
*parser
)
2686 const int expected
[] = { IDENT
, '.', COMPLETE
, 0 };
2688 parser
->pstate
->parse_completion
= 1;
2690 rust_lex_test_sequence
(parser
, "something.wha", ARRAY_SIZE
(expected
),
2692 rust_lex_test_sequence
(parser
, "something.", ARRAY_SIZE
(expected
),
2695 parser
->pstate
->parse_completion
= 0;
2698 /* Test pushback. */
2701 rust_lex_test_push_back
(rust_parser
*parser
)
2706 rust_lex_test_init
(parser
, ">>=");
2708 token
= rustyylex
(&lval
, parser
);
2709 SELF_CHECK
(token
== COMPOUND_ASSIGN
);
2710 SELF_CHECK
(lval.opcode
== BINOP_RSH
);
2712 parser
->push_back
('=');
2714 token
= rustyylex
(&lval
, parser
);
2715 SELF_CHECK
(token
== '=');
2717 token
= rustyylex
(&lval
, parser
);
2718 SELF_CHECK
(token
== 0);
2721 /* Unit test the lexer. */
2724 rust_lex_tests
(void)
2728 // Set up dummy "parser", so that rust_type works.
2729 struct parser_state ps
(&rust_language_defn
, target_gdbarch
(),
2730 nullptr
, 0, 0, nullptr
, 0, nullptr
);
2731 rust_parser parser
(&ps
);
2733 rust_lex_test_one
(&parser
, "", 0);
2734 rust_lex_test_one
(&parser
, " \t \n \r ", 0);
2735 rust_lex_test_one
(&parser
, "thread 23", 0);
2736 rust_lex_test_one
(&parser
, "task 23", 0);
2737 rust_lex_test_one
(&parser
, "th 104", 0);
2738 rust_lex_test_one
(&parser
, "ta 97", 0);
2740 rust_lex_int_test
(&parser
, "'z'", 'z', INTEGER
);
2741 rust_lex_int_test
(&parser
, "'\\xff'", 0xff, INTEGER
);
2742 rust_lex_int_test
(&parser
, "'\\u{1016f}'", 0x1016f, INTEGER
);
2743 rust_lex_int_test
(&parser
, "b'z'", 'z', INTEGER
);
2744 rust_lex_int_test
(&parser
, "b'\\xfe'", 0xfe, INTEGER
);
2745 rust_lex_int_test
(&parser
, "b'\\xFE'", 0xfe, INTEGER
);
2746 rust_lex_int_test
(&parser
, "b'\\xfE'", 0xfe, INTEGER
);
2748 /* Test all escapes in both modes. */
2749 rust_lex_int_test
(&parser
, "'\\n'", '\n', INTEGER
);
2750 rust_lex_int_test
(&parser
, "'\\r'", '\r', INTEGER
);
2751 rust_lex_int_test
(&parser
, "'\\t'", '\t', INTEGER
);
2752 rust_lex_int_test
(&parser
, "'\\\\'", '\\', INTEGER
);
2753 rust_lex_int_test
(&parser
, "'\\0'", '\0', INTEGER
);
2754 rust_lex_int_test
(&parser
, "'\\''", '\'', INTEGER
);
2755 rust_lex_int_test
(&parser
, "'\\\"'", '"', INTEGER
);
2757 rust_lex_int_test
(&parser
, "b'\\n'", '\n', INTEGER
);
2758 rust_lex_int_test
(&parser
, "b'\\r'", '\r', INTEGER
);
2759 rust_lex_int_test
(&parser
, "b'\\t'", '\t', INTEGER
);
2760 rust_lex_int_test
(&parser
, "b'\\\\'", '\\', INTEGER
);
2761 rust_lex_int_test
(&parser
, "b'\\0'", '\0', INTEGER
);
2762 rust_lex_int_test
(&parser
, "b'\\''", '\'', INTEGER
);
2763 rust_lex_int_test
(&parser
, "b'\\\"'", '"', INTEGER
);
2765 rust_lex_exception_test
(&parser
, "'z", "Unterminated character literal");
2766 rust_lex_exception_test
(&parser
, "b'\\x0'", "Not enough hex digits seen");
2767 rust_lex_exception_test
(&parser
, "b'\\u{0}'",
2768 "Unicode escape in byte literal");
2769 rust_lex_exception_test
(&parser
, "'\\x0'", "Not enough hex digits seen");
2770 rust_lex_exception_test
(&parser
, "'\\u0'", "Missing '{' in Unicode escape");
2771 rust_lex_exception_test
(&parser
, "'\\u{0", "Missing '}' in Unicode escape");
2772 rust_lex_exception_test
(&parser
, "'\\u{0000007}", "Overlong hex escape");
2773 rust_lex_exception_test
(&parser
, "'\\u{}", "Not enough hex digits seen");
2774 rust_lex_exception_test
(&parser
, "'\\Q'", "Invalid escape \\Q in literal");
2775 rust_lex_exception_test
(&parser
, "b'\\Q'", "Invalid escape \\Q in literal");
2777 rust_lex_int_test
(&parser
, "23", 23, DECIMAL_INTEGER
);
2778 rust_lex_int_test
(&parser
, "2_344__29", 234429, INTEGER
);
2779 rust_lex_int_test
(&parser
, "0x1f", 0x1f, INTEGER
);
2780 rust_lex_int_test
(&parser
, "23usize", 23, INTEGER
);
2781 rust_lex_int_test
(&parser
, "23i32", 23, INTEGER
);
2782 rust_lex_int_test
(&parser
, "0x1_f", 0x1f, INTEGER
);
2783 rust_lex_int_test
(&parser
, "0b1_101011__", 0x6b, INTEGER
);
2784 rust_lex_int_test
(&parser
, "0o001177i64", 639, INTEGER
);
2785 rust_lex_int_test
(&parser
, "0x123456789u64", 0x123456789ull
, INTEGER
);
2787 rust_lex_test_trailing_dot
(&parser
);
2789 rust_lex_test_one
(&parser
, "23.", FLOAT
);
2790 rust_lex_test_one
(&parser
, "23.99f32", FLOAT
);
2791 rust_lex_test_one
(&parser
, "23e7", FLOAT
);
2792 rust_lex_test_one
(&parser
, "23E-7", FLOAT
);
2793 rust_lex_test_one
(&parser
, "23e+7", FLOAT
);
2794 rust_lex_test_one
(&parser
, "23.99e+7f64", FLOAT
);
2795 rust_lex_test_one
(&parser
, "23.82f32", FLOAT
);
2797 rust_lex_stringish_test
(&parser
, "hibob", "hibob", IDENT
);
2798 rust_lex_stringish_test
(&parser
, "hibob__93", "hibob__93", IDENT
);
2799 rust_lex_stringish_test
(&parser
, "thread", "thread", IDENT
);
2801 rust_lex_stringish_test
(&parser
, "\"string\"", "string", STRING
);
2802 rust_lex_stringish_test
(&parser
, "\"str\\ting\"", "str\ting", STRING
);
2803 rust_lex_stringish_test
(&parser
, "\"str\\\"ing\"", "str\"ing", STRING
);
2804 rust_lex_stringish_test
(&parser
, "r\"str\\ing\"", "str\\ing", STRING
);
2805 rust_lex_stringish_test
(&parser
, "r#\"str\\ting\"#", "str\\ting", STRING
);
2806 rust_lex_stringish_test
(&parser
, "r###\"str\\\"ing\"###", "str\\\"ing",
2809 rust_lex_stringish_test
(&parser
, "b\"string\"", "string", BYTESTRING
);
2810 rust_lex_stringish_test
(&parser
, "b\"\x73tring\"", "string", BYTESTRING
);
2811 rust_lex_stringish_test
(&parser
, "b\"str\\\"ing\"", "str\"ing", BYTESTRING
);
2812 rust_lex_stringish_test
(&parser
, "br####\"\\x73tring\"####", "\\x73tring",
2815 for
(i
= 0; i
< ARRAY_SIZE
(identifier_tokens
); ++i
)
2816 rust_lex_test_one
(&parser
, identifier_tokens
[i
].name
,
2817 identifier_tokens
[i
].value
);
2819 for
(i
= 0; i
< ARRAY_SIZE
(operator_tokens
); ++i
)
2820 rust_lex_test_one
(&parser
, operator_tokens
[i
].name
,
2821 operator_tokens
[i
].value
);
2823 rust_lex_test_completion
(&parser
);
2824 rust_lex_test_push_back
(&parser
);
2827 #endif /* GDB_SELF_TEST */
2830 _initialize_rust_exp
(void)
2832 int code
= regcomp
(&number_regex
, number_regex_text
, REG_EXTENDED
);
2833 /* If the regular expression was incorrect, it was a programming
2835 gdb_assert
(code
== 0);
2838 selftests
::register_test
("rust-lex", rust_lex_tests
);