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