gengtype.c (get_output_file_name): Declaration moved to gengtype.h.
[gcc.git] / gcc / gengtype-parse.c
1 /* Process source files and output type information.
2 Copyright (C) 2006, 2007 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 #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
34 struct token
35 {
36 const char *value;
37 int code;
38 bool valid;
39 };
40 static 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. */
44 static inline int
45 token (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. */
57 static inline const char *
58 advance (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. */
67 static 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. */
92 static 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. */
108 static const char *
109 print_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)
116 return token_names[code - CHAR_TOKEN_OFFSET]; /* don't quote these */
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. */
124 static inline const char *
125 print_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. */
133 static void ATTRIBUTE_PRINTF_1
134 parse_error (const char *msg, ...)
135 {
136 va_list ap;
137
138 fprintf (stderr, "%s:%d: parse error: ",
139 get_input_file_name (lexer_line.file), lexer_line.line);
140
141 va_start (ap, msg);
142 vfprintf (stderr, msg, ap);
143 va_end (ap);
144
145 fputc ('\n', stderr);
146
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. */
152 static const char *
153 require (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. */
168 static const char *
169 require2 (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. */
187 static const char *
188 string_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);
203 buf = XRESIZEVEC (char, CONST_CAST (char *, s1), l1 + l2 + 1);
204 memcpy (buf + l1, s2, l2 + 1);
205 XDELETE (CONST_CAST (char *, s2));
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. */
214 static const char *
215 typedef_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 (')');
226 r = concat ("VEC_", c1, "_", c2, (char *) 0);
227 free (CONST_CAST (char *, c1));
228 free (CONST_CAST (char *, c2));
229 return r;
230 }
231 else
232 return require (ID);
233 }
234
235 /* Absorb a sequence of tokens delimited by balanced ()[]{}. */
236 static void
237 consume_balanced (int opener, int closer)
238 {
239 require (opener);
240 for (;;)
241 switch (token ())
242 {
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;
255
256 case '}':
257 case ']':
258 case ')':
259 if (token () != closer)
260 parse_error ("unbalanced delimiters - expected '%c', have '%c'",
261 closer, token ());
262 advance ();
263 return;
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. */
276 static void
277 consume_until_semi (bool immediate)
278 {
279 if (immediate && token () != ';')
280 require (';');
281 for (;;)
282 switch (token ())
283 {
284 case ';':
285 advance ();
286 return;
287 default:
288 advance ();
289 break;
290
291 case '(':
292 consume_balanced ('(', ')');
293 break;
294 case '[':
295 consume_balanced ('[', ']');
296 break;
297 case '{':
298 consume_balanced ('{', '}');
299 break;
300
301 case '}':
302 case ']':
303 case ')':
304 parse_error ("unmatched '%c' while scanning for ';'", token ());
305 return;
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. */
318 static bool
319 consume_until_comma_or_semi (bool immediate)
320 {
321 if (immediate && token () != ',' && token () != ';')
322 require2 (',', ';');
323 for (;;)
324 switch (token ())
325 {
326 case ',':
327 advance ();
328 return true;
329 case ';':
330 advance ();
331 return false;
332 default:
333 advance ();
334 break;
335
336 case '(':
337 consume_balanced ('(', ')');
338 break;
339 case '[':
340 consume_balanced ('[', ']');
341 break;
342 case '{':
343 consume_balanced ('{', '}');
344 break;
345
346 case '}':
347 case ']':
348 case ')':
349 parse_error ("unmatched '%s' while scanning for ',' or ';'",
350 print_cur_token ());
351 return false;
352
353 case EOF_TOKEN:
354 parse_error ("unexpected end of file while scanning for ',' or ';'");
355 return false;
356 }
357 }
358 \f
359
360 /* GTY(()) option handling. */
361 static type_p type (options_p *optsp, bool nested);
362
363 /* Optional parenthesized string: ('(' string_seq ')')? */
364 static options_p
365 str_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. */
386 static type_p
387 absdecl (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 ')' */
406 static options_p
407 type_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 ')' */
417 static options_p
418 nestedptr_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:
435 ID str_optvalue_opt
436 | PTR_ALIAS type_optvalue
437 | PARAM_IS type_optvalue
438 | NESTED_PTR nestedptr_optvalue
439 */
440 static options_p
441 option (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:
460 parse_error ("expected an option keyword, have %s", print_cur_token ());
461 advance ();
462 return create_option (prev, "", "");
463 }
464 }
465
466 /* One comma-separated list of options. */
467 static options_p
468 option_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? ')' ')' */
482 static options_p
483 gtymarker (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. */
497 static options_p
498 gtymarker_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:
512 \epsilon
513 array_and_function_declarators_opt ARRAY
514 array_and_function_declarators_opt '(' ... ')'
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
521 static type_p
522 array_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
540 static type_p inner_declarator (type_p, const char **, options_p *);
541
542 /* direct_declarator:
543 '(' inner_declarator ')'
544 gtymarker_opt ID array_and_function_declarators_opt
545
546 Subroutine of declarator, mutually recursive with inner_declarator;
547 do not use elsewhere. */
548 static type_p
549 direct_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
583 char * (*pfc) (void)
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:
595 '*' inner_declarator
596 direct_declarator
597
598 Mutually recursive subroutine of direct_declarator; do not use
599 elsewhere. */
600
601 static type_p
602 inner_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
625 static type_p
626 declarator (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 (
642 type bitfield ';'
643 | type declarator bitfield? ( ',' declarator bitfield? )+ ';'
644 )+
645
646 Knows that such declarations must end with a close brace (or,
647 erroneously, at EOF).
648 */
649 static pair_p
650 struct_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
699 SCALAR
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.
707 */
708 static type_p
709 type (options_p *optsp, bool nested)
710 {
711 const char *s;
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;
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);
738 advance ();
739
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 {
747 is_gty = GTY_BEFORE_ID;
748 opts = gtymarker_opt ();
749 }
750
751 if (token () == ID)
752 s = advance ();
753 else
754 s = xasprintf ("anonymous:%s:%d", lexer_line.file, lexer_line.line);
755
756 /* Unfortunately above GTY_TOKEN check does not capture the
757 typedef struct_type GTY case. */
758 if (token () == GTY_TOKEN)
759 {
760 is_gty = GTY_AFTER_ID;
761 opts = gtymarker_opt ();
762 }
763
764 if (is_gty)
765 {
766 if (token () == '{')
767 {
768 pair_p fields;
769
770 if (is_gty == GTY_AFTER_ID)
771 parse_error ("GTY must be specified before identifier");
772
773 advance ();
774 fields = struct_field_seq ();
775 require ('}');
776 return new_structure (s, is_union, &lexer_line, fields, opts);
777 }
778 }
779 else if (token () == '{')
780 consume_balanced ('{', '}');
781 if (opts)
782 *optsp = opts;
783 return find_structure (s, is_union);
784 }
785
786 case ENUM:
787 advance ();
788 if (token () == ID)
789 s = advance ();
790 else
791 s = xasprintf ("anonymous:%s:%d", lexer_line.file, lexer_line.line);
792
793 if (token () == '{')
794 consume_balanced ('{', '}');
795 return create_scalar_type (s);
796
797 default:
798 parse_error ("expected a type specifier, have %s", print_cur_token ());
799 advance ();
800 return create_scalar_type ("erroneous type");
801 }
802 }
803 \f
804 /* Top level constructs. */
805
806 /* Dispatch declarations beginning with 'typedef'. */
807
808 static void
809 typedef_decl (void)
810 {
811 type_p ty, dty;
812 const char *name;
813 options_p opts;
814 bool another;
815
816 gcc_assert (token () == TYPEDEF);
817 advance ();
818
819 ty = type (&opts, false);
820 if (!ty)
821 return;
822 if (opts)
823 parse_error ("GTY((...)) cannot be applied to a typedef");
824 do
825 {
826 dty = declarator (ty, &name, &opts);
827 if (opts)
828 parse_error ("GTY((...)) cannot be applied to a typedef");
829
830 /* Yet another place where we could have junk (notably attributes)
831 after the declarator. */
832 another = consume_until_comma_or_semi (false);
833 if (dty)
834 do_typedef (name, dty, &lexer_line);
835 }
836 while (another);
837 }
838
839 /* Structure definition: type() does all the work. */
840
841 static void
842 struct_or_union (void)
843 {
844 options_p dummy;
845 type (&dummy, false);
846 /* There may be junk after the type: notably, we cannot currently
847 distinguish 'struct foo *function(prototype);' from 'struct foo;'
848 ... we could call declarator(), but it's a waste of time at
849 present. Instead, just eat whatever token is currently lookahead
850 and go back to lexical skipping mode. */
851 advance ();
852 }
853
854 /* GC root declaration:
855 (extern|static) gtymarker? type ID array_declarators_opt (';'|'=')
856 If the gtymarker is not present, we ignore the rest of the declaration. */
857 static void
858 extern_or_static (void)
859 {
860 options_p opts, opts2, dopts;
861 type_p ty, dty;
862 const char *name;
863 require2 (EXTERN, STATIC);
864
865 if (token () != GTY_TOKEN)
866 {
867 advance ();
868 return;
869 }
870
871 opts = gtymarker ();
872 ty = type (&opts2, true); /* if we get here, it's got a GTY(()) */
873 dty = declarator (ty, &name, &dopts);
874
875 if ((opts && dopts) || (opts && opts2) || (opts2 && dopts))
876 parse_error ("GTY((...)) specified more than once for %s", name);
877 else if (opts2)
878 opts = opts2;
879 else if (dopts)
880 opts = dopts;
881
882 if (dty)
883 {
884 note_variable (name, adjust_field_type (dty, opts), opts, &lexer_line);
885 require2 (';', '=');
886 }
887 }
888
889 /* Definition of a generic VEC structure:
890
891 'DEF_VEC_[IPO]' '(' id ')' ';'
892
893 Scalar VECs require slightly different treatment than otherwise -
894 that's handled in note_def_vec, we just pass it along.*/
895 static void
896 def_vec (void)
897 {
898 bool is_scalar = (token () == DEFVEC_I);
899 const char *type;
900
901 require2 (DEFVEC_OP, DEFVEC_I);
902 require ('(');
903 type = require2 (ID, SCALAR);
904 require (')');
905 require (';');
906
907 if (!type)
908 return;
909
910 note_def_vec (type, is_scalar, &lexer_line);
911 note_def_vec_alloc (type, "none", &lexer_line);
912 }
913
914 /* Definition of an allocation strategy for a VEC structure:
915
916 'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';'
917
918 For purposes of gengtype, this just declares a wrapper structure. */
919 static void
920 def_vec_alloc (void)
921 {
922 const char *type, *astrat;
923
924 require (DEFVEC_ALLOC);
925 require ('(');
926 type = require2 (ID, SCALAR);
927 require (',');
928 astrat = require (ID);
929 require (')');
930 require (';');
931
932 if (!type || !astrat)
933 return;
934
935 note_def_vec_alloc (type, astrat, &lexer_line);
936 }
937
938 /* Parse the file FNAME for GC-relevant declarations and definitions.
939 This is the only entry point to this file. */
940 void
941 parse_file (const char *fname)
942 {
943 yybegin (fname);
944 for (;;)
945 {
946 switch (token ())
947 {
948 case EXTERN:
949 case STATIC:
950 extern_or_static ();
951 break;
952
953 case STRUCT:
954 case UNION:
955 struct_or_union ();
956 break;
957
958 case TYPEDEF:
959 typedef_decl ();
960 break;
961
962 case DEFVEC_OP:
963 case DEFVEC_I:
964 def_vec ();
965 break;
966
967 case DEFVEC_ALLOC:
968 def_vec_alloc ();
969 break;
970
971 case EOF_TOKEN:
972 goto eof;
973
974 default:
975 parse_error ("unexpected top level token, %s", print_cur_token ());
976 goto eof;
977 }
978 lexer_toplevel_done = 1;
979 }
980
981 eof:
982 advance ();
983 yyend ();
984 }