]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gengtype-parse.c
alias-1.c: Require alias support.
[thirdparty/gcc.git] / gcc / gengtype-parse.c
CommitLineData
703d89ab 1/* Process source files and output type information.
9dcd6f09 2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
703d89ab 3
e1b793e7 4 This file is part of GCC.
703d89ab 5
e1b793e7
BS
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.
703d89ab 10
e1b793e7
BS
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.
703d89ab 15
e1b793e7
BS
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/>. */
703d89ab
ZW
19
20#include "bconfig.h"
21#include "system.h"
22#include "gengtype.h"
23
24/* This is a simple recursive-descent parser which understands a subset of
25 the C type grammar.
26
27 Rule functions are suffixed _seq if they scan a sequence of items;
28 _opt if they may consume zero tokens; _seqopt if both are true. The
29 "consume_" prefix indicates that a sequence of tokens is parsed for
30 syntactic correctness and then thrown away. */
31
32/* Simple one-token lookahead mechanism. */
33
34struct token
35{
36 const char *value;
37 int code;
38 bool valid;
39};
40static struct token T;
41
42/* Retrieve the code of the current token; if there is no current token,
43 get the next one from the lexer. */
44static inline int
45token (void)
46{
47 if (!T.valid)
48 {
49 T.code = yylex (&T.value);
50 T.valid = true;
51 }
52 return T.code;
53}
54
55/* Retrieve the value of the current token (if any) and mark it consumed.
56 The next call to token() will get another token from the lexer. */
57static inline const char *
58advance (void)
59{
60 T.valid = false;
61 return T.value;
62}
63
64/* Diagnostics. */
65
66/* This array is indexed by the token code minus CHAR_TOKEN_OFFSET. */
67static const char *const token_names[] = {
68 "GTY",
69 "typedef",
70 "extern",
71 "static",
72 "union",
73 "struct",
74 "enum",
75 "VEC",
76 "DEF_VEC_[OP]",
77 "DEF_VEC_I",
78 "DEF_VEC_ALLOC_[IOP]",
79 "...",
80 "ptr_alias",
81 "nested_ptr",
82 "a param<N>_is option",
83 "a number",
84 "a scalar type",
85 "an identifier",
86 "a string constant",
87 "a character constant",
88 "an array declarator",
89};
90
91/* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */
92static const char *const token_value_format[] = {
93 "%s",
94 "'%s'",
95 "'%s'",
96 "'%s'",
97 "'\"%s\"'",
98 "\"'%s'\"",
99 "'[%s]'",
100};
101
102/* Produce a printable representation for a token defined by CODE and
103 VALUE. This sometimes returns pointers into malloc memory and
104 sometimes not, therefore it is unsafe to free the pointer it
105 returns, so that memory is leaked. This does not matter, as this
106 function is only used for diagnostics, and in a successful run of
107 the program there will be none. */
108static const char *
109print_token (int code, const char *value)
110{
111 if (code < CHAR_TOKEN_OFFSET)
112 return xasprintf ("'%c'", code);
113 else if (code < FIRST_TOKEN_WITH_VALUE)
114 return xasprintf ("'%s'", token_names[code - CHAR_TOKEN_OFFSET]);
115 else if (!value)
e1b793e7 116 return token_names[code - CHAR_TOKEN_OFFSET]; /* don't quote these */
703d89ab
ZW
117 else
118 return xasprintf (token_value_format[code - FIRST_TOKEN_WITH_VALUE],
119 value);
120}
121
122/* Convenience wrapper around print_token which produces the printable
123 representation of the current token. */
124static inline const char *
125print_cur_token (void)
126{
127 return print_token (T.code, T.value);
128}
129
130/* Report a parse error on the current line, with diagnostic MSG.
131 Behaves as standard printf with respect to additional arguments and
132 format escapes. */
133static void ATTRIBUTE_PRINTF_1
134parse_error (const char *msg, ...)
135{
136 va_list ap;
137
14c4815e
BS
138 fprintf (stderr, "%s:%d: parse error: ",
139 get_input_file_name (lexer_line.file), lexer_line.line);
703d89ab
ZW
140
141 va_start (ap, msg);
142 vfprintf (stderr, msg, ap);
143 va_end (ap);
144
ad58aabe
DN
145 fputc ('\n', stderr);
146
703d89ab
ZW
147 hit_error = true;
148}
149
150/* If the next token does not have code T, report a parse error; otherwise
151 return the token's value. */
152static const char *
153require (int t)
154{
155 int u = token ();
156 const char *v = advance ();
157 if (u != t)
158 {
159 parse_error ("expected %s, have %s",
160 print_token (t, 0), print_token (u, v));
161 return 0;
162 }
163 return v;
164}
165
166/* If the next token does not have one of the codes T1 or T2, report a
167 parse error; otherwise return the token's value. */
168static const char *
169require2 (int t1, int t2)
170{
171 int u = token ();
172 const char *v = advance ();
173 if (u != t1 && u != t2)
174 {
175 parse_error ("expected %s or %s, have %s",
176 print_token (t1, 0), print_token (t2, 0),
177 print_token (u, v));
178 return 0;
179 }
180 return v;
181}
182
183/* Near-terminals. */
184
185/* C-style string constant concatenation: STRING+
186 Bare STRING should appear nowhere else in this file. */
187static const char *
188string_seq (void)
189{
190 const char *s1, *s2;
191 size_t l1, l2;
192 char *buf;
193
194 s1 = require (STRING);
195 if (s1 == 0)
196 return "";
197 while (token () == STRING)
198 {
199 s2 = advance ();
200
201 l1 = strlen (s1);
202 l2 = strlen (s2);
e1b793e7 203 buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1);
703d89ab 204 memcpy (buf + l1, s2, l2 + 1);
b1d5455a 205 XDELETE (CONST_CAST (char *, s2));
703d89ab
ZW
206 s1 = buf;
207 }
208 return s1;
209}
210
211/* typedef_name: either an ID, or VEC(x,y) which is translated to VEC_x_y.
212 Use only where VEC(x,y) is legitimate, i.e. in positions where a
213 typedef name may appear. */
214static const char *
215typedef_name (void)
216{
217 if (token () == VEC_TOKEN)
218 {
219 const char *c1, *c2, *r;
220 advance ();
221 require ('(');
222 c1 = require2 (ID, SCALAR);
223 require (',');
224 c2 = require (ID);
225 require (')');
e1b793e7 226 r = concat ("VEC_", c1, "_", c2, (char *) 0);
b1d5455a
KG
227 free (CONST_CAST (char *, c1));
228 free (CONST_CAST (char *, c2));
703d89ab
ZW
229 return r;
230 }
231 else
232 return require (ID);
233}
234
235/* Absorb a sequence of tokens delimited by balanced ()[]{}. */
236static void
237consume_balanced (int opener, int closer)
238{
239 require (opener);
240 for (;;)
241 switch (token ())
242 {
e1b793e7
BS
243 default:
244 advance ();
245 break;
246 case '(':
247 consume_balanced ('(', ')');
248 break;
249 case '[':
250 consume_balanced ('[', ']');
251 break;
252 case '{':
253 consume_balanced ('{', '}');
254 break;
703d89ab
ZW
255
256 case '}':
257 case ']':
258 case ')':
259 if (token () != closer)
260 parse_error ("unbalanced delimiters - expected '%c', have '%c'",
261 closer, token ());
e1b793e7
BS
262 advance ();
263 return;
703d89ab
ZW
264
265 case EOF_TOKEN:
266 parse_error ("unexpected end of file within %c%c-delimited construct",
267 opener, closer);
268 return;
269 }
270}
271
272/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
273 expressions, until we encounter a semicolon outside any such
274 delimiters; absorb that too. If IMMEDIATE is true, it is an error
275 if the semicolon is not the first token encountered. */
276static void
277consume_until_semi (bool immediate)
278{
279 if (immediate && token () != ';')
280 require (';');
281 for (;;)
282 switch (token ())
283 {
e1b793e7
BS
284 case ';':
285 advance ();
286 return;
287 default:
288 advance ();
289 break;
703d89ab 290
e1b793e7
BS
291 case '(':
292 consume_balanced ('(', ')');
293 break;
294 case '[':
295 consume_balanced ('[', ']');
296 break;
297 case '{':
298 consume_balanced ('{', '}');
299 break;
703d89ab
ZW
300
301 case '}':
302 case ']':
303 case ')':
304 parse_error ("unmatched '%c' while scanning for ';'", token ());
e1b793e7 305 return;
703d89ab
ZW
306
307 case EOF_TOKEN:
308 parse_error ("unexpected end of file while scanning for ';'");
309 return;
310 }
311}
312
313/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
314 expressions, until we encounter a comma or semicolon outside any
315 such delimiters; absorb that too. If IMMEDIATE is true, it is an
316 error if the comma or semicolon is not the first token encountered.
317 Returns true if the loop ended with a comma. */
318static bool
319consume_until_comma_or_semi (bool immediate)
320{
321 if (immediate && token () != ',' && token () != ';')
322 require2 (',', ';');
323 for (;;)
324 switch (token ())
325 {
e1b793e7
BS
326 case ',':
327 advance ();
328 return true;
329 case ';':
330 advance ();
331 return false;
332 default:
333 advance ();
334 break;
703d89ab 335
e1b793e7
BS
336 case '(':
337 consume_balanced ('(', ')');
338 break;
339 case '[':
340 consume_balanced ('[', ']');
341 break;
342 case '{':
343 consume_balanced ('{', '}');
344 break;
703d89ab
ZW
345
346 case '}':
347 case ']':
348 case ')':
349 parse_error ("unmatched '%s' while scanning for ',' or ';'",
350 print_cur_token ());
e1b793e7 351 return false;
703d89ab
ZW
352
353 case EOF_TOKEN:
354 parse_error ("unexpected end of file while scanning for ',' or ';'");
355 return false;
356 }
357}
703d89ab 358\f
e1b793e7 359
703d89ab
ZW
360/* GTY(()) option handling. */
361static type_p type (options_p *optsp, bool nested);
362
363/* Optional parenthesized string: ('(' string_seq ')')? */
364static options_p
365str_optvalue_opt (options_p prev)
366{
367 const char *name = advance ();
368 const char *value = "";
369 if (token () == '(')
370 {
371 advance ();
372 value = string_seq ();
373 require (')');
374 }
375 return create_option (prev, name, value);
376}
377
378/* absdecl: type '*'*
379 -- a vague approximation to what the C standard calls an abstract
380 declarator. The only kinds that are actually used are those that
381 are just a bare type and those that have trailing pointer-stars.
382 Further kinds should be implemented if and when they become
383 necessary. Used only within GTY(()) option values, therefore
384 further GTY(()) tags within the type are invalid. Note that the
385 return value has already been run through adjust_field_type. */
386static type_p
387absdecl (void)
388{
389 type_p ty;
390 options_p opts;
391
392 ty = type (&opts, true);
393 while (token () == '*')
394 {
395 ty = create_pointer (ty);
396 advance ();
397 }
398
399 if (opts)
400 parse_error ("nested GTY(()) options are invalid");
401
402 return adjust_field_type (ty, 0);
403}
404
405/* Type-option: '(' absdecl ')' */
406static options_p
407type_optvalue (options_p prev, const char *name)
408{
409 type_p ty;
410 require ('(');
411 ty = absdecl ();
412 require (')');
413 return create_option (prev, name, ty);
414}
415
416/* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */
417static options_p
418nestedptr_optvalue (options_p prev)
419{
420 type_p ty;
421 const char *from, *to;
422
423 require ('(');
424 ty = absdecl ();
425 require (',');
426 to = string_seq ();
427 require (',');
428 from = string_seq ();
429 require (')');
430
431 return create_nested_ptr_option (prev, ty, to, from);
432}
433
434/* One GTY(()) option:
e1b793e7
BS
435 ID str_optvalue_opt
436 | PTR_ALIAS type_optvalue
437 | PARAM_IS type_optvalue
438 | NESTED_PTR nestedptr_optvalue
439*/
703d89ab
ZW
440static options_p
441option (options_p prev)
442{
443 switch (token ())
444 {
445 case ID:
446 return str_optvalue_opt (prev);
447
448 case PTR_ALIAS:
449 advance ();
450 return type_optvalue (prev, "ptr_alias");
451
452 case PARAM_IS:
453 return type_optvalue (prev, advance ());
454
455 case NESTED_PTR:
456 advance ();
457 return nestedptr_optvalue (prev);
458
459 default:
e1b793e7 460 parse_error ("expected an option keyword, have %s", print_cur_token ());
703d89ab
ZW
461 advance ();
462 return create_option (prev, "", "");
463 }
464}
465
466/* One comma-separated list of options. */
467static options_p
468option_seq (void)
469{
470 options_p o;
471
472 o = option (0);
473 while (token () == ',')
474 {
475 advance ();
476 o = option (o);
477 }
478 return o;
479}
480
481/* GTY marker: 'GTY' '(' '(' option_seq? ')' ')' */
482static options_p
483gtymarker (void)
484{
485 options_p result = 0;
486 require (GTY_TOKEN);
487 require ('(');
488 require ('(');
489 if (token () != ')')
490 result = option_seq ();
491 require (')');
492 require (')');
493 return result;
494}
495
496/* Optional GTY marker. */
497static options_p
498gtymarker_opt (void)
499{
500 if (token () != GTY_TOKEN)
501 return 0;
502 return gtymarker ();
503}
504\f
505/* Declarators. The logic here is largely lifted from c-parser.c.
506 Note that we do not have to process abstract declarators, which can
507 appear only in parameter type lists or casts (but see absdecl,
508 above). Also, type qualifiers are thrown out in gengtype-lex.l so
509 we don't have to do it. */
510
511/* array_and_function_declarators_opt:
e1b793e7
BS
512 \epsilon
513 array_and_function_declarators_opt ARRAY
514 array_and_function_declarators_opt '(' ... ')'
703d89ab
ZW
515
516 where '...' indicates stuff we ignore except insofar as grouping
517 symbols ()[]{} must balance.
518
519 Subroutine of direct_declarator - do not use elsewhere. */
520
521static type_p
522array_and_function_declarators_opt (type_p ty)
523{
524 if (token () == ARRAY)
525 {
526 const char *array = advance ();
527 return create_array (array_and_function_declarators_opt (ty), array);
528 }
529 else if (token () == '(')
530 {
531 /* We don't need exact types for functions. */
532 consume_balanced ('(', ')');
533 array_and_function_declarators_opt (ty);
534 return create_scalar_type ("function type");
535 }
536 else
537 return ty;
538}
539
540static type_p inner_declarator (type_p, const char **, options_p *);
541
542/* direct_declarator:
e1b793e7
BS
543 '(' inner_declarator ')'
544 gtymarker_opt ID array_and_function_declarators_opt
703d89ab
ZW
545
546 Subroutine of declarator, mutually recursive with inner_declarator;
547 do not use elsewhere. */
548static type_p
549direct_declarator (type_p ty, const char **namep, options_p *optsp)
550{
551 /* The first token in a direct-declarator must be an ID, a
552 GTY marker, or an open parenthesis. */
553 switch (token ())
554 {
555 case GTY_TOKEN:
556 *optsp = gtymarker ();
557 /* fall through */
558 case ID:
559 *namep = require (ID);
560 break;
561
562 case '(':
563 advance ();
564 ty = inner_declarator (ty, namep, optsp);
565 require (')');
566 break;
567
568 default:
569 parse_error ("expected '(', 'GTY', or an identifier, have %s",
570 print_cur_token ());
571 /* Do _not_ advance if what we have is a close squiggle brace, as
572 we will get much better error recovery that way. */
573 if (token () != '}')
574 advance ();
575 return 0;
576 }
577 return array_and_function_declarators_opt (ty);
578}
579
580/* The difference between inner_declarator and declarator is in the
581 handling of stars. Consider this declaration:
582
e1b793e7 583 char * (*pfc) (void)
703d89ab
ZW
584
585 It declares a pointer to a function that takes no arguments and
586 returns a char*. To construct the correct type for this
587 declaration, the star outside the parentheses must be processed
588 _before_ the function type, the star inside the parentheses must
589 be processed _after_ the function type. To accomplish this,
590 declarator() creates pointers before recursing (it is actually
591 coded as a while loop), whereas inner_declarator() recurses before
592 creating pointers. */
593
594/* inner_declarator:
e1b793e7
BS
595 '*' inner_declarator
596 direct_declarator
703d89ab
ZW
597
598 Mutually recursive subroutine of direct_declarator; do not use
599 elsewhere. */
600
601static type_p
602inner_declarator (type_p ty, const char **namep, options_p *optsp)
603{
604 if (token () == '*')
605 {
606 type_p inner;
607 advance ();
608 inner = inner_declarator (ty, namep, optsp);
609 if (inner == 0)
610 return 0;
611 else
612 return create_pointer (ty);
613 }
614 else
615 return direct_declarator (ty, namep, optsp);
616}
617
618/* declarator: '*'+ direct_declarator
619
620 This is the sole public interface to this part of the grammar.
621 Arguments are the type known so far, a pointer to where the name
622 may be stored, and a pointer to where GTY options may be stored.
623 Returns the final type. */
624
625static type_p
626declarator (type_p ty, const char **namep, options_p *optsp)
627{
628 *namep = 0;
629 *optsp = 0;
630 while (token () == '*')
631 {
632 advance ();
633 ty = create_pointer (ty);
634 }
635 return direct_declarator (ty, namep, optsp);
636}
637\f
638/* Types and declarations. */
639
640/* Structure field(s) declaration:
641 (
e1b793e7
BS
642 type bitfield ';'
643 | type declarator bitfield? ( ',' declarator bitfield? )+ ';'
703d89ab
ZW
644 )+
645
646 Knows that such declarations must end with a close brace (or,
647 erroneously, at EOF).
e1b793e7 648*/
703d89ab
ZW
649static pair_p
650struct_field_seq (void)
651{
652 pair_p f = 0;
653 type_p ty, dty;
654 options_p opts, dopts;
655 const char *name;
656 bool another;
657
658 do
659 {
660 ty = type (&opts, true);
661 /* Another piece of the IFCVT_EXTRA_FIELDS special case, see type(). */
662 if (!ty && token () == '}')
663 break;
664
665 if (!ty || token () == ':')
666 {
667 consume_until_semi (false);
668 continue;
669 }
670
671 do
672 {
673 dty = declarator (ty, &name, &dopts);
674 /* There could be any number of weird things after the declarator,
675 notably bitfield declarations and __attribute__s. If this
676 function returns true, the last thing was a comma, so we have
677 more than one declarator paired with the current type. */
678 another = consume_until_comma_or_semi (false);
679
680 if (!dty)
681 continue;
682
683 if (opts && dopts)
684 parse_error ("two GTY(()) options for field %s", name);
685 if (opts && !dopts)
686 dopts = opts;
687
688 f = create_field_at (f, dty, name, dopts, &lexer_line);
689 }
690 while (another);
691 }
692 while (token () != '}' && token () != EOF_TOKEN);
693 return nreverse_pairs (f);
694}
695
696/* This is called type(), but what it parses (sort of) is what C calls
697 declaration-specifiers and specifier-qualifier-list:
698
e1b793e7 699 SCALAR
703d89ab
ZW
700 | ID // typedef
701 | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )?
702 | ENUM ID ( '{' ... '}' )?
703
704 Returns a partial type; under some conditions (notably
705 "struct foo GTY((...)) thing;") it may write an options
706 structure to *OPTSP.
e1b793e7 707*/
703d89ab
ZW
708static type_p
709type (options_p *optsp, bool nested)
710{
711 const char *s;
703d89ab
ZW
712 *optsp = 0;
713 switch (token ())
714 {
715 case SCALAR:
716 s = advance ();
717 return create_scalar_type (s);
718
719 case ID:
720 case VEC_TOKEN:
721 s = typedef_name ();
722 return resolve_typedef (s, &lexer_line);
723
724 case STRUCT:
725 case UNION:
726 {
727 options_p opts = 0;
e1b793e7
BS
728 /* GTY annotations follow attribute syntax
729 GTY_BEFORE_ID is for union/struct declarations
730 GTY_AFTER_ID is for variable declarations. */
731 enum
732 {
733 NO_GTY,
734 GTY_BEFORE_ID,
735 GTY_AFTER_ID
736 } is_gty = NO_GTY;
737 bool is_union = (token () == UNION);
703d89ab
ZW
738 advance ();
739
703d89ab
ZW
740 /* Top-level structures that are not explicitly tagged GTY(())
741 are treated as mere forward declarations. This is because
742 there are a lot of structures that we don't need to know
743 about, and some of those have weird macro stuff in them
744 that we can't handle. */
745 if (nested || token () == GTY_TOKEN)
746 {
e1b793e7
BS
747 is_gty = GTY_BEFORE_ID;
748 opts = gtymarker_opt ();
703d89ab 749 }
d1b38208
TG
750
751 if (token () == ID)
752 s = advance ();
753 else
a618dbe3
L
754 s = xasprintf ("anonymous:%s:%d",
755 get_input_file_name (lexer_line.file),
756 lexer_line.line);
d1b38208 757
e1b793e7
BS
758 /* Unfortunately above GTY_TOKEN check does not capture the
759 typedef struct_type GTY case. */
d1b38208
TG
760 if (token () == GTY_TOKEN)
761 {
e1b793e7
BS
762 is_gty = GTY_AFTER_ID;
763 opts = gtymarker_opt ();
d1b38208 764 }
b8698a0f 765
e1b793e7
BS
766 if (is_gty)
767 {
768 if (token () == '{')
769 {
770 pair_p fields;
771
772 if (is_gty == GTY_AFTER_ID)
773 parse_error ("GTY must be specified before identifier");
774
775 advance ();
776 fields = struct_field_seq ();
777 require ('}');
778 return new_structure (s, is_union, &lexer_line, fields, opts);
779 }
780 }
781 else if (token () == '{')
782 consume_balanced ('{', '}');
703d89ab
ZW
783 if (opts)
784 *optsp = opts;
785 return find_structure (s, is_union);
786 }
787
788 case ENUM:
789 advance ();
e1b793e7
BS
790 if (token () == ID)
791 s = advance ();
792 else
a618dbe3
L
793 s = xasprintf ("anonymous:%s:%d",
794 get_input_file_name (lexer_line.file),
795 lexer_line.line);
703d89ab
ZW
796
797 if (token () == '{')
e1b793e7 798 consume_balanced ('{', '}');
703d89ab
ZW
799 return create_scalar_type (s);
800
801 default:
802 parse_error ("expected a type specifier, have %s", print_cur_token ());
803 advance ();
804 return create_scalar_type ("erroneous type");
805 }
806}
807\f
808/* Top level constructs. */
809
810/* Dispatch declarations beginning with 'typedef'. */
811
812static void
813typedef_decl (void)
814{
815 type_p ty, dty;
816 const char *name;
817 options_p opts;
818 bool another;
819
820 gcc_assert (token () == TYPEDEF);
821 advance ();
822
823 ty = type (&opts, false);
824 if (!ty)
825 return;
826 if (opts)
827 parse_error ("GTY((...)) cannot be applied to a typedef");
828 do
829 {
830 dty = declarator (ty, &name, &opts);
831 if (opts)
832 parse_error ("GTY((...)) cannot be applied to a typedef");
833
834 /* Yet another place where we could have junk (notably attributes)
835 after the declarator. */
836 another = consume_until_comma_or_semi (false);
837 if (dty)
838 do_typedef (name, dty, &lexer_line);
839 }
840 while (another);
841}
842
843/* Structure definition: type() does all the work. */
844
845static void
846struct_or_union (void)
847{
848 options_p dummy;
849 type (&dummy, false);
850 /* There may be junk after the type: notably, we cannot currently
851 distinguish 'struct foo *function(prototype);' from 'struct foo;'
852 ... we could call declarator(), but it's a waste of time at
853 present. Instead, just eat whatever token is currently lookahead
854 and go back to lexical skipping mode. */
855 advance ();
856}
857
858/* GC root declaration:
e1b793e7 859 (extern|static) gtymarker? type ID array_declarators_opt (';'|'=')
703d89ab
ZW
860 If the gtymarker is not present, we ignore the rest of the declaration. */
861static void
862extern_or_static (void)
863{
864 options_p opts, opts2, dopts;
865 type_p ty, dty;
866 const char *name;
867 require2 (EXTERN, STATIC);
868
869 if (token () != GTY_TOKEN)
870 {
871 advance ();
872 return;
873 }
874
875 opts = gtymarker ();
e1b793e7
BS
876 ty = type (&opts2, true); /* if we get here, it's got a GTY(()) */
877 dty = declarator (ty, &name, &dopts);
703d89ab
ZW
878
879 if ((opts && dopts) || (opts && opts2) || (opts2 && dopts))
880 parse_error ("GTY((...)) specified more than once for %s", name);
881 else if (opts2)
882 opts = opts2;
883 else if (dopts)
884 opts = dopts;
885
886 if (dty)
887 {
888 note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line);
889 require2 (';', '=');
890 }
891}
892
893/* Definition of a generic VEC structure:
894
895 'DEF_VEC_[IPO]' '(' id ')' ';'
896
897 Scalar VECs require slightly different treatment than otherwise -
898 that's handled in note_def_vec, we just pass it along.*/
899static void
900def_vec (void)
901{
e1b793e7 902 bool is_scalar = (token () == DEFVEC_I);
703d89ab
ZW
903 const char *type;
904
905 require2 (DEFVEC_OP, DEFVEC_I);
906 require ('(');
907 type = require2 (ID, SCALAR);
908 require (')');
909 require (';');
910
911 if (!type)
912 return;
913
914 note_def_vec (type, is_scalar, &lexer_line);
915 note_def_vec_alloc (type, "none", &lexer_line);
916}
917
918/* Definition of an allocation strategy for a VEC structure:
919
920 'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';'
921
922 For purposes of gengtype, this just declares a wrapper structure. */
923static void
924def_vec_alloc (void)
925{
926 const char *type, *astrat;
927
928 require (DEFVEC_ALLOC);
929 require ('(');
930 type = require2 (ID, SCALAR);
931 require (',');
932 astrat = require (ID);
933 require (')');
934 require (';');
935
936 if (!type || !astrat)
937 return;
938
939 note_def_vec_alloc (type, astrat, &lexer_line);
940}
941
942/* Parse the file FNAME for GC-relevant declarations and definitions.
943 This is the only entry point to this file. */
944void
945parse_file (const char *fname)
946{
947 yybegin (fname);
948 for (;;)
949 {
950 switch (token ())
951 {
952 case EXTERN:
953 case STATIC:
954 extern_or_static ();
955 break;
956
957 case STRUCT:
958 case UNION:
959 struct_or_union ();
960 break;
961
962 case TYPEDEF:
963 typedef_decl ();
964 break;
965
966 case DEFVEC_OP:
967 case DEFVEC_I:
968 def_vec ();
969 break;
970
971 case DEFVEC_ALLOC:
972 def_vec_alloc ();
973 break;
974
975 case EOF_TOKEN:
976 goto eof;
977
978 default:
979 parse_error ("unexpected top level token, %s", print_cur_token ());
980 goto eof;
981 }
982 lexer_toplevel_done = 1;
983 }
984
985 eof:
986 advance ();
987 yyend ();
988}