Implement Ada operator overloading
[deliverable/binutils-gdb.git] / gdb / rust-exp.y
CommitLineData
c44af4eb 1/* Bison parser for Rust expressions, for GDB.
3666a048 2 Copyright (C) 2016-2021 Free Software Foundation, Inc.
c44af4eb
TT
3
4 This file is part of GDB.
5
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.
10
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.
15
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/>. */
18
56ba65a0
TT
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. */
23%pure-parser
24%lex-param {struct rust_parser *parser}
25%parse-param {struct rust_parser *parser}
26
c44af4eb
TT
27/* Removing the last conflict seems difficult. */
28%expect 1
29
30%{
31
32#include "defs.h"
33
34#include "block.h"
35#include "charset.h"
36#include "cp-support.h"
c44af4eb
TT
37#include "gdb_obstack.h"
38#include "gdb_regex.h"
39#include "rust-lang.h"
40#include "parser-defs.h"
268a13a5 41#include "gdbsupport/selftest.h"
c44af4eb 42#include "value.h"
0d12e84c 43#include "gdbarch.h"
c1299a23
TT
44#include "rust-exp.h"
45#include <unordered_map>
c44af4eb
TT
46
47#define GDB_YY_REMAP_PREFIX rust
48#include "yy-remap.h"
49
50#define RUSTSTYPE YYSTYPE
51
c44af4eb 52struct rust_op;
3232fabd 53typedef std::vector<const struct rust_op *> rust_op_vector;
c44af4eb
TT
54
55/* A typed integer constant. */
56
57struct typed_val_int
58{
59 LONGEST val;
60 struct type *type;
61};
62
63/* A typed floating point constant. */
64
65struct typed_val_float
66{
edd079d9 67 gdb_byte val[16];
c44af4eb
TT
68 struct type *type;
69};
70
71/* An identifier and an expression. This is used to represent one
72 element of a struct initializer. */
73
74struct set_field
75{
76 struct stoken name;
77 const struct rust_op *init;
78};
79
3232fabd 80typedef std::vector<set_field> rust_set_vector;
c44af4eb 81
56ba65a0
TT
82%}
83
84%union
85{
86 /* A typed integer constant. */
87 struct typed_val_int typed_val_int;
88
89 /* A typed floating point constant. */
90 struct typed_val_float typed_val_float;
91
92 /* An identifier or string. */
93 struct stoken sval;
94
95 /* A token representing an opcode, like "==". */
96 enum exp_opcode opcode;
97
98 /* A list of expressions; for example, the arguments to a function
99 call. */
100 rust_op_vector *params;
101
102 /* A list of field initializers. */
103 rust_set_vector *field_inits;
104
105 /* A single field initializer. */
106 struct set_field one_field_init;
107
108 /* An expression. */
109 const struct rust_op *op;
110
111 /* A plain integer, for example used to count the number of
112 "super::" prefixes on a path. */
113 unsigned int depth;
114}
115
116%{
117
118struct rust_parser;
119static int rustyylex (YYSTYPE *, rust_parser *);
120static void rustyyerror (rust_parser *parser, const char *msg);
121
c44af4eb 122static struct stoken make_stoken (const char *);
c44af4eb
TT
123
124/* A regular expression for matching Rust numbers. This is split up
125 since it is very long and this gives us a way to comment the
126 sections. */
127
db92ac45 128static const char number_regex_text[] =
c44af4eb
TT
129 /* subexpression 1: allows use of alternation, otherwise uninteresting */
130 "^("
131 /* First comes floating point. */
132 /* Recognize number after the decimal point, with optional
133 exponent and optional type suffix.
134 subexpression 2: allows "?", otherwise uninteresting
135 subexpression 3: if present, type suffix
136 */
137 "[0-9][0-9_]*\\.[0-9][0-9_]*([eE][-+]?[0-9][0-9_]*)?(f32|f64)?"
138#define FLOAT_TYPE1 3
139 "|"
140 /* Recognize exponent without decimal point, with optional type
141 suffix.
142 subexpression 4: if present, type suffix
143 */
144#define FLOAT_TYPE2 4
145 "[0-9][0-9_]*[eE][-+]?[0-9][0-9_]*(f32|f64)?"
146 "|"
147 /* "23." is a valid floating point number, but "23.e5" and
148 "23.f32" are not. So, handle the trailing-. case
149 separately. */
150 "[0-9][0-9_]*\\."
151 "|"
152 /* Finally come integers.
153 subexpression 5: text of integer
154 subexpression 6: if present, type suffix
155 subexpression 7: allows use of alternation, otherwise uninteresting
156 */
157#define INT_TEXT 5
158#define INT_TYPE 6
159 "(0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*)"
160 "([iu](size|8|16|32|64))?"
161 ")";
162/* The number of subexpressions to allocate space for, including the
163 "0th" whole match subexpression. */
164#define NUM_SUBEXPRESSIONS 8
165
166/* The compiled number-matching regex. */
167
168static regex_t number_regex;
169
3232fabd
TT
170/* An instance of this is created before parsing, and destroyed when
171 parsing is finished. */
172
173struct rust_parser
174{
175 rust_parser (struct parser_state *state)
176 : rust_ast (nullptr),
177 pstate (state)
178 {
3232fabd
TT
179 }
180
181 ~rust_parser ()
182 {
3232fabd
TT
183 }
184
185 /* Create a new rust_set_vector. The storage for the new vector is
186 managed by this class. */
187 rust_set_vector *new_set_vector ()
188 {
189 rust_set_vector *result = new rust_set_vector;
190 set_vectors.push_back (std::unique_ptr<rust_set_vector> (result));
191 return result;
192 }
193
194 /* Create a new rust_ops_vector. The storage for the new vector is
195 managed by this class. */
196 rust_op_vector *new_op_vector ()
197 {
198 rust_op_vector *result = new rust_op_vector;
199 op_vectors.push_back (std::unique_ptr<rust_op_vector> (result));
200 return result;
201 }
202
203 /* Return the parser's language. */
204 const struct language_defn *language () const
205 {
73923d7e 206 return pstate->language ();
3232fabd
TT
207 }
208
209 /* Return the parser's gdbarch. */
210 struct gdbarch *arch () const
211 {
fa9f5be6 212 return pstate->gdbarch ();
3232fabd
TT
213 }
214
56ba65a0
TT
215 /* A helper to look up a Rust type, or fail. This only works for
216 types defined by rust_language_arch_info. */
217
218 struct type *get_type (const char *name)
219 {
220 struct type *type;
221
222 type = language_lookup_primitive_type (language (), arch (), name);
223 if (type == NULL)
224 error (_("Could not find Rust type %s"), name);
225 return type;
226 }
227
228 const char *copy_name (const char *name, int len);
229 struct stoken concat3 (const char *s1, const char *s2, const char *s3);
230 const struct rust_op *crate_name (const struct rust_op *name);
231 const struct rust_op *super_name (const struct rust_op *ident,
232 unsigned int n_supers);
233
234 int lex_character (YYSTYPE *lvalp);
235 int lex_number (YYSTYPE *lvalp);
236 int lex_string (YYSTYPE *lvalp);
237 int lex_identifier (YYSTYPE *lvalp);
5776fca3
TT
238 uint32_t lex_hex (int min, int max);
239 uint32_t lex_escape (int is_byte);
240 int lex_operator (YYSTYPE *lvalp);
241 void push_back (char c);
56ba65a0 242
699bd4cf
TT
243 void update_innermost_block (struct block_symbol sym);
244 struct block_symbol lookup_symbol (const char *name,
245 const struct block *block,
246 const domain_enum domain);
56ba65a0
TT
247 struct type *rust_lookup_type (const char *name, const struct block *block);
248 std::vector<struct type *> convert_params_to_types (rust_op_vector *params);
249 struct type *convert_ast_to_type (const struct rust_op *operation);
250 const char *convert_name (const struct rust_op *operation);
c1299a23
TT
251 std::vector<expr::operation_up> convert_params_to_expression
252 (rust_op_vector *params, const struct rust_op *top);
253 expr::operation_up convert_ast_to_expression (const struct rust_op *opn,
254 const struct rust_op *top,
255 bool want_type = false);
56ba65a0
TT
256
257 struct rust_op *ast_basic_type (enum type_code typecode);
258 const struct rust_op *ast_operation (enum exp_opcode opcode,
259 const struct rust_op *left,
260 const struct rust_op *right);
261 const struct rust_op *ast_compound_assignment
262 (enum exp_opcode opcode, const struct rust_op *left,
263 const struct rust_op *rust_op);
264 const struct rust_op *ast_literal (struct typed_val_int val);
265 const struct rust_op *ast_dliteral (struct typed_val_float val);
266 const struct rust_op *ast_structop (const struct rust_op *left,
267 const char *name,
268 int completing);
269 const struct rust_op *ast_structop_anonymous
270 (const struct rust_op *left, struct typed_val_int number);
271 const struct rust_op *ast_unary (enum exp_opcode opcode,
272 const struct rust_op *expr);
273 const struct rust_op *ast_cast (const struct rust_op *expr,
274 const struct rust_op *type);
275 const struct rust_op *ast_call_ish (enum exp_opcode opcode,
276 const struct rust_op *expr,
277 rust_op_vector *params);
278 const struct rust_op *ast_path (struct stoken name,
279 rust_op_vector *params);
280 const struct rust_op *ast_string (struct stoken str);
281 const struct rust_op *ast_struct (const struct rust_op *name,
282 rust_set_vector *fields);
283 const struct rust_op *ast_range (const struct rust_op *lhs,
284 const struct rust_op *rhs,
285 bool inclusive);
286 const struct rust_op *ast_array_type (const struct rust_op *lhs,
287 struct typed_val_int val);
288 const struct rust_op *ast_slice_type (const struct rust_op *type);
289 const struct rust_op *ast_reference_type (const struct rust_op *type);
290 const struct rust_op *ast_pointer_type (const struct rust_op *type,
291 int is_mut);
292 const struct rust_op *ast_function_type (const struct rust_op *result,
293 rust_op_vector *params);
294 const struct rust_op *ast_tuple_type (rust_op_vector *params);
295
296
3232fabd
TT
297 /* A pointer to this is installed globally. */
298 auto_obstack obstack;
299
300 /* Result of parsing. Points into obstack. */
301 const struct rust_op *rust_ast;
302
303 /* This keeps track of the various vectors we allocate. */
304 std::vector<std::unique_ptr<rust_set_vector>> set_vectors;
305 std::vector<std::unique_ptr<rust_op_vector>> op_vectors;
306
307 /* The parser state gdb gave us. */
308 struct parser_state *pstate;
28aaf3fd
TT
309
310 /* Depth of parentheses. */
311 int paren_depth = 0;
3232fabd 312};
c44af4eb 313
56ba65a0
TT
314/* Rust AST operations. We build a tree of these; then lower them to
315 gdb expressions when parsing has completed. */
c44af4eb
TT
316
317struct rust_op
318{
319 /* The opcode. */
320 enum exp_opcode opcode;
321 /* If OPCODE is OP_TYPE, then this holds information about what type
322 is described by this node. */
323 enum type_code typecode;
324 /* Indicates whether OPCODE actually represents a compound
325 assignment. For example, if OPCODE is GTGT and this is false,
326 then this rust_op represents an ordinary ">>"; but if this is
327 true, then this rust_op represents ">>=". Unused in other
328 cases. */
329 unsigned int compound_assignment : 1;
330 /* Only used by a field expression; if set, indicates that the field
331 name occurred at the end of the expression and is eligible for
332 completion. */
333 unsigned int completing : 1;
6873858b
TT
334 /* For OP_RANGE, indicates whether the range is inclusive or
335 exclusive. */
336 unsigned int inclusive : 1;
c44af4eb
TT
337 /* Operands of expression. Which one is used and how depends on the
338 particular opcode. */
339 RUSTSTYPE left;
340 RUSTSTYPE right;
341};
342
343%}
344
345%token <sval> GDBVAR
346%token <sval> IDENT
347%token <sval> COMPLETE
348%token <typed_val_int> INTEGER
349%token <typed_val_int> DECIMAL_INTEGER
350%token <sval> STRING
351%token <sval> BYTESTRING
352%token <typed_val_float> FLOAT
353%token <opcode> COMPOUND_ASSIGN
354
355/* Keyword tokens. */
356%token <voidval> KW_AS
357%token <voidval> KW_IF
358%token <voidval> KW_TRUE
359%token <voidval> KW_FALSE
360%token <voidval> KW_SUPER
361%token <voidval> KW_SELF
362%token <voidval> KW_MUT
363%token <voidval> KW_EXTERN
364%token <voidval> KW_CONST
365%token <voidval> KW_FN
cdf5a07c 366%token <voidval> KW_SIZEOF
c44af4eb
TT
367
368/* Operator tokens. */
369%token <voidval> DOTDOT
6873858b 370%token <voidval> DOTDOTEQ
c44af4eb
TT
371%token <voidval> OROR
372%token <voidval> ANDAND
373%token <voidval> EQEQ
374%token <voidval> NOTEQ
375%token <voidval> LTEQ
376%token <voidval> GTEQ
377%token <voidval> LSH RSH
378%token <voidval> COLONCOLON
379%token <voidval> ARROW
380
381%type <op> type
382%type <op> path_for_expr
383%type <op> identifier_path_for_expr
384%type <op> path_for_type
385%type <op> identifier_path_for_type
386%type <op> just_identifiers_for_type
387
388%type <params> maybe_type_list
389%type <params> type_list
390
391%type <depth> super_path
392
393%type <op> literal
394%type <op> expr
395%type <op> field_expr
396%type <op> idx_expr
397%type <op> unop_expr
398%type <op> binop_expr
399%type <op> binop_expr_expr
400%type <op> type_cast_expr
401%type <op> assignment_expr
402%type <op> compound_assignment_expr
403%type <op> paren_expr
404%type <op> call_expr
405%type <op> path_expr
406%type <op> tuple_expr
407%type <op> unit_expr
408%type <op> struct_expr
409%type <op> array_expr
410%type <op> range_expr
411
412%type <params> expr_list
413%type <params> maybe_expr_list
414%type <params> paren_expr_list
415
416%type <field_inits> struct_expr_list
417%type <one_field_init> struct_expr_tail
418
419/* Precedence. */
6873858b 420%nonassoc DOTDOT DOTDOTEQ
c44af4eb
TT
421%right '=' COMPOUND_ASSIGN
422%left OROR
423%left ANDAND
424%nonassoc EQEQ NOTEQ '<' '>' LTEQ GTEQ
425%left '|'
426%left '^'
427%left '&'
428%left LSH RSH
429%left '@'
430%left '+' '-'
431%left '*' '/' '%'
432/* These could be %precedence in Bison, but that isn't a yacc
433 feature. */
434%left KW_AS
435%left UNARY
436%left '[' '.' '('
437
438%%
439
440start:
441 expr
442 {
443 /* If we are completing and see a valid parse,
444 rust_ast will already have been set. */
56ba65a0
TT
445 if (parser->rust_ast == NULL)
446 parser->rust_ast = $1;
c44af4eb
TT
447 }
448;
449
450/* Note that the Rust grammar includes a method_call_expr, but we
451 handle this differently, to avoid a shift/reduce conflict with
452 call_expr. */
453expr:
454 literal
455| path_expr
456| tuple_expr
457| unit_expr
458| struct_expr
459| field_expr
460| array_expr
461| idx_expr
462| range_expr
d8344f3d
TT
463| unop_expr /* Must precede call_expr because of ambiguity with
464 sizeof. */
c44af4eb
TT
465| binop_expr
466| paren_expr
467| call_expr
468;
469
470tuple_expr:
471 '(' expr ',' maybe_expr_list ')'
472 {
3232fabd 473 $4->push_back ($2);
c44af4eb
TT
474 error (_("Tuple expressions not supported yet"));
475 }
476;
477
478unit_expr:
479 '(' ')'
480 {
481 struct typed_val_int val;
482
483 val.type
d8344f3d 484 = (language_lookup_primitive_type
56ba65a0 485 (parser->language (), parser->arch (),
d8344f3d 486 "()"));
c44af4eb 487 val.val = 0;
56ba65a0 488 $$ = parser->ast_literal (val);
c44af4eb
TT
489 }
490;
491
492/* To avoid a shift/reduce conflict with call_expr, we don't handle
493 tuple struct expressions here, but instead when examining the
494 AST. */
495struct_expr:
496 path_for_expr '{' struct_expr_list '}'
56ba65a0 497 { $$ = parser->ast_struct ($1, $3); }
c44af4eb
TT
498;
499
500struct_expr_tail:
501 DOTDOT expr
502 {
503 struct set_field sf;
504
505 sf.name.ptr = NULL;
506 sf.name.length = 0;
507 sf.init = $2;
508
509 $$ = sf;
510 }
511| IDENT ':' expr
512 {
513 struct set_field sf;
514
515 sf.name = $1;
516 sf.init = $3;
517 $$ = sf;
518 }
92630041
TT
519| IDENT
520 {
521 struct set_field sf;
522
523 sf.name = $1;
56ba65a0 524 sf.init = parser->ast_path ($1, NULL);
92630041
TT
525 $$ = sf;
526 }
c44af4eb
TT
527;
528
c44af4eb 529struct_expr_list:
12df5c00
TT
530 /* %empty */
531 {
56ba65a0 532 $$ = parser->new_set_vector ();
12df5c00
TT
533 }
534| struct_expr_tail
c44af4eb 535 {
56ba65a0 536 rust_set_vector *result = parser->new_set_vector ();
3232fabd 537 result->push_back ($1);
c44af4eb
TT
538 $$ = result;
539 }
540| IDENT ':' expr ',' struct_expr_list
541 {
542 struct set_field sf;
543
544 sf.name = $1;
545 sf.init = $3;
3232fabd 546 $5->push_back (sf);
c44af4eb
TT
547 $$ = $5;
548 }
92630041
TT
549| IDENT ',' struct_expr_list
550 {
551 struct set_field sf;
552
553 sf.name = $1;
56ba65a0 554 sf.init = parser->ast_path ($1, NULL);
92630041
TT
555 $3->push_back (sf);
556 $$ = $3;
557 }
c44af4eb
TT
558;
559
560array_expr:
561 '[' KW_MUT expr_list ']'
56ba65a0 562 { $$ = parser->ast_call_ish (OP_ARRAY, NULL, $3); }
c44af4eb 563| '[' expr_list ']'
56ba65a0 564 { $$ = parser->ast_call_ish (OP_ARRAY, NULL, $2); }
c44af4eb 565| '[' KW_MUT expr ';' expr ']'
56ba65a0 566 { $$ = parser->ast_operation (OP_RUST_ARRAY, $3, $5); }
c44af4eb 567| '[' expr ';' expr ']'
56ba65a0 568 { $$ = parser->ast_operation (OP_RUST_ARRAY, $2, $4); }
c44af4eb
TT
569;
570
571range_expr:
572 expr DOTDOT
56ba65a0 573 { $$ = parser->ast_range ($1, NULL, false); }
c44af4eb 574| expr DOTDOT expr
56ba65a0 575 { $$ = parser->ast_range ($1, $3, false); }
6873858b 576| expr DOTDOTEQ expr
56ba65a0 577 { $$ = parser->ast_range ($1, $3, true); }
c44af4eb 578| DOTDOT expr
56ba65a0 579 { $$ = parser->ast_range (NULL, $2, false); }
6873858b 580| DOTDOTEQ expr
56ba65a0 581 { $$ = parser->ast_range (NULL, $2, true); }
c44af4eb 582| DOTDOT
56ba65a0 583 { $$ = parser->ast_range (NULL, NULL, false); }
c44af4eb
TT
584;
585
586literal:
587 INTEGER
56ba65a0 588 { $$ = parser->ast_literal ($1); }
c44af4eb 589| DECIMAL_INTEGER
56ba65a0 590 { $$ = parser->ast_literal ($1); }
c44af4eb 591| FLOAT
56ba65a0 592 { $$ = parser->ast_dliteral ($1); }
c44af4eb
TT
593| STRING
594 {
c44af4eb
TT
595 struct set_field field;
596 struct typed_val_int val;
597 struct stoken token;
598
56ba65a0 599 rust_set_vector *fields = parser->new_set_vector ();
c44af4eb
TT
600
601 /* Wrap the raw string in the &str struct. */
602 field.name.ptr = "data_ptr";
603 field.name.length = strlen (field.name.ptr);
56ba65a0
TT
604 field.init = parser->ast_unary (UNOP_ADDR,
605 parser->ast_string ($1));
3232fabd 606 fields->push_back (field);
c44af4eb 607
56ba65a0 608 val.type = parser->get_type ("usize");
c44af4eb
TT
609 val.val = $1.length;
610
611 field.name.ptr = "length";
612 field.name.length = strlen (field.name.ptr);
56ba65a0 613 field.init = parser->ast_literal (val);
3232fabd 614 fields->push_back (field);
c44af4eb
TT
615
616 token.ptr = "&str";
617 token.length = strlen (token.ptr);
56ba65a0
TT
618 $$ = parser->ast_struct (parser->ast_path (token, NULL),
619 fields);
c44af4eb
TT
620 }
621| BYTESTRING
56ba65a0 622 { $$ = parser->ast_string ($1); }
c44af4eb
TT
623| KW_TRUE
624 {
625 struct typed_val_int val;
626
56ba65a0
TT
627 val.type = language_bool_type (parser->language (),
628 parser->arch ());
c44af4eb 629 val.val = 1;
56ba65a0 630 $$ = parser->ast_literal (val);
c44af4eb
TT
631 }
632| KW_FALSE
633 {
634 struct typed_val_int val;
635
56ba65a0
TT
636 val.type = language_bool_type (parser->language (),
637 parser->arch ());
c44af4eb 638 val.val = 0;
56ba65a0 639 $$ = parser->ast_literal (val);
c44af4eb
TT
640 }
641;
642
643field_expr:
644 expr '.' IDENT
56ba65a0 645 { $$ = parser->ast_structop ($1, $3.ptr, 0); }
c44af4eb
TT
646| expr '.' COMPLETE
647 {
56ba65a0
TT
648 $$ = parser->ast_structop ($1, $3.ptr, 1);
649 parser->rust_ast = $$;
c44af4eb
TT
650 }
651| expr '.' DECIMAL_INTEGER
56ba65a0 652 { $$ = parser->ast_structop_anonymous ($1, $3); }
c44af4eb
TT
653;
654
655idx_expr:
656 expr '[' expr ']'
56ba65a0 657 { $$ = parser->ast_operation (BINOP_SUBSCRIPT, $1, $3); }
c44af4eb
TT
658;
659
660unop_expr:
661 '+' expr %prec UNARY
56ba65a0 662 { $$ = parser->ast_unary (UNOP_PLUS, $2); }
c44af4eb
TT
663
664| '-' expr %prec UNARY
56ba65a0 665 { $$ = parser->ast_unary (UNOP_NEG, $2); }
c44af4eb
TT
666
667| '!' expr %prec UNARY
668 {
669 /* Note that we provide a Rust-specific evaluator
670 override for UNOP_COMPLEMENT, so it can do the
671 right thing for both bool and integral
672 values. */
56ba65a0 673 $$ = parser->ast_unary (UNOP_COMPLEMENT, $2);
c44af4eb
TT
674 }
675
676| '*' expr %prec UNARY
56ba65a0 677 { $$ = parser->ast_unary (UNOP_IND, $2); }
c44af4eb
TT
678
679| '&' expr %prec UNARY
56ba65a0 680 { $$ = parser->ast_unary (UNOP_ADDR, $2); }
c44af4eb
TT
681
682| '&' KW_MUT expr %prec UNARY
56ba65a0 683 { $$ = parser->ast_unary (UNOP_ADDR, $3); }
d8344f3d 684| KW_SIZEOF '(' expr ')' %prec UNARY
56ba65a0 685 { $$ = parser->ast_unary (UNOP_SIZEOF, $3); }
c44af4eb
TT
686;
687
688binop_expr:
689 binop_expr_expr
690| type_cast_expr
691| assignment_expr
692| compound_assignment_expr
693;
694
695binop_expr_expr:
696 expr '*' expr
56ba65a0 697 { $$ = parser->ast_operation (BINOP_MUL, $1, $3); }
c44af4eb
TT
698
699| expr '@' expr
56ba65a0 700 { $$ = parser->ast_operation (BINOP_REPEAT, $1, $3); }
c44af4eb
TT
701
702| expr '/' expr
56ba65a0 703 { $$ = parser->ast_operation (BINOP_DIV, $1, $3); }
c44af4eb
TT
704
705| expr '%' expr
56ba65a0 706 { $$ = parser->ast_operation (BINOP_REM, $1, $3); }
c44af4eb
TT
707
708| expr '<' expr
56ba65a0 709 { $$ = parser->ast_operation (BINOP_LESS, $1, $3); }
c44af4eb
TT
710
711| expr '>' expr
56ba65a0 712 { $$ = parser->ast_operation (BINOP_GTR, $1, $3); }
c44af4eb
TT
713
714| expr '&' expr
56ba65a0 715 { $$ = parser->ast_operation (BINOP_BITWISE_AND, $1, $3); }
c44af4eb
TT
716
717| expr '|' expr
56ba65a0 718 { $$ = parser->ast_operation (BINOP_BITWISE_IOR, $1, $3); }
c44af4eb
TT
719
720| expr '^' expr
56ba65a0 721 { $$ = parser->ast_operation (BINOP_BITWISE_XOR, $1, $3); }
c44af4eb
TT
722
723| expr '+' expr
56ba65a0 724 { $$ = parser->ast_operation (BINOP_ADD, $1, $3); }
c44af4eb
TT
725
726| expr '-' expr
56ba65a0 727 { $$ = parser->ast_operation (BINOP_SUB, $1, $3); }
c44af4eb
TT
728
729| expr OROR expr
56ba65a0 730 { $$ = parser->ast_operation (BINOP_LOGICAL_OR, $1, $3); }
c44af4eb
TT
731
732| expr ANDAND expr
56ba65a0 733 { $$ = parser->ast_operation (BINOP_LOGICAL_AND, $1, $3); }
c44af4eb
TT
734
735| expr EQEQ expr
56ba65a0 736 { $$ = parser->ast_operation (BINOP_EQUAL, $1, $3); }
c44af4eb
TT
737
738| expr NOTEQ expr
56ba65a0 739 { $$ = parser->ast_operation (BINOP_NOTEQUAL, $1, $3); }
c44af4eb
TT
740
741| expr LTEQ expr
56ba65a0 742 { $$ = parser->ast_operation (BINOP_LEQ, $1, $3); }
c44af4eb
TT
743
744| expr GTEQ expr
56ba65a0 745 { $$ = parser->ast_operation (BINOP_GEQ, $1, $3); }
c44af4eb
TT
746
747| expr LSH expr
56ba65a0 748 { $$ = parser->ast_operation (BINOP_LSH, $1, $3); }
c44af4eb
TT
749
750| expr RSH expr
56ba65a0 751 { $$ = parser->ast_operation (BINOP_RSH, $1, $3); }
c44af4eb
TT
752;
753
754type_cast_expr:
755 expr KW_AS type
56ba65a0 756 { $$ = parser->ast_cast ($1, $3); }
c44af4eb
TT
757;
758
759assignment_expr:
760 expr '=' expr
56ba65a0 761 { $$ = parser->ast_operation (BINOP_ASSIGN, $1, $3); }
c44af4eb
TT
762;
763
764compound_assignment_expr:
765 expr COMPOUND_ASSIGN expr
56ba65a0 766 { $$ = parser->ast_compound_assignment ($2, $1, $3); }
c44af4eb
TT
767
768;
769
770paren_expr:
771 '(' expr ')'
772 { $$ = $2; }
773;
774
775expr_list:
776 expr
777 {
56ba65a0 778 $$ = parser->new_op_vector ();
3232fabd 779 $$->push_back ($1);
c44af4eb
TT
780 }
781| expr_list ',' expr
782 {
3232fabd 783 $1->push_back ($3);
c44af4eb
TT
784 $$ = $1;
785 }
786;
787
788maybe_expr_list:
789 /* %empty */
790 {
791 /* The result can't be NULL. */
56ba65a0 792 $$ = parser->new_op_vector ();
c44af4eb
TT
793 }
794| expr_list
795 { $$ = $1; }
796;
797
798paren_expr_list:
d8344f3d 799 '(' maybe_expr_list ')'
c44af4eb
TT
800 { $$ = $2; }
801;
802
803call_expr:
804 expr paren_expr_list
56ba65a0 805 { $$ = parser->ast_call_ish (OP_FUNCALL, $1, $2); }
c44af4eb
TT
806;
807
808maybe_self_path:
809 /* %empty */
810| KW_SELF COLONCOLON
811;
812
813super_path:
814 KW_SUPER COLONCOLON
815 { $$ = 1; }
816| super_path KW_SUPER COLONCOLON
817 { $$ = $1 + 1; }
818;
819
820path_expr:
821 path_for_expr
822 { $$ = $1; }
823| GDBVAR
56ba65a0 824 { $$ = parser->ast_path ($1, NULL); }
c44af4eb 825| KW_SELF
56ba65a0 826 { $$ = parser->ast_path (make_stoken ("self"), NULL); }
c44af4eb
TT
827;
828
829path_for_expr:
830 identifier_path_for_expr
831| KW_SELF COLONCOLON identifier_path_for_expr
56ba65a0 832 { $$ = parser->super_name ($3, 0); }
c44af4eb 833| maybe_self_path super_path identifier_path_for_expr
56ba65a0 834 { $$ = parser->super_name ($3, $2); }
c44af4eb 835| COLONCOLON identifier_path_for_expr
56ba65a0 836 { $$ = parser->crate_name ($2); }
c44af4eb
TT
837| KW_EXTERN identifier_path_for_expr
838 {
839 /* This is a gdb extension to make it possible to
840 refer to items in other crates. It just bypasses
841 adding the current crate to the front of the
842 name. */
56ba65a0
TT
843 $$ = parser->ast_path (parser->concat3 ("::",
844 $2->left.sval.ptr,
845 NULL),
846 $2->right.params);
c44af4eb
TT
847 }
848;
849
850identifier_path_for_expr:
851 IDENT
56ba65a0 852 { $$ = parser->ast_path ($1, NULL); }
c44af4eb
TT
853| identifier_path_for_expr COLONCOLON IDENT
854 {
56ba65a0
TT
855 $$ = parser->ast_path (parser->concat3 ($1->left.sval.ptr,
856 "::", $3.ptr),
857 NULL);
c44af4eb
TT
858 }
859| identifier_path_for_expr COLONCOLON '<' type_list '>'
56ba65a0 860 { $$ = parser->ast_path ($1->left.sval, $4); }
c44af4eb
TT
861| identifier_path_for_expr COLONCOLON '<' type_list RSH
862 {
56ba65a0 863 $$ = parser->ast_path ($1->left.sval, $4);
5776fca3 864 parser->push_back ('>');
c44af4eb
TT
865 }
866;
867
868path_for_type:
869 identifier_path_for_type
870| KW_SELF COLONCOLON identifier_path_for_type
56ba65a0 871 { $$ = parser->super_name ($3, 0); }
c44af4eb 872| maybe_self_path super_path identifier_path_for_type
56ba65a0 873 { $$ = parser->super_name ($3, $2); }
c44af4eb 874| COLONCOLON identifier_path_for_type
56ba65a0 875 { $$ = parser->crate_name ($2); }
c44af4eb
TT
876| KW_EXTERN identifier_path_for_type
877 {
878 /* This is a gdb extension to make it possible to
879 refer to items in other crates. It just bypasses
880 adding the current crate to the front of the
881 name. */
56ba65a0
TT
882 $$ = parser->ast_path (parser->concat3 ("::",
883 $2->left.sval.ptr,
884 NULL),
885 $2->right.params);
c44af4eb
TT
886 }
887;
888
889just_identifiers_for_type:
890 IDENT
56ba65a0 891 { $$ = parser->ast_path ($1, NULL); }
c44af4eb
TT
892| just_identifiers_for_type COLONCOLON IDENT
893 {
56ba65a0
TT
894 $$ = parser->ast_path (parser->concat3 ($1->left.sval.ptr,
895 "::", $3.ptr),
896 NULL);
c44af4eb
TT
897 }
898;
899
900identifier_path_for_type:
901 just_identifiers_for_type
902| just_identifiers_for_type '<' type_list '>'
56ba65a0 903 { $$ = parser->ast_path ($1->left.sval, $3); }
c44af4eb
TT
904| just_identifiers_for_type '<' type_list RSH
905 {
56ba65a0 906 $$ = parser->ast_path ($1->left.sval, $3);
5776fca3 907 parser->push_back ('>');
c44af4eb
TT
908 }
909;
910
911type:
912 path_for_type
913| '[' type ';' INTEGER ']'
56ba65a0 914 { $$ = parser->ast_array_type ($2, $4); }
c44af4eb 915| '[' type ';' DECIMAL_INTEGER ']'
56ba65a0 916 { $$ = parser->ast_array_type ($2, $4); }
c44af4eb 917| '&' '[' type ']'
56ba65a0 918 { $$ = parser->ast_slice_type ($3); }
c44af4eb 919| '&' type
56ba65a0 920 { $$ = parser->ast_reference_type ($2); }
c44af4eb 921| '*' KW_MUT type
56ba65a0 922 { $$ = parser->ast_pointer_type ($3, 1); }
c44af4eb 923| '*' KW_CONST type
56ba65a0 924 { $$ = parser->ast_pointer_type ($3, 0); }
c44af4eb 925| KW_FN '(' maybe_type_list ')' ARROW type
56ba65a0 926 { $$ = parser->ast_function_type ($6, $3); }
c44af4eb 927| '(' maybe_type_list ')'
56ba65a0 928 { $$ = parser->ast_tuple_type ($2); }
c44af4eb
TT
929;
930
931maybe_type_list:
932 /* %empty */
933 { $$ = NULL; }
934| type_list
935 { $$ = $1; }
936;
937
938type_list:
939 type
940 {
56ba65a0 941 rust_op_vector *result = parser->new_op_vector ();
3232fabd 942 result->push_back ($1);
c44af4eb
TT
943 $$ = result;
944 }
945| type_list ',' type
946 {
3232fabd 947 $1->push_back ($3);
c44af4eb
TT
948 $$ = $1;
949 }
950;
951
952%%
953
954/* A struct of this type is used to describe a token. */
955
956struct token_info
957{
958 const char *name;
959 int value;
960 enum exp_opcode opcode;
961};
962
963/* Identifier tokens. */
964
965static const struct token_info identifier_tokens[] =
966{
967 { "as", KW_AS, OP_NULL },
968 { "false", KW_FALSE, OP_NULL },
969 { "if", 0, OP_NULL },
970 { "mut", KW_MUT, OP_NULL },
971 { "const", KW_CONST, OP_NULL },
972 { "self", KW_SELF, OP_NULL },
973 { "super", KW_SUPER, OP_NULL },
974 { "true", KW_TRUE, OP_NULL },
975 { "extern", KW_EXTERN, OP_NULL },
976 { "fn", KW_FN, OP_NULL },
cdf5a07c 977 { "sizeof", KW_SIZEOF, OP_NULL },
c44af4eb
TT
978};
979
980/* Operator tokens, sorted longest first. */
981
982static const struct token_info operator_tokens[] =
983{
984 { ">>=", COMPOUND_ASSIGN, BINOP_RSH },
985 { "<<=", COMPOUND_ASSIGN, BINOP_LSH },
986
987 { "<<", LSH, OP_NULL },
988 { ">>", RSH, OP_NULL },
989 { "&&", ANDAND, OP_NULL },
990 { "||", OROR, OP_NULL },
991 { "==", EQEQ, OP_NULL },
992 { "!=", NOTEQ, OP_NULL },
993 { "<=", LTEQ, OP_NULL },
994 { ">=", GTEQ, OP_NULL },
995 { "+=", COMPOUND_ASSIGN, BINOP_ADD },
996 { "-=", COMPOUND_ASSIGN, BINOP_SUB },
997 { "*=", COMPOUND_ASSIGN, BINOP_MUL },
998 { "/=", COMPOUND_ASSIGN, BINOP_DIV },
999 { "%=", COMPOUND_ASSIGN, BINOP_REM },
1000 { "&=", COMPOUND_ASSIGN, BINOP_BITWISE_AND },
1001 { "|=", COMPOUND_ASSIGN, BINOP_BITWISE_IOR },
1002 { "^=", COMPOUND_ASSIGN, BINOP_BITWISE_XOR },
6873858b 1003 { "..=", DOTDOTEQ, OP_NULL },
c44af4eb
TT
1004
1005 { "::", COLONCOLON, OP_NULL },
1006 { "..", DOTDOT, OP_NULL },
1007 { "->", ARROW, OP_NULL }
1008};
1009
1010/* Helper function to copy to the name obstack. */
1011
56ba65a0
TT
1012const char *
1013rust_parser::copy_name (const char *name, int len)
c44af4eb 1014{
0cf9feb9 1015 return obstack_strndup (&obstack, name, len);
c44af4eb
TT
1016}
1017
1018/* Helper function to make an stoken from a C string. */
1019
1020static struct stoken
1021make_stoken (const char *p)
1022{
1023 struct stoken result;
1024
1025 result.ptr = p;
1026 result.length = strlen (result.ptr);
1027 return result;
1028}
1029
1030/* Helper function to concatenate three strings on the name
1031 obstack. */
1032
56ba65a0
TT
1033struct stoken
1034rust_parser::concat3 (const char *s1, const char *s2, const char *s3)
c44af4eb 1035{
56ba65a0 1036 return make_stoken (obconcat (&obstack, s1, s2, s3, (char *) NULL));
c44af4eb
TT
1037}
1038
1039/* Return an AST node referring to NAME, but relative to the crate's
1040 name. */
1041
56ba65a0
TT
1042const struct rust_op *
1043rust_parser::crate_name (const struct rust_op *name)
c44af4eb 1044{
1e58a4a4 1045 std::string crate = rust_crate_for_block (pstate->expression_context_block);
c44af4eb
TT
1046 struct stoken result;
1047
1048 gdb_assert (name->opcode == OP_VAR_VALUE);
1049
03c85b11 1050 if (crate.empty ())
c44af4eb 1051 error (_("Could not find crate for current location"));
56ba65a0 1052 result = make_stoken (obconcat (&obstack, "::", crate.c_str (), "::",
c44af4eb 1053 name->left.sval.ptr, (char *) NULL));
c44af4eb
TT
1054
1055 return ast_path (result, name->right.params);
1056}
1057
1058/* Create an AST node referring to a "super::" qualified name. IDENT
1059 is the base name and N_SUPERS is how many "super::"s were
1060 provided. N_SUPERS can be zero. */
1061
56ba65a0
TT
1062const struct rust_op *
1063rust_parser::super_name (const struct rust_op *ident, unsigned int n_supers)
c44af4eb 1064{
1e58a4a4 1065 const char *scope = block_scope (pstate->expression_context_block);
c44af4eb
TT
1066 int offset;
1067
1068 gdb_assert (ident->opcode == OP_VAR_VALUE);
1069
1070 if (scope[0] == '\0')
1071 error (_("Couldn't find namespace scope for self::"));
1072
1073 if (n_supers > 0)
1074 {
c44af4eb 1075 int len;
8001f118 1076 std::vector<int> offsets;
78cc6c2d 1077 unsigned int current_len;
c44af4eb 1078
c44af4eb 1079 current_len = cp_find_first_component (scope);
c44af4eb
TT
1080 while (scope[current_len] != '\0')
1081 {
8001f118 1082 offsets.push_back (current_len);
c44af4eb 1083 gdb_assert (scope[current_len] == ':');
c44af4eb
TT
1084 /* The "::". */
1085 current_len += 2;
1086 current_len += cp_find_first_component (scope
1087 + current_len);
1088 }
1089
8001f118 1090 len = offsets.size ();
c44af4eb
TT
1091 if (n_supers >= len)
1092 error (_("Too many super:: uses from '%s'"), scope);
1093
8001f118 1094 offset = offsets[len - n_supers];
c44af4eb
TT
1095 }
1096 else
1097 offset = strlen (scope);
1098
56ba65a0
TT
1099 obstack_grow (&obstack, "::", 2);
1100 obstack_grow (&obstack, scope, offset);
1101 obstack_grow (&obstack, "::", 2);
1102 obstack_grow0 (&obstack, ident->left.sval.ptr, ident->left.sval.length);
c44af4eb 1103
56ba65a0 1104 return ast_path (make_stoken ((const char *) obstack_finish (&obstack)),
c44af4eb
TT
1105 ident->right.params);
1106}
1107
aee1fcdf 1108/* A helper that updates the innermost block as appropriate. */
c44af4eb 1109
699bd4cf
TT
1110void
1111rust_parser::update_innermost_block (struct block_symbol sym)
c44af4eb 1112{
aee1fcdf 1113 if (symbol_read_needs_frame (sym.symbol))
699bd4cf 1114 pstate->block_tracker->update (sym);
c44af4eb
TT
1115}
1116
c44af4eb
TT
1117/* Lex a hex number with at least MIN digits and at most MAX
1118 digits. */
1119
5776fca3
TT
1120uint32_t
1121rust_parser::lex_hex (int min, int max)
c44af4eb
TT
1122{
1123 uint32_t result = 0;
1124 int len = 0;
1125 /* We only want to stop at MAX if we're lexing a byte escape. */
1126 int check_max = min == max;
1127
1128 while ((check_max ? len <= max : 1)
5776fca3
TT
1129 && ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'f')
1130 || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'F')
1131 || (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')))
c44af4eb
TT
1132 {
1133 result *= 16;
5776fca3
TT
1134 if (pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'f')
1135 result = result + 10 + pstate->lexptr[0] - 'a';
1136 else if (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'F')
1137 result = result + 10 + pstate->lexptr[0] - 'A';
c44af4eb 1138 else
5776fca3
TT
1139 result = result + pstate->lexptr[0] - '0';
1140 ++pstate->lexptr;
c44af4eb
TT
1141 ++len;
1142 }
1143
1144 if (len < min)
1145 error (_("Not enough hex digits seen"));
1146 if (len > max)
1147 {
1148 gdb_assert (min != max);
1149 error (_("Overlong hex escape"));
1150 }
1151
1152 return result;
1153}
1154
1155/* Lex an escape. IS_BYTE is true if we're lexing a byte escape;
1156 otherwise we're lexing a character escape. */
1157
5776fca3
TT
1158uint32_t
1159rust_parser::lex_escape (int is_byte)
c44af4eb
TT
1160{
1161 uint32_t result;
1162
5776fca3
TT
1163 gdb_assert (pstate->lexptr[0] == '\\');
1164 ++pstate->lexptr;
1165 switch (pstate->lexptr[0])
c44af4eb
TT
1166 {
1167 case 'x':
5776fca3 1168 ++pstate->lexptr;
c44af4eb
TT
1169 result = lex_hex (2, 2);
1170 break;
1171
1172 case 'u':
1173 if (is_byte)
1174 error (_("Unicode escape in byte literal"));
5776fca3
TT
1175 ++pstate->lexptr;
1176 if (pstate->lexptr[0] != '{')
c44af4eb 1177 error (_("Missing '{' in Unicode escape"));
5776fca3 1178 ++pstate->lexptr;
c44af4eb
TT
1179 result = lex_hex (1, 6);
1180 /* Could do range checks here. */
5776fca3 1181 if (pstate->lexptr[0] != '}')
c44af4eb 1182 error (_("Missing '}' in Unicode escape"));
5776fca3 1183 ++pstate->lexptr;
c44af4eb
TT
1184 break;
1185
1186 case 'n':
1187 result = '\n';
5776fca3 1188 ++pstate->lexptr;
c44af4eb
TT
1189 break;
1190 case 'r':
1191 result = '\r';
5776fca3 1192 ++pstate->lexptr;
c44af4eb
TT
1193 break;
1194 case 't':
1195 result = '\t';
5776fca3 1196 ++pstate->lexptr;
c44af4eb
TT
1197 break;
1198 case '\\':
1199 result = '\\';
5776fca3 1200 ++pstate->lexptr;
c44af4eb
TT
1201 break;
1202 case '0':
1203 result = '\0';
5776fca3 1204 ++pstate->lexptr;
c44af4eb
TT
1205 break;
1206 case '\'':
1207 result = '\'';
5776fca3 1208 ++pstate->lexptr;
c44af4eb
TT
1209 break;
1210 case '"':
1211 result = '"';
5776fca3 1212 ++pstate->lexptr;
c44af4eb
TT
1213 break;
1214
1215 default:
5776fca3 1216 error (_("Invalid escape \\%c in literal"), pstate->lexptr[0]);
c44af4eb
TT
1217 }
1218
1219 return result;
1220}
1221
1222/* Lex a character constant. */
1223
56ba65a0
TT
1224int
1225rust_parser::lex_character (YYSTYPE *lvalp)
c44af4eb
TT
1226{
1227 int is_byte = 0;
1228 uint32_t value;
1229
5776fca3 1230 if (pstate->lexptr[0] == 'b')
c44af4eb
TT
1231 {
1232 is_byte = 1;
5776fca3 1233 ++pstate->lexptr;
c44af4eb 1234 }
5776fca3
TT
1235 gdb_assert (pstate->lexptr[0] == '\'');
1236 ++pstate->lexptr;
c44af4eb 1237 /* This should handle UTF-8 here. */
5776fca3 1238 if (pstate->lexptr[0] == '\\')
c44af4eb
TT
1239 value = lex_escape (is_byte);
1240 else
1241 {
5776fca3
TT
1242 value = pstate->lexptr[0] & 0xff;
1243 ++pstate->lexptr;
c44af4eb
TT
1244 }
1245
5776fca3 1246 if (pstate->lexptr[0] != '\'')
c44af4eb 1247 error (_("Unterminated character literal"));
5776fca3 1248 ++pstate->lexptr;
c44af4eb 1249
56ba65a0
TT
1250 lvalp->typed_val_int.val = value;
1251 lvalp->typed_val_int.type = get_type (is_byte ? "u8" : "char");
c44af4eb
TT
1252
1253 return INTEGER;
1254}
1255
1256/* Return the offset of the double quote if STR looks like the start
1257 of a raw string, or 0 if STR does not start a raw string. */
1258
1259static int
1260starts_raw_string (const char *str)
1261{
1262 const char *save = str;
1263
1264 if (str[0] != 'r')
1265 return 0;
1266 ++str;
1267 while (str[0] == '#')
1268 ++str;
1269 if (str[0] == '"')
1270 return str - save;
1271 return 0;
1272}
1273
1274/* Return true if STR looks like the end of a raw string that had N
1275 hashes at the start. */
1276
65c40c95 1277static bool
c44af4eb
TT
1278ends_raw_string (const char *str, int n)
1279{
1280 int i;
1281
1282 gdb_assert (str[0] == '"');
1283 for (i = 0; i < n; ++i)
1284 if (str[i + 1] != '#')
65c40c95
TT
1285 return false;
1286 return true;
c44af4eb
TT
1287}
1288
1289/* Lex a string constant. */
1290
56ba65a0
TT
1291int
1292rust_parser::lex_string (YYSTYPE *lvalp)
c44af4eb 1293{
5776fca3 1294 int is_byte = pstate->lexptr[0] == 'b';
c44af4eb 1295 int raw_length;
c44af4eb
TT
1296
1297 if (is_byte)
5776fca3
TT
1298 ++pstate->lexptr;
1299 raw_length = starts_raw_string (pstate->lexptr);
1300 pstate->lexptr += raw_length;
1301 gdb_assert (pstate->lexptr[0] == '"');
1302 ++pstate->lexptr;
c44af4eb
TT
1303
1304 while (1)
1305 {
1306 uint32_t value;
1307
1308 if (raw_length > 0)
1309 {
5776fca3
TT
1310 if (pstate->lexptr[0] == '"' && ends_raw_string (pstate->lexptr,
1311 raw_length - 1))
c44af4eb
TT
1312 {
1313 /* Exit with lexptr pointing after the final "#". */
5776fca3 1314 pstate->lexptr += raw_length;
c44af4eb
TT
1315 break;
1316 }
5776fca3 1317 else if (pstate->lexptr[0] == '\0')
c44af4eb
TT
1318 error (_("Unexpected EOF in string"));
1319
5776fca3 1320 value = pstate->lexptr[0] & 0xff;
c44af4eb
TT
1321 if (is_byte && value > 127)
1322 error (_("Non-ASCII value in raw byte string"));
56ba65a0 1323 obstack_1grow (&obstack, value);
c44af4eb 1324
5776fca3 1325 ++pstate->lexptr;
c44af4eb 1326 }
5776fca3 1327 else if (pstate->lexptr[0] == '"')
c44af4eb
TT
1328 {
1329 /* Make sure to skip the quote. */
5776fca3 1330 ++pstate->lexptr;
c44af4eb
TT
1331 break;
1332 }
5776fca3 1333 else if (pstate->lexptr[0] == '\\')
c44af4eb
TT
1334 {
1335 value = lex_escape (is_byte);
1336
1337 if (is_byte)
56ba65a0 1338 obstack_1grow (&obstack, value);
c44af4eb
TT
1339 else
1340 convert_between_encodings ("UTF-32", "UTF-8", (gdb_byte *) &value,
1341 sizeof (value), sizeof (value),
56ba65a0 1342 &obstack, translit_none);
c44af4eb 1343 }
5776fca3 1344 else if (pstate->lexptr[0] == '\0')
c44af4eb
TT
1345 error (_("Unexpected EOF in string"));
1346 else
1347 {
5776fca3 1348 value = pstate->lexptr[0] & 0xff;
c44af4eb
TT
1349 if (is_byte && value > 127)
1350 error (_("Non-ASCII value in byte string"));
56ba65a0 1351 obstack_1grow (&obstack, value);
5776fca3 1352 ++pstate->lexptr;
c44af4eb
TT
1353 }
1354 }
1355
56ba65a0
TT
1356 lvalp->sval.length = obstack_object_size (&obstack);
1357 lvalp->sval.ptr = (const char *) obstack_finish (&obstack);
c44af4eb
TT
1358 return is_byte ? BYTESTRING : STRING;
1359}
1360
1361/* Return true if STRING starts with whitespace followed by a digit. */
1362
65c40c95 1363static bool
c44af4eb
TT
1364space_then_number (const char *string)
1365{
1366 const char *p = string;
1367
1368 while (p[0] == ' ' || p[0] == '\t')
1369 ++p;
1370 if (p == string)
65c40c95 1371 return false;
c44af4eb
TT
1372
1373 return *p >= '0' && *p <= '9';
1374}
1375
1376/* Return true if C can start an identifier. */
1377
65c40c95 1378static bool
c44af4eb
TT
1379rust_identifier_start_p (char c)
1380{
1381 return ((c >= 'a' && c <= 'z')
1382 || (c >= 'A' && c <= 'Z')
1383 || c == '_'
1384 || c == '$');
1385}
1386
1387/* Lex an identifier. */
1388
56ba65a0
TT
1389int
1390rust_parser::lex_identifier (YYSTYPE *lvalp)
c44af4eb 1391{
5776fca3 1392 const char *start = pstate->lexptr;
c44af4eb
TT
1393 unsigned int length;
1394 const struct token_info *token;
1395 int i;
5776fca3 1396 int is_gdb_var = pstate->lexptr[0] == '$';
c44af4eb 1397
5776fca3 1398 gdb_assert (rust_identifier_start_p (pstate->lexptr[0]));
c44af4eb 1399
5776fca3 1400 ++pstate->lexptr;
c44af4eb
TT
1401
1402 /* For the time being this doesn't handle Unicode rules. Non-ASCII
1403 identifiers are gated anyway. */
5776fca3
TT
1404 while ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'z')
1405 || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'Z')
1406 || pstate->lexptr[0] == '_'
1407 || (is_gdb_var && pstate->lexptr[0] == '$')
1408 || (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9'))
1409 ++pstate->lexptr;
c44af4eb
TT
1410
1411
5776fca3 1412 length = pstate->lexptr - start;
c44af4eb
TT
1413 token = NULL;
1414 for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
1415 {
1416 if (length == strlen (identifier_tokens[i].name)
1417 && strncmp (identifier_tokens[i].name, start, length) == 0)
1418 {
1419 token = &identifier_tokens[i];
1420 break;
1421 }
1422 }
1423
1424 if (token != NULL)
1425 {
1426 if (token->value == 0)
1427 {
1428 /* Leave the terminating token alone. */
5776fca3 1429 pstate->lexptr = start;
c44af4eb
TT
1430 return 0;
1431 }
1432 }
1433 else if (token == NULL
1434 && (strncmp (start, "thread", length) == 0
1435 || strncmp (start, "task", length) == 0)
5776fca3 1436 && space_then_number (pstate->lexptr))
c44af4eb
TT
1437 {
1438 /* "task" or "thread" followed by a number terminates the
1439 parse, per gdb rules. */
5776fca3 1440 pstate->lexptr = start;
c44af4eb
TT
1441 return 0;
1442 }
1443
2a612529 1444 if (token == NULL || (pstate->parse_completion && pstate->lexptr[0] == '\0'))
56ba65a0 1445 lvalp->sval = make_stoken (copy_name (start, length));
c44af4eb 1446
2a612529 1447 if (pstate->parse_completion && pstate->lexptr[0] == '\0')
c44af4eb
TT
1448 {
1449 /* Prevent rustyylex from returning two COMPLETE tokens. */
5776fca3 1450 pstate->prev_lexptr = pstate->lexptr;
c44af4eb
TT
1451 return COMPLETE;
1452 }
1453
1454 if (token != NULL)
1455 return token->value;
1456 if (is_gdb_var)
1457 return GDBVAR;
1458 return IDENT;
1459}
1460
1461/* Lex an operator. */
1462
5776fca3
TT
1463int
1464rust_parser::lex_operator (YYSTYPE *lvalp)
c44af4eb
TT
1465{
1466 const struct token_info *token = NULL;
1467 int i;
1468
1469 for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
1470 {
5776fca3 1471 if (strncmp (operator_tokens[i].name, pstate->lexptr,
c44af4eb
TT
1472 strlen (operator_tokens[i].name)) == 0)
1473 {
5776fca3 1474 pstate->lexptr += strlen (operator_tokens[i].name);
c44af4eb
TT
1475 token = &operator_tokens[i];
1476 break;
1477 }
1478 }
1479
1480 if (token != NULL)
1481 {
56ba65a0 1482 lvalp->opcode = token->opcode;
c44af4eb
TT
1483 return token->value;
1484 }
1485
5776fca3 1486 return *pstate->lexptr++;
c44af4eb
TT
1487}
1488
1489/* Lex a number. */
1490
56ba65a0
TT
1491int
1492rust_parser::lex_number (YYSTYPE *lvalp)
c44af4eb
TT
1493{
1494 regmatch_t subexps[NUM_SUBEXPRESSIONS];
1495 int match;
1496 int is_integer = 0;
1497 int could_be_decimal = 1;
347dc102 1498 int implicit_i32 = 0;
8001f118 1499 const char *type_name = NULL;
c44af4eb
TT
1500 struct type *type;
1501 int end_index;
1502 int type_index = -1;
8001f118 1503 int i;
c44af4eb 1504
5776fca3
TT
1505 match = regexec (&number_regex, pstate->lexptr, ARRAY_SIZE (subexps),
1506 subexps, 0);
c44af4eb
TT
1507 /* Failure means the regexp is broken. */
1508 gdb_assert (match == 0);
1509
1510 if (subexps[INT_TEXT].rm_so != -1)
1511 {
1512 /* Integer part matched. */
1513 is_integer = 1;
1514 end_index = subexps[INT_TEXT].rm_eo;
1515 if (subexps[INT_TYPE].rm_so == -1)
347dc102
TT
1516 {
1517 type_name = "i32";
1518 implicit_i32 = 1;
1519 }
c44af4eb
TT
1520 else
1521 {
1522 type_index = INT_TYPE;
1523 could_be_decimal = 0;
1524 }
1525 }
1526 else if (subexps[FLOAT_TYPE1].rm_so != -1)
1527 {
1528 /* Found floating point type suffix. */
1529 end_index = subexps[FLOAT_TYPE1].rm_so;
1530 type_index = FLOAT_TYPE1;
1531 }
1532 else if (subexps[FLOAT_TYPE2].rm_so != -1)
1533 {
1534 /* Found floating point type suffix. */
1535 end_index = subexps[FLOAT_TYPE2].rm_so;
1536 type_index = FLOAT_TYPE2;
1537 }
1538 else
1539 {
1540 /* Any other floating point match. */
1541 end_index = subexps[0].rm_eo;
1542 type_name = "f64";
1543 }
1544
1545 /* We need a special case if the final character is ".". In this
1546 case we might need to parse an integer. For example, "23.f()" is
1547 a request for a trait method call, not a syntax error involving
1548 the floating point number "23.". */
1549 gdb_assert (subexps[0].rm_eo > 0);
5776fca3 1550 if (pstate->lexptr[subexps[0].rm_eo - 1] == '.')
c44af4eb 1551 {
5776fca3 1552 const char *next = skip_spaces (&pstate->lexptr[subexps[0].rm_eo]);
c44af4eb
TT
1553
1554 if (rust_identifier_start_p (*next) || *next == '.')
1555 {
1556 --subexps[0].rm_eo;
1557 is_integer = 1;
1558 end_index = subexps[0].rm_eo;
1559 type_name = "i32";
1560 could_be_decimal = 1;
347dc102 1561 implicit_i32 = 1;
c44af4eb
TT
1562 }
1563 }
1564
1565 /* Compute the type name if we haven't already. */
8001f118 1566 std::string type_name_holder;
c44af4eb
TT
1567 if (type_name == NULL)
1568 {
1569 gdb_assert (type_index != -1);
5776fca3
TT
1570 type_name_holder = std::string ((pstate->lexptr
1571 + subexps[type_index].rm_so),
8001f118
TT
1572 (subexps[type_index].rm_eo
1573 - subexps[type_index].rm_so));
1574 type_name = type_name_holder.c_str ();
c44af4eb
TT
1575 }
1576
1577 /* Look up the type. */
56ba65a0 1578 type = get_type (type_name);
c44af4eb
TT
1579
1580 /* Copy the text of the number and remove the "_"s. */
8001f118 1581 std::string number;
5776fca3 1582 for (i = 0; i < end_index && pstate->lexptr[i]; ++i)
c44af4eb 1583 {
5776fca3 1584 if (pstate->lexptr[i] == '_')
c44af4eb
TT
1585 could_be_decimal = 0;
1586 else
5776fca3 1587 number.push_back (pstate->lexptr[i]);
c44af4eb 1588 }
c44af4eb
TT
1589
1590 /* Advance past the match. */
5776fca3 1591 pstate->lexptr += subexps[0].rm_eo;
c44af4eb
TT
1592
1593 /* Parse the number. */
1594 if (is_integer)
1595 {
347dc102 1596 uint64_t value;
c44af4eb 1597 int radix = 10;
8001f118
TT
1598 int offset = 0;
1599
c44af4eb
TT
1600 if (number[0] == '0')
1601 {
1602 if (number[1] == 'x')
1603 radix = 16;
1604 else if (number[1] == 'o')
1605 radix = 8;
1606 else if (number[1] == 'b')
1607 radix = 2;
1608 if (radix != 10)
1609 {
8001f118 1610 offset = 2;
c44af4eb
TT
1611 could_be_decimal = 0;
1612 }
1613 }
347dc102 1614
8dc433a0 1615 value = strtoulst (number.c_str () + offset, NULL, radix);
347dc102 1616 if (implicit_i32 && value >= ((uint64_t) 1) << 31)
56ba65a0 1617 type = get_type ("i64");
347dc102 1618
56ba65a0
TT
1619 lvalp->typed_val_int.val = value;
1620 lvalp->typed_val_int.type = type;
c44af4eb
TT
1621 }
1622 else
1623 {
56ba65a0 1624 lvalp->typed_val_float.type = type;
edd079d9 1625 bool parsed = parse_float (number.c_str (), number.length (),
56ba65a0
TT
1626 lvalp->typed_val_float.type,
1627 lvalp->typed_val_float.val);
edd079d9 1628 gdb_assert (parsed);
c44af4eb
TT
1629 }
1630
c44af4eb
TT
1631 return is_integer ? (could_be_decimal ? DECIMAL_INTEGER : INTEGER) : FLOAT;
1632}
1633
1634/* The lexer. */
1635
1636static int
56ba65a0 1637rustyylex (YYSTYPE *lvalp, rust_parser *parser)
c44af4eb 1638{
5776fca3
TT
1639 struct parser_state *pstate = parser->pstate;
1640
c44af4eb 1641 /* Skip all leading whitespace. */
5776fca3
TT
1642 while (pstate->lexptr[0] == ' '
1643 || pstate->lexptr[0] == '\t'
1644 || pstate->lexptr[0] == '\r'
1645 || pstate->lexptr[0] == '\n')
1646 ++pstate->lexptr;
c44af4eb
TT
1647
1648 /* If we hit EOF and we're completing, then return COMPLETE -- maybe
1649 we're completing an empty string at the end of a field_expr.
1650 But, we don't want to return two COMPLETE tokens in a row. */
5776fca3 1651 if (pstate->lexptr[0] == '\0' && pstate->lexptr == pstate->prev_lexptr)
c44af4eb 1652 return 0;
5776fca3
TT
1653 pstate->prev_lexptr = pstate->lexptr;
1654 if (pstate->lexptr[0] == '\0')
c44af4eb 1655 {
2a612529 1656 if (pstate->parse_completion)
c44af4eb 1657 {
56ba65a0 1658 lvalp->sval = make_stoken ("");
c44af4eb
TT
1659 return COMPLETE;
1660 }
1661 return 0;
1662 }
1663
5776fca3 1664 if (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')
56ba65a0 1665 return parser->lex_number (lvalp);
5776fca3 1666 else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '\'')
56ba65a0 1667 return parser->lex_character (lvalp);
5776fca3 1668 else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '"')
56ba65a0 1669 return parser->lex_string (lvalp);
5776fca3 1670 else if (pstate->lexptr[0] == 'b' && starts_raw_string (pstate->lexptr + 1))
56ba65a0 1671 return parser->lex_string (lvalp);
5776fca3 1672 else if (starts_raw_string (pstate->lexptr))
56ba65a0 1673 return parser->lex_string (lvalp);
5776fca3 1674 else if (rust_identifier_start_p (pstate->lexptr[0]))
56ba65a0 1675 return parser->lex_identifier (lvalp);
5776fca3 1676 else if (pstate->lexptr[0] == '"')
56ba65a0 1677 return parser->lex_string (lvalp);
5776fca3 1678 else if (pstate->lexptr[0] == '\'')
56ba65a0 1679 return parser->lex_character (lvalp);
5776fca3 1680 else if (pstate->lexptr[0] == '}' || pstate->lexptr[0] == ']')
c44af4eb
TT
1681 {
1682 /* Falls through to lex_operator. */
28aaf3fd 1683 --parser->paren_depth;
c44af4eb 1684 }
5776fca3 1685 else if (pstate->lexptr[0] == '(' || pstate->lexptr[0] == '{')
c44af4eb
TT
1686 {
1687 /* Falls through to lex_operator. */
28aaf3fd 1688 ++parser->paren_depth;
c44af4eb 1689 }
5776fca3 1690 else if (pstate->lexptr[0] == ',' && pstate->comma_terminates
8621b685 1691 && parser->paren_depth == 0)
c44af4eb
TT
1692 return 0;
1693
5776fca3 1694 return parser->lex_operator (lvalp);
c44af4eb
TT
1695}
1696
1697/* Push back a single character to be re-lexed. */
1698
5776fca3
TT
1699void
1700rust_parser::push_back (char c)
c44af4eb
TT
1701{
1702 /* Can't be called before any lexing. */
5776fca3 1703 gdb_assert (pstate->prev_lexptr != NULL);
c44af4eb 1704
5776fca3
TT
1705 --pstate->lexptr;
1706 gdb_assert (*pstate->lexptr == c);
c44af4eb
TT
1707}
1708
1709\f
1710
1711/* Make an arbitrary operation and fill in the fields. */
1712
56ba65a0
TT
1713const struct rust_op *
1714rust_parser::ast_operation (enum exp_opcode opcode, const struct rust_op *left,
1715 const struct rust_op *right)
c44af4eb 1716{
56ba65a0 1717 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1718
1719 result->opcode = opcode;
1720 result->left.op = left;
1721 result->right.op = right;
1722
1723 return result;
1724}
1725
1726/* Make a compound assignment operation. */
1727
56ba65a0
TT
1728const struct rust_op *
1729rust_parser::ast_compound_assignment (enum exp_opcode opcode,
1730 const struct rust_op *left,
1731 const struct rust_op *right)
c44af4eb 1732{
56ba65a0 1733 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1734
1735 result->opcode = opcode;
1736 result->compound_assignment = 1;
1737 result->left.op = left;
1738 result->right.op = right;
1739
1740 return result;
1741}
1742
1743/* Make a typed integer literal operation. */
1744
56ba65a0
TT
1745const struct rust_op *
1746rust_parser::ast_literal (struct typed_val_int val)
c44af4eb 1747{
56ba65a0 1748 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1749
1750 result->opcode = OP_LONG;
1751 result->left.typed_val_int = val;
1752
1753 return result;
1754}
1755
1756/* Make a typed floating point literal operation. */
1757
56ba65a0
TT
1758const struct rust_op *
1759rust_parser::ast_dliteral (struct typed_val_float val)
c44af4eb 1760{
56ba65a0 1761 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb 1762
edd079d9 1763 result->opcode = OP_FLOAT;
c44af4eb
TT
1764 result->left.typed_val_float = val;
1765
1766 return result;
1767}
1768
1769/* Make a unary operation. */
1770
56ba65a0
TT
1771const struct rust_op *
1772rust_parser::ast_unary (enum exp_opcode opcode, const struct rust_op *expr)
c44af4eb
TT
1773{
1774 return ast_operation (opcode, expr, NULL);
1775}
1776
1777/* Make a cast operation. */
1778
56ba65a0
TT
1779const struct rust_op *
1780rust_parser::ast_cast (const struct rust_op *expr, const struct rust_op *type)
c44af4eb 1781{
56ba65a0 1782 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1783
1784 result->opcode = UNOP_CAST;
1785 result->left.op = expr;
1786 result->right.op = type;
1787
1788 return result;
1789}
1790
1791/* Make a call-like operation. This is nominally a function call, but
1792 when lowering we may discover that it actually represents the
1793 creation of a tuple struct. */
1794
56ba65a0
TT
1795const struct rust_op *
1796rust_parser::ast_call_ish (enum exp_opcode opcode, const struct rust_op *expr,
1797 rust_op_vector *params)
c44af4eb 1798{
56ba65a0 1799 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1800
1801 result->opcode = opcode;
1802 result->left.op = expr;
1803 result->right.params = params;
1804
1805 return result;
1806}
1807
1808/* Make a structure creation operation. */
1809
56ba65a0
TT
1810const struct rust_op *
1811rust_parser::ast_struct (const struct rust_op *name, rust_set_vector *fields)
c44af4eb 1812{
56ba65a0 1813 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1814
1815 result->opcode = OP_AGGREGATE;
1816 result->left.op = name;
1817 result->right.field_inits = fields;
1818
1819 return result;
1820}
1821
1822/* Make an identifier path. */
1823
56ba65a0
TT
1824const struct rust_op *
1825rust_parser::ast_path (struct stoken path, rust_op_vector *params)
c44af4eb 1826{
56ba65a0 1827 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1828
1829 result->opcode = OP_VAR_VALUE;
1830 result->left.sval = path;
1831 result->right.params = params;
1832
1833 return result;
1834}
1835
1836/* Make a string constant operation. */
1837
56ba65a0
TT
1838const struct rust_op *
1839rust_parser::ast_string (struct stoken str)
c44af4eb 1840{
56ba65a0 1841 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1842
1843 result->opcode = OP_STRING;
1844 result->left.sval = str;
1845
1846 return result;
1847}
1848
1849/* Make a field expression. */
1850
56ba65a0
TT
1851const struct rust_op *
1852rust_parser::ast_structop (const struct rust_op *left, const char *name,
1853 int completing)
c44af4eb 1854{
56ba65a0 1855 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1856
1857 result->opcode = STRUCTOP_STRUCT;
1858 result->completing = completing;
1859 result->left.op = left;
1860 result->right.sval = make_stoken (name);
1861
1862 return result;
1863}
1864
1865/* Make an anonymous struct operation, like 'x.0'. */
1866
56ba65a0
TT
1867const struct rust_op *
1868rust_parser::ast_structop_anonymous (const struct rust_op *left,
1869 struct typed_val_int number)
c44af4eb 1870{
56ba65a0 1871 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1872
1873 result->opcode = STRUCTOP_ANONYMOUS;
1874 result->left.op = left;
1875 result->right.typed_val_int = number;
1876
1877 return result;
1878}
1879
1880/* Make a range operation. */
1881
56ba65a0
TT
1882const struct rust_op *
1883rust_parser::ast_range (const struct rust_op *lhs, const struct rust_op *rhs,
1884 bool inclusive)
c44af4eb 1885{
56ba65a0 1886 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb 1887
01739a3b 1888 result->opcode = OP_RANGE;
6873858b 1889 result->inclusive = inclusive;
c44af4eb
TT
1890 result->left.op = lhs;
1891 result->right.op = rhs;
1892
1893 return result;
1894}
1895
1896/* A helper function to make a type-related AST node. */
1897
56ba65a0
TT
1898struct rust_op *
1899rust_parser::ast_basic_type (enum type_code typecode)
c44af4eb 1900{
56ba65a0 1901 struct rust_op *result = OBSTACK_ZALLOC (&obstack, struct rust_op);
c44af4eb
TT
1902
1903 result->opcode = OP_TYPE;
1904 result->typecode = typecode;
1905 return result;
1906}
1907
1908/* Create an AST node describing an array type. */
1909
56ba65a0
TT
1910const struct rust_op *
1911rust_parser::ast_array_type (const struct rust_op *lhs,
1912 struct typed_val_int val)
c44af4eb
TT
1913{
1914 struct rust_op *result = ast_basic_type (TYPE_CODE_ARRAY);
1915
1916 result->left.op = lhs;
1917 result->right.typed_val_int = val;
1918 return result;
1919}
1920
1921/* Create an AST node describing a reference type. */
1922
56ba65a0
TT
1923const struct rust_op *
1924rust_parser::ast_slice_type (const struct rust_op *type)
c44af4eb
TT
1925{
1926 /* Use TYPE_CODE_COMPLEX just because it is handy. */
1927 struct rust_op *result = ast_basic_type (TYPE_CODE_COMPLEX);
1928
1929 result->left.op = type;
1930 return result;
1931}
1932
1933/* Create an AST node describing a reference type. */
1934
56ba65a0
TT
1935const struct rust_op *
1936rust_parser::ast_reference_type (const struct rust_op *type)
c44af4eb
TT
1937{
1938 struct rust_op *result = ast_basic_type (TYPE_CODE_REF);
1939
1940 result->left.op = type;
1941 return result;
1942}
1943
1944/* Create an AST node describing a pointer type. */
1945
56ba65a0
TT
1946const struct rust_op *
1947rust_parser::ast_pointer_type (const struct rust_op *type, int is_mut)
c44af4eb
TT
1948{
1949 struct rust_op *result = ast_basic_type (TYPE_CODE_PTR);
1950
1951 result->left.op = type;
1952 /* For the time being we ignore is_mut. */
1953 return result;
1954}
1955
1956/* Create an AST node describing a function type. */
1957
56ba65a0
TT
1958const struct rust_op *
1959rust_parser::ast_function_type (const struct rust_op *rtype,
1960 rust_op_vector *params)
c44af4eb
TT
1961{
1962 struct rust_op *result = ast_basic_type (TYPE_CODE_FUNC);
1963
1964 result->left.op = rtype;
1965 result->right.params = params;
1966 return result;
1967}
1968
1969/* Create an AST node describing a tuple type. */
1970
56ba65a0
TT
1971const struct rust_op *
1972rust_parser::ast_tuple_type (rust_op_vector *params)
c44af4eb
TT
1973{
1974 struct rust_op *result = ast_basic_type (TYPE_CODE_STRUCT);
1975
1976 result->left.params = params;
1977 return result;
1978}
1979
1980/* A helper to appropriately munge NAME and BLOCK depending on the
1981 presence of a leading "::". */
1982
1983static void
1984munge_name_and_block (const char **name, const struct block **block)
1985{
1986 /* If it is a global reference, skip the current block in favor of
1987 the static block. */
1988 if (strncmp (*name, "::", 2) == 0)
1989 {
1990 *name += 2;
1991 *block = block_static_block (*block);
1992 }
1993}
1994
1995/* Like lookup_symbol, but handles Rust namespace conventions, and
1996 doesn't require field_of_this_result. */
1997
699bd4cf
TT
1998struct block_symbol
1999rust_parser::lookup_symbol (const char *name, const struct block *block,
2000 const domain_enum domain)
c44af4eb
TT
2001{
2002 struct block_symbol result;
2003
2004 munge_name_and_block (&name, &block);
2005
699bd4cf 2006 result = ::lookup_symbol (name, block, domain, NULL);
c44af4eb
TT
2007 if (result.symbol != NULL)
2008 update_innermost_block (result);
2009 return result;
2010}
2011
2012/* Look up a type, following Rust namespace conventions. */
2013
56ba65a0
TT
2014struct type *
2015rust_parser::rust_lookup_type (const char *name, const struct block *block)
c44af4eb
TT
2016{
2017 struct block_symbol result;
2018 struct type *type;
2019
2020 munge_name_and_block (&name, &block);
2021
699bd4cf 2022 result = ::lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
c44af4eb
TT
2023 if (result.symbol != NULL)
2024 {
2025 update_innermost_block (result);
2026 return SYMBOL_TYPE (result.symbol);
2027 }
2028
b858499d 2029 type = lookup_typename (language (), name, NULL, 1);
c44af4eb
TT
2030 if (type != NULL)
2031 return type;
2032
2033 /* Last chance, try a built-in type. */
56ba65a0 2034 return language_lookup_primitive_type (language (), arch (), name);
c44af4eb
TT
2035}
2036
c44af4eb
TT
2037/* Convert a vector of rust_ops representing types to a vector of
2038 types. */
2039
56ba65a0
TT
2040std::vector<struct type *>
2041rust_parser::convert_params_to_types (rust_op_vector *params)
c44af4eb 2042{
8001f118 2043 std::vector<struct type *> result;
c44af4eb 2044
1632f8ba
DR
2045 if (params != nullptr)
2046 {
2047 for (const rust_op *op : *params)
dda83cd7 2048 result.push_back (convert_ast_to_type (op));
1632f8ba 2049 }
c44af4eb 2050
c44af4eb
TT
2051 return result;
2052}
2053
2054/* Convert a rust_op representing a type to a struct type *. */
2055
56ba65a0
TT
2056struct type *
2057rust_parser::convert_ast_to_type (const struct rust_op *operation)
c44af4eb
TT
2058{
2059 struct type *type, *result = NULL;
2060
2061 if (operation->opcode == OP_VAR_VALUE)
2062 {
56ba65a0 2063 const char *varname = convert_name (operation);
c44af4eb 2064
1e58a4a4 2065 result = rust_lookup_type (varname, pstate->expression_context_block);
c44af4eb
TT
2066 if (result == NULL)
2067 error (_("No typed name '%s' in current context"), varname);
2068 return result;
2069 }
2070
2071 gdb_assert (operation->opcode == OP_TYPE);
2072
2073 switch (operation->typecode)
2074 {
2075 case TYPE_CODE_ARRAY:
56ba65a0 2076 type = convert_ast_to_type (operation->left.op);
c44af4eb
TT
2077 if (operation->right.typed_val_int.val < 0)
2078 error (_("Negative array length"));
2079 result = lookup_array_range_type (type, 0,
2080 operation->right.typed_val_int.val - 1);
2081 break;
2082
2083 case TYPE_CODE_COMPLEX:
2084 {
56ba65a0 2085 struct type *usize = get_type ("usize");
c44af4eb 2086
56ba65a0 2087 type = convert_ast_to_type (operation->left.op);
c44af4eb
TT
2088 result = rust_slice_type ("&[*gdb*]", type, usize);
2089 }
2090 break;
2091
2092 case TYPE_CODE_REF:
2093 case TYPE_CODE_PTR:
2094 /* For now we treat &x and *x identically. */
56ba65a0 2095 type = convert_ast_to_type (operation->left.op);
c44af4eb
TT
2096 result = lookup_pointer_type (type);
2097 break;
2098
2099 case TYPE_CODE_FUNC:
2100 {
8001f118 2101 std::vector<struct type *> args
56ba65a0 2102 (convert_params_to_types (operation->right.params));
c44af4eb
TT
2103 struct type **argtypes = NULL;
2104
56ba65a0 2105 type = convert_ast_to_type (operation->left.op);
8001f118
TT
2106 if (!args.empty ())
2107 argtypes = args.data ();
c44af4eb
TT
2108
2109 result
8001f118 2110 = lookup_function_type_with_arguments (type, args.size (),
c44af4eb
TT
2111 argtypes);
2112 result = lookup_pointer_type (result);
c44af4eb
TT
2113 }
2114 break;
2115
2116 case TYPE_CODE_STRUCT:
2117 {
8001f118 2118 std::vector<struct type *> args
56ba65a0 2119 (convert_params_to_types (operation->left.params));
c44af4eb 2120 int i;
c44af4eb
TT
2121 const char *name;
2122
56ba65a0 2123 obstack_1grow (&obstack, '(');
8001f118 2124 for (i = 0; i < args.size (); ++i)
c44af4eb 2125 {
8001f118 2126 std::string type_name = type_to_string (args[i]);
c44af4eb
TT
2127
2128 if (i > 0)
56ba65a0
TT
2129 obstack_1grow (&obstack, ',');
2130 obstack_grow_str (&obstack, type_name.c_str ());
c44af4eb
TT
2131 }
2132
56ba65a0
TT
2133 obstack_grow_str0 (&obstack, ")");
2134 name = (const char *) obstack_finish (&obstack);
c44af4eb
TT
2135
2136 /* We don't allow creating new tuple types (yet), but we do
2137 allow looking up existing tuple types. */
1e58a4a4 2138 result = rust_lookup_type (name, pstate->expression_context_block);
c44af4eb
TT
2139 if (result == NULL)
2140 error (_("could not find tuple type '%s'"), name);
c44af4eb
TT
2141 }
2142 break;
2143
2144 default:
2145 gdb_assert_not_reached ("unhandled opcode in convert_ast_to_type");
2146 }
2147
2148 gdb_assert (result != NULL);
2149 return result;
2150}
2151
2152/* A helper function to turn a rust_op representing a name into a full
2153 name. This applies generic arguments as needed. The returned name
2154 is allocated on the work obstack. */
2155
56ba65a0
TT
2156const char *
2157rust_parser::convert_name (const struct rust_op *operation)
c44af4eb 2158{
c44af4eb 2159 int i;
c44af4eb
TT
2160
2161 gdb_assert (operation->opcode == OP_VAR_VALUE);
2162
2163 if (operation->right.params == NULL)
2164 return operation->left.sval.ptr;
2165
8001f118 2166 std::vector<struct type *> types
56ba65a0 2167 (convert_params_to_types (operation->right.params));
c44af4eb 2168
56ba65a0
TT
2169 obstack_grow_str (&obstack, operation->left.sval.ptr);
2170 obstack_1grow (&obstack, '<');
8001f118 2171 for (i = 0; i < types.size (); ++i)
c44af4eb 2172 {
8001f118 2173 std::string type_name = type_to_string (types[i]);
c44af4eb
TT
2174
2175 if (i > 0)
56ba65a0 2176 obstack_1grow (&obstack, ',');
c44af4eb 2177
56ba65a0 2178 obstack_grow_str (&obstack, type_name.c_str ());
c44af4eb 2179 }
56ba65a0 2180 obstack_grow_str0 (&obstack, ">");
c44af4eb 2181
56ba65a0 2182 return (const char *) obstack_finish (&obstack);
c44af4eb
TT
2183}
2184
c44af4eb
TT
2185/* A helper function that converts a vec of rust_ops to a gdb
2186 expression. */
2187
c1299a23 2188std::vector<expr::operation_up>
56ba65a0
TT
2189rust_parser::convert_params_to_expression (rust_op_vector *params,
2190 const struct rust_op *top)
c44af4eb 2191{
c1299a23 2192 std::vector<expr::operation_up> result;
3232fabd 2193 for (const rust_op *elem : *params)
c1299a23
TT
2194 result.push_back (convert_ast_to_expression (elem, top));
2195 result.shrink_to_fit ();
2196 return result;
c44af4eb
TT
2197}
2198
c1299a23
TT
2199typedef expr::operation_up binop_maker_ftype (expr::operation_up &&,
2200 expr::operation_up &&);
2201
2202/* Map from an expression opcode to a function that will create an
2203 instance of the appropriate operation subclass. Only binary
2204 operations are handled this way. */
2205static std::unordered_map<exp_opcode, binop_maker_ftype *> maker_map;
2206
c44af4eb
TT
2207/* Lower a rust_op to a gdb expression. STATE is the parser state.
2208 OPERATION is the operation to lower. TOP is a pointer to the
2209 top-most operation; it is used to handle the special case where the
2210 top-most expression is an identifier and can be optionally lowered
8880f2a9
TT
2211 to OP_TYPE. WANT_TYPE is a flag indicating that, if the expression
2212 is the name of a type, then emit an OP_TYPE for it (rather than
2213 erroring). If WANT_TYPE is set, then the similar TOP handling is
2214 not done. */
c44af4eb 2215
c1299a23 2216expr::operation_up
56ba65a0
TT
2217rust_parser::convert_ast_to_expression (const struct rust_op *operation,
2218 const struct rust_op *top,
2219 bool want_type)
c44af4eb 2220{
c1299a23
TT
2221 using namespace expr;
2222
c44af4eb
TT
2223 switch (operation->opcode)
2224 {
2225 case OP_LONG:
c1299a23
TT
2226 return operation_up
2227 (new long_const_operation (operation->left.typed_val_int.type,
2228 operation->left.typed_val_int.val));
c44af4eb 2229
edd079d9 2230 case OP_FLOAT:
c1299a23
TT
2231 {
2232 float_data data;
2233 memcpy (data.data (), operation->left.typed_val_float.val,
2234 sizeof (operation->left.typed_val_float.val));
2235 return operation_up
2236 (new float_const_operation (operation->left.typed_val_float.type,
2237 data));
2238 }
c44af4eb
TT
2239
2240 case STRUCTOP_STRUCT:
2241 {
c1299a23
TT
2242 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2243 auto result = new rust_structop (std::move (lhs),
2244 operation->right.sval.ptr);
c44af4eb 2245 if (operation->completing)
c1299a23
TT
2246 pstate->mark_struct_expression (result);
2247 return operation_up (result);
c44af4eb 2248 }
c44af4eb
TT
2249
2250 case STRUCTOP_ANONYMOUS:
2251 {
c1299a23 2252 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
c44af4eb 2253
c1299a23
TT
2254 return operation_up
2255 (new rust_struct_anon (operation->right.typed_val_int.val,
2256 std::move (lhs)));
c44af4eb 2257 }
c44af4eb 2258
8880f2a9 2259 case UNOP_SIZEOF:
c1299a23
TT
2260 {
2261 operation_up lhs = convert_ast_to_expression (operation->left.op, top,
2262 true);
2263 return operation_up
2264 (new unop_sizeof_operation (std::move (lhs)));
2265 }
8880f2a9 2266
c44af4eb 2267 case UNOP_PLUS:
c1299a23
TT
2268 {
2269 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2270 return operation_up
2271 (new unary_plus_operation (std::move (lhs)));
2272 }
c44af4eb 2273 case UNOP_NEG:
c1299a23
TT
2274 {
2275 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2276 return operation_up
2277 (new unary_neg_operation (std::move (lhs)));
2278 }
c44af4eb 2279 case UNOP_COMPLEMENT:
c1299a23
TT
2280 {
2281 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2282 return operation_up
2283 (new rust_unop_compl_operation (std::move (lhs)));
2284 }
c44af4eb 2285 case UNOP_IND:
c1299a23
TT
2286 {
2287 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2288 return operation_up
2289 (new rust_unop_ind_operation (std::move (lhs)));
2290 }
c44af4eb 2291 case UNOP_ADDR:
c1299a23
TT
2292 {
2293 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2294 return operation_up
2295 (new rust_unop_addr_operation (std::move (lhs)));
2296 }
c44af4eb
TT
2297
2298 case BINOP_SUBSCRIPT:
2299 case BINOP_MUL:
2300 case BINOP_REPEAT:
2301 case BINOP_DIV:
2302 case BINOP_REM:
2303 case BINOP_LESS:
2304 case BINOP_GTR:
2305 case BINOP_BITWISE_AND:
2306 case BINOP_BITWISE_IOR:
2307 case BINOP_BITWISE_XOR:
2308 case BINOP_ADD:
2309 case BINOP_SUB:
2310 case BINOP_LOGICAL_OR:
2311 case BINOP_LOGICAL_AND:
2312 case BINOP_EQUAL:
2313 case BINOP_NOTEQUAL:
2314 case BINOP_LEQ:
2315 case BINOP_GEQ:
2316 case BINOP_LSH:
2317 case BINOP_RSH:
2318 case BINOP_ASSIGN:
2319 case OP_RUST_ARRAY:
c1299a23
TT
2320 {
2321 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2322 operation_up rhs = convert_ast_to_expression (operation->right.op,
2323 top);
2324 operation_up result;
2325 if (operation->compound_assignment)
2326 result = (operation_up
2327 (new assign_modify_operation (operation->opcode,
2328 std::move (lhs),
2329 std::move (rhs))));
2330 else
2331 {
2332 auto iter = maker_map.find (operation->opcode);
2333 gdb_assert (iter != maker_map.end ());
2334 result = iter->second (std::move (lhs), std::move (rhs));
2335 }
c44af4eb 2336
c1299a23
TT
2337 if (operation->compound_assignment
2338 || operation->opcode == BINOP_ASSIGN)
2339 {
2340 struct type *type
2341 = language_lookup_primitive_type (pstate->language (),
2342 pstate->gdbarch (),
2343 "()");
2344
2345 operation_up nil (new long_const_operation (type, 0));
2346 result.reset (new comma_operation (std::move (result),
2347 std::move (nil)));
2348 }
c44af4eb 2349
c1299a23
TT
2350 return result;
2351 }
c44af4eb
TT
2352
2353 case UNOP_CAST:
2354 {
56ba65a0 2355 struct type *type = convert_ast_to_type (operation->right.op);
c1299a23
TT
2356 operation_up lhs = convert_ast_to_expression (operation->left.op, top);
2357 return operation_up (new unop_cast_operation (std::move (lhs), type));
c44af4eb 2358 }
c44af4eb
TT
2359
2360 case OP_FUNCALL:
2361 {
2362 if (operation->left.op->opcode == OP_VAR_VALUE)
2363 {
2364 struct type *type;
56ba65a0 2365 const char *varname = convert_name (operation->left.op);
c44af4eb 2366
1e58a4a4
TT
2367 type = rust_lookup_type (varname,
2368 pstate->expression_context_block);
c44af4eb
TT
2369 if (type != NULL)
2370 {
2371 /* This is actually a tuple struct expression, not a
2372 call expression. */
3232fabd 2373 rust_op_vector *params = operation->right.params;
c44af4eb 2374
78134374 2375 if (type->code () != TYPE_CODE_NAMESPACE)
c44af4eb
TT
2376 {
2377 if (!rust_tuple_struct_type_p (type))
2378 error (_("Type %s is not a tuple struct"), varname);
2379
c1299a23
TT
2380 std::vector<std::pair<std::string, operation_up>> args
2381 (params->size ());
3232fabd 2382 for (int i = 0; i < params->size (); ++i)
c44af4eb
TT
2383 {
2384 char *cell = get_print_cell ();
2385
c1299a23
TT
2386 operation_up op
2387 = convert_ast_to_expression ((*params)[i], top);
c44af4eb 2388 xsnprintf (cell, PRINT_CELL_SIZE, "__%d", i);
c1299a23 2389 args[i] = { cell, std::move (op) };
c44af4eb
TT
2390 }
2391
c1299a23
TT
2392 return make_operation<rust_aggregate_operation>
2393 (type, operation_up (), std::move (args));
c44af4eb
TT
2394 }
2395 }
2396 }
c1299a23
TT
2397 operation_up callee = convert_ast_to_expression (operation->left.op,
2398 top);
2399 std::vector<operation_up> args
2400 = convert_params_to_expression (operation->right.params, top);
2401 return make_operation<funcall_operation> (std::move (callee),
2402 std::move (args));
c44af4eb 2403 }
c44af4eb
TT
2404
2405 case OP_ARRAY:
c1299a23
TT
2406 {
2407 gdb_assert (operation->left.op == NULL);
2408 std::vector<operation_up> subexps
2409 = convert_params_to_expression (operation->right.params, top);
2410 return make_operation<array_operation>
2411 (0, operation->right.params->size () - 1, std::move (subexps));
2412 }
c44af4eb
TT
2413
2414 case OP_VAR_VALUE:
2415 {
2416 struct block_symbol sym;
2417 const char *varname;
2418
2419 if (operation->left.sval.ptr[0] == '$')
2420 {
c1299a23
TT
2421 pstate->push_dollar (operation->left.sval);
2422 return pstate->pop ();
c44af4eb
TT
2423 }
2424
56ba65a0 2425 varname = convert_name (operation);
699bd4cf
TT
2426 sym = lookup_symbol (varname, pstate->expression_context_block,
2427 VAR_DOMAIN);
c1299a23 2428 operation_up result;
65547233 2429 if (sym.symbol != NULL && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF)
c1299a23 2430 result.reset (new var_value_operation (sym.symbol, sym.block));
c44af4eb
TT
2431 else
2432 {
65547233 2433 struct type *type = NULL;
c44af4eb 2434
65547233
TT
2435 if (sym.symbol != NULL)
2436 {
2437 gdb_assert (SYMBOL_CLASS (sym.symbol) == LOC_TYPEDEF);
2438 type = SYMBOL_TYPE (sym.symbol);
2439 }
2440 if (type == NULL)
1e58a4a4
TT
2441 type = rust_lookup_type (varname,
2442 pstate->expression_context_block);
c44af4eb
TT
2443 if (type == NULL)
2444 error (_("No symbol '%s' in current context"), varname);
2445
8880f2a9 2446 if (!want_type
78134374 2447 && type->code () == TYPE_CODE_STRUCT
1f704f76 2448 && type->num_fields () == 0)
c44af4eb
TT
2449 {
2450 /* A unit-like struct. */
c1299a23 2451 result.reset (new rust_aggregate_operation (type, {}, {}));
c44af4eb 2452 }
8880f2a9 2453 else if (want_type || operation == top)
c1299a23 2454 result.reset (new type_operation (type));
8880f2a9
TT
2455 else
2456 error (_("Found type '%s', which can't be "
2457 "evaluated in this context"),
2458 varname);
c44af4eb 2459 }
c1299a23
TT
2460
2461 return result;
c44af4eb 2462 }
c44af4eb
TT
2463
2464 case OP_AGGREGATE:
2465 {
3232fabd 2466 rust_set_vector *fields = operation->right.field_inits;
c44af4eb
TT
2467 struct type *type;
2468 const char *name;
2469
c1299a23
TT
2470 operation_up others;
2471 std::vector<std::pair<std::string, operation_up>> field_v;
3232fabd 2472 for (const set_field &init : *fields)
c44af4eb 2473 {
c1299a23 2474 operation_up expr = convert_ast_to_expression (init.init, top);
c44af4eb 2475
3232fabd 2476 if (init.name.ptr == NULL)
c1299a23
TT
2477 others = std::move (expr);
2478 else
2479 field_v.emplace_back (init.name.ptr, std::move (expr));
c44af4eb
TT
2480 }
2481
56ba65a0 2482 name = convert_name (operation->left.op);
1e58a4a4 2483 type = rust_lookup_type (name, pstate->expression_context_block);
c44af4eb
TT
2484 if (type == NULL)
2485 error (_("Could not find type '%s'"), operation->left.sval.ptr);
2486
78134374 2487 if (type->code () != TYPE_CODE_STRUCT
c44af4eb
TT
2488 || rust_tuple_type_p (type)
2489 || rust_tuple_struct_type_p (type))
2490 error (_("Struct expression applied to non-struct type"));
2491
c1299a23
TT
2492 return operation_up
2493 (new rust_aggregate_operation (type, std::move (others),
2494 std::move (field_v)));
c44af4eb 2495 }
c44af4eb
TT
2496
2497 case OP_STRING:
c1299a23
TT
2498 return (operation_up
2499 (new string_operation (::copy_name (operation->left.sval))));
c44af4eb 2500
01739a3b 2501 case OP_RANGE:
c44af4eb 2502 {
f2d8e4c5 2503 enum range_flag kind = (RANGE_HIGH_BOUND_DEFAULT
2f1b18db 2504 | RANGE_LOW_BOUND_DEFAULT);
c1299a23 2505 operation_up lhs, rhs;
c44af4eb
TT
2506
2507 if (operation->left.op != NULL)
2508 {
c1299a23 2509 lhs = convert_ast_to_expression (operation->left.op, top);
2f1b18db 2510 kind &= ~RANGE_LOW_BOUND_DEFAULT;
c44af4eb
TT
2511 }
2512 if (operation->right.op != NULL)
2513 {
c1299a23 2514 rhs = convert_ast_to_expression (operation->right.op, top);
2f1b18db
AB
2515 if (kind == (RANGE_HIGH_BOUND_DEFAULT | RANGE_LOW_BOUND_DEFAULT))
2516 {
2517 kind = RANGE_LOW_BOUND_DEFAULT;
2518 if (!operation->inclusive)
2519 kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
2520 }
c44af4eb
TT
2521 else
2522 {
2f1b18db
AB
2523 gdb_assert (kind == RANGE_HIGH_BOUND_DEFAULT);
2524 kind = RANGE_STANDARD;
2525 if (!operation->inclusive)
2526 kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
c44af4eb
TT
2527 }
2528 }
6873858b
TT
2529 else
2530 {
2531 /* Nothing should make an inclusive range without an upper
2532 bound. */
2533 gdb_assert (!operation->inclusive);
2534 }
2535
c1299a23
TT
2536 return operation_up (new rust_range_operation (kind,
2537 std::move (lhs),
2538 std::move (rhs)));
c44af4eb 2539 }
c44af4eb
TT
2540
2541 default:
2542 gdb_assert_not_reached ("unhandled opcode in convert_ast_to_expression");
2543 }
2544}
2545
2546\f
2547
2548/* The parser as exposed to gdb. */
2549
2550int
1c485265 2551rust_language::parser (struct parser_state *state) const
c44af4eb
TT
2552{
2553 int result;
c44af4eb 2554
3232fabd
TT
2555 /* This sets various globals and also clears them on
2556 destruction. */
2557 rust_parser parser (state);
8268c778 2558
56ba65a0 2559 result = rustyyparse (&parser);
c44af4eb 2560
2a612529 2561 if (!result || (state->parse_completion && parser.rust_ast != NULL))
c1299a23
TT
2562 {
2563 expr::operation_up op
2564 = parser.convert_ast_to_expression (parser.rust_ast, parser.rust_ast);
2565 state->set_operation (std::move (op));
2566 }
c44af4eb 2567
c44af4eb
TT
2568 return result;
2569}
2570
2571/* The parser error handler. */
2572
69d340c6 2573static void
56ba65a0 2574rustyyerror (rust_parser *parser, const char *msg)
c44af4eb 2575{
5776fca3
TT
2576 const char *where = (parser->pstate->prev_lexptr
2577 ? parser->pstate->prev_lexptr
2578 : parser->pstate->lexptr);
69d340c6 2579 error (_("%s in expression, near `%s'."), msg, where);
c44af4eb
TT
2580}
2581
2582\f
2583
2584#if GDB_SELF_TEST
2585
2586/* Initialize the lexer for testing. */
2587
2588static void
28aaf3fd 2589rust_lex_test_init (rust_parser *parser, const char *input)
c44af4eb 2590{
5776fca3
TT
2591 parser->pstate->prev_lexptr = NULL;
2592 parser->pstate->lexptr = input;
28aaf3fd 2593 parser->paren_depth = 0;
c44af4eb
TT
2594}
2595
2596/* A test helper that lexes a string, expecting a single token. It
2597 returns the lexer data for this token. */
2598
2599static RUSTSTYPE
56ba65a0 2600rust_lex_test_one (rust_parser *parser, const char *input, int expected)
c44af4eb
TT
2601{
2602 int token;
2603 RUSTSTYPE result;
2604
28aaf3fd 2605 rust_lex_test_init (parser, input);
c44af4eb 2606
56ba65a0 2607 token = rustyylex (&result, parser);
c44af4eb 2608 SELF_CHECK (token == expected);
c44af4eb
TT
2609
2610 if (token)
2611 {
56ba65a0
TT
2612 RUSTSTYPE ignore;
2613 token = rustyylex (&ignore, parser);
c44af4eb
TT
2614 SELF_CHECK (token == 0);
2615 }
2616
2617 return result;
2618}
2619
2620/* Test that INPUT lexes as the integer VALUE. */
2621
2622static void
8dc433a0
TT
2623rust_lex_int_test (rust_parser *parser, const char *input,
2624 LONGEST value, int kind)
c44af4eb 2625{
56ba65a0 2626 RUSTSTYPE result = rust_lex_test_one (parser, input, kind);
c44af4eb
TT
2627 SELF_CHECK (result.typed_val_int.val == value);
2628}
2629
2630/* Test that INPUT throws an exception with text ERR. */
2631
2632static void
56ba65a0
TT
2633rust_lex_exception_test (rust_parser *parser, const char *input,
2634 const char *err)
c44af4eb 2635{
a70b8144 2636 try
c44af4eb
TT
2637 {
2638 /* The "kind" doesn't matter. */
56ba65a0 2639 rust_lex_test_one (parser, input, DECIMAL_INTEGER);
c44af4eb
TT
2640 SELF_CHECK (0);
2641 }
230d2906 2642 catch (const gdb_exception_error &except)
c44af4eb 2643 {
3d6e9d23 2644 SELF_CHECK (strcmp (except.what (), err) == 0);
c44af4eb 2645 }
c44af4eb
TT
2646}
2647
2648/* Test that INPUT lexes as the identifier, string, or byte-string
2649 VALUE. KIND holds the expected token kind. */
2650
2651static void
56ba65a0
TT
2652rust_lex_stringish_test (rust_parser *parser, const char *input,
2653 const char *value, int kind)
c44af4eb 2654{
56ba65a0 2655 RUSTSTYPE result = rust_lex_test_one (parser, input, kind);
c44af4eb
TT
2656 SELF_CHECK (result.sval.length == strlen (value));
2657 SELF_CHECK (strncmp (result.sval.ptr, value, result.sval.length) == 0);
2658}
2659
2660/* Helper to test that a string parses as a given token sequence. */
2661
2662static void
56ba65a0
TT
2663rust_lex_test_sequence (rust_parser *parser, const char *input, int len,
2664 const int expected[])
c44af4eb
TT
2665{
2666 int i;
2667
5776fca3 2668 parser->pstate->lexptr = input;
28aaf3fd 2669 parser->paren_depth = 0;
c44af4eb
TT
2670
2671 for (i = 0; i < len; ++i)
2672 {
56ba65a0
TT
2673 RUSTSTYPE ignore;
2674 int token = rustyylex (&ignore, parser);
c44af4eb
TT
2675
2676 SELF_CHECK (token == expected[i]);
2677 }
2678}
2679
2680/* Tests for an integer-parsing corner case. */
2681
2682static void
56ba65a0 2683rust_lex_test_trailing_dot (rust_parser *parser)
c44af4eb
TT
2684{
2685 const int expected1[] = { DECIMAL_INTEGER, '.', IDENT, '(', ')', 0 };
2686 const int expected2[] = { INTEGER, '.', IDENT, '(', ')', 0 };
2687 const int expected3[] = { FLOAT, EQEQ, '(', ')', 0 };
2688 const int expected4[] = { DECIMAL_INTEGER, DOTDOT, DECIMAL_INTEGER, 0 };
2689
56ba65a0
TT
2690 rust_lex_test_sequence (parser, "23.g()", ARRAY_SIZE (expected1), expected1);
2691 rust_lex_test_sequence (parser, "23_0.g()", ARRAY_SIZE (expected2),
2692 expected2);
2693 rust_lex_test_sequence (parser, "23.==()", ARRAY_SIZE (expected3),
2694 expected3);
2695 rust_lex_test_sequence (parser, "23..25", ARRAY_SIZE (expected4), expected4);
c44af4eb
TT
2696}
2697
2698/* Tests of completion. */
2699
2700static void
56ba65a0 2701rust_lex_test_completion (rust_parser *parser)
c44af4eb
TT
2702{
2703 const int expected[] = { IDENT, '.', COMPLETE, 0 };
2704
2a612529 2705 parser->pstate->parse_completion = 1;
c44af4eb 2706
56ba65a0
TT
2707 rust_lex_test_sequence (parser, "something.wha", ARRAY_SIZE (expected),
2708 expected);
2709 rust_lex_test_sequence (parser, "something.", ARRAY_SIZE (expected),
2710 expected);
c44af4eb 2711
2a612529 2712 parser->pstate->parse_completion = 0;
c44af4eb
TT
2713}
2714
2715/* Test pushback. */
2716
2717static void
56ba65a0 2718rust_lex_test_push_back (rust_parser *parser)
c44af4eb
TT
2719{
2720 int token;
56ba65a0 2721 RUSTSTYPE lval;
c44af4eb 2722
28aaf3fd 2723 rust_lex_test_init (parser, ">>=");
c44af4eb 2724
56ba65a0 2725 token = rustyylex (&lval, parser);
c44af4eb 2726 SELF_CHECK (token == COMPOUND_ASSIGN);
56ba65a0 2727 SELF_CHECK (lval.opcode == BINOP_RSH);
c44af4eb 2728
5776fca3 2729 parser->push_back ('=');
c44af4eb 2730
56ba65a0 2731 token = rustyylex (&lval, parser);
c44af4eb
TT
2732 SELF_CHECK (token == '=');
2733
56ba65a0 2734 token = rustyylex (&lval, parser);
c44af4eb
TT
2735 SELF_CHECK (token == 0);
2736}
2737
2738/* Unit test the lexer. */
2739
2740static void
2741rust_lex_tests (void)
2742{
2743 int i;
2744
0874fd07
AB
2745 /* Set up dummy "parser", so that rust_type works. */
2746 struct parser_state ps (language_def (language_rust), target_gdbarch (),
c5c41205 2747 nullptr, 0, 0, nullptr, 0, nullptr, false);
edd079d9 2748 rust_parser parser (&ps);
c44af4eb 2749
56ba65a0
TT
2750 rust_lex_test_one (&parser, "", 0);
2751 rust_lex_test_one (&parser, " \t \n \r ", 0);
2752 rust_lex_test_one (&parser, "thread 23", 0);
2753 rust_lex_test_one (&parser, "task 23", 0);
2754 rust_lex_test_one (&parser, "th 104", 0);
2755 rust_lex_test_one (&parser, "ta 97", 0);
2756
2757 rust_lex_int_test (&parser, "'z'", 'z', INTEGER);
2758 rust_lex_int_test (&parser, "'\\xff'", 0xff, INTEGER);
2759 rust_lex_int_test (&parser, "'\\u{1016f}'", 0x1016f, INTEGER);
2760 rust_lex_int_test (&parser, "b'z'", 'z', INTEGER);
2761 rust_lex_int_test (&parser, "b'\\xfe'", 0xfe, INTEGER);
2762 rust_lex_int_test (&parser, "b'\\xFE'", 0xfe, INTEGER);
2763 rust_lex_int_test (&parser, "b'\\xfE'", 0xfe, INTEGER);
c44af4eb
TT
2764
2765 /* Test all escapes in both modes. */
56ba65a0
TT
2766 rust_lex_int_test (&parser, "'\\n'", '\n', INTEGER);
2767 rust_lex_int_test (&parser, "'\\r'", '\r', INTEGER);
2768 rust_lex_int_test (&parser, "'\\t'", '\t', INTEGER);
2769 rust_lex_int_test (&parser, "'\\\\'", '\\', INTEGER);
2770 rust_lex_int_test (&parser, "'\\0'", '\0', INTEGER);
2771 rust_lex_int_test (&parser, "'\\''", '\'', INTEGER);
2772 rust_lex_int_test (&parser, "'\\\"'", '"', INTEGER);
2773
2774 rust_lex_int_test (&parser, "b'\\n'", '\n', INTEGER);
2775 rust_lex_int_test (&parser, "b'\\r'", '\r', INTEGER);
2776 rust_lex_int_test (&parser, "b'\\t'", '\t', INTEGER);
2777 rust_lex_int_test (&parser, "b'\\\\'", '\\', INTEGER);
2778 rust_lex_int_test (&parser, "b'\\0'", '\0', INTEGER);
2779 rust_lex_int_test (&parser, "b'\\''", '\'', INTEGER);
2780 rust_lex_int_test (&parser, "b'\\\"'", '"', INTEGER);
2781
2782 rust_lex_exception_test (&parser, "'z", "Unterminated character literal");
2783 rust_lex_exception_test (&parser, "b'\\x0'", "Not enough hex digits seen");
2784 rust_lex_exception_test (&parser, "b'\\u{0}'",
2785 "Unicode escape in byte literal");
2786 rust_lex_exception_test (&parser, "'\\x0'", "Not enough hex digits seen");
2787 rust_lex_exception_test (&parser, "'\\u0'", "Missing '{' in Unicode escape");
2788 rust_lex_exception_test (&parser, "'\\u{0", "Missing '}' in Unicode escape");
2789 rust_lex_exception_test (&parser, "'\\u{0000007}", "Overlong hex escape");
2790 rust_lex_exception_test (&parser, "'\\u{}", "Not enough hex digits seen");
2791 rust_lex_exception_test (&parser, "'\\Q'", "Invalid escape \\Q in literal");
2792 rust_lex_exception_test (&parser, "b'\\Q'", "Invalid escape \\Q in literal");
2793
2794 rust_lex_int_test (&parser, "23", 23, DECIMAL_INTEGER);
2795 rust_lex_int_test (&parser, "2_344__29", 234429, INTEGER);
2796 rust_lex_int_test (&parser, "0x1f", 0x1f, INTEGER);
2797 rust_lex_int_test (&parser, "23usize", 23, INTEGER);
2798 rust_lex_int_test (&parser, "23i32", 23, INTEGER);
2799 rust_lex_int_test (&parser, "0x1_f", 0x1f, INTEGER);
2800 rust_lex_int_test (&parser, "0b1_101011__", 0x6b, INTEGER);
2801 rust_lex_int_test (&parser, "0o001177i64", 639, INTEGER);
8dc433a0 2802 rust_lex_int_test (&parser, "0x123456789u64", 0x123456789ull, INTEGER);
56ba65a0
TT
2803
2804 rust_lex_test_trailing_dot (&parser);
2805
2806 rust_lex_test_one (&parser, "23.", FLOAT);
2807 rust_lex_test_one (&parser, "23.99f32", FLOAT);
2808 rust_lex_test_one (&parser, "23e7", FLOAT);
2809 rust_lex_test_one (&parser, "23E-7", FLOAT);
2810 rust_lex_test_one (&parser, "23e+7", FLOAT);
2811 rust_lex_test_one (&parser, "23.99e+7f64", FLOAT);
2812 rust_lex_test_one (&parser, "23.82f32", FLOAT);
2813
2814 rust_lex_stringish_test (&parser, "hibob", "hibob", IDENT);
2815 rust_lex_stringish_test (&parser, "hibob__93", "hibob__93", IDENT);
2816 rust_lex_stringish_test (&parser, "thread", "thread", IDENT);
2817
2818 rust_lex_stringish_test (&parser, "\"string\"", "string", STRING);
2819 rust_lex_stringish_test (&parser, "\"str\\ting\"", "str\ting", STRING);
2820 rust_lex_stringish_test (&parser, "\"str\\\"ing\"", "str\"ing", STRING);
2821 rust_lex_stringish_test (&parser, "r\"str\\ing\"", "str\\ing", STRING);
2822 rust_lex_stringish_test (&parser, "r#\"str\\ting\"#", "str\\ting", STRING);
2823 rust_lex_stringish_test (&parser, "r###\"str\\\"ing\"###", "str\\\"ing",
2824 STRING);
2825
2826 rust_lex_stringish_test (&parser, "b\"string\"", "string", BYTESTRING);
2827 rust_lex_stringish_test (&parser, "b\"\x73tring\"", "string", BYTESTRING);
2828 rust_lex_stringish_test (&parser, "b\"str\\\"ing\"", "str\"ing", BYTESTRING);
2829 rust_lex_stringish_test (&parser, "br####\"\\x73tring\"####", "\\x73tring",
c44af4eb
TT
2830 BYTESTRING);
2831
2832 for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
56ba65a0
TT
2833 rust_lex_test_one (&parser, identifier_tokens[i].name,
2834 identifier_tokens[i].value);
c44af4eb
TT
2835
2836 for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
56ba65a0
TT
2837 rust_lex_test_one (&parser, operator_tokens[i].name,
2838 operator_tokens[i].value);
c44af4eb 2839
56ba65a0
TT
2840 rust_lex_test_completion (&parser);
2841 rust_lex_test_push_back (&parser);
c44af4eb
TT
2842}
2843
2844#endif /* GDB_SELF_TEST */
2845
6c265988 2846void _initialize_rust_exp ();
c44af4eb 2847void
6c265988 2848_initialize_rust_exp ()
c44af4eb
TT
2849{
2850 int code = regcomp (&number_regex, number_regex_text, REG_EXTENDED);
2851 /* If the regular expression was incorrect, it was a programming
2852 error. */
2853 gdb_assert (code == 0);
2854
c1299a23
TT
2855 using namespace expr;
2856 maker_map[BINOP_SUBSCRIPT] = make_operation<rust_subscript_operation>;
2857 maker_map[BINOP_MUL] = make_operation<mul_operation>;
2858 maker_map[BINOP_REPEAT] = make_operation<repeat_operation>;
2859 maker_map[BINOP_DIV] = make_operation<div_operation>;
2860 maker_map[BINOP_REM] = make_operation<rem_operation>;
2861 maker_map[BINOP_LESS] = make_operation<less_operation>;
2862 maker_map[BINOP_GTR] = make_operation<gtr_operation>;
2863 maker_map[BINOP_BITWISE_AND] = make_operation<bitwise_and_operation>;
2864 maker_map[BINOP_BITWISE_IOR] = make_operation<bitwise_ior_operation>;
2865 maker_map[BINOP_BITWISE_XOR] = make_operation<bitwise_xor_operation>;
2866 maker_map[BINOP_ADD] = make_operation<add_operation>;
2867 maker_map[BINOP_SUB] = make_operation<sub_operation>;
2868 maker_map[BINOP_LOGICAL_OR] = make_operation<logical_or_operation>;
2869 maker_map[BINOP_LOGICAL_AND] = make_operation<logical_and_operation>;
2870 maker_map[BINOP_EQUAL] = make_operation<equal_operation>;
2871 maker_map[BINOP_NOTEQUAL] = make_operation<notequal_operation>;
2872 maker_map[BINOP_LEQ] = make_operation<leq_operation>;
2873 maker_map[BINOP_GEQ] = make_operation<geq_operation>;
2874 maker_map[BINOP_LSH] = make_operation<lsh_operation>;
2875 maker_map[BINOP_RSH] = make_operation<rsh_operation>;
2876 maker_map[BINOP_ASSIGN] = make_operation<assign_operation>;
2877 maker_map[OP_RUST_ARRAY] = make_operation<rust_array_operation>;
2878
c44af4eb 2879#if GDB_SELF_TEST
1526853e 2880 selftests::register_test ("rust-lex", rust_lex_tests);
c44af4eb
TT
2881#endif
2882}
This page took 0.693567 seconds and 4 git commands to generate.