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