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