Mercurial > hg > CbC > CbC_gcc
comparison gcc/gengtype-state.c @ 68:561a7518be6b
update gcc-4.6
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 07:07:55 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
67:f6334be47118 | 68:561a7518be6b |
---|---|
1 /* Gengtype persistent state serialization & de-serialization. | |
2 Useful for gengtype in plugin mode. | |
3 | |
4 Copyright (C) 2010 Free Software Foundation, Inc. | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. | |
21 | |
22 Contributed by Jeremie Salvucci <jeremie.salvucci@free.fr> | |
23 and Basile Starynkevitch <basile@starynkevitch.net> | |
24 */ | |
25 | |
26 #include "bconfig.h" | |
27 #include "system.h" | |
28 #include "errors.h" /* For fatal. */ | |
29 #include "double-int.h" | |
30 #include "hashtab.h" | |
31 #include "version.h" /* For version_string & pkgversion_string. */ | |
32 #include "obstack.h" | |
33 #include "gengtype.h" | |
34 | |
35 | |
36 | |
37 /* Gives the file location of a type, if any. */ | |
38 static inline struct fileloc* | |
39 type_lineloc (const_type_p ty) | |
40 { | |
41 if (!ty) | |
42 return NULL; | |
43 switch (ty->kind) | |
44 { | |
45 case TYPE_NONE: | |
46 gcc_unreachable (); | |
47 case TYPE_STRUCT: | |
48 case TYPE_UNION: | |
49 case TYPE_LANG_STRUCT: | |
50 return CONST_CAST (struct fileloc*, &ty->u.s.line); | |
51 case TYPE_PARAM_STRUCT: | |
52 return CONST_CAST (struct fileloc*, &ty->u.param_struct.line); | |
53 case TYPE_SCALAR: | |
54 case TYPE_STRING: | |
55 case TYPE_POINTER: | |
56 case TYPE_ARRAY: | |
57 return NULL; | |
58 default: | |
59 gcc_unreachable (); | |
60 } | |
61 } | |
62 | |
63 /* The state file has simplistic lispy lexical tokens. Its lexer gives | |
64 a linked list of struct state_token_st, thru the peek_state_token | |
65 function. Lexical tokens are consumed with next_state_tokens. */ | |
66 | |
67 | |
68 /* The lexical kind of each lispy token. */ | |
69 enum state_token_en | |
70 { | |
71 STOK_NONE, /* Never used. */ | |
72 STOK_INTEGER, /* Integer token. */ | |
73 STOK_STRING, /* String token. */ | |
74 STOK_LEFTPAR, /* Left opening parenthesis. */ | |
75 STOK_RIGHTPAR, /* Right closing parenthesis. */ | |
76 STOK_NAME /* hash-consed name or identifier. */ | |
77 }; | |
78 | |
79 | |
80 /* Structure and hash-table used to share identifiers or names. */ | |
81 struct state_ident_st | |
82 { | |
83 /* TODO: We could improve the parser by reserving identifiers for | |
84 state keywords and adding a keyword number for them. That would | |
85 mean adding another field in this state_ident_st struct. */ | |
86 char stid_name[1]; /* actually bigger & null terminated */ | |
87 }; | |
88 static htab_t state_ident_tab; | |
89 | |
90 | |
91 /* The state_token_st structure is for lexical tokens in the read | |
92 state file. The stok_kind field discriminates the union. Tokens | |
93 are allocated by peek_state_token which calls read_a_state_token | |
94 which allocate them. Tokens are freed by calls to | |
95 next_state_tokens. Token are organized in a FIFO look-ahead queue | |
96 filled by peek_state_token. */ | |
97 struct state_token_st | |
98 { | |
99 enum state_token_en stok_kind; /* the lexical kind | |
100 discriminates the stok_un | |
101 union */ | |
102 int stok_line; /* the line number */ | |
103 int stok_col; /* the column number */ | |
104 const char *stok_file; /* the file path */ | |
105 struct state_token_st *stok_next; /* the next token in the | |
106 queue, when peeked */ | |
107 union /* discriminated by stok_kind! */ | |
108 { | |
109 int stok_num; /* when STOK_INTEGER */ | |
110 char stok_string[1]; /* when STOK_STRING, actual size is | |
111 bigger and null terminated */ | |
112 struct state_ident_st *stok_ident; /* when STOK_IDENT */ | |
113 void *stok_ptr; /* null otherwise */ | |
114 } | |
115 stok_un; | |
116 }; | |
117 | |
118 | |
119 | |
120 | |
121 #define NULL_STATE_TOKEN (struct state_token_st*)0 | |
122 | |
123 /* the state_token pointer contains the leftmost current token. The | |
124 tokens are organized in a linked queue, using stok_next, for token | |
125 look-ahead. */ | |
126 struct state_token_st *state_token = NULL_STATE_TOKEN; | |
127 | |
128 /* Used by the reading lexer. */ | |
129 static FILE *state_file; | |
130 static const char *state_path = NULL; | |
131 static int state_line = 0; | |
132 static long state_bol = 0; /* offset of beginning of line */ | |
133 | |
134 | |
135 /* Counter of written types. */ | |
136 static int state_written_type_count = 0; | |
137 | |
138 | |
139 /* Fatal error messages when reading the state. They are extremely | |
140 unlikely, and only appear when this gengtype-state.c file is buggy, | |
141 or when reading a gengtype state which was not generated by the | |
142 same version of gengtype or GCC. */ | |
143 | |
144 | |
145 /* Fatal message while reading state. */ | |
146 static inline void | |
147 fatal_reading_state (struct state_token_st* tok, const char*msg) | |
148 { | |
149 if (tok) | |
150 fatal ("%s:%d:%d: Invalid state file; %s", | |
151 tok->stok_file, tok->stok_line, tok->stok_col, | |
152 msg); | |
153 else | |
154 fatal ("%s:%d: Invalid state file; %s", | |
155 state_path, state_line, msg); | |
156 } | |
157 | |
158 | |
159 /* Fatal printf-like message while reading state. This can't be a | |
160 function, because there is no way to pass a va_arg to a variant of | |
161 fatal. */ | |
162 #define fatal_reading_state_printf(Tok,Fmt,...) do { \ | |
163 struct state_token_st* badtok = Tok; \ | |
164 if (badtok) \ | |
165 fatal ("%s:%d:%d: Invalid state file; " Fmt, \ | |
166 badtok->stok_file, \ | |
167 badtok->stok_line, \ | |
168 badtok->stok_col, __VA_ARGS__); \ | |
169 else \ | |
170 fatal ("%s:%d: Invalid state file; " Fmt, \ | |
171 state_path, state_line, __VA_ARGS__); \ | |
172 } while(0) | |
173 | |
174 | |
175 /* Find or allocate an identifier in our name hash table. */ | |
176 static struct state_ident_st * | |
177 state_ident_by_name (const char *name, enum insert_option optins) | |
178 { | |
179 PTR *slot = NULL; | |
180 int namlen = 0; | |
181 struct state_ident_st *stid = NULL; | |
182 | |
183 if (!name || !name[0]) | |
184 return NULL; | |
185 | |
186 slot = htab_find_slot (state_ident_tab, name, optins); | |
187 if (!slot) | |
188 return NULL; | |
189 | |
190 namlen = strlen (name); | |
191 stid = | |
192 (struct state_ident_st *) xmalloc (sizeof (struct state_ident_st) + | |
193 namlen); | |
194 memset (stid, 0, sizeof (struct state_ident_st) + namlen); | |
195 strcpy (stid->stid_name, name); | |
196 *slot = stid; | |
197 | |
198 return stid; | |
199 } | |
200 | |
201 /* Our token lexer is heavily inspired by MELT's lexer, and share some | |
202 code with the file gcc/melt-runtime.c of the GCC MELT branch! We | |
203 really want the gengtype state to be easily parsable by MELT. This | |
204 is a usual lispy lexing routine, dealing with spaces and comments, | |
205 numbers, parenthesis, names, strings. */ | |
206 static struct state_token_st * | |
207 read_a_state_token (void) | |
208 { | |
209 int c = 0; | |
210 long curoff = 0; | |
211 struct state_token_st *tk = NULL; | |
212 | |
213 again: /* Read again, e.g. after a comment or spaces. */ | |
214 c = getc (state_file); | |
215 if (c == EOF) | |
216 return NULL; | |
217 | |
218 /* Handle spaces, count lines. */ | |
219 if (c == '\n') | |
220 { | |
221 state_line++; | |
222 state_bol = curoff = ftell (state_file); | |
223 goto again; | |
224 }; | |
225 if (ISSPACE (c)) | |
226 goto again; | |
227 /* Skip comments starting with semi-colon. */ | |
228 if (c == ';') | |
229 { | |
230 do | |
231 { | |
232 c = getc (state_file); | |
233 } | |
234 while (c > 0 && c != '\n'); | |
235 if (c == '\n') | |
236 { | |
237 state_line++; | |
238 state_bol = curoff = ftell (state_file); | |
239 } | |
240 goto again; | |
241 }; | |
242 /* Read signed numbers. */ | |
243 if (ISDIGIT (c) || c == '-' || c == '+') | |
244 { /* number */ | |
245 int n = 0; | |
246 ungetc (c, state_file); | |
247 curoff = ftell (state_file); | |
248 if (fscanf (state_file, "%d", &n) <= 0) | |
249 fatal_reading_state (NULL_STATE_TOKEN, "Lexical error in number"); | |
250 tk = XCNEW (struct state_token_st); | |
251 tk->stok_kind = STOK_INTEGER; | |
252 tk->stok_line = state_line; | |
253 tk->stok_col = curoff - state_bol; | |
254 tk->stok_file = state_path; | |
255 tk->stok_next = NULL; | |
256 tk->stok_un.stok_num = n; | |
257 | |
258 return tk; | |
259 } | |
260 /* Read an opening left parenthesis. */ | |
261 else if (c == '(') | |
262 { | |
263 curoff = ftell (state_file); | |
264 tk = XCNEW (struct state_token_st); | |
265 tk->stok_kind = STOK_LEFTPAR; | |
266 tk->stok_line = state_line; | |
267 tk->stok_col = curoff - state_bol; | |
268 tk->stok_file = state_path; | |
269 tk->stok_next = NULL; | |
270 | |
271 return tk; | |
272 } | |
273 /* Read an closing right parenthesis. */ | |
274 else if (c == ')') | |
275 { | |
276 curoff = ftell (state_file); | |
277 tk = XCNEW (struct state_token_st); | |
278 tk->stok_kind = STOK_RIGHTPAR; | |
279 tk->stok_line = state_line; | |
280 tk->stok_col = curoff - state_bol; | |
281 tk->stok_file = state_path; | |
282 tk->stok_next = NULL; | |
283 | |
284 return tk; | |
285 } | |
286 /* Read identifiers, using an obstack. */ | |
287 else if (ISALPHA (c) || c == '_' || c == '$' || c == '!' || c == '#') | |
288 { | |
289 struct obstack id_obstack; | |
290 struct state_ident_st *sid = NULL; | |
291 char *ids = NULL; | |
292 obstack_init (&id_obstack); | |
293 curoff = ftell (state_file); | |
294 while (ISALNUM (c) || c == '_' || c == '$' || c == '!' || c == '#') | |
295 { | |
296 obstack_1grow (&id_obstack, c); | |
297 c = getc (state_file); | |
298 if (c < 0) | |
299 break; | |
300 }; | |
301 if (c >= 0) | |
302 ungetc (c, state_file); | |
303 obstack_1grow (&id_obstack, (char) 0); | |
304 ids = XOBFINISH (&id_obstack, char *); | |
305 sid = state_ident_by_name (ids, INSERT); | |
306 obstack_free (&id_obstack, ids); | |
307 ids = NULL; | |
308 tk = XCNEW (struct state_token_st); | |
309 tk->stok_kind = STOK_NAME; | |
310 tk->stok_line = state_line; | |
311 tk->stok_col = curoff - state_bol; | |
312 tk->stok_file = state_path; | |
313 tk->stok_next = NULL; | |
314 tk->stok_un.stok_ident = sid; | |
315 | |
316 return tk; | |
317 } | |
318 /* Read a string, dealing with escape sequences a la C! */ | |
319 else if (c == '"') | |
320 { | |
321 char *cstr = NULL; | |
322 int cslen = 0; | |
323 struct obstack bstring_obstack; | |
324 obstack_init (&bstring_obstack); | |
325 curoff = ftell (state_file); | |
326 while ((c = getc (state_file)) != '"' && c >= 0) | |
327 { | |
328 if (ISPRINT (c) && c != '\\') | |
329 obstack_1grow (&bstring_obstack, (char) c); | |
330 else if (ISSPACE (c) && c != '\n') | |
331 obstack_1grow (&bstring_obstack, (char) c); | |
332 else if (c == '\\') | |
333 { | |
334 c = getc (state_file); | |
335 switch (c) | |
336 { | |
337 case 'a': | |
338 obstack_1grow (&bstring_obstack, '\a'); | |
339 c = getc (state_file); | |
340 break; | |
341 case 'b': | |
342 obstack_1grow (&bstring_obstack, '\b'); | |
343 c = getc (state_file); | |
344 break; | |
345 case 't': | |
346 obstack_1grow (&bstring_obstack, '\t'); | |
347 c = getc (state_file); | |
348 break; | |
349 case 'n': | |
350 obstack_1grow (&bstring_obstack, '\n'); | |
351 c = getc (state_file); | |
352 break; | |
353 case 'v': | |
354 obstack_1grow (&bstring_obstack, '\v'); | |
355 c = getc (state_file); | |
356 break; | |
357 case 'f': | |
358 obstack_1grow (&bstring_obstack, '\f'); | |
359 c = getc (state_file); | |
360 break; | |
361 case 'r': | |
362 obstack_1grow (&bstring_obstack, '\r'); | |
363 c = getc (state_file); | |
364 break; | |
365 case '"': | |
366 obstack_1grow (&bstring_obstack, '\"'); | |
367 c = getc (state_file); | |
368 break; | |
369 case '\\': | |
370 obstack_1grow (&bstring_obstack, '\\'); | |
371 c = getc (state_file); | |
372 break; | |
373 case ' ': | |
374 obstack_1grow (&bstring_obstack, ' '); | |
375 c = getc (state_file); | |
376 break; | |
377 case 'x': | |
378 { | |
379 unsigned int cx = 0; | |
380 if (fscanf (state_file, "%02x", &cx) > 0 && cx > 0) | |
381 obstack_1grow (&bstring_obstack, cx); | |
382 else | |
383 fatal_reading_state | |
384 (NULL_STATE_TOKEN, | |
385 "Lexical error in string hex escape"); | |
386 c = getc (state_file); | |
387 break; | |
388 } | |
389 default: | |
390 fatal_reading_state | |
391 (NULL_STATE_TOKEN, | |
392 "Lexical error - unknown string escape"); | |
393 } | |
394 } | |
395 else | |
396 fatal_reading_state (NULL_STATE_TOKEN, "Lexical error..."); | |
397 }; | |
398 if (c != '"') | |
399 fatal_reading_state (NULL_STATE_TOKEN, "Unterminated string"); | |
400 obstack_1grow (&bstring_obstack, '\0'); | |
401 cstr = XOBFINISH (&bstring_obstack, char *); | |
402 cslen = strlen (cstr); | |
403 tk = (struct state_token_st *) | |
404 xcalloc (sizeof (struct state_token_st) + cslen, 1); | |
405 tk->stok_kind = STOK_STRING; | |
406 tk->stok_line = state_line; | |
407 tk->stok_col = curoff - state_bol; | |
408 tk->stok_file = state_path; | |
409 tk->stok_next = NULL; | |
410 strcpy (tk->stok_un.stok_string, cstr); | |
411 obstack_free (&bstring_obstack, cstr); | |
412 | |
413 return tk; | |
414 } | |
415 /* Got an unexpected character. */ | |
416 fatal_reading_state_printf | |
417 (NULL_STATE_TOKEN, | |
418 "Lexical error at offset %ld - bad character \\%03o = '%c'", | |
419 ftell (state_file), c, c); | |
420 } | |
421 | |
422 /* Used for lexical look-ahead. Retrieves the lexical token of rank | |
423 DEPTH, starting with 0 when reading the state file. Gives null on | |
424 end of file. */ | |
425 static struct state_token_st * | |
426 peek_state_token (int depth) | |
427 { | |
428 int remdepth = depth; | |
429 struct state_token_st **ptoken = &state_token; | |
430 struct state_token_st *tok = NULL; | |
431 | |
432 while (remdepth >= 0) | |
433 { | |
434 if (*ptoken == NULL) | |
435 { | |
436 *ptoken = tok = read_a_state_token (); | |
437 if (tok == NULL) | |
438 return NULL; | |
439 } | |
440 tok = *ptoken; | |
441 ptoken = &((*ptoken)->stok_next); | |
442 remdepth--; | |
443 } | |
444 | |
445 return tok; | |
446 } | |
447 | |
448 /* Consume the next DEPTH tokens and free them. */ | |
449 static void | |
450 next_state_tokens (int depth) | |
451 { | |
452 struct state_token_st *n; | |
453 | |
454 while (depth > 0) | |
455 { | |
456 if (state_token != NULL) | |
457 { | |
458 n = state_token->stok_next; | |
459 free (state_token); | |
460 state_token = n; | |
461 } | |
462 else | |
463 fatal_reading_state (NULL_STATE_TOKEN, "Tokens stack empty"); | |
464 | |
465 depth--; | |
466 } | |
467 } | |
468 | |
469 /* Safely retrieve the lexical kind of a token. */ | |
470 static inline enum state_token_en | |
471 state_token_kind (struct state_token_st *p) | |
472 { | |
473 if (p == NULL) | |
474 return STOK_NONE; | |
475 else | |
476 return p->stok_kind; | |
477 } | |
478 | |
479 /* Test if a token is a given name i.e. an identifier. */ | |
480 static inline bool | |
481 state_token_is_name (struct state_token_st *p, const char *name) | |
482 { | |
483 if (p == NULL) | |
484 return false; | |
485 | |
486 if (p->stok_kind != STOK_NAME) | |
487 return false; | |
488 | |
489 return !strcmp (p->stok_un.stok_ident->stid_name, name); | |
490 } | |
491 | |
492 | |
493 /* Following routines are useful for serializing datas. | |
494 * | |
495 * We want to serialize : | |
496 * - typedefs list | |
497 * - structures list | |
498 * - param_structs list | |
499 * - variables list | |
500 * | |
501 * So, we have one routine for each kind of data. The main writing | |
502 * routine is write_state. The main reading routine is | |
503 * read_state. Most writing routines write_state_FOO have a | |
504 * corresponding reading routine read_state_FOO. Reading is done in a | |
505 * recursive descending way, and any read error is fatal. | |
506 */ | |
507 | |
508 /* When reading the state, we need to remember the previously seen | |
509 types by their state_number, since GTY-ed types are usually | |
510 shared. */ | |
511 static htab_t state_seen_types; | |
512 | |
513 /* Return the length of a linked list made of pairs. */ | |
514 static int pair_list_length (pair_p list); | |
515 | |
516 /* Write a pair */ | |
517 static void write_state_pair (pair_p); | |
518 | |
519 /* return the number of pairs written. Should match the length given | |
520 by pair_list_length. */ | |
521 static int write_state_pair_list (pair_p list); | |
522 | |
523 /* Write a type. When a type is written, its state_number is updated, | |
524 to ensure that a "reference" to a seen type is written on next | |
525 occurrences. */ | |
526 static void write_state_type (type_p); | |
527 | |
528 /* Write a null-terminatel string using our Lispy lexical conventions, | |
529 similar to those of C or MELT. */ | |
530 static void write_state_a_string (const char *s); | |
531 | |
532 /* Compute the length of a list of pairs, starting from the first | |
533 one. */ | |
534 static int | |
535 pair_list_length (pair_p list) | |
536 { | |
537 int nbpair = 0; | |
538 pair_p l = NULL; | |
539 for (l = list; l; l = l->next) | |
540 nbpair++; | |
541 return nbpair; | |
542 } | |
543 | |
544 /* Write a file location. Files relative to $(srcdir) are quite | |
545 frequent and are handled specially. This ensures that two gengtype | |
546 state file-s produced by gengtype on the same GCC source tree are | |
547 very similar and can be reasonably compared with diff, even if the | |
548 two GCC source trees have different absolute paths. */ | |
549 static void | |
550 write_state_fileloc (struct fileloc *floc) | |
551 { | |
552 | |
553 if (floc != NULL && floc->line > 0) | |
554 { | |
555 const char *srcrelpath = NULL; | |
556 gcc_assert (floc->file != NULL); | |
557 /* Most of the files are inside $(srcdir) so it is worth to | |
558 handle them specially. */ | |
559 srcrelpath = get_file_srcdir_relative_path (floc->file); | |
560 if (srcrelpath != NULL) | |
561 { | |
562 fprintf (state_file, "\n(!srcfileloc "); | |
563 write_state_a_string (srcrelpath); | |
564 } | |
565 else | |
566 { | |
567 fprintf (state_file, "\n(!fileloc "); | |
568 write_state_a_string (get_input_file_name (floc->file)); | |
569 } | |
570 fprintf (state_file, " %d", floc->line); | |
571 fprintf (state_file, ")\n"); | |
572 } | |
573 else | |
574 fprintf (state_file, "nil "); | |
575 } | |
576 | |
577 /* Write a list of fields. */ | |
578 static void | |
579 write_state_fields (pair_p fields) | |
580 { | |
581 int nbfields = pair_list_length (fields); | |
582 int nbpairs = 0; | |
583 fprintf (state_file, "\n(!fields %d ", nbfields); | |
584 nbpairs = write_state_pair_list (fields); | |
585 gcc_assert (nbpairs == nbfields); | |
586 fprintf (state_file, ")\n"); | |
587 } | |
588 | |
589 /* Write a null-terminated string in our lexical convention, very | |
590 similar to the convention of C. */ | |
591 static void | |
592 write_state_a_string (const char *s) | |
593 { | |
594 char c; | |
595 | |
596 fputs (" \"", state_file); | |
597 for (; *s != 0; s++) | |
598 { | |
599 c = *s; | |
600 switch (c) | |
601 { | |
602 case '\a': | |
603 fputs ("\\a", state_file); | |
604 break; | |
605 case '\b': | |
606 fputs ("\\b", state_file); | |
607 break; | |
608 case '\t': | |
609 fputs ("\\t", state_file); | |
610 break; | |
611 case '\n': | |
612 fputs ("\\n", state_file); | |
613 break; | |
614 case '\v': | |
615 fputs ("\\v", state_file); | |
616 break; | |
617 case '\f': | |
618 fputs ("\\f", state_file); | |
619 break; | |
620 case '\r': | |
621 fputs ("\\r", state_file); | |
622 break; | |
623 case '\"': | |
624 fputs ("\\\"", state_file); | |
625 break; | |
626 case '\\': | |
627 fputs ("\\\\", state_file); | |
628 break; | |
629 default: | |
630 if (ISPRINT (c)) | |
631 putc (c, state_file); | |
632 else | |
633 fprintf (state_file, "\\x%02x", (unsigned) c); | |
634 } | |
635 } | |
636 fputs ("\"", state_file); | |
637 } | |
638 | |
639 /* Our option-s have three kinds, each with its writer. */ | |
640 static void | |
641 write_state_string_option (options_p current) | |
642 { | |
643 fprintf (state_file, "string "); | |
644 if (current->info.string != NULL) | |
645 write_state_a_string (current->info.string); | |
646 else | |
647 fprintf (state_file, " nil "); | |
648 } | |
649 | |
650 static void | |
651 write_state_type_option (options_p current) | |
652 { | |
653 fprintf (state_file, "type "); | |
654 write_state_type (current->info.type); | |
655 } | |
656 | |
657 static void | |
658 write_state_nested_option (options_p current) | |
659 { | |
660 fprintf (state_file, "nested "); | |
661 write_state_type (current->info.nested->type); | |
662 if (current->info.nested->convert_from != NULL) | |
663 write_state_a_string (current->info.nested->convert_from); | |
664 else | |
665 fprintf (state_file, " nil "); | |
666 | |
667 if (current->info.nested->convert_to != NULL) | |
668 write_state_a_string (current->info.nested->convert_to); | |
669 else | |
670 fprintf (state_file, " nil "); | |
671 } | |
672 | |
673 static void | |
674 write_state_option (options_p current) | |
675 { | |
676 fprintf (state_file, "\n(!option "); | |
677 | |
678 if (current->name != NULL) | |
679 fprintf (state_file, "%s ", current->name); | |
680 else | |
681 fprintf (state_file, "nil "); | |
682 | |
683 switch (current->kind) | |
684 { | |
685 case OPTION_STRING: | |
686 write_state_string_option (current); | |
687 break; | |
688 case OPTION_TYPE: | |
689 write_state_type_option (current); | |
690 break; | |
691 case OPTION_NESTED: | |
692 write_state_nested_option (current); | |
693 break; | |
694 default: | |
695 fatal ("Option tag unknown"); | |
696 } | |
697 | |
698 fprintf (state_file, ")\n"); | |
699 } | |
700 | |
701 | |
702 | |
703 /* Write a list of GTY options. */ | |
704 static void | |
705 write_state_options (options_p opt) | |
706 { | |
707 options_p current; | |
708 | |
709 if (opt == NULL) | |
710 { | |
711 fprintf (state_file, "nil "); | |
712 return; | |
713 } | |
714 | |
715 fprintf (state_file, "\n(!options "); | |
716 for (current = opt; current != NULL; current = current->next) | |
717 write_state_option (current); | |
718 fprintf (state_file, ")\n"); | |
719 } | |
720 | |
721 | |
722 /* Write a bitmap representing a set of GCC front-end languages. */ | |
723 static void | |
724 write_state_lang_bitmap (lang_bitmap bitmap) | |
725 { | |
726 fprintf (state_file, "%d ", (int) bitmap); | |
727 } | |
728 | |
729 /* Write version information. */ | |
730 static void | |
731 write_state_version (const char *version) | |
732 { | |
733 fprintf (state_file, "\n(!version "); | |
734 write_state_a_string (version); | |
735 fprintf (state_file, ")\n"); | |
736 } | |
737 | |
738 /* Common routine to write the common content of all types. */ | |
739 static void write_state_common_type_content (type_p current); | |
740 | |
741 /* Write a scalar type. We have only two of these. */ | |
742 static void | |
743 write_state_scalar_type (type_p current) | |
744 { | |
745 if (current == &scalar_nonchar) | |
746 fprintf (state_file, "scalar_nonchar "); | |
747 else if (current == &scalar_char) | |
748 fprintf (state_file, "scalar_char "); | |
749 else | |
750 fatal ("Unexpected type in write_state_scalar_type"); | |
751 | |
752 write_state_common_type_content (current); | |
753 } | |
754 | |
755 /* Write the string type. There is only one such thing! */ | |
756 static void | |
757 write_state_string_type (type_p current) | |
758 { | |
759 if (current == &string_type) | |
760 { | |
761 fprintf (state_file, "string "); | |
762 write_state_common_type_content (current); | |
763 } | |
764 else | |
765 fatal ("Unexpected type in write_state_string_type"); | |
766 } | |
767 | |
768 | |
769 /* Common code to write structure like types. */ | |
770 static void | |
771 write_state_struct_union_type (type_p current, const char *kindstr) | |
772 { | |
773 DBGPRINTF ("%s type @ %p #%d '%s'", kindstr, (void *) current, | |
774 current->state_number, current->u.s.tag); | |
775 fprintf (state_file, "%s ", kindstr); | |
776 write_state_common_type_content (current); | |
777 if (current->u.s.tag != NULL) | |
778 write_state_a_string (current->u.s.tag); | |
779 else | |
780 fprintf (state_file, "nil"); | |
781 | |
782 write_state_fileloc (type_lineloc (current)); | |
783 write_state_fields (current->u.s.fields); | |
784 write_state_options (current->u.s.opt); | |
785 write_state_lang_bitmap (current->u.s.bitmap); | |
786 } | |
787 | |
788 | |
789 /* Write a GTY struct type. */ | |
790 static void | |
791 write_state_struct_type (type_p current) | |
792 { | |
793 write_state_struct_union_type (current, "struct"); | |
794 write_state_type (current->u.s.lang_struct); | |
795 } | |
796 | |
797 /* write a GTY union type. */ | |
798 static void | |
799 write_state_union_type (type_p current) | |
800 { | |
801 write_state_struct_union_type (current, "union"); | |
802 write_state_type (current->u.s.lang_struct); | |
803 } | |
804 | |
805 /* Write a lang_struct type. This is tricky and was painful to debug, | |
806 we deal with the next field specifically within their lang_struct | |
807 subfield, which points to a linked list of homonumous types. | |
808 Change this function with extreme care, see also | |
809 read_state_lang_struct_type. */ | |
810 static void | |
811 write_state_lang_struct_type (type_p current) | |
812 { | |
813 int nbhomontype = 0; | |
814 type_p hty = NULL; | |
815 const char *homoname = 0; | |
816 write_state_struct_union_type (current, "lang_struct"); | |
817 /* lang_struct-ures are particularily tricky, since their | |
818 u.s.lang_struct field gives a list of homonymous struct-s or | |
819 union-s! */ | |
820 DBGPRINTF ("lang_struct @ %p #%d", (void *) current, current->state_number); | |
821 for (hty = current->u.s.lang_struct; hty != NULL; hty = hty->next) | |
822 { | |
823 nbhomontype++; | |
824 DBGPRINTF ("homonymous #%d hty @ %p #%d '%s'", nbhomontype, | |
825 (void *) hty, hty->state_number, hty->u.s.tag); | |
826 /* Every member of the homonymous list should have the same tag. */ | |
827 gcc_assert (UNION_OR_STRUCT_P (hty)); | |
828 gcc_assert (hty->u.s.lang_struct == current); | |
829 if (!homoname) | |
830 homoname = hty->u.s.tag; | |
831 gcc_assert (strcmp (homoname, hty->u.s.tag) == 0); | |
832 } | |
833 fprintf (state_file, "(!homotypes %d\n", nbhomontype); | |
834 for (hty = current->u.s.lang_struct; hty != NULL; hty = hty->next) | |
835 write_state_type (hty); | |
836 fprintf (state_file, ")\n"); | |
837 } | |
838 | |
839 /* Write a parametrized structure GTY type. */ | |
840 static void | |
841 write_state_param_struct_type (type_p current) | |
842 { | |
843 int i; | |
844 | |
845 fprintf (state_file, "param_struct "); | |
846 write_state_common_type_content (current); | |
847 write_state_type (current->u.param_struct.stru); | |
848 for (i = 0; i < NUM_PARAM; i++) | |
849 { | |
850 if (current->u.param_struct.param[i] != NULL) | |
851 write_state_type (current->u.param_struct.param[i]); | |
852 else | |
853 fprintf (state_file, "nil "); | |
854 } | |
855 write_state_fileloc (¤t->u.param_struct.line); | |
856 } | |
857 | |
858 /* Write a pointer type. */ | |
859 static void | |
860 write_state_pointer_type (type_p current) | |
861 { | |
862 fprintf (state_file, "pointer "); | |
863 write_state_common_type_content (current); | |
864 write_state_type (current->u.p); | |
865 } | |
866 | |
867 /* Write an array type. */ | |
868 static void | |
869 write_state_array_type (type_p current) | |
870 { | |
871 fprintf (state_file, "array "); | |
872 write_state_common_type_content (current); | |
873 if (current->u.a.len != NULL) | |
874 write_state_a_string (current->u.a.len); | |
875 else | |
876 fprintf (state_file, " nil"); | |
877 | |
878 fprintf (state_file, " "); | |
879 write_state_type (current->u.a.p); | |
880 } | |
881 | |
882 /* Write the gc_used information. */ | |
883 static void | |
884 write_state_gc_used (enum gc_used_enum gus) | |
885 { | |
886 switch (gus) | |
887 { | |
888 case GC_UNUSED: | |
889 fprintf (state_file, " gc_unused"); | |
890 break; | |
891 case GC_USED: | |
892 fprintf (state_file, " gc_used"); | |
893 break; | |
894 case GC_MAYBE_POINTED_TO: | |
895 fprintf (state_file, " gc_maybe_pointed_to"); | |
896 break; | |
897 case GC_POINTED_TO: | |
898 fprintf (state_file, " gc_pointed_to"); | |
899 break; | |
900 default: | |
901 gcc_unreachable (); | |
902 } | |
903 } | |
904 | |
905 /* Utility routine to write the common content of all types. Notice | |
906 that the next field is *not* written on purpose. */ | |
907 static void | |
908 write_state_common_type_content (type_p current) | |
909 { | |
910 fprintf (state_file, "%d ", current->state_number); | |
911 /* We do not write the next type, because list of types are | |
912 explicitly written. However, lang_struct are special in that | |
913 respect. See function write_state_lang_struct_type for more. */ | |
914 write_state_type (current->pointer_to); | |
915 write_state_gc_used (current->gc_used); | |
916 } | |
917 | |
918 | |
919 /* The important and recursive routine writing GTY types as understood | |
920 by gengtype. Types which have a positive state_number have already | |
921 been seen and written. */ | |
922 static void | |
923 write_state_type (type_p current) | |
924 { | |
925 if (current == NULL) | |
926 { | |
927 fprintf (state_file, "nil "); | |
928 return; | |
929 } | |
930 | |
931 fprintf (state_file, "\n(!type "); | |
932 | |
933 if (current->state_number > 0) | |
934 fprintf (state_file, "already_seen %d", current->state_number); | |
935 else | |
936 { | |
937 state_written_type_count++; | |
938 DBGPRINTF ("writing type #%d @%p old number %d", state_written_type_count, | |
939 (void *) current, current->state_number); | |
940 current->state_number = state_written_type_count; | |
941 switch (current->kind) | |
942 { | |
943 case TYPE_STRUCT: | |
944 write_state_struct_type (current); | |
945 break; | |
946 case TYPE_UNION: | |
947 write_state_union_type (current); | |
948 break; | |
949 case TYPE_POINTER: | |
950 write_state_pointer_type (current); | |
951 break; | |
952 case TYPE_ARRAY: | |
953 write_state_array_type (current); | |
954 break; | |
955 case TYPE_LANG_STRUCT: | |
956 write_state_lang_struct_type (current); | |
957 break; | |
958 case TYPE_PARAM_STRUCT: | |
959 write_state_param_struct_type (current); | |
960 break; | |
961 case TYPE_SCALAR: | |
962 write_state_scalar_type (current); | |
963 break; | |
964 case TYPE_STRING: | |
965 write_state_string_type (current); | |
966 break; | |
967 | |
968 default: | |
969 fatal ("Unexpected type..."); | |
970 } | |
971 } | |
972 | |
973 fprintf (state_file, ")\n"); | |
974 } | |
975 | |
976 | |
977 /* Write a pair. */ | |
978 static void | |
979 write_state_pair (pair_p current) | |
980 { | |
981 if (current == NULL) | |
982 { | |
983 fprintf (state_file, "nil)"); | |
984 return; | |
985 } | |
986 | |
987 fprintf (state_file, "\n(!pair "); | |
988 | |
989 if (current->name != NULL) | |
990 write_state_a_string (current->name); | |
991 else | |
992 write_state_a_string ("nil"); | |
993 | |
994 write_state_type (current->type); | |
995 write_state_fileloc (&(current->line)); | |
996 write_state_options (current->opt); | |
997 | |
998 fprintf (state_file, ")"); | |
999 } | |
1000 | |
1001 /* Write a pair list and return the number of pairs written. */ | |
1002 static int | |
1003 write_state_pair_list (pair_p list) | |
1004 { | |
1005 int nbpair = 0; | |
1006 pair_p current; | |
1007 | |
1008 for (current = list; current != NULL; current = current->next) | |
1009 { | |
1010 write_state_pair (current); | |
1011 nbpair++; | |
1012 } | |
1013 return nbpair; | |
1014 | |
1015 } | |
1016 | |
1017 /* When writing imported linked lists, like typedefs, structures, | |
1018 param_structs, ... we count their length first and write it. These | |
1019 eases the reading, and enables an extra verification on the number | |
1020 of actually read items. */ | |
1021 | |
1022 /* Write our typedefs. */ | |
1023 static void | |
1024 write_state_typedefs (void) | |
1025 { | |
1026 int nbtypedefs = pair_list_length (typedefs); | |
1027 int nbpairs = 0; | |
1028 fprintf (state_file, "\n(!typedefs %d\n", nbtypedefs); | |
1029 nbpairs = write_state_pair_list (typedefs); | |
1030 gcc_assert (nbpairs == nbtypedefs); | |
1031 fprintf (state_file, ")\n"); | |
1032 if (verbosity_level >= 2) | |
1033 printf ("%s wrote %d typedefs\n", progname, nbtypedefs); | |
1034 } | |
1035 | |
1036 /* Write our structures. */ | |
1037 static void | |
1038 write_state_structures (void) | |
1039 { | |
1040 int nbstruct = 0; | |
1041 type_p current; | |
1042 | |
1043 for (current = structures; current != NULL; current = current->next) | |
1044 nbstruct++; | |
1045 | |
1046 fprintf (state_file, "\n(!structures %d\n", nbstruct); | |
1047 | |
1048 for (current = structures; current != NULL; current = current->next) | |
1049 write_state_type (current); | |
1050 | |
1051 fprintf (state_file, ")\n"); | |
1052 if (verbosity_level >= 2) | |
1053 printf ("%s wrote %d structures in state\n", progname, nbstruct); | |
1054 } | |
1055 | |
1056 /* Write our param_struct-s. */ | |
1057 static void | |
1058 write_state_param_structs (void) | |
1059 { | |
1060 int nbparamstruct = 0; | |
1061 type_p current; | |
1062 | |
1063 for (current = param_structs; current != NULL; current = current->next) | |
1064 nbparamstruct++; | |
1065 | |
1066 fprintf (state_file, "\n(!param_structs %d\n", nbparamstruct); | |
1067 | |
1068 for (current = param_structs; current != NULL; current = current->next) | |
1069 write_state_type (current); | |
1070 | |
1071 fprintf (state_file, ")\n"); | |
1072 } | |
1073 | |
1074 /* Write our variables. */ | |
1075 static void | |
1076 write_state_variables (void) | |
1077 { | |
1078 int nbvars = pair_list_length (variables); | |
1079 int nbpairs = 0; | |
1080 fprintf (state_file, "\n(!variables %d\n", nbvars); | |
1081 nbpairs = write_state_pair_list (variables); | |
1082 gcc_assert (nbpairs == nbvars); | |
1083 fprintf (state_file, ")\n"); | |
1084 if (verbosity_level >= 2) | |
1085 printf ("%s wrote %d variables.\n", progname, nbvars); | |
1086 } | |
1087 | |
1088 /* Write the source directory. File locations within the source | |
1089 directory have been written specifically. */ | |
1090 static void | |
1091 write_state_srcdir (void) | |
1092 { | |
1093 fprintf (state_file, "\n(!srcdir "); | |
1094 write_state_a_string (srcdir); | |
1095 fprintf (state_file, ")\n"); | |
1096 } | |
1097 | |
1098 /* Count and write the list of our files. */ | |
1099 static void | |
1100 write_state_files_list (void) | |
1101 { | |
1102 int i = 0; | |
1103 /* Write the list of files with their lang_bitmap. */ | |
1104 fprintf (state_file, "\n(!fileslist %d\n", (int) num_gt_files); | |
1105 for (i = 0; i < (int) num_gt_files; i++) | |
1106 { | |
1107 const char *cursrcrelpath = NULL; | |
1108 const input_file *curfil = gt_files[i]; | |
1109 /* Most of the files are inside $(srcdir) so it is worth to | |
1110 handle them specially. */ | |
1111 cursrcrelpath = get_file_srcdir_relative_path (curfil); | |
1112 if (cursrcrelpath) | |
1113 { | |
1114 fprintf (state_file, "(!srcfile %d ", get_lang_bitmap (curfil)); | |
1115 write_state_a_string (cursrcrelpath); | |
1116 } | |
1117 else | |
1118 { | |
1119 fprintf (state_file, "(!file %d ", get_lang_bitmap (curfil)); | |
1120 write_state_a_string (get_input_file_name (curfil)); | |
1121 } | |
1122 fprintf (state_file, ")\n"); | |
1123 } | |
1124 fprintf (state_file, ")\n"); | |
1125 } | |
1126 | |
1127 /* Write the list of GCC front-end languages. */ | |
1128 static void | |
1129 write_state_languages (void) | |
1130 { | |
1131 int i = 0; | |
1132 fprintf (state_file, "\n(!languages %d", (int) num_lang_dirs); | |
1133 for (i = 0; i < (int) num_lang_dirs; i++) | |
1134 { | |
1135 /* Languages names are identifiers, we expect only letters or | |
1136 underscores or digits in them. In particular, C++ is not a | |
1137 valid language name, but cp is valid. */ | |
1138 fprintf (state_file, " %s", lang_dir_names[i]); | |
1139 } | |
1140 fprintf (state_file, ")\n"); | |
1141 } | |
1142 | |
1143 /* Write the trailer. */ | |
1144 static void | |
1145 write_state_trailer (void) | |
1146 { | |
1147 /* This test should probably catch IO errors like disk full... */ | |
1148 if (fputs ("\n(!endfile)\n", state_file) == EOF) | |
1149 fatal ("failed to write state trailer [%s]", xstrerror (errno)); | |
1150 } | |
1151 | |
1152 /* The write_state routine is the only writing routine called by main | |
1153 in gengtype.c. To avoid messing the state if gengtype is | |
1154 interrupted or aborted, we write a temporary file and rename it | |
1155 after having written it in totality. */ | |
1156 void | |
1157 write_state (const char *state_path) | |
1158 { | |
1159 long statelen = 0; | |
1160 time_t now = 0; | |
1161 char *temp_state_path = NULL; | |
1162 char tempsuffix[40]; | |
1163 time (&now); | |
1164 | |
1165 /* We write a unique temporary file which is renamed when complete | |
1166 * only. So even if gengtype is interrupted, the written state file | |
1167 * won't be partially written, since the temporary file is not yet | |
1168 * renamed in that case. */ | |
1169 memset (tempsuffix, 0, sizeof (tempsuffix)); | |
1170 snprintf (tempsuffix, sizeof (tempsuffix) - 1, "-%ld-%d.tmp", (long) now, | |
1171 (int) getpid ()); | |
1172 temp_state_path = concat (state_path, tempsuffix, NULL); | |
1173 state_file = fopen (temp_state_path, "w"); | |
1174 if (state_file == NULL) | |
1175 fatal ("Failed to open file %s for writing state: %s", | |
1176 temp_state_path, xstrerror (errno)); | |
1177 if (verbosity_level >= 3) | |
1178 printf ("%s writing state file %s temporarily in %s\n", | |
1179 progname, state_path, temp_state_path); | |
1180 /* This is the first line of the state. Perhaps the file utility | |
1181 could know about that, so don't change it often. */ | |
1182 fprintf (state_file, ";;;;@@@@ GCC gengtype state\n"); | |
1183 /* Output a few comments for humans. */ | |
1184 fprintf (state_file, | |
1185 ";;; DON'T EDIT THIS FILE, since generated by GCC's gengtype\n"); | |
1186 fprintf (state_file, | |
1187 ";;; The format of this file is tied to a particular version of GCC.\n"); | |
1188 fprintf (state_file, | |
1189 ";;; Don't parse this file wihout knowing GCC gengtype internals.\n"); | |
1190 fprintf (state_file, | |
1191 ";;; This file should be parsed by the same %s which wrote it.\n", | |
1192 progname); | |
1193 fprintf (state_file, ";;; file %s generated on %s\n", state_path, | |
1194 ctime (&now)); | |
1195 /* The first non-comment significant line gives the version string. */ | |
1196 write_state_version (version_string); | |
1197 write_state_srcdir (); | |
1198 write_state_languages (); | |
1199 write_state_files_list (); | |
1200 write_state_structures (); | |
1201 write_state_typedefs (); | |
1202 write_state_param_structs (); | |
1203 write_state_variables (); | |
1204 write_state_trailer (); | |
1205 statelen = ftell (state_file); | |
1206 if (ferror (state_file)) | |
1207 fatal ("output error when writing state file %s [%s]", | |
1208 temp_state_path, xstrerror (errno)); | |
1209 if (fclose (state_file)) | |
1210 fatal ("failed to close state file %s [%s]", | |
1211 temp_state_path, xstrerror (errno)); | |
1212 if (rename (temp_state_path, state_path)) | |
1213 fatal ("failed to rename %s to state file %s [%s]", temp_state_path, | |
1214 state_path, xstrerror (errno)); | |
1215 free (temp_state_path); | |
1216 | |
1217 if (verbosity_level >= 1) | |
1218 printf ("%s wrote state file %s of %ld bytes with %d GTY-ed types\n", | |
1219 progname, state_path, statelen, state_written_type_count); | |
1220 | |
1221 } | |
1222 | |
1223 /** End of writing routines! The corresponding reading routines follow. **/ | |
1224 | |
1225 | |
1226 | |
1227 /* Forward declarations, since some read_state_* functions are | |
1228 recursive! */ | |
1229 static void read_state_fileloc (struct fileloc *line); | |
1230 static void read_state_options (options_p *opt); | |
1231 static void read_state_type (type_p *current); | |
1232 static void read_state_pair (pair_p *pair); | |
1233 /* Return the number of pairs actually read. */ | |
1234 static int read_state_pair_list (pair_p *list); | |
1235 static void read_state_fields (pair_p *fields); | |
1236 static void read_state_common_type_content (type_p current); | |
1237 | |
1238 | |
1239 | |
1240 | |
1241 /* Record into the state_seen_types hash-table a type which we are | |
1242 reading, to enable recursive or circular references to it. */ | |
1243 static void | |
1244 record_type (type_p type) | |
1245 { | |
1246 PTR *slot; | |
1247 | |
1248 slot = htab_find_slot (state_seen_types, type, INSERT); | |
1249 gcc_assert (slot); | |
1250 | |
1251 *slot = type; | |
1252 } | |
1253 | |
1254 /* Read an already seen type. */ | |
1255 static void | |
1256 read_state_already_seen_type (type_p *type) | |
1257 { | |
1258 struct state_token_st *t0 = peek_state_token (0); | |
1259 | |
1260 if (state_token_kind (t0) == STOK_INTEGER) | |
1261 { | |
1262 PTR *slot = NULL; | |
1263 struct type loctype = { TYPE_SCALAR, 0, 0, 0, GC_UNUSED, {0} }; | |
1264 | |
1265 loctype.state_number = t0->stok_un.stok_num; | |
1266 slot = htab_find_slot (state_seen_types, &loctype, NO_INSERT); | |
1267 if (slot == NULL) | |
1268 { | |
1269 fatal_reading_state (t0, "Unknown type"); | |
1270 } | |
1271 | |
1272 next_state_tokens (1); | |
1273 *type = (type_p) *slot; | |
1274 } | |
1275 else | |
1276 { | |
1277 fatal_reading_state (t0, "Bad seen type"); | |
1278 } | |
1279 } | |
1280 | |
1281 | |
1282 /* Read the scalar_nonchar type. */ | |
1283 static void | |
1284 read_state_scalar_nonchar_type (type_p *type) | |
1285 { | |
1286 *type = &scalar_nonchar; | |
1287 read_state_common_type_content (*type); | |
1288 } | |
1289 | |
1290 | |
1291 /* Read the scalar_char type. */ | |
1292 static void | |
1293 read_state_scalar_char_type (type_p *type) | |
1294 { | |
1295 *type = &scalar_char; | |
1296 read_state_common_type_content (*type); | |
1297 } | |
1298 | |
1299 | |
1300 /* Read the string_type. */ | |
1301 static void | |
1302 read_state_string_type (type_p *type) | |
1303 { | |
1304 *type = &string_type; | |
1305 read_state_common_type_content (*type); | |
1306 } | |
1307 | |
1308 | |
1309 /* Read a lang_bitmap representing a set of GCC front-end languages. */ | |
1310 static void | |
1311 read_state_lang_bitmap (lang_bitmap *bitmap) | |
1312 { | |
1313 struct state_token_st *t; | |
1314 | |
1315 t = peek_state_token (0); | |
1316 if (state_token_kind (t) == STOK_INTEGER) | |
1317 { | |
1318 *bitmap = t->stok_un.stok_num; | |
1319 next_state_tokens (1); | |
1320 } | |
1321 else | |
1322 { | |
1323 fatal_reading_state (t, "Bad syntax for bitmap"); | |
1324 } | |
1325 } | |
1326 | |
1327 | |
1328 /* Read a GTY-ed struct type. */ | |
1329 static void | |
1330 read_state_struct_type (type_p type) | |
1331 { | |
1332 struct state_token_st *t0; | |
1333 | |
1334 type->kind = TYPE_STRUCT; | |
1335 read_state_common_type_content (type); | |
1336 t0 = peek_state_token (0); | |
1337 if (state_token_kind (t0) == STOK_STRING) | |
1338 { | |
1339 if (state_token_is_name (t0, "nil")) | |
1340 { | |
1341 type->u.s.tag = NULL; | |
1342 DBGPRINTF ("read anonymous struct type @%p #%d", | |
1343 (void *) type, type->state_number); | |
1344 } | |
1345 else | |
1346 { | |
1347 type->u.s.tag = xstrdup (t0->stok_un.stok_string); | |
1348 DBGPRINTF ("read struct type @%p #%d '%s'", | |
1349 (void *) type, type->state_number, type->u.s.tag); | |
1350 } | |
1351 | |
1352 next_state_tokens (1); | |
1353 read_state_fileloc (&(type->u.s.line)); | |
1354 read_state_fields (&(type->u.s.fields)); | |
1355 read_state_options (&(type->u.s.opt)); | |
1356 read_state_lang_bitmap (&(type->u.s.bitmap)); | |
1357 read_state_type (&(type->u.s.lang_struct)); | |
1358 } | |
1359 else | |
1360 { | |
1361 fatal_reading_state (t0, "Bad tag in struct type"); | |
1362 } | |
1363 } | |
1364 | |
1365 | |
1366 /* Read a GTY-ed union type. */ | |
1367 static void | |
1368 read_state_union_type (type_p type) | |
1369 { | |
1370 struct state_token_st *t0; | |
1371 | |
1372 type->kind = TYPE_UNION; | |
1373 read_state_common_type_content (type); | |
1374 t0 = peek_state_token (0); | |
1375 if (state_token_kind (t0) == STOK_STRING) | |
1376 { | |
1377 if (state_token_is_name (t0, "nil")) | |
1378 { | |
1379 type->u.s.tag = NULL; | |
1380 DBGPRINTF ("read anonymous union type @%p #%d", | |
1381 (void *) type, type->state_number); | |
1382 } | |
1383 else | |
1384 { | |
1385 type->u.s.tag = xstrdup (t0->stok_un.stok_string); | |
1386 DBGPRINTF ("read union type @%p #%d '%s'", | |
1387 (void *) type, type->state_number, type->u.s.tag); | |
1388 } | |
1389 next_state_tokens (1); | |
1390 read_state_fileloc (&(type->u.s.line)); | |
1391 read_state_fields (&(type->u.s.fields)); | |
1392 read_state_options (&(type->u.s.opt)); | |
1393 read_state_lang_bitmap (&(type->u.s.bitmap)); | |
1394 read_state_type (&(type->u.s.lang_struct)); | |
1395 } | |
1396 else | |
1397 fatal_reading_state (t0, "Bad tag in union type"); | |
1398 } | |
1399 | |
1400 | |
1401 /* Read a GTY-ed pointer type. */ | |
1402 static void | |
1403 read_state_pointer_type (type_p type) | |
1404 { | |
1405 type->kind = TYPE_POINTER; | |
1406 read_state_common_type_content (type); | |
1407 DBGPRINTF ("read pointer type @%p #%d", (void *) type, type->state_number); | |
1408 read_state_type (&(type->u.p)); | |
1409 } | |
1410 | |
1411 | |
1412 /* Read a GTY-ed array type. */ | |
1413 static void | |
1414 read_state_array_type (type_p type) | |
1415 { | |
1416 struct state_token_st *t0; | |
1417 | |
1418 type->kind = TYPE_ARRAY; | |
1419 read_state_common_type_content (type); | |
1420 t0 = peek_state_token (0); | |
1421 if (state_token_kind (t0) == STOK_STRING) | |
1422 { | |
1423 type->u.a.len = xstrdup (t0->stok_un.stok_string); | |
1424 DBGPRINTF ("read array type @%p #%d length '%s'", | |
1425 (void *) type, type->state_number, type->u.a.len); | |
1426 next_state_tokens (1); | |
1427 } | |
1428 | |
1429 else if (state_token_is_name (t0, "nil")) | |
1430 { | |
1431 type->u.a.len = NULL; | |
1432 DBGPRINTF ("read array type @%p #%d without length", | |
1433 (void *) type, type->state_number); | |
1434 next_state_tokens (1); | |
1435 } | |
1436 | |
1437 else | |
1438 fatal_reading_state (t0, "Bad array name type"); | |
1439 read_state_type (&(type->u.a.p)); | |
1440 } | |
1441 | |
1442 | |
1443 | |
1444 /* Read a lang_struct type for GTY-ed struct-s which depends upon GCC | |
1445 front-end languages. This is a tricky function and it was painful | |
1446 to debug. Change it with extreme care. See also | |
1447 write_state_lang_struct_type. */ | |
1448 static void | |
1449 read_state_lang_struct_type (type_p type) | |
1450 { | |
1451 struct state_token_st *t0 = NULL; | |
1452 struct state_token_st *t1 = NULL; | |
1453 struct state_token_st *t2 = NULL; | |
1454 | |
1455 type->kind = TYPE_LANG_STRUCT; | |
1456 read_state_common_type_content (type); | |
1457 t0 = peek_state_token (0); | |
1458 if (state_token_kind (t0) == STOK_STRING) | |
1459 { | |
1460 if (state_token_is_name (t0, "nil")) | |
1461 { | |
1462 DBGPRINTF ("read anonymous lang_struct type @%p #%d", | |
1463 (void *) type, type->state_number); | |
1464 type->u.s.tag = NULL; | |
1465 } | |
1466 else | |
1467 { | |
1468 type->u.s.tag = xstrdup (t0->stok_un.stok_string); | |
1469 DBGPRINTF ("read lang_struct type @%p #%d '%s'", | |
1470 (void *) type, type->state_number, type->u.s.tag); | |
1471 } | |
1472 next_state_tokens (1); | |
1473 } | |
1474 else | |
1475 fatal_reading_state (t0, "Bad tag in lang struct type"); | |
1476 read_state_fileloc (&(type->u.s.line)); | |
1477 read_state_fields (&(type->u.s.fields)); | |
1478 read_state_options (&(type->u.s.opt)); | |
1479 read_state_lang_bitmap (&(type->u.s.bitmap)); | |
1480 /* Within lang_struct-ures, the lang_struct field is a linked list | |
1481 of homonymous types! */ | |
1482 t0 = peek_state_token (0); | |
1483 t1 = peek_state_token (1); | |
1484 t2 = peek_state_token (2); | |
1485 /* Parse (!homotypes <number-types> <type-1> .... <type-n>) */ | |
1486 if (state_token_kind (t0) == STOK_LEFTPAR | |
1487 && state_token_is_name (t1, "!homotypes") | |
1488 && state_token_kind (t2) == STOK_INTEGER) | |
1489 { | |
1490 type_p *prevty = &type->u.s.lang_struct; | |
1491 int nbhomotype = t2->stok_un.stok_num; | |
1492 int i = 0; | |
1493 t0 = t1 = t2 = NULL; | |
1494 next_state_tokens (3); | |
1495 for (i = 0; i < nbhomotype; i++) | |
1496 { | |
1497 read_state_type (prevty); | |
1498 t0 = peek_state_token (0); | |
1499 if (*prevty) | |
1500 prevty = &(*prevty)->next; | |
1501 else | |
1502 fatal_reading_state (t0, | |
1503 "expecting type in homotype list for lang_struct"); | |
1504 }; | |
1505 if (state_token_kind (t0) != STOK_RIGHTPAR) | |
1506 fatal_reading_state (t0, | |
1507 "expecting ) in homotype list for lang_struct"); | |
1508 next_state_tokens (1); | |
1509 } | |
1510 else | |
1511 fatal_reading_state (t0, "expecting !homotypes for lang_struct"); | |
1512 } | |
1513 | |
1514 | |
1515 /* Read a param_struct type for GTY parametrized structures. */ | |
1516 static void | |
1517 read_state_param_struct_type (type_p type) | |
1518 { | |
1519 int i; | |
1520 struct state_token_st *t0; | |
1521 | |
1522 type->kind = TYPE_PARAM_STRUCT; | |
1523 read_state_common_type_content (type); | |
1524 DBGPRINTF ("read param_struct type @%p #%d", | |
1525 (void *) type, type->state_number); | |
1526 read_state_type (&(type->u.param_struct.stru)); | |
1527 | |
1528 for (i = 0; i < NUM_PARAM; i++) | |
1529 { | |
1530 t0 = peek_state_token (0); | |
1531 if (state_token_is_name (t0, "nil")) | |
1532 { | |
1533 type->u.param_struct.param[i] = NULL; | |
1534 next_state_tokens (1); | |
1535 } | |
1536 else | |
1537 read_state_type (&(type->u.param_struct.param[i])); | |
1538 } | |
1539 read_state_fileloc (&(type->u.param_struct.line)); | |
1540 } | |
1541 | |
1542 | |
1543 /* Read the gc used information. */ | |
1544 static void | |
1545 read_state_gc_used (enum gc_used_enum *pgus) | |
1546 { | |
1547 struct state_token_st *t0 = peek_state_token (0); | |
1548 if (state_token_is_name (t0, "gc_unused")) | |
1549 *pgus = GC_UNUSED; | |
1550 else if (state_token_is_name (t0, "gc_used")) | |
1551 *pgus = GC_USED; | |
1552 else if (state_token_is_name (t0, "gc_maybe_pointed_to")) | |
1553 *pgus = GC_MAYBE_POINTED_TO; | |
1554 else if (state_token_is_name (t0, "gc_pointed_to")) | |
1555 *pgus = GC_POINTED_TO; | |
1556 else | |
1557 fatal_reading_state (t0, "invalid gc_used information"); | |
1558 next_state_tokens (1); | |
1559 } | |
1560 | |
1561 | |
1562 /* Utility function to read the common content of types. */ | |
1563 static void | |
1564 read_state_common_type_content (type_p current) | |
1565 { | |
1566 struct state_token_st *t0 = peek_state_token (0); | |
1567 | |
1568 if (state_token_kind (t0) == STOK_INTEGER) | |
1569 { | |
1570 current->state_number = t0->stok_un.stok_num; | |
1571 next_state_tokens (1); | |
1572 record_type (current); | |
1573 } | |
1574 else | |
1575 fatal_reading_state_printf (t0, | |
1576 "Expected integer for state_number line %d", | |
1577 state_line); | |
1578 /* We don't read the next field of the type. */ | |
1579 read_state_type (¤t->pointer_to); | |
1580 read_state_gc_used (¤t->gc_used); | |
1581 } | |
1582 | |
1583 | |
1584 /* Read a GTY-ed type. */ | |
1585 void | |
1586 read_state_type (type_p *current) | |
1587 { | |
1588 struct state_token_st *t0 = peek_state_token (0); | |
1589 struct state_token_st *t1 = peek_state_token (1); | |
1590 | |
1591 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1592 state_token_is_name (t1, "!type")) | |
1593 { | |
1594 next_state_tokens (2); | |
1595 t0 = peek_state_token (0); | |
1596 if (state_token_is_name (t0, "already_seen")) | |
1597 { | |
1598 next_state_tokens (1); | |
1599 read_state_already_seen_type (current); | |
1600 } | |
1601 else | |
1602 { | |
1603 t0 = peek_state_token (0); | |
1604 | |
1605 if (state_token_is_name (t0, "scalar_nonchar")) | |
1606 { | |
1607 next_state_tokens (1); | |
1608 read_state_scalar_nonchar_type (current); | |
1609 } | |
1610 else if (state_token_is_name (t0, "scalar_char")) | |
1611 { | |
1612 next_state_tokens (1); | |
1613 read_state_scalar_char_type (current); | |
1614 } | |
1615 else if (state_token_is_name (t0, "string")) | |
1616 { | |
1617 next_state_tokens (1); | |
1618 read_state_string_type (current); | |
1619 } | |
1620 else if (state_token_is_name (t0, "struct")) | |
1621 { | |
1622 *current = XCNEW (struct type); | |
1623 next_state_tokens (1); | |
1624 read_state_struct_type (*current); | |
1625 } | |
1626 else if (state_token_is_name (t0, "union")) | |
1627 { | |
1628 *current = XCNEW (struct type); | |
1629 next_state_tokens (1); | |
1630 read_state_union_type (*current); | |
1631 } | |
1632 else if (state_token_is_name (t0, "lang_struct")) | |
1633 { | |
1634 *current = XCNEW (struct type); | |
1635 next_state_tokens (1); | |
1636 read_state_lang_struct_type (*current); | |
1637 } | |
1638 else if (state_token_is_name (t0, "param_struct")) | |
1639 { | |
1640 *current = XCNEW (struct type); | |
1641 next_state_tokens (1); | |
1642 read_state_param_struct_type (*current); | |
1643 } | |
1644 else if (state_token_is_name (t0, "pointer")) | |
1645 { | |
1646 *current = XCNEW (struct type); | |
1647 next_state_tokens (1); | |
1648 read_state_pointer_type (*current); | |
1649 } | |
1650 else if (state_token_is_name (t0, "array")) | |
1651 { | |
1652 *current = XCNEW (struct type); | |
1653 next_state_tokens (1); | |
1654 read_state_array_type (*current); | |
1655 } | |
1656 else | |
1657 fatal_reading_state (t0, "bad type in (!type"); | |
1658 } | |
1659 t0 = peek_state_token (0); | |
1660 if (state_token_kind (t0) != STOK_RIGHTPAR) | |
1661 fatal_reading_state (t0, "missing ) in type"); | |
1662 next_state_tokens (1); | |
1663 } | |
1664 else if (state_token_is_name (t0, "nil")) | |
1665 { | |
1666 next_state_tokens (1); | |
1667 *current = NULL; | |
1668 } | |
1669 else | |
1670 fatal_reading_state (t0, "bad type syntax"); | |
1671 } | |
1672 | |
1673 | |
1674 /* Read a file location. Files within the source directory are dealt | |
1675 with specifically. */ | |
1676 void | |
1677 read_state_fileloc (struct fileloc *floc) | |
1678 { | |
1679 bool issrcfile = false; | |
1680 struct state_token_st *t0 = peek_state_token (0); | |
1681 struct state_token_st *t1 = peek_state_token (1); | |
1682 | |
1683 gcc_assert (floc != NULL); | |
1684 gcc_assert (srcdir != NULL); | |
1685 | |
1686 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1687 (state_token_is_name (t1, "!fileloc") | |
1688 || (issrcfile = state_token_is_name (t1, "!srcfileloc")))) | |
1689 { | |
1690 next_state_tokens (2); | |
1691 t0 = peek_state_token (0); | |
1692 t1 = peek_state_token (1); | |
1693 if (state_token_kind (t0) == STOK_STRING && | |
1694 state_token_kind (t1) == STOK_INTEGER) | |
1695 { | |
1696 char *path = t0->stok_un.stok_string; | |
1697 if (issrcfile) | |
1698 { | |
1699 static const char dirsepstr[2] = { DIR_SEPARATOR, (char) 0 }; | |
1700 char *fullpath = concat (srcdir, dirsepstr, path, NULL); | |
1701 floc->file = input_file_by_name (fullpath); | |
1702 free (fullpath); | |
1703 } | |
1704 else | |
1705 floc->file = input_file_by_name (path); | |
1706 floc->line = t1->stok_un.stok_num; | |
1707 next_state_tokens (2); | |
1708 } | |
1709 else | |
1710 fatal_reading_state (t0, | |
1711 "Bad fileloc syntax, expected path string and line"); | |
1712 t0 = peek_state_token (0); | |
1713 if (state_token_kind (t0) != STOK_RIGHTPAR) | |
1714 fatal_reading_state (t0, "Bad fileloc syntax, expected )"); | |
1715 next_state_tokens (1); | |
1716 } | |
1717 else if (state_token_is_name (t0, "nil")) | |
1718 { | |
1719 next_state_tokens (1); | |
1720 floc->file = NULL; | |
1721 floc->line = 0; | |
1722 } | |
1723 else | |
1724 fatal_reading_state (t0, "Bad fileloc syntax"); | |
1725 } | |
1726 | |
1727 | |
1728 /* Read the fields of a GTY-ed type. */ | |
1729 void | |
1730 read_state_fields (pair_p *fields) | |
1731 { | |
1732 pair_p tmp = NULL; | |
1733 struct state_token_st *t0 = peek_state_token (0); | |
1734 struct state_token_st *t1 = peek_state_token (1); | |
1735 struct state_token_st *t2 = peek_state_token (2); | |
1736 | |
1737 if (state_token_kind (t0) == STOK_LEFTPAR | |
1738 && state_token_is_name (t1, "!fields") | |
1739 && state_token_kind (t2) == STOK_INTEGER) | |
1740 { | |
1741 int nbfields = t2->stok_un.stok_num; | |
1742 int nbpairs = 0; | |
1743 next_state_tokens (3); | |
1744 nbpairs = read_state_pair_list (&tmp); | |
1745 t0 = peek_state_token (0); | |
1746 if (nbpairs != nbfields) | |
1747 fatal_reading_state_printf | |
1748 (t0, | |
1749 "Mismatched fields number, expected %d got %d", nbpairs, nbfields); | |
1750 if (state_token_kind (t0) == STOK_RIGHTPAR) | |
1751 next_state_tokens (1); | |
1752 else | |
1753 fatal_reading_state (t0, "Bad fields expecting )"); | |
1754 } | |
1755 | |
1756 *fields = tmp; | |
1757 } | |
1758 | |
1759 | |
1760 /* Read a string option. */ | |
1761 static void | |
1762 read_state_string_option (options_p opt) | |
1763 { | |
1764 struct state_token_st *t0 = peek_state_token (0); | |
1765 opt->kind = OPTION_STRING; | |
1766 if (state_token_kind (t0) == STOK_STRING) | |
1767 { | |
1768 opt->info.string = xstrdup (t0->stok_un.stok_string); | |
1769 next_state_tokens (1); | |
1770 } | |
1771 else if (state_token_is_name (t0, "nil")) | |
1772 { | |
1773 opt->info.string = NULL; | |
1774 next_state_tokens (1); | |
1775 } | |
1776 else | |
1777 fatal_reading_state (t0, "Missing name in string option"); | |
1778 } | |
1779 | |
1780 | |
1781 /* Read a type option. */ | |
1782 static void | |
1783 read_state_type_option (options_p opt) | |
1784 { | |
1785 opt->kind = OPTION_TYPE; | |
1786 read_state_type (&(opt->info.type)); | |
1787 } | |
1788 | |
1789 | |
1790 /* Read a nested option. */ | |
1791 static void | |
1792 read_state_nested_option (options_p opt) | |
1793 { | |
1794 struct state_token_st *t0; | |
1795 | |
1796 opt->info.nested = XCNEW (struct nested_ptr_data); | |
1797 opt->kind = OPTION_NESTED; | |
1798 read_state_type (&(opt->info.nested->type)); | |
1799 t0 = peek_state_token (0); | |
1800 if (state_token_kind (t0) == STOK_STRING) | |
1801 { | |
1802 opt->info.nested->convert_from = xstrdup (t0->stok_un.stok_string); | |
1803 next_state_tokens (1); | |
1804 } | |
1805 else if (state_token_is_name (t0, "nil")) | |
1806 { | |
1807 opt->info.nested->convert_from = NULL; | |
1808 next_state_tokens (1); | |
1809 } | |
1810 else | |
1811 fatal_reading_state (t0, "Bad nested convert_from option"); | |
1812 | |
1813 t0 = peek_state_token (0); | |
1814 if (state_token_kind (t0) == STOK_STRING) | |
1815 { | |
1816 opt->info.nested->convert_to = xstrdup (t0->stok_un.stok_string); | |
1817 next_state_tokens (1); | |
1818 } | |
1819 else if (state_token_is_name (t0, "nil")) | |
1820 { | |
1821 opt->info.nested->convert_to = NULL; | |
1822 next_state_tokens (1); | |
1823 } | |
1824 else | |
1825 fatal_reading_state (t0, "Bad nested convert_from option"); | |
1826 } | |
1827 | |
1828 | |
1829 /* Read an GTY option. */ | |
1830 static void | |
1831 read_state_option (options_p *opt) | |
1832 { | |
1833 struct state_token_st *t0 = peek_state_token (0); | |
1834 struct state_token_st *t1 = peek_state_token (1); | |
1835 | |
1836 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1837 state_token_is_name (t1, "!option")) | |
1838 { | |
1839 next_state_tokens (2); | |
1840 t0 = peek_state_token (0); | |
1841 if (state_token_kind (t0) == STOK_NAME) | |
1842 { | |
1843 *opt = XCNEW (struct options); | |
1844 if (state_token_is_name (t0, "nil")) | |
1845 (*opt)->name = NULL; | |
1846 else | |
1847 (*opt)->name = t0->stok_un.stok_ident->stid_name; | |
1848 next_state_tokens (1); | |
1849 t0 = peek_state_token (0); | |
1850 if (state_token_kind (t0) == STOK_NAME) | |
1851 { | |
1852 if (state_token_is_name (t0, "string")) | |
1853 { | |
1854 next_state_tokens (1); | |
1855 read_state_string_option (*opt); | |
1856 } | |
1857 else if (state_token_is_name (t0, "type")) | |
1858 { | |
1859 next_state_tokens (1); | |
1860 read_state_type_option (*opt); | |
1861 } | |
1862 else if (state_token_is_name (t0, "nested")) | |
1863 { | |
1864 next_state_tokens (1); | |
1865 read_state_nested_option (*opt); | |
1866 } | |
1867 else | |
1868 fatal_reading_state (t0, "Bad option type"); | |
1869 t0 = peek_state_token (0); | |
1870 if (state_token_kind (t0) != STOK_RIGHTPAR) | |
1871 fatal_reading_state (t0, "Bad syntax in option, expecting )"); | |
1872 | |
1873 next_state_tokens (1); | |
1874 } | |
1875 else | |
1876 fatal_reading_state (t0, "Missing option type"); | |
1877 } | |
1878 else | |
1879 fatal_reading_state (t0, "Bad name for option"); | |
1880 } | |
1881 else | |
1882 fatal_reading_state (t0, "Bad option, waiting for )"); | |
1883 } | |
1884 | |
1885 /* Read a list of options. */ | |
1886 void | |
1887 read_state_options (options_p *opt) | |
1888 { | |
1889 options_p head = NULL; | |
1890 options_p previous = NULL; | |
1891 options_p current_option = NULL; | |
1892 struct state_token_st *t0 = peek_state_token (0); | |
1893 struct state_token_st *t1 = peek_state_token (1); | |
1894 | |
1895 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1896 state_token_is_name (t1, "!options")) | |
1897 { | |
1898 next_state_tokens (2); | |
1899 t0 = peek_state_token (0); | |
1900 while (state_token_kind (t0) != STOK_RIGHTPAR) | |
1901 { | |
1902 read_state_option (¤t_option); | |
1903 if (head == NULL) | |
1904 { | |
1905 head = current_option; | |
1906 previous = head; | |
1907 } | |
1908 else | |
1909 { | |
1910 previous->next = current_option; | |
1911 previous = current_option; | |
1912 } | |
1913 t0 = peek_state_token (0); | |
1914 } | |
1915 next_state_tokens (1); | |
1916 } | |
1917 else if (state_token_is_name (t0, "nil")) | |
1918 { | |
1919 next_state_tokens (1); | |
1920 } | |
1921 else | |
1922 fatal_reading_state (t0, "Bad options syntax"); | |
1923 | |
1924 *opt = head; | |
1925 } | |
1926 | |
1927 | |
1928 /* Read a version, and check against the version of the gengtype. */ | |
1929 static void | |
1930 read_state_version (const char *version_string) | |
1931 { | |
1932 struct state_token_st *t0 = peek_state_token (0); | |
1933 struct state_token_st *t1 = peek_state_token (1); | |
1934 | |
1935 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1936 state_token_is_name (t1, "!version")) | |
1937 { | |
1938 next_state_tokens (2); | |
1939 t0 = peek_state_token (0); | |
1940 t1 = peek_state_token (1); | |
1941 if (state_token_kind (t0) == STOK_STRING && | |
1942 state_token_kind (t1) == STOK_RIGHTPAR) | |
1943 { | |
1944 /* Check that the read version string is the same as current | |
1945 version. */ | |
1946 if (strcmp (version_string, t0->stok_un.stok_string)) | |
1947 fatal_reading_state_printf (t0, | |
1948 "version string mismatch; expecting %s but got %s", | |
1949 version_string, | |
1950 t0->stok_un.stok_string); | |
1951 next_state_tokens (2); | |
1952 } | |
1953 else | |
1954 fatal_reading_state (t0, "Missing version or right parenthesis"); | |
1955 } | |
1956 else | |
1957 fatal_reading_state (t0, "Bad version syntax"); | |
1958 } | |
1959 | |
1960 | |
1961 /* Read a pair. */ | |
1962 void | |
1963 read_state_pair (pair_p *current) | |
1964 { | |
1965 struct state_token_st *t0 = peek_state_token (0); | |
1966 struct state_token_st *t1 = peek_state_token (1); | |
1967 if (state_token_kind (t0) == STOK_LEFTPAR && | |
1968 state_token_is_name (t1, "!pair")) | |
1969 { | |
1970 *current = XCNEW (struct pair); | |
1971 next_state_tokens (2); | |
1972 t0 = peek_state_token (0); | |
1973 if (state_token_kind (t0) == STOK_STRING) | |
1974 { | |
1975 if (strcmp (t0->stok_un.stok_string, "nil") == 0) | |
1976 { | |
1977 (*current)->name = NULL; | |
1978 } | |
1979 else | |
1980 { | |
1981 (*current)->name = xstrdup (t0->stok_un.stok_string); | |
1982 } | |
1983 next_state_tokens (1); | |
1984 read_state_type (&((*current)->type)); | |
1985 read_state_fileloc (&((*current)->line)); | |
1986 read_state_options (&((*current)->opt));; | |
1987 t0 = peek_state_token (0); | |
1988 if (state_token_kind (t0) == STOK_RIGHTPAR) | |
1989 { | |
1990 next_state_tokens (1); | |
1991 } | |
1992 else | |
1993 { | |
1994 fatal_reading_state (t0, "Bad syntax for pair, )"); | |
1995 } | |
1996 } | |
1997 else | |
1998 { | |
1999 fatal_reading_state (t0, "Bad name for pair"); | |
2000 } | |
2001 } | |
2002 else if (state_token_kind (t0) == STOK_NAME && | |
2003 state_token_is_name (t0, "nil")) | |
2004 { | |
2005 next_state_tokens (1); | |
2006 *current = NULL; | |
2007 } | |
2008 else | |
2009 fatal_reading_state_printf (t0, "Bad syntax for pair, (!pair %d", | |
2010 state_token->stok_kind); | |
2011 } | |
2012 | |
2013 | |
2014 /* Return the number of pairs actually read. */ | |
2015 int | |
2016 read_state_pair_list (pair_p *list) | |
2017 { | |
2018 int nbpair = 0; | |
2019 pair_p head = NULL; | |
2020 pair_p previous = NULL; | |
2021 pair_p tmp = NULL; | |
2022 struct state_token_st *t0 = peek_state_token (0); | |
2023 while (t0 && state_token_kind (t0) != STOK_RIGHTPAR) | |
2024 { | |
2025 read_state_pair (&tmp); | |
2026 if (head == NULL) | |
2027 { | |
2028 head = tmp; | |
2029 previous = head; | |
2030 } | |
2031 else | |
2032 { | |
2033 previous->next = tmp; | |
2034 previous = tmp; | |
2035 } | |
2036 t0 = peek_state_token (0); | |
2037 nbpair++; | |
2038 } | |
2039 | |
2040 /* don't consume the ); the caller will eat it. */ | |
2041 *list = head; | |
2042 return nbpair; | |
2043 } | |
2044 | |
2045 /* Read the typedefs. */ | |
2046 static void | |
2047 read_state_typedefs (pair_p *typedefs) | |
2048 { | |
2049 int nbtypedefs = 0; | |
2050 pair_p list = NULL; | |
2051 struct state_token_st *t0 = peek_state_token (0); | |
2052 struct state_token_st *t1 = peek_state_token (1); | |
2053 struct state_token_st *t2 = peek_state_token (2); | |
2054 | |
2055 if (state_token_kind (t0) == STOK_LEFTPAR | |
2056 && state_token_is_name (t1, "!typedefs") | |
2057 && state_token_kind (t2) == STOK_INTEGER) | |
2058 { | |
2059 int nbpairs = 0; | |
2060 nbtypedefs = t2->stok_un.stok_num; | |
2061 next_state_tokens (3); | |
2062 nbpairs = read_state_pair_list (&list); | |
2063 t0 = peek_state_token (0); | |
2064 if (nbpairs != nbtypedefs) | |
2065 fatal_reading_state_printf | |
2066 (t0, | |
2067 "invalid number of typedefs, expected %d but got %d", | |
2068 nbtypedefs, nbpairs); | |
2069 if (state_token_kind (t0) == STOK_RIGHTPAR) | |
2070 next_state_tokens (1); | |
2071 else | |
2072 fatal_reading_state (t0, "Bad typedefs syntax )"); | |
2073 } | |
2074 else | |
2075 fatal_reading_state (t0, "Bad typedefs syntax (!typedefs"); | |
2076 | |
2077 if (verbosity_level >= 2) | |
2078 printf ("%s read %d typedefs from state\n", progname, nbtypedefs); | |
2079 *typedefs = list; | |
2080 } | |
2081 | |
2082 | |
2083 /* Read the structures. */ | |
2084 static void | |
2085 read_state_structures (type_p *structures) | |
2086 { | |
2087 type_p head = NULL; | |
2088 type_p previous = NULL; | |
2089 type_p tmp; | |
2090 int nbstruct = 0, countstruct = 0; | |
2091 struct state_token_st *t0 = peek_state_token (0); | |
2092 struct state_token_st *t1 = peek_state_token (1); | |
2093 struct state_token_st *t2 = peek_state_token (2); | |
2094 | |
2095 if (state_token_kind (t0) == STOK_LEFTPAR | |
2096 && state_token_is_name (t1, "!structures") | |
2097 && state_token_kind (t2) == STOK_INTEGER) | |
2098 { | |
2099 nbstruct = t2->stok_un.stok_num; | |
2100 next_state_tokens (3); | |
2101 t0 = peek_state_token (0); | |
2102 while (t0 && state_token_kind (t0) != STOK_RIGHTPAR) | |
2103 { | |
2104 tmp = NULL; | |
2105 read_state_type (&tmp); | |
2106 countstruct++; | |
2107 if (head == NULL) | |
2108 { | |
2109 head = tmp; | |
2110 previous = head; | |
2111 } | |
2112 else | |
2113 { | |
2114 previous->next = tmp; | |
2115 previous = tmp; | |
2116 } | |
2117 t0 = peek_state_token (0); | |
2118 } | |
2119 next_state_tokens (1); | |
2120 } | |
2121 else | |
2122 fatal_reading_state (t0, "Bad structures syntax"); | |
2123 if (countstruct != nbstruct) | |
2124 fatal_reading_state_printf (NULL_STATE_TOKEN, | |
2125 "expected %d structures but got %d", | |
2126 nbstruct, countstruct); | |
2127 if (verbosity_level >= 2) | |
2128 printf ("%s read %d structures from state\n", progname, nbstruct); | |
2129 *structures = head; | |
2130 } | |
2131 | |
2132 | |
2133 /* Read the param_struct-s. */ | |
2134 static void | |
2135 read_state_param_structs (type_p *param_structs) | |
2136 { | |
2137 int nbparamstructs = 0; | |
2138 int countparamstructs = 0; | |
2139 type_p head = NULL; | |
2140 type_p previous; | |
2141 type_p tmp; | |
2142 struct state_token_st *t0 = peek_state_token (0); | |
2143 struct state_token_st *t1 = peek_state_token (1); | |
2144 struct state_token_st *t2 = peek_state_token (2); | |
2145 | |
2146 if (state_token_kind (t0) == STOK_LEFTPAR | |
2147 && state_token_is_name (t1, "!param_structs") | |
2148 && state_token_kind (t2) == STOK_INTEGER) | |
2149 { | |
2150 nbparamstructs = t2->stok_un.stok_num; | |
2151 next_state_tokens (3); | |
2152 t0 = t1 = t2 = NULL; | |
2153 t0 = peek_state_token (0); | |
2154 while (state_token_kind (t0) != STOK_RIGHTPAR) | |
2155 { | |
2156 tmp = NULL; | |
2157 read_state_type (&tmp); | |
2158 if (head == NULL) | |
2159 { | |
2160 head = tmp; | |
2161 previous = head; | |
2162 } | |
2163 else | |
2164 { | |
2165 previous->next = tmp; | |
2166 previous = tmp; | |
2167 } | |
2168 t0 = peek_state_token (0); | |
2169 countparamstructs++; | |
2170 } | |
2171 next_state_tokens (1); | |
2172 } | |
2173 else | |
2174 fatal_reading_state (t0, "Bad param_structs syntax"); | |
2175 t0 = peek_state_token (0); | |
2176 if (countparamstructs != nbparamstructs) | |
2177 fatal_reading_state_printf | |
2178 (t0, | |
2179 "invalid number of param_structs expected %d got %d", | |
2180 nbparamstructs, countparamstructs); | |
2181 *param_structs = head; | |
2182 } | |
2183 | |
2184 | |
2185 /* Read the variables. */ | |
2186 static void | |
2187 read_state_variables (pair_p *variables) | |
2188 { | |
2189 pair_p list = NULL; | |
2190 int nbvars = 0; | |
2191 struct state_token_st *t0 = peek_state_token (0); | |
2192 struct state_token_st *t1 = peek_state_token (1); | |
2193 struct state_token_st *t2 = peek_state_token (2); | |
2194 | |
2195 if (state_token_kind (t0) == STOK_LEFTPAR | |
2196 && state_token_is_name (t1, "!variables") | |
2197 && state_token_kind (t2) == STOK_INTEGER) | |
2198 { | |
2199 int nbpairs = 0; | |
2200 nbvars = t2->stok_un.stok_num; | |
2201 next_state_tokens (3); | |
2202 nbpairs = read_state_pair_list (&list); | |
2203 t0 = peek_state_token (0); | |
2204 if (nbpairs != nbvars) | |
2205 fatal_reading_state_printf | |
2206 (t0, "Invalid number of variables, expected %d but got %d", | |
2207 nbvars, nbpairs); | |
2208 if (state_token_kind (t0) == STOK_RIGHTPAR) | |
2209 next_state_tokens (1); | |
2210 else | |
2211 fatal_reading_state (t0, "Waiting for ) in variables"); | |
2212 } | |
2213 else | |
2214 fatal_reading_state (t0, "Bad variables syntax"); | |
2215 *variables = list; | |
2216 if (verbosity_level >= 2) | |
2217 printf ("%s read %d variables from state\n", progname, nbvars); | |
2218 } | |
2219 | |
2220 | |
2221 /* Read the source directory. */ | |
2222 static void | |
2223 read_state_srcdir (void) | |
2224 { | |
2225 struct state_token_st *t0 = peek_state_token (0); | |
2226 struct state_token_st *t1 = peek_state_token (1); | |
2227 if (state_token_kind (t0) == STOK_LEFTPAR && | |
2228 state_token_is_name (t1, "!srcdir")) | |
2229 { | |
2230 next_state_tokens (2); | |
2231 t0 = peek_state_token (0); | |
2232 t1 = peek_state_token (1); | |
2233 if (state_token_kind (t0) == STOK_STRING && | |
2234 state_token_kind (t1) == STOK_RIGHTPAR) | |
2235 { | |
2236 srcdir = xstrdup (t0->stok_un.stok_string); | |
2237 srcdir_len = strlen (srcdir); | |
2238 next_state_tokens (2); | |
2239 return; | |
2240 } | |
2241 } | |
2242 | |
2243 fatal_reading_state (t0, "Bad srcdir in state_file"); | |
2244 } | |
2245 | |
2246 | |
2247 /* Read the sequence of GCC front-end languages. */ | |
2248 static void | |
2249 read_state_languages (void) | |
2250 { | |
2251 struct state_token_st *t0 = peek_state_token (0); | |
2252 struct state_token_st *t1 = peek_state_token (1); | |
2253 struct state_token_st *t2 = peek_state_token (2); | |
2254 if (state_token_kind (t0) == STOK_LEFTPAR | |
2255 && state_token_is_name (t1, "!languages") | |
2256 && state_token_kind (t2) == STOK_INTEGER) | |
2257 { | |
2258 int i = 0; | |
2259 num_lang_dirs = t2->stok_un.stok_num; | |
2260 lang_dir_names = XCNEWVEC (const char *, num_lang_dirs); | |
2261 next_state_tokens (3); | |
2262 t0 = t1 = t2 = NULL; | |
2263 for (i = 0; i < (int) num_lang_dirs; i++) | |
2264 { | |
2265 t0 = peek_state_token (0); | |
2266 if (state_token_kind (t0) != STOK_NAME) | |
2267 fatal_reading_state (t0, "expecting language name in state file"); | |
2268 lang_dir_names[i] = t0->stok_un.stok_ident->stid_name; | |
2269 next_state_tokens (1); | |
2270 } | |
2271 t0 = peek_state_token (0); | |
2272 if (state_token_kind (t0) != STOK_RIGHTPAR) | |
2273 fatal_reading_state (t0, "missing ) in languages list of state file"); | |
2274 next_state_tokens (1); | |
2275 } | |
2276 else | |
2277 fatal_reading_state (t0, "expecting languages list in state file"); | |
2278 | |
2279 } | |
2280 | |
2281 /* Read the sequence of files. */ | |
2282 static void | |
2283 read_state_files_list (void) | |
2284 { | |
2285 struct state_token_st *t0 = peek_state_token (0); | |
2286 struct state_token_st *t1 = peek_state_token (1); | |
2287 struct state_token_st *t2 = peek_state_token (2); | |
2288 | |
2289 if (state_token_kind (t0) == STOK_LEFTPAR | |
2290 && state_token_is_name (t1, "!fileslist") | |
2291 && state_token_kind (t2) == STOK_INTEGER) | |
2292 { | |
2293 int i = 0; | |
2294 num_gt_files = t2->stok_un.stok_num; | |
2295 next_state_tokens (3); | |
2296 t0 = t1 = t2 = NULL; | |
2297 gt_files = XCNEWVEC (const input_file *, num_gt_files); | |
2298 for (i = 0; i < (int) num_gt_files; i++) | |
2299 { | |
2300 bool issrcfile = FALSE; | |
2301 t0 = t1 = t2 = NULL; | |
2302 t0 = peek_state_token (0); | |
2303 t1 = peek_state_token (1); | |
2304 t2 = peek_state_token (2); | |
2305 if (state_token_kind (t0) == STOK_LEFTPAR | |
2306 && (state_token_is_name (t1, "!file") | |
2307 || (issrcfile = state_token_is_name (t1, "!srcfile"))) | |
2308 && state_token_kind (t2) == STOK_INTEGER) | |
2309 { | |
2310 lang_bitmap bmap = t2->stok_un.stok_num; | |
2311 next_state_tokens (3); | |
2312 t0 = t1 = t2 = NULL; | |
2313 t0 = peek_state_token (0); | |
2314 t1 = peek_state_token (1); | |
2315 if (state_token_kind (t0) == STOK_STRING | |
2316 && state_token_kind (t1) == STOK_RIGHTPAR) | |
2317 { | |
2318 const char *fnam = t0->stok_un.stok_string; | |
2319 /* Allocate & fill a gt_file entry with space for the lang_bitmap before! */ | |
2320 input_file *curgt = NULL; | |
2321 if (issrcfile) | |
2322 { | |
2323 static const char dirsepstr[2] = | |
2324 { DIR_SEPARATOR, (char) 0 }; | |
2325 char *fullpath = concat (srcdir, dirsepstr, fnam, NULL); | |
2326 curgt = input_file_by_name (fullpath); | |
2327 free (fullpath); | |
2328 } | |
2329 else | |
2330 curgt = input_file_by_name (fnam); | |
2331 set_lang_bitmap (curgt, bmap); | |
2332 gt_files[i] = curgt; | |
2333 next_state_tokens (2); | |
2334 } | |
2335 else | |
2336 fatal_reading_state (t0, | |
2337 "bad file in !fileslist of state file"); | |
2338 } | |
2339 else | |
2340 fatal_reading_state (t0, | |
2341 "expecting file in !fileslist of state file"); | |
2342 }; | |
2343 t0 = peek_state_token (0); | |
2344 if (!state_token_kind (t0) == STOK_RIGHTPAR) | |
2345 fatal_reading_state (t0, "missing ) for !fileslist in state file"); | |
2346 next_state_tokens (1); | |
2347 } | |
2348 else | |
2349 fatal_reading_state (t0, "missing !fileslist in state file"); | |
2350 } | |
2351 | |
2352 | |
2353 /* Read the trailer. */ | |
2354 static void | |
2355 read_state_trailer (void) | |
2356 { | |
2357 struct state_token_st *t0 = peek_state_token (0); | |
2358 struct state_token_st *t1 = peek_state_token (1); | |
2359 struct state_token_st *t2 = peek_state_token (2); | |
2360 | |
2361 if (state_token_kind (t0) == STOK_LEFTPAR | |
2362 && state_token_is_name (t1, "!endfile") | |
2363 && state_token_kind (t2) == STOK_RIGHTPAR) | |
2364 next_state_tokens (3); | |
2365 else | |
2366 fatal_reading_state (t0, "missing !endfile in state file"); | |
2367 } | |
2368 | |
2369 | |
2370 /* Utility functions for the state_seen_types hash table. */ | |
2371 static unsigned | |
2372 hash_type_number (const void *ty) | |
2373 { | |
2374 const struct type *type = (const struct type *) ty; | |
2375 | |
2376 return type->state_number; | |
2377 } | |
2378 | |
2379 static int | |
2380 equals_type_number (const void *ty1, const void *ty2) | |
2381 { | |
2382 const struct type *type1 = (const struct type *) ty1; | |
2383 const struct type *type2 = (const struct type *) ty2; | |
2384 | |
2385 return type1->state_number == type2->state_number; | |
2386 } | |
2387 | |
2388 | |
2389 /* The function reading the state, called by main from gengtype.c. */ | |
2390 void | |
2391 read_state (const char *path) | |
2392 { | |
2393 state_file = fopen (path, "r"); | |
2394 if (state_file == NULL) | |
2395 fatal ("Failed to open state file %s for reading [%s]", path, | |
2396 xstrerror (errno)); | |
2397 state_path = path; | |
2398 state_line = 1; | |
2399 | |
2400 if (verbosity_level >= 1) | |
2401 { | |
2402 printf ("%s reading state file %s;", progname, state_path); | |
2403 if (verbosity_level >= 2) | |
2404 putchar ('\n'); | |
2405 fflush (stdout); | |
2406 } | |
2407 | |
2408 state_seen_types = | |
2409 htab_create (2017, hash_type_number, equals_type_number, NULL); | |
2410 state_ident_tab = | |
2411 htab_create (4027, htab_hash_string, (htab_eq) strcmp, NULL); | |
2412 read_state_version (version_string); | |
2413 read_state_srcdir (); | |
2414 read_state_languages (); | |
2415 read_state_files_list (); | |
2416 read_state_structures (&structures); | |
2417 if (ferror (state_file)) | |
2418 fatal_reading_state_printf | |
2419 (NULL_STATE_TOKEN, "input error while reading state [%s]", | |
2420 xstrerror (errno)); | |
2421 read_state_typedefs (&typedefs); | |
2422 read_state_param_structs (¶m_structs); | |
2423 read_state_variables (&variables); | |
2424 read_state_trailer (); | |
2425 | |
2426 if (verbosity_level >= 1) | |
2427 { | |
2428 printf ("%s read %ld bytes.\n", progname, ftell (state_file)); | |
2429 fflush (stdout); | |
2430 }; | |
2431 | |
2432 if (fclose (state_file)) | |
2433 fatal ("failed to close read state file %s [%s]", | |
2434 path, xstrerror (errno)); | |
2435 state_file = NULL; | |
2436 state_path = NULL; | |
2437 } | |
2438 | |
2439 /* End of file gengtype-state.c. */ |