File: | build/gcc/gengtype-parse.cc |
Warning: | line 989, column 7 Value stored to 'kind' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Process source files and output type information. |
2 | Copyright (C) 2006-2023 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free |
8 | Software Foundation; either version 3, or (at your option) any later |
9 | version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ |
19 | |
20 | #ifdef HOST_GENERATOR_FILE |
21 | #include "config.h" |
22 | #define GENERATOR_FILE1 1 |
23 | #else |
24 | #include "bconfig.h" |
25 | #endif |
26 | #include "system.h" |
27 | #include "gengtype.h" |
28 | |
29 | /* This is a simple recursive-descent parser which understands a subset of |
30 | the C type grammar. |
31 | |
32 | Rule functions are suffixed _seq if they scan a sequence of items; |
33 | _opt if they may consume zero tokens; _seqopt if both are true. The |
34 | "consume_" prefix indicates that a sequence of tokens is parsed for |
35 | syntactic correctness and then thrown away. */ |
36 | |
37 | /* Simple one-token lookahead mechanism. */ |
38 | |
39 | struct token |
40 | { |
41 | const char *value; |
42 | int code; |
43 | bool valid; |
44 | }; |
45 | static struct token T; |
46 | |
47 | /* Retrieve the code of the current token; if there is no current token, |
48 | get the next one from the lexer. */ |
49 | static inline int |
50 | token (void) |
51 | { |
52 | if (!T.valid) |
53 | { |
54 | T.code = yylex (&T.value); |
55 | T.valid = true; |
56 | } |
57 | return T.code; |
58 | } |
59 | |
60 | /* Retrieve the value of the current token (if any) and mark it consumed. |
61 | The next call to token() will get another token from the lexer. */ |
62 | static inline const char * |
63 | advance (void) |
64 | { |
65 | T.valid = false; |
66 | return T.value; |
67 | } |
68 | |
69 | /* Diagnostics. */ |
70 | |
71 | /* This array is indexed by the token code minus CHAR_TOKEN_OFFSET. */ |
72 | static const char *const token_names[] = { |
73 | "GTY", |
74 | "typedef", |
75 | "extern", |
76 | "static", |
77 | "union", |
78 | "struct", |
79 | "enum", |
80 | "...", |
81 | "ptr_alias", |
82 | "nested_ptr", |
83 | "a param<N>_is option", |
84 | "a number", |
85 | "a scalar type", |
86 | "an identifier", |
87 | "a string constant", |
88 | "a character constant", |
89 | "an array declarator", |
90 | "a C++ keyword to ignore" |
91 | }; |
92 | |
93 | /* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */ |
94 | static const char *const token_value_format[] = { |
95 | "%s", |
96 | "'%s'", |
97 | "'%s'", |
98 | "'%s'", |
99 | "'\"%s\"'", |
100 | "\"'%s'\"", |
101 | "'[%s]'", |
102 | "'%s'", |
103 | }; |
104 | |
105 | /* Produce a printable representation for a token defined by CODE and |
106 | VALUE. This sometimes returns pointers into malloc memory and |
107 | sometimes not, therefore it is unsafe to free the pointer it |
108 | returns, so that memory is leaked. This does not matter, as this |
109 | function is only used for diagnostics, and in a successful run of |
110 | the program there will be none. */ |
111 | static const char * |
112 | print_token (int code, const char *value) |
113 | { |
114 | if (code < CHAR_TOKEN_OFFSET) |
115 | return xasprintf ("'%c'", code); |
116 | else if (code < FIRST_TOKEN_WITH_VALUE) |
117 | return xasprintf ("'%s'", token_names[code - CHAR_TOKEN_OFFSET]); |
118 | else if (!value) |
119 | return token_names[code - CHAR_TOKEN_OFFSET]; /* don't quote these */ |
120 | else |
121 | return xasprintf (token_value_format[code - FIRST_TOKEN_WITH_VALUE], |
122 | value); |
123 | } |
124 | |
125 | /* Convenience wrapper around print_token which produces the printable |
126 | representation of the current token. */ |
127 | static inline const char * |
128 | print_cur_token (void) |
129 | { |
130 | return print_token (T.code, T.value); |
131 | } |
132 | |
133 | /* Report a parse error on the current line, with diagnostic MSG. |
134 | Behaves as standard printf with respect to additional arguments and |
135 | format escapes. */ |
136 | static void ATTRIBUTE_PRINTF_1__attribute__ ((__format__ (__printf__, 1, 2))) __attribute__ ((__nonnull__ (1))) |
137 | parse_error (const char *msg, ...) |
138 | { |
139 | va_list ap; |
140 | |
141 | fprintf (stderrstderr, "%s:%d: parse error: ", |
142 | get_input_file_name (lexer_line.file), lexer_line.line); |
143 | |
144 | va_start (ap, msg)__builtin_va_start(ap, msg); |
145 | vfprintf (stderrstderr, msg, ap); |
146 | va_end (ap)__builtin_va_end(ap); |
147 | |
148 | fputc ('\n', stderr)fputc_unlocked ('\n', stderr); |
149 | |
150 | hit_error = true; |
151 | } |
152 | |
153 | /* If the next token does not have code T, report a parse error; otherwise |
154 | return the token's value. */ |
155 | static const char * |
156 | require (int t) |
157 | { |
158 | int u = token (); |
159 | const char *v = advance (); |
160 | if (u != t) |
161 | { |
162 | parse_error ("expected %s, have %s", |
163 | print_token (t, 0), print_token (u, v)); |
164 | return 0; |
165 | } |
166 | return v; |
167 | } |
168 | |
169 | /* As per require, but do not advance. */ |
170 | static const char * |
171 | require_without_advance (int t) |
172 | { |
173 | int u = token (); |
174 | const char *v = T.value; |
175 | if (u != t) |
176 | { |
177 | parse_error ("expected %s, have %s", |
178 | print_token (t, 0), print_token (u, v)); |
179 | return 0; |
180 | } |
181 | return v; |
182 | } |
183 | |
184 | /* If the next token does not have one of the codes T1 or T2, report a |
185 | parse error; otherwise return the token's value. */ |
186 | static const char * |
187 | require2 (int t1, int t2) |
188 | { |
189 | int u = token (); |
190 | const char *v = advance (); |
191 | if (u != t1 && u != t2) |
192 | { |
193 | parse_error ("expected %s or %s, have %s", |
194 | print_token (t1, 0), print_token (t2, 0), |
195 | print_token (u, v)); |
196 | return 0; |
197 | } |
198 | return v; |
199 | } |
200 | |
201 | /* If the next token does not have one of the codes T1, T2, T3 or T4, report a |
202 | parse error; otherwise return the token's value. */ |
203 | static const char * |
204 | require4 (int t1, int t2, int t3, int t4) |
205 | { |
206 | int u = token (); |
207 | const char *v = advance (); |
208 | if (u != t1 && u != t2 && u != t3 && u != t4) |
209 | { |
210 | parse_error ("expected %s, %s, %s or %s, have %s", |
211 | print_token (t1, 0), print_token (t2, 0), |
212 | print_token (t3, 0), print_token (t4, 0), |
213 | print_token (u, v)); |
214 | return 0; |
215 | } |
216 | return v; |
217 | } |
218 | |
219 | /* Near-terminals. */ |
220 | |
221 | /* C-style string constant concatenation: STRING+ |
222 | Bare STRING should appear nowhere else in this file. */ |
223 | static const char * |
224 | string_seq (void) |
225 | { |
226 | const char *s1, *s2; |
227 | size_t l1, l2; |
228 | char *buf; |
229 | |
230 | s1 = require (STRING); |
231 | if (s1 == 0) |
232 | return ""; |
233 | while (token () == STRING) |
234 | { |
235 | s2 = advance (); |
236 | |
237 | l1 = strlen (s1); |
238 | l2 = strlen (s2); |
239 | buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1)((char *) xrealloc ((void *) ((const_cast<char *> ((s1) ))), sizeof (char) * (l1 + l2 + 1))); |
240 | memcpy (buf + l1, s2, l2 + 1); |
241 | XDELETE (CONST_CAST (char *, s2))free ((void*) ((const_cast<char *> ((s2))))); |
242 | s1 = buf; |
243 | } |
244 | return s1; |
245 | } |
246 | |
247 | |
248 | /* The caller has detected a template declaration that starts |
249 | with TMPL_NAME. Parse up to the closing '>'. This recognizes |
250 | simple template declarations of the form ID<ID1,ID2,...,IDn>, |
251 | potentially with a single level of indirection e.g. |
252 | ID<ID1 *, ID2, ID3 *, ..., IDn>. |
253 | It does not try to parse anything more sophisticated than that. |
254 | |
255 | Returns the template declaration string "ID<ID1,ID2,...,IDn>". */ |
256 | |
257 | static const char * |
258 | require_template_declaration (const char *tmpl_name) |
259 | { |
260 | char *str; |
261 | int num_indirections = 0; |
262 | |
263 | /* Recognize the opening '<'. */ |
264 | require ('<'); |
265 | str = concat (tmpl_name, "<", (char *) 0); |
266 | |
267 | /* Read the comma-separated list of identifiers. */ |
268 | int depth = 1; |
269 | while (depth > 0) |
270 | { |
271 | if (token () == ENUM) |
272 | { |
273 | advance (); |
274 | str = concat (str, "enum ", (char *) 0); |
275 | continue; |
276 | } |
277 | if (token () == NUM |
278 | || token () == ':' |
279 | || token () == '+') |
280 | { |
281 | str = concat (str, advance (), (char *) 0); |
282 | continue; |
283 | } |
284 | if (token () == '<') |
285 | { |
286 | advance (); |
287 | str = concat (str, "<", (char *) 0); |
288 | depth += 1; |
289 | continue; |
290 | } |
291 | if (token () == '>') |
292 | { |
293 | advance (); |
294 | str = concat (str, ">", (char *) 0); |
295 | depth -= 1; |
296 | continue; |
297 | } |
298 | const char *id = require4 (SCALAR, ID, '*', ','); |
299 | if (id == NULLnullptr) |
300 | { |
301 | if (T.code == '*') |
302 | { |
303 | id = "*"; |
304 | if (num_indirections++) |
305 | parse_error ("only one level of indirection is supported" |
306 | " in template arguments"); |
307 | } |
308 | else |
309 | id = ","; |
310 | } |
311 | else |
312 | num_indirections = 0; |
313 | str = concat (str, id, (char *) 0); |
314 | } |
315 | return str; |
316 | } |
317 | |
318 | |
319 | /* typedef_name: either an ID, or a template type |
320 | specification of the form ID<t1,t2,...,tn>. */ |
321 | |
322 | static const char * |
323 | typedef_name (void) |
324 | { |
325 | const char *id = require (ID); |
326 | if (token () == '<') |
327 | return require_template_declaration (id); |
328 | else |
329 | return id; |
330 | } |
331 | |
332 | /* Absorb a sequence of tokens delimited by balanced ()[]{}. */ |
333 | static void |
334 | consume_balanced (int opener, int closer) |
335 | { |
336 | require (opener); |
337 | for (;;) |
338 | switch (token ()) |
339 | { |
340 | default: |
341 | advance (); |
342 | break; |
343 | case '(': |
344 | consume_balanced ('(', ')'); |
345 | break; |
346 | case '[': |
347 | consume_balanced ('[', ']'); |
348 | break; |
349 | case '{': |
350 | consume_balanced ('{', '}'); |
351 | break; |
352 | |
353 | case '}': |
354 | case ']': |
355 | case ')': |
356 | if (token () != closer) |
357 | parse_error ("unbalanced delimiters - expected '%c', have '%c'", |
358 | closer, token ()); |
359 | advance (); |
360 | return; |
361 | |
362 | case EOF_TOKEN: |
363 | parse_error ("unexpected end of file within %c%c-delimited construct", |
364 | opener, closer); |
365 | return; |
366 | } |
367 | } |
368 | |
369 | /* Absorb a sequence of tokens, possibly including ()[]{}-delimited |
370 | expressions, until we encounter an end-of-statement marker (a ';' or |
371 | a '}') outside any such delimiters; absorb that too. */ |
372 | |
373 | static void |
374 | consume_until_eos (void) |
375 | { |
376 | for (;;) |
377 | switch (token ()) |
378 | { |
379 | case ';': |
380 | advance (); |
381 | return; |
382 | |
383 | case '{': |
384 | consume_balanced ('{', '}'); |
385 | return; |
386 | |
387 | case '(': |
388 | consume_balanced ('(', ')'); |
389 | break; |
390 | |
391 | case '[': |
392 | consume_balanced ('[', ']'); |
393 | break; |
394 | |
395 | case '}': |
396 | case ']': |
397 | case ')': |
398 | parse_error ("unmatched '%c' while scanning for ';'", token ()); |
399 | return; |
400 | |
401 | case EOF_TOKEN: |
402 | parse_error ("unexpected end of file while scanning for ';'"); |
403 | return; |
404 | |
405 | default: |
406 | advance (); |
407 | break; |
408 | } |
409 | } |
410 | |
411 | /* Absorb a sequence of tokens, possibly including ()[]{}-delimited |
412 | expressions, until we encounter a comma or semicolon outside any |
413 | such delimiters; absorb that too. Returns true if the loop ended |
414 | with a comma. */ |
415 | |
416 | static bool |
417 | consume_until_comma_or_eos () |
418 | { |
419 | for (;;) |
420 | switch (token ()) |
421 | { |
422 | case ',': |
423 | advance (); |
424 | return true; |
425 | |
426 | case ';': |
427 | advance (); |
428 | return false; |
429 | |
430 | case '{': |
431 | consume_balanced ('{', '}'); |
432 | return false; |
433 | |
434 | case '(': |
435 | consume_balanced ('(', ')'); |
436 | break; |
437 | |
438 | case '[': |
439 | consume_balanced ('[', ']'); |
440 | break; |
441 | |
442 | case '}': |
443 | case ']': |
444 | case ')': |
445 | parse_error ("unmatched '%s' while scanning for ',' or ';'", |
446 | print_cur_token ()); |
447 | return false; |
448 | |
449 | case EOF_TOKEN: |
450 | parse_error ("unexpected end of file while scanning for ',' or ';'"); |
451 | return false; |
452 | |
453 | default: |
454 | advance (); |
455 | break; |
456 | } |
457 | } |
458 | |
459 | |
460 | /* GTY(()) option handling. */ |
461 | static type_p type (options_p *optsp, bool nested); |
462 | |
463 | /* Optional parenthesized string: ('(' string_seq ')')? */ |
464 | static options_p |
465 | str_optvalue_opt (options_p prev) |
466 | { |
467 | const char *name = advance (); |
468 | const char *value = ""; |
469 | if (token () == '(') |
470 | { |
471 | advance (); |
472 | value = string_seq (); |
473 | require (')'); |
474 | } |
475 | return create_string_option (prev, name, value); |
476 | } |
477 | |
478 | /* absdecl: type '*'* |
479 | -- a vague approximation to what the C standard calls an abstract |
480 | declarator. The only kinds that are actually used are those that |
481 | are just a bare type and those that have trailing pointer-stars. |
482 | Further kinds should be implemented if and when they become |
483 | necessary. Used only within GTY(()) option values, therefore |
484 | further GTY(()) tags within the type are invalid. Note that the |
485 | return value has already been run through adjust_field_type. */ |
486 | static type_p |
487 | absdecl (void) |
488 | { |
489 | type_p ty; |
490 | options_p opts; |
491 | |
492 | ty = type (&opts, true); |
493 | while (token () == '*') |
494 | { |
495 | ty = create_pointer (ty); |
496 | advance (); |
497 | } |
498 | |
499 | if (opts) |
500 | parse_error ("nested GTY(()) options are invalid"); |
501 | |
502 | return adjust_field_type (ty, 0); |
503 | } |
504 | |
505 | /* Type-option: '(' absdecl ')' */ |
506 | static options_p |
507 | type_optvalue (options_p prev, const char *name) |
508 | { |
509 | type_p ty; |
510 | require ('('); |
511 | ty = absdecl (); |
512 | require (')'); |
513 | return create_type_option (prev, name, ty); |
514 | } |
515 | |
516 | /* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */ |
517 | static options_p |
518 | nestedptr_optvalue (options_p prev) |
519 | { |
520 | type_p ty; |
521 | const char *from, *to; |
522 | |
523 | require ('('); |
524 | ty = absdecl (); |
525 | require (','); |
526 | to = string_seq (); |
527 | require (','); |
528 | from = string_seq (); |
529 | require (')'); |
530 | |
531 | return create_nested_ptr_option (prev, ty, to, from); |
532 | } |
533 | |
534 | /* One GTY(()) option: |
535 | ID str_optvalue_opt |
536 | | PTR_ALIAS type_optvalue |
537 | | NESTED_PTR nestedptr_optvalue |
538 | */ |
539 | static options_p |
540 | option (options_p prev) |
541 | { |
542 | switch (token ()) |
543 | { |
544 | case ID: |
545 | return str_optvalue_opt (prev); |
546 | |
547 | case PTR_ALIAS: |
548 | advance (); |
549 | return type_optvalue (prev, "ptr_alias"); |
550 | |
551 | case NESTED_PTR: |
552 | advance (); |
553 | return nestedptr_optvalue (prev); |
554 | |
555 | case USER_GTY: |
556 | advance (); |
557 | return create_string_option (prev, "user", ""); |
558 | |
559 | default: |
560 | parse_error ("expected an option keyword, have %s", print_cur_token ()); |
561 | advance (); |
562 | return create_string_option (prev, "", ""); |
563 | } |
564 | } |
565 | |
566 | /* One comma-separated list of options. */ |
567 | static options_p |
568 | option_seq (void) |
569 | { |
570 | options_p o; |
571 | |
572 | o = option (0); |
573 | while (token () == ',') |
574 | { |
575 | advance (); |
576 | o = option (o); |
577 | } |
578 | return o; |
579 | } |
580 | |
581 | /* GTY marker: 'GTY' '(' '(' option_seq? ')' ')' */ |
582 | static options_p |
583 | gtymarker (void) |
584 | { |
585 | options_p result = 0; |
586 | require (GTY_TOKEN); |
587 | require ('('); |
588 | require ('('); |
589 | if (token () != ')') |
590 | result = option_seq (); |
591 | require (')'); |
592 | require (')'); |
593 | return result; |
594 | } |
595 | |
596 | /* Optional GTY marker. */ |
597 | static options_p |
598 | gtymarker_opt (void) |
599 | { |
600 | if (token () != GTY_TOKEN) |
601 | return 0; |
602 | return gtymarker (); |
603 | } |
604 | |
605 | |
606 | |
607 | /* Declarators. The logic here is largely lifted from c-parser.cc. |
608 | Note that we do not have to process abstract declarators, which can |
609 | appear only in parameter type lists or casts (but see absdecl, |
610 | above). Also, type qualifiers are thrown out in gengtype-lex.l so |
611 | we don't have to do it. */ |
612 | |
613 | /* array_and_function_declarators_opt: |
614 | \epsilon |
615 | array_and_function_declarators_opt ARRAY |
616 | array_and_function_declarators_opt '(' ... ')' |
617 | |
618 | where '...' indicates stuff we ignore except insofar as grouping |
619 | symbols ()[]{} must balance. |
620 | |
621 | Subroutine of direct_declarator - do not use elsewhere. */ |
622 | |
623 | static type_p |
624 | array_and_function_declarators_opt (type_p ty) |
625 | { |
626 | if (token () == ARRAY) |
627 | { |
628 | const char *array = advance (); |
629 | return create_array (array_and_function_declarators_opt (ty), array); |
630 | } |
631 | else if (token () == '(') |
632 | { |
633 | /* We don't need exact types for functions. */ |
634 | consume_balanced ('(', ')'); |
635 | array_and_function_declarators_opt (ty); |
636 | return create_scalar_type ("function type"); |
637 | } |
638 | else |
639 | return ty; |
640 | } |
641 | |
642 | static type_p inner_declarator (type_p, const char **, options_p *, bool); |
643 | |
644 | /* direct_declarator: |
645 | '(' inner_declarator ')' |
646 | '(' \epsilon ')' <-- C++ ctors/dtors |
647 | gtymarker_opt ID array_and_function_declarators_opt |
648 | |
649 | Subroutine of declarator, mutually recursive with inner_declarator; |
650 | do not use elsewhere. |
651 | |
652 | IN_STRUCT is true if we are called while parsing structures or classes. */ |
653 | |
654 | static type_p |
655 | direct_declarator (type_p ty, const char **namep, options_p *optsp, |
656 | bool in_struct) |
657 | { |
658 | /* The first token in a direct-declarator must be an ID, a |
659 | GTY marker, or an open parenthesis. */ |
660 | switch (token ()) |
661 | { |
662 | case GTY_TOKEN: |
663 | *optsp = gtymarker (); |
664 | /* fall through */ |
665 | |
666 | case ID: |
667 | *namep = require (ID); |
668 | /* If the next token is '(', we are parsing a function declaration. |
669 | Functions are ignored by gengtype, so we return NULL. */ |
670 | if (token () == '(') |
671 | return NULLnullptr; |
672 | break; |
673 | |
674 | case '(': |
675 | /* If the declarator starts with a '(', we have three options. We |
676 | are either parsing 'TYPE (*ID)' (i.e., a function pointer) |
677 | or 'TYPE(...)'. |
678 | |
679 | The latter will be a constructor iff we are inside a |
680 | structure or class. Otherwise, it could be a typedef, but |
681 | since we explicitly reject typedefs inside structures, we can |
682 | assume that we found a ctor and return NULL. */ |
683 | advance (); |
684 | if (in_struct && token () != '*') |
685 | { |
686 | /* Found a constructor. Find and consume the closing ')'. */ |
687 | while (token () != ')') |
688 | advance (); |
689 | advance (); |
690 | /* Tell the caller to ignore this. */ |
691 | return NULLnullptr; |
692 | } |
693 | ty = inner_declarator (ty, namep, optsp, in_struct); |
694 | require (')'); |
695 | break; |
696 | |
697 | case IGNORABLE_CXX_KEYWORD: |
698 | /* Any C++ keyword like 'operator' means that we are not looking |
699 | at a regular data declarator. */ |
700 | return NULLnullptr; |
701 | |
702 | default: |
703 | parse_error ("expected '(', ')', 'GTY', or an identifier, have %s", |
704 | print_cur_token ()); |
705 | /* Do _not_ advance if what we have is a close squiggle brace, as |
706 | we will get much better error recovery that way. */ |
707 | if (token () != '}') |
708 | advance (); |
709 | return 0; |
710 | } |
711 | return array_and_function_declarators_opt (ty); |
712 | } |
713 | |
714 | /* The difference between inner_declarator and declarator is in the |
715 | handling of stars. Consider this declaration: |
716 | |
717 | char * (*pfc) (void) |
718 | |
719 | It declares a pointer to a function that takes no arguments and |
720 | returns a char*. To construct the correct type for this |
721 | declaration, the star outside the parentheses must be processed |
722 | _before_ the function type, the star inside the parentheses must |
723 | be processed _after_ the function type. To accomplish this, |
724 | declarator() creates pointers before recursing (it is actually |
725 | coded as a while loop), whereas inner_declarator() recurses before |
726 | creating pointers. */ |
727 | |
728 | /* inner_declarator: |
729 | '*' inner_declarator |
730 | direct_declarator |
731 | |
732 | Mutually recursive subroutine of direct_declarator; do not use |
733 | elsewhere. |
734 | |
735 | IN_STRUCT is true if we are called while parsing structures or classes. */ |
736 | |
737 | static type_p |
738 | inner_declarator (type_p ty, const char **namep, options_p *optsp, |
739 | bool in_struct) |
740 | { |
741 | if (token () == '*') |
742 | { |
743 | type_p inner; |
744 | advance (); |
745 | inner = inner_declarator (ty, namep, optsp, in_struct); |
746 | if (inner == 0) |
747 | return 0; |
748 | else |
749 | return create_pointer (ty); |
750 | } |
751 | else |
752 | return direct_declarator (ty, namep, optsp, in_struct); |
753 | } |
754 | |
755 | /* declarator: '*'+ direct_declarator |
756 | |
757 | This is the sole public interface to this part of the grammar. |
758 | Arguments are the type known so far, a pointer to where the name |
759 | may be stored, and a pointer to where GTY options may be stored. |
760 | |
761 | IN_STRUCT is true when we are called to parse declarators inside |
762 | a structure or class. |
763 | |
764 | Returns the final type. */ |
765 | |
766 | static type_p |
767 | declarator (type_p ty, const char **namep, options_p *optsp, |
768 | bool in_struct = false) |
769 | { |
770 | *namep = 0; |
771 | *optsp = 0; |
772 | while (token () == '*') |
773 | { |
774 | advance (); |
775 | ty = create_pointer (ty); |
776 | } |
777 | return direct_declarator (ty, namep, optsp, in_struct); |
778 | } |
779 | |
780 | /* Types and declarations. */ |
781 | |
782 | /* Structure field(s) declaration: |
783 | ( |
784 | type bitfield ';' |
785 | | type declarator bitfield? ( ',' declarator bitfield? )+ ';' |
786 | )* |
787 | |
788 | Knows that such declarations must end with a close brace (or, |
789 | erroneously, at EOF). |
790 | */ |
791 | static pair_p |
792 | struct_field_seq (void) |
793 | { |
794 | pair_p f = 0; |
795 | type_p ty, dty; |
796 | options_p opts, dopts; |
797 | const char *name; |
798 | bool another; |
799 | |
800 | while (token () != '}' && token () != EOF_TOKEN) |
801 | { |
802 | ty = type (&opts, true); |
803 | |
804 | /* Ignore access-control keywords ("public:" etc). */ |
805 | while (!ty && token () == IGNORABLE_CXX_KEYWORD) |
806 | { |
807 | const char *keyword = advance (); |
808 | if (strcmp (keyword, "public:") != 0 |
809 | && strcmp (keyword, "private:") != 0 |
810 | && strcmp (keyword, "protected:") != 0) |
811 | break; |
812 | ty = type (&opts, true); |
813 | } |
814 | |
815 | if (!ty || token () == ':') |
816 | { |
817 | consume_until_eos (); |
818 | continue; |
819 | } |
820 | |
821 | do |
822 | { |
823 | dty = declarator (ty, &name, &dopts, true); |
824 | |
825 | /* There could be any number of weird things after the declarator, |
826 | notably bitfield declarations and __attribute__s. If this |
827 | function returns true, the last thing was a comma, so we have |
828 | more than one declarator paired with the current type. */ |
829 | another = consume_until_comma_or_eos (); |
830 | |
831 | if (!dty) |
832 | continue; |
833 | |
834 | if (opts && dopts) |
835 | parse_error ("two GTY(()) options for field %s", name); |
836 | if (opts && !dopts) |
837 | dopts = opts; |
838 | |
839 | f = create_field_at (f, dty, name, dopts, &lexer_line); |
840 | } |
841 | while (another); |
842 | } |
843 | return nreverse_pairs (f); |
844 | } |
845 | |
846 | /* Return true if OPTS contain the option named STR. */ |
847 | |
848 | bool |
849 | opts_have (options_p opts, const char *str) |
850 | { |
851 | for (options_p opt = opts; opt; opt = opt->next) |
852 | if (strcmp (opt->name, str) == 0) |
853 | return true; |
854 | return false; |
855 | } |
856 | |
857 | |
858 | /* This is called type(), but what it parses (sort of) is what C calls |
859 | declaration-specifiers and specifier-qualifier-list: |
860 | |
861 | SCALAR |
862 | | ID // typedef |
863 | | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )? |
864 | | ENUM ID ( '{' ... '}' )? |
865 | |
866 | Returns a partial type; under some conditions (notably |
867 | "struct foo GTY((...)) thing;") it may write an options |
868 | structure to *OPTSP. |
869 | |
870 | NESTED is true when parsing a declaration already known to have a |
871 | GTY marker. In these cases, typedef and enum declarations are not |
872 | allowed because gengtype only understands types at the global |
873 | scope. */ |
874 | |
875 | static type_p |
876 | type (options_p *optsp, bool nested) |
877 | { |
878 | const char *s; |
879 | *optsp = 0; |
880 | switch (token ()) |
881 | { |
882 | case SCALAR: |
883 | s = advance (); |
884 | return create_scalar_type (s); |
885 | |
886 | case ID: |
887 | s = typedef_name (); |
888 | return resolve_typedef (s, &lexer_line); |
889 | |
890 | case IGNORABLE_CXX_KEYWORD: |
891 | /* By returning NULL here, we indicate to the caller that they |
892 | should ignore everything following this keyword up to the |
893 | next ';' or '}'. */ |
894 | return NULLnullptr; |
895 | |
896 | case STRUCT: |
897 | case UNION: |
898 | { |
899 | type_p base_class = NULLnullptr; |
900 | options_p opts = 0; |
901 | /* GTY annotations follow attribute syntax |
902 | GTY_BEFORE_ID is for union/struct declarations |
903 | GTY_AFTER_ID is for variable declarations. */ |
904 | enum |
905 | { |
906 | NO_GTY, |
907 | GTY_BEFORE_ID, |
908 | GTY_AFTER_ID |
909 | } is_gty = NO_GTY; |
910 | enum typekind kind = (token () == UNION) ? TYPE_UNION : TYPE_STRUCT; |
911 | advance (); |
912 | |
913 | /* Top-level structures that are not explicitly tagged GTY(()) |
914 | are treated as mere forward declarations. This is because |
915 | there are a lot of structures that we don't need to know |
916 | about, and some of those have C++ and macro constructs that |
917 | we cannot handle. */ |
918 | if (nested || token () == GTY_TOKEN) |
919 | { |
920 | is_gty = GTY_BEFORE_ID; |
921 | opts = gtymarker_opt (); |
922 | } |
923 | |
924 | if (token () == ID) |
925 | s = advance (); |
926 | else |
927 | s = xasprintf ("anonymous:%s:%d", |
928 | get_input_file_name (lexer_line.file), |
929 | lexer_line.line); |
930 | |
931 | /* Unfortunately above GTY_TOKEN check does not capture the |
932 | typedef struct_type GTY case. */ |
933 | if (token () == GTY_TOKEN) |
934 | { |
935 | is_gty = GTY_AFTER_ID; |
936 | opts = gtymarker_opt (); |
937 | } |
938 | |
939 | bool is_user_gty = opts_have (opts, "user"); |
940 | |
941 | if (token () == ':') |
942 | { |
943 | if (is_gty && !is_user_gty) |
944 | { |
945 | /* For GTY-marked types that are not "user", parse some C++ |
946 | inheritance specifications. |
947 | We require single-inheritance from a non-template type. */ |
948 | advance (); |
949 | const char *basename = require (ID); |
950 | /* This may be either an access specifier, or the base name. */ |
951 | if (strcmp (basename, "public") == 0 |
952 | || strcmp (basename, "protected") == 0 |
953 | || strcmp (basename, "private") == 0) |
954 | basename = require (ID); |
955 | base_class = find_structure (basename, TYPE_STRUCT); |
956 | if (!base_class) |
957 | parse_error ("unrecognized base class: %s", basename); |
958 | require_without_advance ('{'); |
959 | } |
960 | else |
961 | { |
962 | /* For types lacking GTY-markings, skip over C++ inheritance |
963 | specification (and thus avoid having to parse e.g. template |
964 | types). */ |
965 | while (token () != '{') |
966 | advance (); |
967 | } |
968 | } |
969 | |
970 | if (is_gty) |
971 | { |
972 | if (token () == '{') |
973 | { |
974 | pair_p fields; |
975 | |
976 | if (is_gty == GTY_AFTER_ID) |
977 | parse_error ("GTY must be specified before identifier"); |
978 | |
979 | if (!is_user_gty) |
980 | { |
981 | advance (); |
982 | fields = struct_field_seq (); |
983 | require ('}'); |
984 | } |
985 | else |
986 | { |
987 | /* Do not look inside user defined structures. */ |
988 | fields = NULLnullptr; |
989 | kind = TYPE_USER_STRUCT; |
Value stored to 'kind' is never read | |
990 | consume_balanced ('{', '}'); |
991 | return create_user_defined_type (s, &lexer_line); |
992 | } |
993 | |
994 | return new_structure (s, kind, &lexer_line, fields, opts, |
995 | base_class); |
996 | } |
997 | } |
998 | else if (token () == '{') |
999 | consume_balanced ('{', '}'); |
1000 | if (opts) |
1001 | *optsp = opts; |
1002 | return find_structure (s, kind); |
1003 | } |
1004 | |
1005 | case TYPEDEF: |
1006 | /* In C++, a typedef inside a struct/class/union defines a new |
1007 | type for that inner scope. We cannot support this in |
1008 | gengtype because we have no concept of scoping. |
1009 | |
1010 | We handle typedefs in the global scope separately (see |
1011 | parse_file), so if we find a 'typedef', we must be inside |
1012 | a struct. */ |
1013 | gcc_assert (nested)((void)(!(nested) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gengtype-parse.cc" , 1013, __FUNCTION__), 0 : 0)); |
1014 | parse_error ("typedefs not supported in structures marked with " |
1015 | "automatic GTY markers. Use GTY((user)) to mark " |
1016 | "this structure."); |
1017 | advance (); |
1018 | return NULLnullptr; |
1019 | |
1020 | case ENUM: |
1021 | advance (); |
1022 | if (token () == ID) |
1023 | s = advance (); |
1024 | else |
1025 | s = xasprintf ("anonymous:%s:%d", |
1026 | get_input_file_name (lexer_line.file), |
1027 | lexer_line.line); |
1028 | |
1029 | if (token () == '{') |
1030 | consume_balanced ('{', '}'); |
1031 | |
1032 | /* If after parsing the enum we are at the end of the statement, |
1033 | and we are currently inside a structure, then this was an |
1034 | enum declaration inside this scope. |
1035 | |
1036 | We cannot support this for the same reason we cannot support |
1037 | 'typedef' inside structures (see the TYPEDEF handler above). |
1038 | If this happens, emit an error and return NULL. */ |
1039 | if (nested && token () == ';') |
1040 | { |
1041 | parse_error ("enum definitions not supported in structures marked " |
1042 | "with automatic GTY markers. Use GTY((user)) to mark " |
1043 | "this structure."); |
1044 | advance (); |
1045 | return NULLnullptr; |
1046 | } |
1047 | |
1048 | return create_scalar_type (s); |
1049 | |
1050 | default: |
1051 | parse_error ("expected a type specifier, have %s", print_cur_token ()); |
1052 | advance (); |
1053 | return create_scalar_type ("erroneous type"); |
1054 | } |
1055 | } |
1056 | |
1057 | /* Top level constructs. */ |
1058 | |
1059 | /* Dispatch declarations beginning with 'typedef'. */ |
1060 | |
1061 | static void |
1062 | typedef_decl (void) |
1063 | { |
1064 | type_p ty, dty; |
1065 | const char *name; |
1066 | options_p opts; |
1067 | bool another; |
1068 | |
1069 | gcc_assert (token () == TYPEDEF)((void)(!(token () == TYPEDEF) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gengtype-parse.cc" , 1069, __FUNCTION__), 0 : 0)); |
1070 | advance (); |
1071 | |
1072 | ty = type (&opts, false); |
1073 | if (!ty) |
1074 | return; |
1075 | if (opts) |
1076 | parse_error ("GTY((...)) cannot be applied to a typedef"); |
1077 | do |
1078 | { |
1079 | dty = declarator (ty, &name, &opts); |
1080 | if (opts) |
1081 | parse_error ("GTY((...)) cannot be applied to a typedef"); |
1082 | |
1083 | /* Yet another place where we could have junk (notably attributes) |
1084 | after the declarator. */ |
1085 | another = consume_until_comma_or_eos (); |
1086 | if (dty) |
1087 | do_typedef (name, dty, &lexer_line); |
1088 | } |
1089 | while (another); |
1090 | } |
1091 | |
1092 | /* Structure definition: type() does all the work. */ |
1093 | |
1094 | static void |
1095 | struct_or_union (void) |
1096 | { |
1097 | options_p dummy; |
1098 | type (&dummy, false); |
1099 | /* There may be junk after the type: notably, we cannot currently |
1100 | distinguish 'struct foo *function(prototype);' from 'struct foo;' |
1101 | ... we could call declarator(), but it's a waste of time at |
1102 | present. Instead, just eat whatever token is currently lookahead |
1103 | and go back to lexical skipping mode. */ |
1104 | advance (); |
1105 | } |
1106 | |
1107 | /* GC root declaration: |
1108 | (extern|static) gtymarker? type ID array_declarators_opt (';'|'=') |
1109 | If the gtymarker is not present, we ignore the rest of the declaration. */ |
1110 | static void |
1111 | extern_or_static (void) |
1112 | { |
1113 | options_p opts, opts2, dopts; |
1114 | type_p ty, dty; |
1115 | const char *name; |
1116 | require2 (EXTERN, STATIC); |
1117 | |
1118 | if (token () != GTY_TOKEN) |
1119 | { |
1120 | advance (); |
1121 | return; |
1122 | } |
1123 | |
1124 | opts = gtymarker (); |
1125 | ty = type (&opts2, true); /* if we get here, it's got a GTY(()) */ |
1126 | dty = declarator (ty, &name, &dopts); |
1127 | |
1128 | if ((opts && dopts) || (opts && opts2) || (opts2 && dopts)) |
1129 | parse_error ("GTY((...)) specified more than once for %s", name); |
1130 | else if (opts2) |
1131 | opts = opts2; |
1132 | else if (dopts) |
1133 | opts = dopts; |
1134 | |
1135 | if (dty) |
1136 | { |
1137 | note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line); |
1138 | require2 (';', '='); |
1139 | } |
1140 | } |
1141 | |
1142 | /* Parse the file FNAME for GC-relevant declarations and definitions. |
1143 | This is the only entry point to this file. */ |
1144 | void |
1145 | parse_file (const char *fname) |
1146 | { |
1147 | yybegin (fname); |
1148 | for (;;) |
1149 | { |
1150 | switch (token ()) |
1151 | { |
1152 | case EXTERN: |
1153 | case STATIC: |
1154 | extern_or_static (); |
1155 | break; |
1156 | |
1157 | case STRUCT: |
1158 | case UNION: |
1159 | struct_or_union (); |
1160 | break; |
1161 | |
1162 | case TYPEDEF: |
1163 | typedef_decl (); |
1164 | break; |
1165 | |
1166 | case EOF_TOKEN: |
1167 | goto eof; |
1168 | |
1169 | default: |
1170 | parse_error ("unexpected top level token, %s", print_cur_token ()); |
1171 | goto eof; |
1172 | } |
1173 | lexer_toplevel_done = 1; |
1174 | } |
1175 | |
1176 | eof: |
1177 | advance (); |
1178 | yyend (); |
1179 | } |