cse.c (approx_reg_cost_1, cse_insn): Fix -Wc++-compat and/or -Wcast-qual warnings.
[gcc.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "bconfig.h"
22 #include "system.h"
23 #include "gengtype.h"
24 #include "errors.h" /* for fatal */
25 #include "double-int.h"
26
27 /* Data types, macros, etc. used only in this file. */
28
29 /* Kinds of types we can understand. */
30 enum typekind {
31 TYPE_SCALAR,
32 TYPE_STRING,
33 TYPE_STRUCT,
34 TYPE_UNION,
35 TYPE_POINTER,
36 TYPE_ARRAY,
37 TYPE_LANG_STRUCT,
38 TYPE_PARAM_STRUCT
39 };
40
41 typedef unsigned lang_bitmap;
42
43 /* A way to pass data through to the output end. */
44 struct options
45 {
46 struct options *next;
47 const char *name;
48 const char *info;
49 };
50
51 /* Option data for the 'nested_ptr' option. */
52 struct nested_ptr_data
53 {
54 type_p type;
55 const char *convert_to;
56 const char *convert_from;
57 };
58
59 /* A name and a type. */
60 struct pair
61 {
62 pair_p next;
63 const char *name;
64 type_p type;
65 struct fileloc line;
66 options_p opt;
67 };
68
69 #define NUM_PARAM 10
70
71 /* A description of a type. */
72 enum gc_used_enum
73 {
74 GC_UNUSED = 0,
75 GC_USED,
76 GC_MAYBE_POINTED_TO,
77 GC_POINTED_TO
78 };
79
80 struct type
81 {
82 enum typekind kind;
83 type_p next;
84 type_p pointer_to;
85 enum gc_used_enum gc_used;
86 union {
87 type_p p;
88 struct {
89 const char *tag;
90 struct fileloc line;
91 pair_p fields;
92 options_p opt;
93 lang_bitmap bitmap;
94 type_p lang_struct;
95 } s;
96 bool scalar_is_char;
97 struct {
98 type_p p;
99 const char *len;
100 } a;
101 struct {
102 type_p stru;
103 type_p param[NUM_PARAM];
104 struct fileloc line;
105 } param_struct;
106 } u;
107 };
108
109 #define UNION_P(x) \
110 ((x)->kind == TYPE_UNION || \
111 ((x)->kind == TYPE_LANG_STRUCT \
112 && (x)->u.s.lang_struct->kind == TYPE_UNION))
113 #define UNION_OR_STRUCT_P(x) \
114 ((x)->kind == TYPE_UNION \
115 || (x)->kind == TYPE_STRUCT \
116 || (x)->kind == TYPE_LANG_STRUCT)
117
118 /* Structure representing an output file. */
119 struct outf
120 {
121 struct outf *next;
122 const char *name;
123 size_t buflength;
124 size_t bufused;
125 char *buf;
126 };
127 typedef struct outf * outf_p;
128
129 /* An output file, suitable for definitions, that can see declarations
130 made in INPUT_FILE and is linked into every language that uses
131 INPUT_FILE. */
132 extern outf_p get_output_file_with_visibility
133 (const char *input_file);
134 const char *get_output_file_name (const char *);
135
136 /* Print, like fprintf, to O. */
137 static void oprintf (outf_p o, const char *S, ...)
138 ATTRIBUTE_PRINTF_2;
139
140 /* The list of output files. */
141 static outf_p output_files;
142
143 /* The output header file that is included into pretty much every
144 source file. */
145 static outf_p header_file;
146
147 /* Source directory. */
148 static const char *srcdir;
149
150 /* Length of srcdir name. */
151 static size_t srcdir_len = 0;
152
153 static outf_p create_file (const char *, const char *);
154
155 static const char * get_file_basename (const char *);
156 static const char * get_file_realbasename (const char *);
157 static const char * get_file_srcdir_relative_path (const char *);
158
159 static int get_prefix_langdir_index (const char *);
160 static const char * get_file_langdir (const char *);
161
162 \f
163 /* Nonzero iff an error has occurred. */
164 bool hit_error = false;
165
166 static void gen_rtx_next (void);
167 static void write_rtx_next (void);
168 static void open_base_files (void);
169 static void close_output_files (void);
170
171 /* Report an error at POS, printing MSG. */
172
173 void
174 error_at_line (struct fileloc *pos, const char *msg, ...)
175 {
176 va_list ap;
177
178 va_start (ap, msg);
179
180 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
181 vfprintf (stderr, msg, ap);
182 fputc ('\n', stderr);
183 hit_error = true;
184
185 va_end (ap);
186 }
187
188 /* asprintf, but produces fatal message on out-of-memory. */
189 char *
190 xasprintf (const char *format, ...)
191 {
192 int n;
193 char *result;
194 va_list ap;
195
196 va_start (ap, format);
197 n = vasprintf (&result, format, ap);
198 if (result == NULL || n < 0)
199 fatal ("out of memory");
200 va_end (ap);
201
202 return result;
203 }
204 \f
205 /* Input file handling. */
206
207 /* Table of all input files. */
208 static const char **gt_files;
209 static size_t num_gt_files;
210
211 /* A number of places use the name of this file for a location for
212 things that we can't rely on the source to define. Make sure we
213 can still use pointer comparison on filenames. */
214 static const char this_file[] = __FILE__;
215
216 /* Vector of per-language directories. */
217 static const char **lang_dir_names;
218 static size_t num_lang_dirs;
219
220 /* An array of output files suitable for definitions. There is one
221 BASE_FILES entry for each language. */
222 static outf_p *base_files;
223
224 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
225 INPUT_FILE is used by <lang>.
226
227 This function should be written to assume that a file _is_ used
228 if the situation is unclear. If it wrongly assumes a file _is_ used,
229 a linker error will result. If it wrongly assumes a file _is not_ used,
230 some GC roots may be missed, which is a much harder-to-debug problem.
231
232 The relevant bitmap is stored immediately before the file's name in the
233 buffer set up by read_input_list. It may be unaligned, so we have to
234 read it byte-by-byte. */
235
236 static lang_bitmap
237 get_lang_bitmap (const char *gtfile)
238 {
239
240 if (gtfile == this_file)
241 /* Things defined in this file are universal. */
242 return (((lang_bitmap)1) << num_lang_dirs) - 1;
243 else
244 {
245 lang_bitmap n = 0;
246 int i;
247 for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
248 n = (n << CHAR_BIT) + (unsigned char)gtfile[i];
249 return n;
250 }
251 }
252
253 /* Set the bitmap returned by get_lang_bitmap. The only legitimate
254 caller of this function is read_input_list. */
255 static void
256 set_lang_bitmap (char *gtfile, lang_bitmap n)
257 {
258 int i;
259 for (i = -1; i >= -(int) sizeof (lang_bitmap); i--)
260 {
261 gtfile[i] = n & ((1U << CHAR_BIT)-1);
262 n >>= CHAR_BIT;
263 }
264 }
265
266 /* Scan the input file, LIST, and determine how much space we need to
267 store strings in. Also, count the number of language directories
268 and files. The numbers returned are overestimates as they does not
269 consider repeated files. */
270 static size_t
271 measure_input_list (FILE *list)
272 {
273 size_t n = 0;
274 int c;
275 bool atbol = true;
276 num_lang_dirs = 0;
277 num_gt_files = 0;
278 while ((c = getc (list)) != EOF)
279 {
280 n++;
281 if (atbol)
282 {
283 if (c == '[')
284 num_lang_dirs++;
285 else
286 {
287 /* Add space for a lang_bitmap before the input file name. */
288 n += sizeof (lang_bitmap);
289 num_gt_files++;
290 }
291 atbol = false;
292 }
293
294 if (c == '\n')
295 atbol = true;
296 }
297
298 rewind (list);
299 return n;
300 }
301
302 /* Read one input line from LIST to HEREP (which is updated). A
303 pointer to the string is returned via LINEP. If it was a language
304 subdirectory in square brackets, strip off the square brackets and
305 return true. Otherwise, leave space before the string for a
306 lang_bitmap, and return false. At EOF, returns false, does not
307 touch *HEREP, and sets *LINEP to NULL. POS is used for
308 diagnostics. */
309 static bool
310 read_input_line (FILE *list, char **herep, char **linep,
311 struct fileloc *pos)
312 {
313 char *here = *herep;
314 char *line;
315 int c = getc (list);
316
317 if (c == EOF)
318 {
319 *linep = 0;
320 return false;
321 }
322 else if (c == '[')
323 {
324 /* No space for a lang_bitmap is necessary. Discard the '['. */
325 c = getc (list);
326 line = here;
327 while (c != ']' && c != '\n' && c != EOF)
328 {
329 *here++ = c;
330 c = getc (list);
331 }
332 *here++ = '\0';
333
334 if (c == ']')
335 {
336 c = getc (list); /* eat what should be a newline */
337 if (c != '\n' && c != EOF)
338 error_at_line (pos, "junk on line after language tag [%s]", line);
339 }
340 else
341 error_at_line (pos, "missing close bracket for language tag [%s", line);
342
343 *herep = here;
344 *linep = line;
345 return true;
346 }
347 else
348 {
349 /* Leave space for a lang_bitmap. */
350 memset (here, 0, sizeof (lang_bitmap));
351 here += sizeof (lang_bitmap);
352 line = here;
353 do
354 {
355 *here++ = c;
356 c = getc (list);
357 }
358 while (c != EOF && c != '\n');
359 *here++ = '\0';
360 *herep = here;
361 *linep = line;
362 return false;
363 }
364 }
365
366 /* Read the list of input files from LIST and compute all of the
367 relevant tables. There is one file per line of the list. At
368 first, all the files on the list are language-generic, but
369 eventually a line will appear which is the name of a language
370 subdirectory in square brackets, like this: [cp]. All subsequent
371 files are specific to that language, until another language
372 subdirectory tag appears. Files can appear more than once, if
373 they apply to more than one language. */
374 static void
375 read_input_list (const char *listname)
376 {
377 FILE *list = fopen (listname, "r");
378 if (!list)
379 fatal ("cannot open %s: %s", listname, strerror (errno));
380 else
381 {
382 struct fileloc epos;
383 size_t bufsz = measure_input_list (list);
384 char *buf = XNEWVEC (char, bufsz);
385 char *here = buf;
386 char *committed = buf;
387 char *limit = buf + bufsz;
388 char *line;
389 bool is_language;
390 size_t langno = 0;
391 size_t nfiles = 0;
392 lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
393
394 epos.file = listname;
395 epos.line = 0;
396
397 lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
398 gt_files = XNEWVEC (const char *, num_gt_files);
399
400 for (;;)
401 {
402 next_line:
403 epos.line++;
404 committed = here;
405 is_language = read_input_line (list, &here, &line, &epos);
406 gcc_assert (here <= limit);
407 if (line == 0)
408 break;
409 else if (is_language)
410 {
411 size_t i;
412 gcc_assert (langno <= num_lang_dirs);
413 for (i = 0; i < langno; i++)
414 if (strcmp (lang_dir_names[i], line) == 0)
415 {
416 error_at_line (&epos, "duplicate language tag [%s]", line);
417 curlangs = 1 << i;
418 here = committed;
419 goto next_line;
420 }
421
422 curlangs = 1 << langno;
423 lang_dir_names[langno++] = line;
424 }
425 else
426 {
427 size_t i;
428 gcc_assert (nfiles <= num_gt_files);
429 for (i = 0; i < nfiles; i++)
430 if (strcmp (gt_files[i], line) == 0)
431 {
432 /* Throw away the string we just read, and add the
433 current language to the existing string's bitmap. */
434 lang_bitmap bmap = get_lang_bitmap (gt_files[i]);
435 if (bmap & curlangs)
436 error_at_line (&epos, "file %s specified more than once "
437 "for language %s", line, langno == 0
438 ? "(all)"
439 : lang_dir_names[langno - 1]);
440
441 bmap |= curlangs;
442 set_lang_bitmap (CONST_CAST(char *, gt_files[i]), bmap);
443 here = committed;
444 goto next_line;
445 }
446
447 set_lang_bitmap (line, curlangs);
448 gt_files[nfiles++] = line;
449 }
450 }
451 /* Update the global counts now that we know accurately how many
452 things there are. (We do not bother resizing the arrays down.) */
453 num_lang_dirs = langno;
454 num_gt_files = nfiles;
455 }
456
457 /* Sanity check: any file that resides in a language subdirectory
458 (e.g. 'cp') ought to belong to the corresponding language.
459 ??? Still true if for instance ObjC++ is enabled and C++ isn't?
460 (Can you even do that? Should you be allowed to?) */
461 {
462 size_t f;
463 for (f = 0; f < num_gt_files; f++)
464 {
465 lang_bitmap bitmap = get_lang_bitmap (gt_files[f]);
466 const char *basename = get_file_basename (gt_files[f]);
467 const char *slashpos = strchr (basename, '/');
468
469 if (slashpos)
470 {
471 size_t l;
472 for (l = 0; l < num_lang_dirs; l++)
473 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [l])
474 && memcmp (basename, lang_dir_names[l],
475 strlen (lang_dir_names[l])) == 0)
476 {
477 if (!(bitmap & (1 << l)))
478 error ("%s is in language directory '%s' but is not "
479 "tagged for that language",
480 basename, lang_dir_names[l]);
481 break;
482 }
483 }
484 }
485 }
486
487 if (ferror (list))
488 fatal ("error reading %s: %s", listname, strerror (errno));
489
490 fclose (list);
491 }
492
493
494 \f
495 /* The one and only TYPE_STRING. */
496
497 static struct type string_type = {
498 TYPE_STRING, 0, 0, GC_USED, {0}
499 };
500
501 /* The two and only TYPE_SCALARs. Their u.scalar_is_char flags are
502 set to appropriate values at the beginning of main. */
503
504 static struct type scalar_nonchar = {
505 TYPE_SCALAR, 0, 0, GC_USED, {0}
506 };
507 static struct type scalar_char = {
508 TYPE_SCALAR, 0, 0, GC_USED, {0}
509 };
510
511 /* Lists of various things. */
512
513 static pair_p typedefs;
514 static type_p structures;
515 static type_p param_structs;
516 static pair_p variables;
517
518 static type_p find_param_structure
519 (type_p t, type_p param[NUM_PARAM]);
520 static type_p adjust_field_tree_exp (type_p t, options_p opt);
521 static type_p adjust_field_rtx_def (type_p t, options_p opt);
522
523 /* Define S as a typedef to T at POS. */
524
525 void
526 do_typedef (const char *s, type_p t, struct fileloc *pos)
527 {
528 pair_p p;
529
530 /* temporary kludge - gengtype doesn't handle conditionals or
531 macros. Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
532 is coming from this file (main() sets them up with safe dummy
533 definitions). */
534 if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
535 return;
536
537 for (p = typedefs; p != NULL; p = p->next)
538 if (strcmp (p->name, s) == 0)
539 {
540 if (p->type != t)
541 {
542 error_at_line (pos, "type `%s' previously defined", s);
543 error_at_line (&p->line, "previously defined here");
544 }
545 return;
546 }
547
548 p = XNEW (struct pair);
549 p->next = typedefs;
550 p->name = s;
551 p->type = t;
552 p->line = *pos;
553 typedefs = p;
554 }
555
556 /* Define S as a typename of a scalar. Cannot be used to define
557 typedefs of 'char'. Note: is also used for pointer-to-function
558 typedefs (which are therefore not treated as pointers). */
559
560 void
561 do_scalar_typedef (const char *s, struct fileloc *pos)
562 {
563 do_typedef (s, &scalar_nonchar, pos);
564 }
565
566 /* Return the type previously defined for S. Use POS to report errors. */
567
568 type_p
569 resolve_typedef (const char *s, struct fileloc *pos)
570 {
571 pair_p p;
572 for (p = typedefs; p != NULL; p = p->next)
573 if (strcmp (p->name, s) == 0)
574 return p->type;
575 error_at_line (pos, "unidentified type `%s'", s);
576 return &scalar_nonchar; /* treat as "int" */
577 }
578
579 /* Create and return a new structure with tag NAME (or a union iff
580 ISUNION is nonzero), at POS with fields FIELDS and options O. */
581
582 type_p
583 new_structure (const char *name, int isunion, struct fileloc *pos,
584 pair_p fields, options_p o)
585 {
586 type_p si;
587 type_p s = NULL;
588 lang_bitmap bitmap = get_lang_bitmap (pos->file);
589
590 /* temporary kludge - gengtype doesn't handle conditionals or
591 macros. Ignore any attempt to define struct location_s, unless
592 it is coming from this file (main() sets it up safely). */
593 if (!strcmp (name, "location_s") && !isunion
594 && pos->file != this_file)
595 return find_structure (name, 0);
596
597 for (si = structures; si != NULL; si = si->next)
598 if (strcmp (name, si->u.s.tag) == 0
599 && UNION_P (si) == isunion)
600 {
601 type_p ls = NULL;
602 if (si->kind == TYPE_LANG_STRUCT)
603 {
604 ls = si;
605
606 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
607 if (si->u.s.bitmap == bitmap)
608 s = si;
609 }
610 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
611 {
612 ls = si;
613 si = XCNEW (struct type);
614 memcpy (si, ls, sizeof (struct type));
615 ls->kind = TYPE_LANG_STRUCT;
616 ls->u.s.lang_struct = si;
617 ls->u.s.fields = NULL;
618 si->next = NULL;
619 si->pointer_to = NULL;
620 si->u.s.lang_struct = ls;
621 }
622 else
623 s = si;
624
625 if (ls != NULL && s == NULL)
626 {
627 s = XCNEW (struct type);
628 s->next = ls->u.s.lang_struct;
629 ls->u.s.lang_struct = s;
630 s->u.s.lang_struct = ls;
631 }
632 break;
633 }
634
635 if (s == NULL)
636 {
637 s = XCNEW (struct type);
638 s->next = structures;
639 structures = s;
640 }
641
642 if (s->u.s.line.file != NULL
643 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
644 {
645 error_at_line (pos, "duplicate definition of '%s %s'",
646 isunion ? "union" : "struct", s->u.s.tag);
647 error_at_line (&s->u.s.line, "previous definition here");
648 }
649
650 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
651 s->u.s.tag = name;
652 s->u.s.line = *pos;
653 s->u.s.fields = fields;
654 s->u.s.opt = o;
655 s->u.s.bitmap = bitmap;
656 if (s->u.s.lang_struct)
657 s->u.s.lang_struct->u.s.bitmap |= bitmap;
658
659 /* Reset location_s's location to input.h so that we know where to
660 write out its mark routine. */
661 if (!strcmp (name, "location_s") && !isunion
662 && pos->file == this_file)
663 {
664 size_t n;
665 for (n = 0; n < num_gt_files; n++)
666 if (!strcmp (gt_files[n] + strlen (gt_files[n]) - strlen ("input.h"),
667 "input.h"))
668 {
669 s->u.s.line.file = gt_files[n];
670 break;
671 }
672 }
673
674 return s;
675 }
676
677 /* Return the previously-defined structure with tag NAME (or a union
678 iff ISUNION is nonzero), or a new empty structure or union if none
679 was defined previously. */
680
681 type_p
682 find_structure (const char *name, int isunion)
683 {
684 type_p s;
685
686 for (s = structures; s != NULL; s = s->next)
687 if (strcmp (name, s->u.s.tag) == 0
688 && UNION_P (s) == isunion)
689 return s;
690
691 s = XCNEW (struct type);
692 s->next = structures;
693 structures = s;
694 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
695 s->u.s.tag = name;
696 structures = s;
697 return s;
698 }
699
700 /* Return the previously-defined parameterized structure for structure
701 T and parameters PARAM, or a new parameterized empty structure or
702 union if none was defined previously. */
703
704 static type_p
705 find_param_structure (type_p t, type_p param[NUM_PARAM])
706 {
707 type_p res;
708
709 for (res = param_structs; res; res = res->next)
710 if (res->u.param_struct.stru == t
711 && memcmp (res->u.param_struct.param, param,
712 sizeof (type_p) * NUM_PARAM) == 0)
713 break;
714 if (res == NULL)
715 {
716 res = XCNEW (struct type);
717 res->kind = TYPE_PARAM_STRUCT;
718 res->next = param_structs;
719 param_structs = res;
720 res->u.param_struct.stru = t;
721 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
722 }
723 return res;
724 }
725
726 /* Return a scalar type with name NAME. */
727
728 type_p
729 create_scalar_type (const char *name)
730 {
731 if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
732 return &scalar_char;
733 else
734 return &scalar_nonchar;
735 }
736
737 /* Return a pointer to T. */
738
739 type_p
740 create_pointer (type_p t)
741 {
742 if (! t->pointer_to)
743 {
744 type_p r = XCNEW (struct type);
745 r->kind = TYPE_POINTER;
746 r->u.p = t;
747 t->pointer_to = r;
748 }
749 return t->pointer_to;
750 }
751
752 /* Return an array of length LEN. */
753
754 type_p
755 create_array (type_p t, const char *len)
756 {
757 type_p v;
758
759 v = XCNEW (struct type);
760 v->kind = TYPE_ARRAY;
761 v->u.a.p = t;
762 v->u.a.len = len;
763 return v;
764 }
765
766 /* Return an options structure with name NAME and info INFO. NEXT is the
767 next option in the chain. */
768
769 options_p
770 create_option (options_p next, const char *name, const void *info)
771 {
772 options_p o = XNEW (struct options);
773 o->next = next;
774 o->name = name;
775 o->info = (const char*) info;
776 return o;
777 }
778
779 /* Return an options structure for a "nested_ptr" option. */
780 options_p
781 create_nested_ptr_option (options_p next, type_p t,
782 const char *to, const char *from)
783 {
784 struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
785
786 d->type = adjust_field_type (t, 0);
787 d->convert_to = to;
788 d->convert_from = from;
789 return create_option (next, "nested_ptr", d);
790 }
791
792 /* Add a variable named S of type T with options O defined at POS,
793 to `variables'. */
794
795 void
796 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
797 {
798 pair_p n;
799 n = XNEW (struct pair);
800 n->name = s;
801 n->type = t;
802 n->line = *pos;
803 n->opt = o;
804 n->next = variables;
805 variables = n;
806 }
807
808 /* Most-general structure field creator. */
809 static pair_p
810 create_field_all (pair_p next, type_p type, const char *name, options_p opt,
811 const char *file, int line)
812 {
813 pair_p field;
814
815 field = XNEW (struct pair);
816 field->next = next;
817 field->type = type;
818 field->name = name;
819 field->opt = opt;
820 field->line.file = file;
821 field->line.line = line;
822 return field;
823 }
824
825 /* Create a field that came from the source code we are scanning,
826 i.e. we have a 'struct fileloc', and possibly options; also,
827 adjust_field_type should be called. */
828 pair_p
829 create_field_at (pair_p next, type_p type, const char *name, options_p opt,
830 struct fileloc *pos)
831 {
832 return create_field_all (next, adjust_field_type (type, opt),
833 name, opt, pos->file, pos->line);
834 }
835
836 /* Create a fake field with the given type and name. NEXT is the next
837 field in the chain. */
838 #define create_field(next,type,name) \
839 create_field_all(next,type,name, 0, this_file, __LINE__)
840
841 /* Like create_field, but the field is only valid when condition COND
842 is true. */
843
844 static pair_p
845 create_optional_field_ (pair_p next, type_p type, const char *name,
846 const char *cond, int line)
847 {
848 static int id = 1;
849 pair_p union_fields;
850 type_p union_type;
851
852 /* Create a fake union type with a single nameless field of type TYPE.
853 The field has a tag of "1". This allows us to make the presence
854 of a field of type TYPE depend on some boolean "desc" being true. */
855 union_fields = create_field (NULL, type, "");
856 union_fields->opt = create_option (union_fields->opt, "dot", "");
857 union_fields->opt = create_option (union_fields->opt, "tag", "1");
858 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
859 &lexer_line, union_fields, NULL);
860
861 /* Create the field and give it the new fake union type. Add a "desc"
862 tag that specifies the condition under which the field is valid. */
863 return create_field_all (next, union_type, name,
864 create_option (0, "desc", cond),
865 this_file, line);
866 }
867 #define create_optional_field(next,type,name,cond) \
868 create_optional_field_(next,type,name,cond,__LINE__)
869
870 /* Reverse a linked list of 'struct pair's in place. */
871 pair_p
872 nreverse_pairs (pair_p list)
873 {
874 pair_p prev = 0, p, next;
875 for (p = list; p; p = next)
876 {
877 next = p->next;
878 p->next = prev;
879 prev = p;
880 }
881 return prev;
882 }
883
884 \f
885 /* We don't care how long a CONST_DOUBLE is. */
886 #define CONST_DOUBLE_FORMAT "ww"
887 /* We don't want to see codes that are only for generator files. */
888 #undef GENERATOR_FILE
889
890 enum rtx_code {
891 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
892 #include "rtl.def"
893 #undef DEF_RTL_EXPR
894 NUM_RTX_CODE
895 };
896
897 static const char * const rtx_name[NUM_RTX_CODE] = {
898 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
899 #include "rtl.def"
900 #undef DEF_RTL_EXPR
901 };
902
903 static const char * const rtx_format[NUM_RTX_CODE] = {
904 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
905 #include "rtl.def"
906 #undef DEF_RTL_EXPR
907 };
908
909 static int rtx_next_new[NUM_RTX_CODE];
910
911 /* We also need codes and names for insn notes (not register notes).
912 Note that we do *not* bias the note values here. */
913 enum insn_note {
914 #define DEF_INSN_NOTE(NAME) NAME,
915 #include "insn-notes.def"
916 #undef DEF_INSN_NOTE
917
918 NOTE_INSN_MAX
919 };
920
921 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
922 default field for line number notes. */
923 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
924 #define DEF_INSN_NOTE(NAME) #NAME,
925 #include "insn-notes.def"
926 #undef DEF_INSN_NOTE
927 };
928
929 #undef CONST_DOUBLE_FORMAT
930 #define GENERATOR_FILE
931
932 /* Generate the contents of the rtx_next array. This really doesn't belong
933 in gengtype at all, but it's needed for adjust_field_rtx_def. */
934
935 static void
936 gen_rtx_next (void)
937 {
938 int i;
939 for (i = 0; i < NUM_RTX_CODE; i++)
940 {
941 int k;
942
943 rtx_next_new[i] = -1;
944 if (strncmp (rtx_format[i], "iuu", 3) == 0)
945 rtx_next_new[i] = 2;
946 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
947 rtx_next_new[i] = 1;
948 else
949 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
950 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
951 rtx_next_new[i] = k;
952 }
953 }
954
955 /* Write out the contents of the rtx_next array. */
956 static void
957 write_rtx_next (void)
958 {
959 outf_p f = get_output_file_with_visibility (NULL);
960 int i;
961
962 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
963 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
964 for (i = 0; i < NUM_RTX_CODE; i++)
965 if (rtx_next_new[i] == -1)
966 oprintf (f, " 0,\n");
967 else
968 oprintf (f,
969 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
970 rtx_next_new[i]);
971 oprintf (f, "};\n");
972 }
973
974 /* Handle `special("rtx_def")'. This is a special case for field
975 `fld' of struct rtx_def, which is an array of unions whose values
976 are based in a complex way on the type of RTL. */
977
978 static type_p
979 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
980 {
981 pair_p flds = NULL;
982 options_p nodot;
983 int i;
984 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
985 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
986
987 if (t->kind != TYPE_UNION)
988 {
989 error_at_line (&lexer_line,
990 "special `rtx_def' must be applied to a union");
991 return &string_type;
992 }
993
994 nodot = create_option (NULL, "dot", "");
995
996 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
997 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
998 tree_tp = create_pointer (find_structure ("tree_node", 1));
999 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
1000 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
1001 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
1002 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
1003 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
1004 scalar_tp = &scalar_nonchar; /* rtunion int */
1005
1006 {
1007 pair_p note_flds = NULL;
1008 int c;
1009
1010 for (c = 0; c <= NOTE_INSN_MAX; c++)
1011 {
1012 switch (c)
1013 {
1014 case NOTE_INSN_MAX:
1015 note_flds = create_field (note_flds, &string_type, "rt_str");
1016 break;
1017
1018 case NOTE_INSN_BLOCK_BEG:
1019 case NOTE_INSN_BLOCK_END:
1020 note_flds = create_field (note_flds, tree_tp, "rt_tree");
1021 break;
1022
1023 case NOTE_INSN_VAR_LOCATION:
1024 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
1025 break;
1026
1027 default:
1028 note_flds = create_field (note_flds, scalar_tp, "rt_int");
1029 break;
1030 }
1031 /* NOTE_INSN_MAX is used as the default field for line
1032 number notes. */
1033 if (c == NOTE_INSN_MAX)
1034 note_flds->opt = create_option (nodot, "default", "");
1035 else
1036 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
1037 }
1038 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1039 &lexer_line, note_flds, NULL);
1040 }
1041 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
1042 {
1043 pair_p sym_flds;
1044
1045 sym_flds = create_field (NULL, tree_tp, "rt_tree");
1046 sym_flds->opt = create_option (nodot, "default", "");
1047
1048 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
1049 sym_flds->opt = create_option (nodot, "tag", "1");
1050
1051 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
1052 &lexer_line, sym_flds, NULL);
1053 }
1054 for (i = 0; i < NUM_RTX_CODE; i++)
1055 {
1056 pair_p subfields = NULL;
1057 size_t aindex, nmindex;
1058 const char *sname;
1059 type_p substruct;
1060 char *ftag;
1061
1062 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1063 {
1064 type_p t;
1065 const char *subname;
1066
1067 switch (rtx_format[i][aindex])
1068 {
1069 case '*':
1070 case 'i':
1071 case 'n':
1072 case 'w':
1073 t = scalar_tp;
1074 subname = "rt_int";
1075 break;
1076
1077 case '0':
1078 if (i == MEM && aindex == 1)
1079 t = mem_attrs_tp, subname = "rt_mem";
1080 else if (i == JUMP_INSN && aindex == 8)
1081 t = rtx_tp, subname = "rt_rtx";
1082 else if (i == CODE_LABEL && aindex == 4)
1083 t = scalar_tp, subname = "rt_int";
1084 else if (i == CODE_LABEL && aindex == 5)
1085 t = rtx_tp, subname = "rt_rtx";
1086 else if (i == LABEL_REF
1087 && (aindex == 1 || aindex == 2))
1088 t = rtx_tp, subname = "rt_rtx";
1089 else if (i == NOTE && aindex == 4)
1090 t = note_union_tp, subname = "";
1091 else if (i == NOTE && aindex == 5)
1092 t = scalar_tp, subname = "rt_int";
1093 else if (i == NOTE && aindex >= 7)
1094 t = scalar_tp, subname = "rt_int";
1095 else if (i == ADDR_DIFF_VEC && aindex == 4)
1096 t = scalar_tp, subname = "rt_int";
1097 else if (i == VALUE && aindex == 0)
1098 t = scalar_tp, subname = "rt_int";
1099 else if (i == REG && aindex == 1)
1100 t = scalar_tp, subname = "rt_int";
1101 else if (i == REG && aindex == 2)
1102 t = reg_attrs_tp, subname = "rt_reg";
1103 else if (i == SCRATCH && aindex == 0)
1104 t = scalar_tp, subname = "rt_int";
1105 else if (i == SYMBOL_REF && aindex == 1)
1106 t = scalar_tp, subname = "rt_int";
1107 else if (i == SYMBOL_REF && aindex == 2)
1108 t = symbol_union_tp, subname = "";
1109 else if (i == BARRIER && aindex >= 3)
1110 t = scalar_tp, subname = "rt_int";
1111 else
1112 {
1113 error_at_line (&lexer_line,
1114 "rtx type `%s' has `0' in position %lu, can't handle",
1115 rtx_name[i], (unsigned long) aindex);
1116 t = &string_type;
1117 subname = "rt_int";
1118 }
1119 break;
1120
1121 case 's':
1122 case 'S':
1123 case 'T':
1124 t = &string_type;
1125 subname = "rt_str";
1126 break;
1127
1128 case 'e':
1129 case 'u':
1130 t = rtx_tp;
1131 subname = "rt_rtx";
1132 break;
1133
1134 case 'E':
1135 case 'V':
1136 t = rtvec_tp;
1137 subname = "rt_rtvec";
1138 break;
1139
1140 case 't':
1141 t = tree_tp;
1142 subname = "rt_tree";
1143 break;
1144
1145 case 'b':
1146 t = bitmap_tp;
1147 subname = "rt_bit";
1148 break;
1149
1150 case 'B':
1151 t = basic_block_tp;
1152 subname = "rt_bb";
1153 break;
1154
1155 default:
1156 error_at_line (&lexer_line,
1157 "rtx type `%s' has `%c' in position %lu, can't handle",
1158 rtx_name[i], rtx_format[i][aindex],
1159 (unsigned long)aindex);
1160 t = &string_type;
1161 subname = "rt_int";
1162 break;
1163 }
1164
1165 subfields = create_field (subfields, t,
1166 xasprintf (".fld[%lu].%s",
1167 (unsigned long) aindex,
1168 subname));
1169 subfields->opt = nodot;
1170 if (t == note_union_tp)
1171 subfields->opt = create_option (subfields->opt, "desc",
1172 "NOTE_KIND (&%0)");
1173 if (t == symbol_union_tp)
1174 subfields->opt = create_option (subfields->opt, "desc",
1175 "CONSTANT_POOL_ADDRESS_P (&%0)");
1176 }
1177
1178 if (i == SYMBOL_REF)
1179 {
1180 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
1181 type_p field_tp = find_structure ("block_symbol", 0);
1182 subfields
1183 = create_optional_field (subfields, field_tp, "block_sym",
1184 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
1185 }
1186
1187 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
1188 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1189
1190 ftag = xstrdup (rtx_name[i]);
1191 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1192 ftag[nmindex] = TOUPPER (ftag[nmindex]);
1193
1194 flds = create_field (flds, substruct, "");
1195 flds->opt = create_option (nodot, "tag", ftag);
1196 }
1197
1198 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
1199 }
1200
1201 /* Handle `special("tree_exp")'. This is a special case for
1202 field `operands' of struct tree_exp, which although it claims to contain
1203 pointers to trees, actually sometimes contains pointers to RTL too.
1204 Passed T, the old type of the field, and OPT its options. Returns
1205 a new type for the field. */
1206
1207 static type_p
1208 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
1209 {
1210 pair_p flds;
1211 options_p nodot;
1212
1213 if (t->kind != TYPE_ARRAY)
1214 {
1215 error_at_line (&lexer_line,
1216 "special `tree_exp' must be applied to an array");
1217 return &string_type;
1218 }
1219
1220 nodot = create_option (NULL, "dot", "");
1221
1222 flds = create_field (NULL, t, "");
1223 flds->opt = create_option (nodot, "length",
1224 "TREE_OPERAND_LENGTH ((tree) &%0)");
1225 flds->opt = create_option (flds->opt, "default", "");
1226
1227 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
1228 }
1229
1230 /* Perform any special processing on a type T, about to become the type
1231 of a field. Return the appropriate type for the field.
1232 At present:
1233 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
1234 - Similarly for arrays of pointer-to-char;
1235 - Converts structures for which a parameter is provided to
1236 TYPE_PARAM_STRUCT;
1237 - Handles "special" options.
1238 */
1239
1240 type_p
1241 adjust_field_type (type_p t, options_p opt)
1242 {
1243 int length_p = 0;
1244 const int pointer_p = t->kind == TYPE_POINTER;
1245 type_p params[NUM_PARAM];
1246 int params_p = 0;
1247 int i;
1248
1249 for (i = 0; i < NUM_PARAM; i++)
1250 params[i] = NULL;
1251
1252 for (; opt; opt = opt->next)
1253 if (strcmp (opt->name, "length") == 0)
1254 length_p = 1;
1255 else if (strcmp (opt->name, "param_is") == 0
1256 || (strncmp (opt->name, "param", 5) == 0
1257 && ISDIGIT (opt->name[5])
1258 && strcmp (opt->name + 6, "_is") == 0))
1259 {
1260 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
1261
1262 if (! UNION_OR_STRUCT_P (t)
1263 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1264 {
1265 error_at_line (&lexer_line,
1266 "option `%s' may only be applied to structures or structure pointers",
1267 opt->name);
1268 return t;
1269 }
1270
1271 params_p = 1;
1272 if (params[num] != NULL)
1273 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
1274 if (! ISDIGIT (opt->name[5]))
1275 params[num] = create_pointer (CONST_CAST2(type_p, const char *, opt->info));
1276 else
1277 params[num] = CONST_CAST2 (type_p, const char *, opt->info);
1278 }
1279 else if (strcmp (opt->name, "special") == 0)
1280 {
1281 const char *special_name = opt->info;
1282 if (strcmp (special_name, "tree_exp") == 0)
1283 t = adjust_field_tree_exp (t, opt);
1284 else if (strcmp (special_name, "rtx_def") == 0)
1285 t = adjust_field_rtx_def (t, opt);
1286 else
1287 error_at_line (&lexer_line, "unknown special `%s'", special_name);
1288 }
1289
1290 if (params_p)
1291 {
1292 type_p realt;
1293
1294 if (pointer_p)
1295 t = t->u.p;
1296 realt = find_param_structure (t, params);
1297 t = pointer_p ? create_pointer (realt) : realt;
1298 }
1299
1300 if (! length_p
1301 && pointer_p
1302 && t->u.p->kind == TYPE_SCALAR
1303 && t->u.p->u.scalar_is_char)
1304 return &string_type;
1305 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
1306 && t->u.a.p->u.p->kind == TYPE_SCALAR
1307 && t->u.a.p->u.p->u.scalar_is_char)
1308 return create_array (&string_type, t->u.a.len);
1309
1310 return t;
1311 }
1312
1313 \f
1314 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1315 static void set_gc_used (pair_p);
1316
1317 /* Handle OPT for set_gc_used_type. */
1318
1319 static void
1320 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
1321 int *pass_param, int *length, int *skip, type_p *nested_ptr)
1322 {
1323 options_p o;
1324 for (o = opt; o; o = o->next)
1325 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
1326 set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
1327 GC_POINTED_TO, NULL);
1328 else if (strcmp (o->name, "maybe_undef") == 0)
1329 *maybe_undef = 1;
1330 else if (strcmp (o->name, "use_params") == 0)
1331 *pass_param = 1;
1332 else if (strcmp (o->name, "length") == 0)
1333 *length = 1;
1334 else if (strcmp (o->name, "skip") == 0)
1335 *skip = 1;
1336 else if (strcmp (o->name, "nested_ptr") == 0)
1337 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
1338 }
1339
1340 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
1341
1342 static void
1343 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
1344 {
1345 if (t->gc_used >= level)
1346 return;
1347
1348 t->gc_used = level;
1349
1350 switch (t->kind)
1351 {
1352 case TYPE_STRUCT:
1353 case TYPE_UNION:
1354 {
1355 pair_p f;
1356 int dummy;
1357 type_p dummy2;
1358
1359 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
1360 &dummy2);
1361
1362 for (f = t->u.s.fields; f; f = f->next)
1363 {
1364 int maybe_undef = 0;
1365 int pass_param = 0;
1366 int length = 0;
1367 int skip = 0;
1368 type_p nested_ptr = NULL;
1369 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
1370 &length, &skip, &nested_ptr);
1371
1372 if (nested_ptr && f->type->kind == TYPE_POINTER)
1373 set_gc_used_type (nested_ptr, GC_POINTED_TO,
1374 pass_param ? param : NULL);
1375 else if (length && f->type->kind == TYPE_POINTER)
1376 set_gc_used_type (f->type->u.p, GC_USED, NULL);
1377 else if (maybe_undef && f->type->kind == TYPE_POINTER)
1378 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
1379 else if (pass_param && f->type->kind == TYPE_POINTER && param)
1380 set_gc_used_type (find_param_structure (f->type->u.p, param),
1381 GC_POINTED_TO, NULL);
1382 else if (skip)
1383 ; /* target type is not used through this field */
1384 else
1385 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
1386 }
1387 break;
1388 }
1389
1390 case TYPE_POINTER:
1391 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
1392 break;
1393
1394 case TYPE_ARRAY:
1395 set_gc_used_type (t->u.a.p, GC_USED, param);
1396 break;
1397
1398 case TYPE_LANG_STRUCT:
1399 for (t = t->u.s.lang_struct; t; t = t->next)
1400 set_gc_used_type (t, level, param);
1401 break;
1402
1403 case TYPE_PARAM_STRUCT:
1404 {
1405 int i;
1406 for (i = 0; i < NUM_PARAM; i++)
1407 if (t->u.param_struct.param[i] != 0)
1408 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
1409 }
1410 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
1411 level = GC_POINTED_TO;
1412 else
1413 level = GC_USED;
1414 t->u.param_struct.stru->gc_used = GC_UNUSED;
1415 set_gc_used_type (t->u.param_struct.stru, level,
1416 t->u.param_struct.param);
1417 break;
1418
1419 default:
1420 break;
1421 }
1422 }
1423
1424 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
1425
1426 static void
1427 set_gc_used (pair_p variables)
1428 {
1429 pair_p p;
1430 for (p = variables; p; p = p->next)
1431 set_gc_used_type (p->type, GC_USED, NULL);
1432 }
1433 \f
1434 /* File mapping routines. For each input file, there is one output .c file
1435 (but some output files have many input files), and there is one .h file
1436 for the whole build. */
1437
1438 /* Output file handling. */
1439
1440 /* Create and return an outf_p for a new file for NAME, to be called
1441 ONAME. */
1442
1443 static outf_p
1444 create_file (const char *name, const char *oname)
1445 {
1446 static const char *const hdr[] = {
1447 " Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
1448 "\n",
1449 "This file is part of GCC.\n",
1450 "\n",
1451 "GCC is free software; you can redistribute it and/or modify it under\n",
1452 "the terms of the GNU General Public License as published by the Free\n",
1453 "Software Foundation; either version 3, or (at your option) any later\n",
1454 "version.\n",
1455 "\n",
1456 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1457 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1458 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1459 "for more details.\n",
1460 "\n",
1461 "You should have received a copy of the GNU General Public License\n",
1462 "along with GCC; see the file COPYING3. If not see\n",
1463 "<http://www.gnu.org/licenses/>. */\n",
1464 "\n",
1465 "/* This file is machine generated. Do not edit. */\n"
1466 };
1467 outf_p f;
1468 size_t i;
1469
1470 f = XCNEW (struct outf);
1471 f->next = output_files;
1472 f->name = oname;
1473 output_files = f;
1474
1475 oprintf (f, "/* Type information for %s.\n", name);
1476 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1477 oprintf (f, "%s", hdr[i]);
1478 return f;
1479 }
1480
1481 /* Print, like fprintf, to O.
1482 N.B. You might think this could be implemented more efficiently
1483 with vsnprintf(). Unfortunately, there are C libraries that
1484 provide that function but without the C99 semantics for its return
1485 value, making it impossible to know how much space is required. */
1486 void
1487 oprintf (outf_p o, const char *format, ...)
1488 {
1489 char *s;
1490 size_t slength;
1491 va_list ap;
1492
1493 va_start (ap, format);
1494 slength = vasprintf (&s, format, ap);
1495 if (s == NULL || (int)slength < 0)
1496 fatal ("out of memory");
1497 va_end (ap);
1498
1499 if (o->bufused + slength > o->buflength)
1500 {
1501 size_t new_len = o->buflength;
1502 if (new_len == 0)
1503 new_len = 1024;
1504 do {
1505 new_len *= 2;
1506 } while (o->bufused + slength >= new_len);
1507 o->buf = XRESIZEVEC (char, o->buf, new_len);
1508 o->buflength = new_len;
1509 }
1510 memcpy (o->buf + o->bufused, s, slength);
1511 o->bufused += slength;
1512 free (s);
1513 }
1514
1515 /* Open the global header file and the language-specific header files. */
1516
1517 static void
1518 open_base_files (void)
1519 {
1520 size_t i;
1521
1522 header_file = create_file ("GCC", "gtype-desc.h");
1523
1524 base_files = XNEWVEC (outf_p, num_lang_dirs);
1525
1526 for (i = 0; i < num_lang_dirs; i++)
1527 base_files[i] = create_file (lang_dir_names[i],
1528 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1529
1530 /* gtype-desc.c is a little special, so we create it here. */
1531 {
1532 /* The order of files here matters very much. */
1533 static const char *const ifiles [] = {
1534 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
1535 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1536 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1537 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1538 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1539 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1540 "cfglayout.h", "except.h", "output.h", "cfgloop.h", NULL
1541 };
1542 const char *const *ifp;
1543 outf_p gtype_desc_c;
1544
1545 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1546 for (ifp = ifiles; *ifp; ifp++)
1547 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1548
1549 /* Make sure we handle "cfun" specially. */
1550 oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n");
1551 oprintf (gtype_desc_c, "#undef cfun\n");
1552 }
1553 }
1554
1555 /* For F a filename, return the real basename of F, with all the directory
1556 components skipped. */
1557
1558 static const char *
1559 get_file_realbasename (const char *f)
1560 {
1561 const char * lastslash = strrchr (f, '/');
1562
1563 return (lastslash != NULL) ? lastslash + 1 : f;
1564 }
1565
1566 /* For F a filename, return the relative path to F from $(srcdir) if the
1567 latter is a prefix in F, NULL otherwise. */
1568
1569 static const char *
1570 get_file_srcdir_relative_path (const char *f)
1571 {
1572 if (strlen (f) > srcdir_len
1573 && IS_DIR_SEPARATOR (f[srcdir_len])
1574 && memcmp (f, srcdir, srcdir_len) == 0)
1575 return f + srcdir_len + 1;
1576 else
1577 return NULL;
1578 }
1579
1580 /* For F a filename, return the relative path to F from $(srcdir) if the
1581 latter is a prefix in F, or the real basename of F otherwise. */
1582
1583 static const char *
1584 get_file_basename (const char *f)
1585 {
1586 const char * srcdir_path = get_file_srcdir_relative_path (f);
1587
1588 return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
1589 }
1590
1591 /* For F a filename, return the lang_dir_names relative index of the language
1592 directory that is a prefix in F, if any, -1 otherwise. */
1593
1594 static int
1595 get_prefix_langdir_index (const char *f)
1596 {
1597 size_t f_len = strlen (f);
1598 size_t lang_index;
1599
1600 for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
1601 {
1602 const char * langdir = lang_dir_names [lang_index];
1603 size_t langdir_len = strlen (langdir);
1604
1605 if (f_len > langdir_len
1606 && IS_DIR_SEPARATOR (f[langdir_len])
1607 && memcmp (f, langdir, langdir_len) == 0)
1608 return lang_index;
1609 }
1610
1611 return -1;
1612 }
1613
1614 /* For F a filename, return the name of language directory where F is located,
1615 if any, NULL otherwise. */
1616
1617 static const char *
1618 get_file_langdir (const char *f)
1619 {
1620 /* Get the relative path to F from $(srcdir) and find the language by
1621 comparing the prefix with language directory names. If F is not even
1622 srcdir relative, no point in looking further. */
1623
1624 int lang_index;
1625 const char * srcdir_relative_path = get_file_srcdir_relative_path (f);
1626
1627 if (!srcdir_relative_path)
1628 return NULL;
1629
1630 lang_index = get_prefix_langdir_index (srcdir_relative_path);
1631
1632 return (lang_index >= 0) ? lang_dir_names [lang_index] : NULL;
1633 }
1634
1635 /* The gt- output file name for F. */
1636
1637 static const char *
1638 get_file_gtfilename (const char *f)
1639 {
1640 /* Cook up an initial version of the gt- file name from the file real
1641 basename and the language name, if any. */
1642
1643 const char *basename = get_file_realbasename (f);
1644 const char *langdir = get_file_langdir (f);
1645
1646 char * result =
1647 (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
1648 : xasprintf ("gt-%s", basename));
1649
1650 /* Then replace all non alphanumerics characters by '-' and change the
1651 extenstion to ".h". We expect the input filename extension was at least
1652 one character long. */
1653
1654 char *s = result;
1655
1656 for (; *s != '.'; s++)
1657 if (! ISALNUM (*s) && *s != '-')
1658 *s = '-';
1659
1660 memcpy (s, ".h", sizeof (".h"));
1661
1662 return result;
1663 }
1664
1665 /* An output file, suitable for definitions, that can see declarations
1666 made in INPUT_FILE and is linked into every language that uses
1667 INPUT_FILE. */
1668
1669 outf_p
1670 get_output_file_with_visibility (const char *input_file)
1671 {
1672 outf_p r;
1673 size_t len;
1674 const char *basename;
1675 const char *for_name;
1676 const char *output_name;
1677
1678 /* This can happen when we need a file with visibility on a
1679 structure that we've never seen. We have to just hope that it's
1680 globally visible. */
1681 if (input_file == NULL)
1682 input_file = "system.h";
1683
1684 /* Determine the output file name. */
1685 basename = get_file_basename (input_file);
1686
1687 len = strlen (basename);
1688 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1689 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1690 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1691 {
1692 output_name = get_file_gtfilename (input_file);
1693 for_name = basename;
1694 }
1695 /* Some headers get used by more than one front-end; hence, it
1696 would be inappropriate to spew them out to a single gtype-<lang>.h
1697 (and gengtype doesn't know how to direct spewage into multiple
1698 gtype-<lang>.h headers at this time). Instead, we pair up these
1699 headers with source files (and their special purpose gt-*.h headers). */
1700 else if (strcmp (basename, "c-common.h") == 0)
1701 output_name = "gt-c-common.h", for_name = "c-common.c";
1702 else if (strcmp (basename, "c-tree.h") == 0)
1703 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1704 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1705 && strcmp (basename + 3, "cp-tree.h") == 0)
1706 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1707 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1708 && strcmp (basename + 3, "decl.h") == 0)
1709 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1710 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1711 && strcmp (basename + 3, "name-lookup.h") == 0)
1712 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1713 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1714 && strcmp (basename + 5, "objc-act.h") == 0)
1715 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1716 else
1717 {
1718 int lang_index = get_prefix_langdir_index (basename);
1719
1720 if (lang_index >= 0)
1721 return base_files[lang_index];
1722
1723 output_name = "gtype-desc.c";
1724 for_name = NULL;
1725 }
1726
1727 /* Look through to see if we've ever seen this output filename before. */
1728 for (r = output_files; r; r = r->next)
1729 if (strcmp (r->name, output_name) == 0)
1730 return r;
1731
1732 /* If not, create it. */
1733 r = create_file (for_name, output_name);
1734
1735 return r;
1736 }
1737
1738 /* The name of an output file, suitable for definitions, that can see
1739 declarations made in INPUT_FILE and is linked into every language
1740 that uses INPUT_FILE. */
1741
1742 const char *
1743 get_output_file_name (const char *input_file)
1744 {
1745 return get_output_file_with_visibility (input_file)->name;
1746 }
1747
1748 /* Copy the output to its final destination,
1749 but don't unnecessarily change modification times. */
1750
1751 static void
1752 close_output_files (void)
1753 {
1754 outf_p of;
1755
1756 for (of = output_files; of; of = of->next)
1757 {
1758 FILE * newfile;
1759
1760 newfile = fopen (of->name, "r");
1761 if (newfile != NULL )
1762 {
1763 int no_write_p;
1764 size_t i;
1765
1766 for (i = 0; i < of->bufused; i++)
1767 {
1768 int ch;
1769 ch = fgetc (newfile);
1770 if (ch == EOF || ch != (unsigned char) of->buf[i])
1771 break;
1772 }
1773 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1774 fclose (newfile);
1775
1776 if (no_write_p)
1777 continue;
1778 }
1779
1780 newfile = fopen (of->name, "w");
1781 if (newfile == NULL)
1782 fatal ("opening output file %s: %s", of->name, strerror (errno));
1783 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1784 fatal ("writing output file %s: %s", of->name, strerror (errno));
1785 if (fclose (newfile) != 0)
1786 fatal ("closing output file %s: %s", of->name, strerror (errno));
1787 }
1788 }
1789 \f
1790 struct flist {
1791 struct flist *next;
1792 int started_p;
1793 const char *name;
1794 outf_p f;
1795 };
1796
1797 struct walk_type_data;
1798
1799 /* For scalars and strings, given the item in 'val'.
1800 For structures, given a pointer to the item in 'val'.
1801 For misc. pointers, given the item in 'val'.
1802 */
1803 typedef void (*process_field_fn)
1804 (type_p f, const struct walk_type_data *p);
1805 typedef void (*func_name_fn)
1806 (type_p s, const struct walk_type_data *p);
1807
1808 /* Parameters for write_types. */
1809
1810 struct write_types_data
1811 {
1812 const char *prefix;
1813 const char *param_prefix;
1814 const char *subfield_marker_routine;
1815 const char *marker_routine;
1816 const char *reorder_note_routine;
1817 const char *comment;
1818 int skip_hooks; /* skip hook generation if non zero */
1819 };
1820
1821 static void output_escaped_param (struct walk_type_data *d,
1822 const char *, const char *);
1823 static void output_mangled_typename (outf_p, const_type_p);
1824 static void walk_type (type_p t, struct walk_type_data *d);
1825 static void write_func_for_structure
1826 (type_p orig_s, type_p s, type_p * param,
1827 const struct write_types_data *wtd);
1828 static void write_types_process_field
1829 (type_p f, const struct walk_type_data *d);
1830 static void write_types (type_p structures,
1831 type_p param_structs,
1832 const struct write_types_data *wtd);
1833 static void write_types_local_process_field
1834 (type_p f, const struct walk_type_data *d);
1835 static void write_local_func_for_structure
1836 (type_p orig_s, type_p s, type_p * param);
1837 static void write_local (type_p structures,
1838 type_p param_structs);
1839 static void write_enum_defn (type_p structures, type_p param_structs);
1840 static int contains_scalar_p (type_p t);
1841 static void put_mangled_filename (outf_p , const char *);
1842 static void finish_root_table (struct flist *flp, const char *pfx,
1843 const char *tname, const char *lastname,
1844 const char *name);
1845 static void write_root (outf_p , pair_p, type_p, const char *, int,
1846 struct fileloc *, const char *);
1847 static void write_array (outf_p f, pair_p v,
1848 const struct write_types_data *wtd);
1849 static void write_roots (pair_p);
1850
1851 /* Parameters for walk_type. */
1852
1853 struct walk_type_data
1854 {
1855 process_field_fn process_field;
1856 const void *cookie;
1857 outf_p of;
1858 options_p opt;
1859 const char *val;
1860 const char *prev_val[4];
1861 int indent;
1862 int counter;
1863 struct fileloc *line;
1864 lang_bitmap bitmap;
1865 type_p *param;
1866 int used_length;
1867 type_p orig_s;
1868 const char *reorder_fn;
1869 bool needs_cast_p;
1870 bool fn_wants_lvalue;
1871 };
1872
1873 /* Print a mangled name representing T to OF. */
1874
1875 static void
1876 output_mangled_typename (outf_p of, const_type_p t)
1877 {
1878 if (t == NULL)
1879 oprintf (of, "Z");
1880 else switch (t->kind)
1881 {
1882 case TYPE_POINTER:
1883 oprintf (of, "P");
1884 output_mangled_typename (of, t->u.p);
1885 break;
1886 case TYPE_SCALAR:
1887 oprintf (of, "I");
1888 break;
1889 case TYPE_STRING:
1890 oprintf (of, "S");
1891 break;
1892 case TYPE_STRUCT:
1893 case TYPE_UNION:
1894 case TYPE_LANG_STRUCT:
1895 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1896 break;
1897 case TYPE_PARAM_STRUCT:
1898 {
1899 int i;
1900 for (i = 0; i < NUM_PARAM; i++)
1901 if (t->u.param_struct.param[i] != NULL)
1902 output_mangled_typename (of, t->u.param_struct.param[i]);
1903 output_mangled_typename (of, t->u.param_struct.stru);
1904 }
1905 break;
1906 case TYPE_ARRAY:
1907 gcc_unreachable ();
1908 }
1909 }
1910
1911 /* Print PARAM to D->OF processing escapes. D->VAL references the
1912 current object, D->PREV_VAL the object containing the current
1913 object, ONAME is the name of the option and D->LINE is used to
1914 print error messages. */
1915
1916 static void
1917 output_escaped_param (struct walk_type_data *d, const char *param,
1918 const char *oname)
1919 {
1920 const char *p;
1921
1922 for (p = param; *p; p++)
1923 if (*p != '%')
1924 oprintf (d->of, "%c", *p);
1925 else switch (*++p)
1926 {
1927 case 'h':
1928 oprintf (d->of, "(%s)", d->prev_val[2]);
1929 break;
1930 case '0':
1931 oprintf (d->of, "(%s)", d->prev_val[0]);
1932 break;
1933 case '1':
1934 oprintf (d->of, "(%s)", d->prev_val[1]);
1935 break;
1936 case 'a':
1937 {
1938 const char *pp = d->val + strlen (d->val);
1939 while (pp[-1] == ']')
1940 while (*pp != '[')
1941 pp--;
1942 oprintf (d->of, "%s", pp);
1943 }
1944 break;
1945 default:
1946 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1947 oname, '%', *p);
1948 }
1949 }
1950
1951 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1952 which is of type T. Write code to D->OF to constrain execution (at
1953 the point that D->PROCESS_FIELD is called) to the appropriate
1954 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1955 pointers to those objects. D->PREV_VAL lists the objects
1956 containing the current object, D->OPT is a list of options to
1957 apply, D->INDENT is the current indentation level, D->LINE is used
1958 to print error messages, D->BITMAP indicates which languages to
1959 print the structure for, and D->PARAM is the current parameter
1960 (from an enclosing param_is option). */
1961
1962 static void
1963 walk_type (type_p t, struct walk_type_data *d)
1964 {
1965 const char *length = NULL;
1966 const char *desc = NULL;
1967 int maybe_undef_p = 0;
1968 int use_param_num = -1;
1969 int use_params_p = 0;
1970 options_p oo;
1971 const struct nested_ptr_data *nested_ptr_d = NULL;
1972
1973 d->needs_cast_p = false;
1974 for (oo = d->opt; oo; oo = oo->next)
1975 if (strcmp (oo->name, "length") == 0)
1976 length = oo->info;
1977 else if (strcmp (oo->name, "maybe_undef") == 0)
1978 maybe_undef_p = 1;
1979 else if (strncmp (oo->name, "use_param", 9) == 0
1980 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1981 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1982 else if (strcmp (oo->name, "use_params") == 0)
1983 use_params_p = 1;
1984 else if (strcmp (oo->name, "desc") == 0)
1985 desc = oo->info;
1986 else if (strcmp (oo->name, "mark_hook") == 0)
1987 ;
1988 else if (strcmp (oo->name, "nested_ptr") == 0)
1989 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1990 else if (strcmp (oo->name, "dot") == 0)
1991 ;
1992 else if (strcmp (oo->name, "tag") == 0)
1993 ;
1994 else if (strcmp (oo->name, "special") == 0)
1995 ;
1996 else if (strcmp (oo->name, "skip") == 0)
1997 ;
1998 else if (strcmp (oo->name, "default") == 0)
1999 ;
2000 else if (strcmp (oo->name, "descbits") == 0)
2001 ;
2002 else if (strcmp (oo->name, "param_is") == 0)
2003 ;
2004 else if (strncmp (oo->name, "param", 5) == 0
2005 && ISDIGIT (oo->name[5])
2006 && strcmp (oo->name + 6, "_is") == 0)
2007 ;
2008 else if (strcmp (oo->name, "chain_next") == 0)
2009 ;
2010 else if (strcmp (oo->name, "chain_prev") == 0)
2011 ;
2012 else if (strcmp (oo->name, "chain_circular") == 0)
2013 ;
2014 else if (strcmp (oo->name, "reorder") == 0)
2015 ;
2016 else
2017 error_at_line (d->line, "unknown option `%s'\n", oo->name);
2018
2019 if (d->used_length)
2020 length = NULL;
2021
2022 if (use_params_p)
2023 {
2024 int pointer_p = t->kind == TYPE_POINTER;
2025
2026 if (pointer_p)
2027 t = t->u.p;
2028 if (! UNION_OR_STRUCT_P (t))
2029 error_at_line (d->line, "`use_params' option on unimplemented type");
2030 else
2031 t = find_param_structure (t, d->param);
2032 if (pointer_p)
2033 t = create_pointer (t);
2034 }
2035
2036 if (use_param_num != -1)
2037 {
2038 if (d->param != NULL && d->param[use_param_num] != NULL)
2039 {
2040 type_p nt = d->param[use_param_num];
2041
2042 if (t->kind == TYPE_ARRAY)
2043 nt = create_array (nt, t->u.a.len);
2044 else if (length != NULL && t->kind == TYPE_POINTER)
2045 nt = create_pointer (nt);
2046 d->needs_cast_p = (t->kind != TYPE_POINTER
2047 && (nt->kind == TYPE_POINTER
2048 || nt->kind == TYPE_STRING));
2049 t = nt;
2050 }
2051 else
2052 error_at_line (d->line, "no parameter defined for `%s'",
2053 d->val);
2054 }
2055
2056 if (maybe_undef_p
2057 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
2058 {
2059 error_at_line (d->line,
2060 "field `%s' has invalid option `maybe_undef_p'\n",
2061 d->val);
2062 return;
2063 }
2064
2065 switch (t->kind)
2066 {
2067 case TYPE_SCALAR:
2068 case TYPE_STRING:
2069 d->process_field (t, d);
2070 break;
2071
2072 case TYPE_POINTER:
2073 {
2074 if (maybe_undef_p
2075 && t->u.p->u.s.line.file == NULL)
2076 {
2077 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2078 break;
2079 }
2080
2081 if (! length)
2082 {
2083 if (! UNION_OR_STRUCT_P (t->u.p)
2084 && t->u.p->kind != TYPE_PARAM_STRUCT)
2085 {
2086 error_at_line (d->line,
2087 "field `%s' is pointer to unimplemented type",
2088 d->val);
2089 break;
2090 }
2091
2092 if (nested_ptr_d)
2093 {
2094 const char *oldprevval2 = d->prev_val[2];
2095
2096 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2097 {
2098 error_at_line (d->line,
2099 "field `%s' has invalid "
2100 "option `nested_ptr'\n",
2101 d->val);
2102 return;
2103 }
2104
2105 d->prev_val[2] = d->val;
2106 oprintf (d->of, "%*s{\n", d->indent, "");
2107 d->indent += 2;
2108 d->val = xasprintf ("x%d", d->counter++);
2109 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2110 (nested_ptr_d->type->kind == TYPE_UNION
2111 ? "union" : "struct"),
2112 nested_ptr_d->type->u.s.tag,
2113 d->fn_wants_lvalue ? "" : "const ",
2114 d->val);
2115 oprintf (d->of, "%*s", d->indent + 2, "");
2116 output_escaped_param (d, nested_ptr_d->convert_from,
2117 "nested_ptr");
2118 oprintf (d->of, ";\n");
2119
2120 d->process_field (nested_ptr_d->type, d);
2121
2122 if (d->fn_wants_lvalue)
2123 {
2124 oprintf (d->of, "%*s%s = ", d->indent, "",
2125 d->prev_val[2]);
2126 d->prev_val[2] = d->val;
2127 output_escaped_param (d, nested_ptr_d->convert_to,
2128 "nested_ptr");
2129 oprintf (d->of, ";\n");
2130 }
2131
2132 d->indent -= 2;
2133 oprintf (d->of, "%*s}\n", d->indent, "");
2134 d->val = d->prev_val[2];
2135 d->prev_val[2] = oldprevval2;
2136 }
2137 else
2138 d->process_field (t->u.p, d);
2139 }
2140 else
2141 {
2142 int loopcounter = d->counter++;
2143 const char *oldval = d->val;
2144 const char *oldprevval3 = d->prev_val[3];
2145 char *newval;
2146
2147 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2148 d->indent += 2;
2149 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2150 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
2151 loopcounter, loopcounter);
2152 output_escaped_param (d, length, "length");
2153 oprintf (d->of, "); i%d++) {\n", loopcounter);
2154 d->indent += 2;
2155 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2156 d->used_length = 1;
2157 d->prev_val[3] = oldval;
2158 walk_type (t->u.p, d);
2159 free (newval);
2160 d->val = oldval;
2161 d->prev_val[3] = oldprevval3;
2162 d->used_length = 0;
2163 d->indent -= 2;
2164 oprintf (d->of, "%*s}\n", d->indent, "");
2165 d->process_field(t, d);
2166 d->indent -= 2;
2167 oprintf (d->of, "%*s}\n", d->indent, "");
2168 }
2169 }
2170 break;
2171
2172 case TYPE_ARRAY:
2173 {
2174 int loopcounter = d->counter++;
2175 const char *oldval = d->val;
2176 char *newval;
2177
2178 /* If it's an array of scalars, we optimize by not generating
2179 any code. */
2180 if (t->u.a.p->kind == TYPE_SCALAR)
2181 break;
2182
2183 /* When walking an array, compute the length and store it in a
2184 local variable before walking the array elements, instead of
2185 recomputing the length expression each time through the loop.
2186 This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2187 where the length is stored in the first array element,
2188 because otherwise that operand can get overwritten on the
2189 first iteration. */
2190 oprintf (d->of, "%*s{\n", d->indent, "");
2191 d->indent += 2;
2192 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2193 oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2194 d->indent, "", loopcounter);
2195 if (length)
2196 output_escaped_param (d, length, "length");
2197 else
2198 oprintf (d->of, "%s", t->u.a.len);
2199 oprintf (d->of, ");\n");
2200
2201 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2202 d->indent, "",
2203 loopcounter, loopcounter, loopcounter, loopcounter);
2204 d->indent += 2;
2205 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2206 d->used_length = 1;
2207 walk_type (t->u.a.p, d);
2208 free (newval);
2209 d->used_length = 0;
2210 d->val = oldval;
2211 d->indent -= 2;
2212 oprintf (d->of, "%*s}\n", d->indent, "");
2213 d->indent -= 2;
2214 oprintf (d->of, "%*s}\n", d->indent, "");
2215 }
2216 break;
2217
2218 case TYPE_STRUCT:
2219 case TYPE_UNION:
2220 {
2221 pair_p f;
2222 const char *oldval = d->val;
2223 const char *oldprevval1 = d->prev_val[1];
2224 const char *oldprevval2 = d->prev_val[2];
2225 const int union_p = t->kind == TYPE_UNION;
2226 int seen_default_p = 0;
2227 options_p o;
2228
2229 if (! t->u.s.line.file)
2230 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2231
2232 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2233 {
2234 error_at_line (d->line,
2235 "structure `%s' defined for mismatching languages",
2236 t->u.s.tag);
2237 error_at_line (&t->u.s.line, "one structure defined here");
2238 }
2239
2240 /* Some things may also be defined in the structure's options. */
2241 for (o = t->u.s.opt; o; o = o->next)
2242 if (! desc && strcmp (o->name, "desc") == 0)
2243 desc = o->info;
2244
2245 d->prev_val[2] = oldval;
2246 d->prev_val[1] = oldprevval2;
2247 if (union_p)
2248 {
2249 if (desc == NULL)
2250 {
2251 error_at_line (d->line, "missing `desc' option for union `%s'",
2252 t->u.s.tag);
2253 desc = "1";
2254 }
2255 oprintf (d->of, "%*sswitch (", d->indent, "");
2256 output_escaped_param (d, desc, "desc");
2257 oprintf (d->of, ")\n");
2258 d->indent += 2;
2259 oprintf (d->of, "%*s{\n", d->indent, "");
2260 }
2261 for (f = t->u.s.fields; f; f = f->next)
2262 {
2263 options_p oo;
2264 const char *dot = ".";
2265 const char *tagid = NULL;
2266 int skip_p = 0;
2267 int default_p = 0;
2268 int use_param_p = 0;
2269 char *newval;
2270
2271 d->reorder_fn = NULL;
2272 for (oo = f->opt; oo; oo = oo->next)
2273 if (strcmp (oo->name, "dot") == 0)
2274 dot = oo->info;
2275 else if (strcmp (oo->name, "tag") == 0)
2276 tagid = oo->info;
2277 else if (strcmp (oo->name, "skip") == 0)
2278 skip_p = 1;
2279 else if (strcmp (oo->name, "default") == 0)
2280 default_p = 1;
2281 else if (strcmp (oo->name, "reorder") == 0)
2282 d->reorder_fn = oo->info;
2283 else if (strncmp (oo->name, "use_param", 9) == 0
2284 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2285 use_param_p = 1;
2286
2287 if (skip_p)
2288 continue;
2289
2290 if (union_p && tagid)
2291 {
2292 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2293 d->indent += 2;
2294 }
2295 else if (union_p && default_p)
2296 {
2297 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2298 d->indent += 2;
2299 seen_default_p = 1;
2300 }
2301 else if (! union_p && (default_p || tagid))
2302 error_at_line (d->line,
2303 "can't use `%s' outside a union on field `%s'",
2304 default_p ? "default" : "tag", f->name);
2305 else if (union_p && ! (default_p || tagid)
2306 && f->type->kind == TYPE_SCALAR)
2307 {
2308 fprintf (stderr,
2309 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2310 d->line->file, d->line->line, f->name);
2311 continue;
2312 }
2313 else if (union_p && ! (default_p || tagid))
2314 error_at_line (d->line,
2315 "field `%s' is missing `tag' or `default' option",
2316 f->name);
2317
2318 d->line = &f->line;
2319 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2320 d->opt = f->opt;
2321 d->used_length = false;
2322
2323 if (union_p && use_param_p && d->param == NULL)
2324 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2325 else
2326 walk_type (f->type, d);
2327
2328 free (newval);
2329
2330 if (union_p)
2331 {
2332 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2333 d->indent -= 2;
2334 }
2335 }
2336 d->reorder_fn = NULL;
2337
2338 d->val = oldval;
2339 d->prev_val[1] = oldprevval1;
2340 d->prev_val[2] = oldprevval2;
2341
2342 if (union_p && ! seen_default_p)
2343 {
2344 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2345 oprintf (d->of, "%*s break;\n", d->indent, "");
2346 }
2347 if (union_p)
2348 {
2349 oprintf (d->of, "%*s}\n", d->indent, "");
2350 d->indent -= 2;
2351 }
2352 }
2353 break;
2354
2355 case TYPE_LANG_STRUCT:
2356 {
2357 type_p nt;
2358 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2359 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2360 break;
2361 if (nt == NULL)
2362 error_at_line (d->line, "structure `%s' differs between languages",
2363 t->u.s.tag);
2364 else
2365 walk_type (nt, d);
2366 }
2367 break;
2368
2369 case TYPE_PARAM_STRUCT:
2370 {
2371 type_p *oldparam = d->param;
2372
2373 d->param = t->u.param_struct.param;
2374 walk_type (t->u.param_struct.stru, d);
2375 d->param = oldparam;
2376 }
2377 break;
2378
2379 default:
2380 gcc_unreachable ();
2381 }
2382 }
2383
2384 /* process_field routine for marking routines. */
2385
2386 static void
2387 write_types_process_field (type_p f, const struct walk_type_data *d)
2388 {
2389 const struct write_types_data *wtd;
2390 const char *cast = d->needs_cast_p ? "(void *)" : "";
2391 wtd = (const struct write_types_data *) d->cookie;
2392
2393 switch (f->kind)
2394 {
2395 case TYPE_POINTER:
2396 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2397 wtd->subfield_marker_routine, cast, d->val);
2398 if (wtd->param_prefix)
2399 {
2400 oprintf (d->of, ", %s", d->prev_val[3]);
2401 if (d->orig_s)
2402 {
2403 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2404 output_mangled_typename (d->of, d->orig_s);
2405 }
2406 else
2407 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2408
2409 if (f->u.p->kind == TYPE_PARAM_STRUCT
2410 && f->u.p->u.s.line.file != NULL)
2411 {
2412 oprintf (d->of, ", gt_e_");
2413 output_mangled_typename (d->of, f);
2414 }
2415 else if (UNION_OR_STRUCT_P (f)
2416 && f->u.p->u.s.line.file != NULL)
2417 {
2418 oprintf (d->of, ", gt_ggc_e_");
2419 output_mangled_typename (d->of, f);
2420 }
2421 else
2422 oprintf (d->of, ", gt_types_enum_last");
2423 }
2424 oprintf (d->of, ");\n");
2425 if (d->reorder_fn && wtd->reorder_note_routine)
2426 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2427 wtd->reorder_note_routine, cast, d->val,
2428 d->prev_val[3], d->reorder_fn);
2429 break;
2430
2431 case TYPE_STRING:
2432 case TYPE_STRUCT:
2433 case TYPE_UNION:
2434 case TYPE_LANG_STRUCT:
2435 case TYPE_PARAM_STRUCT:
2436 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2437 output_mangled_typename (d->of, f);
2438 oprintf (d->of, " (%s%s);\n", cast, d->val);
2439 if (d->reorder_fn && wtd->reorder_note_routine)
2440 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2441 wtd->reorder_note_routine, cast, d->val, cast, d->val,
2442 d->reorder_fn);
2443 break;
2444
2445 case TYPE_SCALAR:
2446 break;
2447
2448 default:
2449 gcc_unreachable ();
2450 }
2451 }
2452
2453 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2454
2455 static void
2456 output_type_enum (outf_p of, type_p s)
2457 {
2458 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2459 {
2460 oprintf (of, ", gt_e_");
2461 output_mangled_typename (of, s);
2462 }
2463 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2464 {
2465 oprintf (of, ", gt_ggc_e_");
2466 output_mangled_typename (of, s);
2467 }
2468 else
2469 oprintf (of, ", gt_types_enum_last");
2470 }
2471
2472 /* For S, a structure that's part of ORIG_S, and using parameters
2473 PARAM, write out a routine that:
2474 - Takes a parameter, a void * but actually of type *S
2475 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2476 field of S or its substructures and (in some cases) things
2477 that are pointed to by S.
2478 */
2479
2480 static void
2481 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2482 const struct write_types_data *wtd)
2483 {
2484 const char *fn = s->u.s.line.file;
2485 int i;
2486 const char *chain_next = NULL;
2487 const char *chain_prev = NULL;
2488 const char *chain_circular = NULL;
2489 const char *mark_hook_name = NULL;
2490 options_p opt;
2491 struct walk_type_data d;
2492
2493 /* This is a hack, and not the good kind either. */
2494 for (i = NUM_PARAM - 1; i >= 0; i--)
2495 if (param && param[i] && param[i]->kind == TYPE_POINTER
2496 && UNION_OR_STRUCT_P (param[i]->u.p))
2497 fn = param[i]->u.p->u.s.line.file;
2498
2499 memset (&d, 0, sizeof (d));
2500 d.of = get_output_file_with_visibility (fn);
2501
2502 for (opt = s->u.s.opt; opt; opt = opt->next)
2503 if (strcmp (opt->name, "chain_next") == 0)
2504 chain_next = opt->info;
2505 else if (strcmp (opt->name, "chain_prev") == 0)
2506 chain_prev = opt->info;
2507 else if (strcmp (opt->name, "chain_circular") == 0)
2508 chain_circular = opt->info;
2509 else if (strcmp (opt->name, "mark_hook") == 0)
2510 mark_hook_name = opt->info;
2511
2512 if (chain_prev != NULL && chain_next == NULL)
2513 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2514 if (chain_circular != NULL && chain_next != NULL)
2515 error_at_line (&s->u.s.line, "chain_circular with chain_next");
2516 if (chain_circular != NULL)
2517 chain_next = chain_circular;
2518
2519 d.process_field = write_types_process_field;
2520 d.cookie = wtd;
2521 d.orig_s = orig_s;
2522 d.opt = s->u.s.opt;
2523 d.line = &s->u.s.line;
2524 d.bitmap = s->u.s.bitmap;
2525 d.param = param;
2526 d.prev_val[0] = "*x";
2527 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2528 d.prev_val[3] = "x";
2529 d.val = "(*x)";
2530
2531 oprintf (d.of, "\n");
2532 oprintf (d.of, "void\n");
2533 if (param == NULL)
2534 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2535 else
2536 {
2537 oprintf (d.of, "gt_%s_", wtd->prefix);
2538 output_mangled_typename (d.of, orig_s);
2539 }
2540 oprintf (d.of, " (void *x_p)\n");
2541 oprintf (d.of, "{\n");
2542 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2543 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2544 chain_next == NULL ? "const " : "",
2545 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2546 if (chain_next != NULL)
2547 oprintf (d.of, " %s %s * xlimit = x;\n",
2548 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2549 if (chain_next == NULL)
2550 {
2551 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2552 if (wtd->param_prefix)
2553 {
2554 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2555 output_mangled_typename (d.of, orig_s);
2556 output_type_enum (d.of, orig_s);
2557 }
2558 oprintf (d.of, "))\n");
2559 }
2560 else
2561 {
2562 if (chain_circular != NULL)
2563 oprintf (d.of, " if (!%s (xlimit", wtd->marker_routine);
2564 else
2565 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2566 if (wtd->param_prefix)
2567 {
2568 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2569 output_mangled_typename (d.of, orig_s);
2570 output_type_enum (d.of, orig_s);
2571 }
2572 oprintf (d.of, "))\n");
2573 if (chain_circular != NULL)
2574 oprintf (d.of, " return;\n do\n");
2575 if (mark_hook_name && !wtd->skip_hooks)
2576 {
2577 oprintf (d.of, " {\n");
2578 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2579 }
2580 oprintf (d.of, " xlimit = (");
2581 d.prev_val[2] = "*xlimit";
2582 output_escaped_param (&d, chain_next, "chain_next");
2583 oprintf (d.of, ");\n");
2584 if (mark_hook_name && !wtd->skip_hooks)
2585 oprintf (d.of, " }\n");
2586 if (chain_prev != NULL)
2587 {
2588 oprintf (d.of, " if (x != xlimit)\n");
2589 oprintf (d.of, " for (;;)\n");
2590 oprintf (d.of, " {\n");
2591 oprintf (d.of, " %s %s * const xprev = (",
2592 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2593
2594 d.prev_val[2] = "*x";
2595 output_escaped_param (&d, chain_prev, "chain_prev");
2596 oprintf (d.of, ");\n");
2597 oprintf (d.of, " if (xprev == NULL) break;\n");
2598 oprintf (d.of, " x = xprev;\n");
2599 oprintf (d.of, " (void) %s (xprev",
2600 wtd->marker_routine);
2601 if (wtd->param_prefix)
2602 {
2603 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2604 output_mangled_typename (d.of, orig_s);
2605 output_type_enum (d.of, orig_s);
2606 }
2607 oprintf (d.of, ");\n");
2608 oprintf (d.of, " }\n");
2609 }
2610 if (chain_circular != NULL)
2611 {
2612 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2613 if (wtd->param_prefix)
2614 {
2615 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2616 output_mangled_typename (d.of, orig_s);
2617 output_type_enum (d.of, orig_s);
2618 }
2619 oprintf (d.of, "));\n");
2620 if (mark_hook_name && !wtd->skip_hooks)
2621 oprintf (d.of, " %s (xlimit);\n", mark_hook_name);
2622 oprintf (d.of, " do\n");
2623 }
2624 else
2625 oprintf (d.of, " while (x != xlimit)\n");
2626 }
2627 oprintf (d.of, " {\n");
2628 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2629 {
2630 oprintf (d.of, " %s (x);\n", mark_hook_name);
2631 }
2632 d.prev_val[2] = "*x";
2633 d.indent = 6;
2634 walk_type (s, &d);
2635
2636 if (chain_next != NULL)
2637 {
2638 oprintf (d.of, " x = (");
2639 output_escaped_param (&d, chain_next, "chain_next");
2640 oprintf (d.of, ");\n");
2641 }
2642
2643 oprintf (d.of, " }\n");
2644 if (chain_circular != NULL)
2645 oprintf (d.of, " while (x != xlimit);\n");
2646 oprintf (d.of, "}\n");
2647 }
2648
2649 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2650
2651 static void
2652 write_types (type_p structures, type_p param_structs,
2653 const struct write_types_data *wtd)
2654 {
2655 type_p s;
2656
2657 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2658 for (s = structures; s; s = s->next)
2659 if (s->gc_used == GC_POINTED_TO
2660 || s->gc_used == GC_MAYBE_POINTED_TO)
2661 {
2662 options_p opt;
2663
2664 if (s->gc_used == GC_MAYBE_POINTED_TO
2665 && s->u.s.line.file == NULL)
2666 continue;
2667
2668 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2669 output_mangled_typename (header_file, s);
2670 oprintf (header_file, "(X) do { \\\n");
2671 oprintf (header_file,
2672 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2673 s->u.s.tag);
2674 oprintf (header_file,
2675 " } while (0)\n");
2676
2677 for (opt = s->u.s.opt; opt; opt = opt->next)
2678 if (strcmp (opt->name, "ptr_alias") == 0)
2679 {
2680 const_type_p const t = (const_type_p) opt->info;
2681 if (t->kind == TYPE_STRUCT
2682 || t->kind == TYPE_UNION
2683 || t->kind == TYPE_LANG_STRUCT)
2684 oprintf (header_file,
2685 "#define gt_%sx_%s gt_%sx_%s\n",
2686 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2687 else
2688 error_at_line (&s->u.s.line,
2689 "structure alias is not a structure");
2690 break;
2691 }
2692 if (opt)
2693 continue;
2694
2695 /* Declare the marker procedure only once. */
2696 oprintf (header_file,
2697 "extern void gt_%sx_%s (void *);\n",
2698 wtd->prefix, s->u.s.tag);
2699
2700 if (s->u.s.line.file == NULL)
2701 {
2702 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2703 s->u.s.tag);
2704 continue;
2705 }
2706
2707 if (s->kind == TYPE_LANG_STRUCT)
2708 {
2709 type_p ss;
2710 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2711 write_func_for_structure (s, ss, NULL, wtd);
2712 }
2713 else
2714 write_func_for_structure (s, s, NULL, wtd);
2715 }
2716
2717 for (s = param_structs; s; s = s->next)
2718 if (s->gc_used == GC_POINTED_TO)
2719 {
2720 type_p * param = s->u.param_struct.param;
2721 type_p stru = s->u.param_struct.stru;
2722
2723 /* Declare the marker procedure. */
2724 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2725 output_mangled_typename (header_file, s);
2726 oprintf (header_file, " (void *);\n");
2727
2728 if (stru->u.s.line.file == NULL)
2729 {
2730 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2731 s->u.s.tag);
2732 continue;
2733 }
2734
2735 if (stru->kind == TYPE_LANG_STRUCT)
2736 {
2737 type_p ss;
2738 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2739 write_func_for_structure (s, ss, param, wtd);
2740 }
2741 else
2742 write_func_for_structure (s, stru, param, wtd);
2743 }
2744 }
2745
2746 static const struct write_types_data ggc_wtd =
2747 {
2748 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2749 "GC marker procedures. ",
2750 FALSE
2751 };
2752
2753 static const struct write_types_data pch_wtd =
2754 {
2755 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2756 "gt_pch_note_reorder",
2757 "PCH type-walking procedures. ",
2758 TRUE
2759 };
2760
2761 /* Write out the local pointer-walking routines. */
2762
2763 /* process_field routine for local pointer-walking. */
2764
2765 static void
2766 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2767 {
2768 switch (f->kind)
2769 {
2770 case TYPE_POINTER:
2771 case TYPE_STRUCT:
2772 case TYPE_UNION:
2773 case TYPE_LANG_STRUCT:
2774 case TYPE_PARAM_STRUCT:
2775 case TYPE_STRING:
2776 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2777 d->prev_val[3]);
2778 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2779 break;
2780
2781 case TYPE_SCALAR:
2782 break;
2783
2784 default:
2785 gcc_unreachable ();
2786 }
2787 }
2788
2789 /* For S, a structure that's part of ORIG_S, and using parameters
2790 PARAM, write out a routine that:
2791 - Is of type gt_note_pointers
2792 - Calls PROCESS_FIELD on each field of S or its substructures.
2793 */
2794
2795 static void
2796 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2797 {
2798 const char *fn = s->u.s.line.file;
2799 int i;
2800 struct walk_type_data d;
2801
2802 /* This is a hack, and not the good kind either. */
2803 for (i = NUM_PARAM - 1; i >= 0; i--)
2804 if (param && param[i] && param[i]->kind == TYPE_POINTER
2805 && UNION_OR_STRUCT_P (param[i]->u.p))
2806 fn = param[i]->u.p->u.s.line.file;
2807
2808 memset (&d, 0, sizeof (d));
2809 d.of = get_output_file_with_visibility (fn);
2810
2811 d.process_field = write_types_local_process_field;
2812 d.opt = s->u.s.opt;
2813 d.line = &s->u.s.line;
2814 d.bitmap = s->u.s.bitmap;
2815 d.param = param;
2816 d.prev_val[0] = d.prev_val[2] = "*x";
2817 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2818 d.prev_val[3] = "x";
2819 d.val = "(*x)";
2820 d.fn_wants_lvalue = true;
2821
2822 oprintf (d.of, "\n");
2823 oprintf (d.of, "void\n");
2824 oprintf (d.of, "gt_pch_p_");
2825 output_mangled_typename (d.of, orig_s);
2826 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2827 "\tvoid *x_p,\n"
2828 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2829 "\tATTRIBUTE_UNUSED void *cookie)\n");
2830 oprintf (d.of, "{\n");
2831 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2832 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2833 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2834 d.indent = 2;
2835 walk_type (s, &d);
2836 oprintf (d.of, "}\n");
2837 }
2838
2839 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2840
2841 static void
2842 write_local (type_p structures, type_p param_structs)
2843 {
2844 type_p s;
2845
2846 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2847 for (s = structures; s; s = s->next)
2848 if (s->gc_used == GC_POINTED_TO
2849 || s->gc_used == GC_MAYBE_POINTED_TO)
2850 {
2851 options_p opt;
2852
2853 if (s->u.s.line.file == NULL)
2854 continue;
2855
2856 for (opt = s->u.s.opt; opt; opt = opt->next)
2857 if (strcmp (opt->name, "ptr_alias") == 0)
2858 {
2859 const_type_p const t = (const_type_p) opt->info;
2860 if (t->kind == TYPE_STRUCT
2861 || t->kind == TYPE_UNION
2862 || t->kind == TYPE_LANG_STRUCT)
2863 {
2864 oprintf (header_file, "#define gt_pch_p_");
2865 output_mangled_typename (header_file, s);
2866 oprintf (header_file, " gt_pch_p_");
2867 output_mangled_typename (header_file, t);
2868 oprintf (header_file, "\n");
2869 }
2870 else
2871 error_at_line (&s->u.s.line,
2872 "structure alias is not a structure");
2873 break;
2874 }
2875 if (opt)
2876 continue;
2877
2878 /* Declare the marker procedure only once. */
2879 oprintf (header_file, "extern void gt_pch_p_");
2880 output_mangled_typename (header_file, s);
2881 oprintf (header_file,
2882 "\n (void *, void *, gt_pointer_operator, void *);\n");
2883
2884 if (s->kind == TYPE_LANG_STRUCT)
2885 {
2886 type_p ss;
2887 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2888 write_local_func_for_structure (s, ss, NULL);
2889 }
2890 else
2891 write_local_func_for_structure (s, s, NULL);
2892 }
2893
2894 for (s = param_structs; s; s = s->next)
2895 if (s->gc_used == GC_POINTED_TO)
2896 {
2897 type_p * param = s->u.param_struct.param;
2898 type_p stru = s->u.param_struct.stru;
2899
2900 /* Declare the marker procedure. */
2901 oprintf (header_file, "extern void gt_pch_p_");
2902 output_mangled_typename (header_file, s);
2903 oprintf (header_file,
2904 "\n (void *, void *, gt_pointer_operator, void *);\n");
2905
2906 if (stru->u.s.line.file == NULL)
2907 {
2908 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2909 s->u.s.tag);
2910 continue;
2911 }
2912
2913 if (stru->kind == TYPE_LANG_STRUCT)
2914 {
2915 type_p ss;
2916 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2917 write_local_func_for_structure (s, ss, param);
2918 }
2919 else
2920 write_local_func_for_structure (s, stru, param);
2921 }
2922 }
2923
2924 /* Write out the 'enum' definition for gt_types_enum. */
2925
2926 static void
2927 write_enum_defn (type_p structures, type_p param_structs)
2928 {
2929 type_p s;
2930
2931 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2932 oprintf (header_file, "enum gt_types_enum {\n");
2933 for (s = structures; s; s = s->next)
2934 if (s->gc_used == GC_POINTED_TO
2935 || s->gc_used == GC_MAYBE_POINTED_TO)
2936 {
2937 if (s->gc_used == GC_MAYBE_POINTED_TO
2938 && s->u.s.line.file == NULL)
2939 continue;
2940
2941 oprintf (header_file, " gt_ggc_e_");
2942 output_mangled_typename (header_file, s);
2943 oprintf (header_file, ", \n");
2944 }
2945 for (s = param_structs; s; s = s->next)
2946 if (s->gc_used == GC_POINTED_TO)
2947 {
2948 oprintf (header_file, " gt_e_");
2949 output_mangled_typename (header_file, s);
2950 oprintf (header_file, ", \n");
2951 }
2952 oprintf (header_file, " gt_types_enum_last\n");
2953 oprintf (header_file, "};\n");
2954 }
2955
2956 /* Might T contain any non-pointer elements? */
2957
2958 static int
2959 contains_scalar_p (type_p t)
2960 {
2961 switch (t->kind)
2962 {
2963 case TYPE_STRING:
2964 case TYPE_POINTER:
2965 return 0;
2966 case TYPE_ARRAY:
2967 return contains_scalar_p (t->u.a.p);
2968 default:
2969 /* Could also check for structures that have no non-pointer
2970 fields, but there aren't enough of those to worry about. */
2971 return 1;
2972 }
2973 }
2974
2975 /* Mangle FN and print it to F. */
2976
2977 static void
2978 put_mangled_filename (outf_p f, const char *fn)
2979 {
2980 const char *name = get_output_file_name (fn);
2981 for (; *name != 0; name++)
2982 if (ISALNUM (*name))
2983 oprintf (f, "%c", *name);
2984 else
2985 oprintf (f, "%c", '_');
2986 }
2987
2988 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2989 LASTNAME, and NAME are all strings to insert in various places in
2990 the resulting code. */
2991
2992 static void
2993 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2994 const char *tname, const char *name)
2995 {
2996 struct flist *fli2;
2997
2998 for (fli2 = flp; fli2; fli2 = fli2->next)
2999 if (fli2->started_p)
3000 {
3001 oprintf (fli2->f, " %s\n", lastname);
3002 oprintf (fli2->f, "};\n\n");
3003 }
3004
3005 for (fli2 = flp; fli2; fli2 = fli2->next)
3006 if (fli2->started_p)
3007 {
3008 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3009 int fnum;
3010
3011 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3012 if (bitmap & 1)
3013 {
3014 oprintf (base_files[fnum],
3015 "extern const struct %s gt_%s_",
3016 tname, pfx);
3017 put_mangled_filename (base_files[fnum], fli2->name);
3018 oprintf (base_files[fnum], "[];\n");
3019 }
3020 }
3021
3022 {
3023 size_t fnum;
3024 for (fnum = 0; fnum < num_lang_dirs; fnum++)
3025 oprintf (base_files [fnum],
3026 "const struct %s * const %s[] = {\n",
3027 tname, name);
3028 }
3029
3030
3031 for (fli2 = flp; fli2; fli2 = fli2->next)
3032 if (fli2->started_p)
3033 {
3034 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3035 int fnum;
3036
3037 fli2->started_p = 0;
3038
3039 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3040 if (bitmap & 1)
3041 {
3042 oprintf (base_files[fnum], " gt_%s_", pfx);
3043 put_mangled_filename (base_files[fnum], fli2->name);
3044 oprintf (base_files[fnum], ",\n");
3045 }
3046 }
3047
3048 {
3049 size_t fnum;
3050 for (fnum = 0; fnum < num_lang_dirs; fnum++)
3051 {
3052 oprintf (base_files[fnum], " NULL\n");
3053 oprintf (base_files[fnum], "};\n");
3054 }
3055 }
3056 }
3057
3058 /* Write out to F the table entry and any marker routines needed to
3059 mark NAME as TYPE. The original variable is V, at LINE.
3060 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
3061 is nonzero iff we are building the root table for hash table caches. */
3062
3063 static void
3064 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3065 struct fileloc *line, const char *if_marked)
3066 {
3067 switch (type->kind)
3068 {
3069 case TYPE_STRUCT:
3070 {
3071 pair_p fld;
3072 for (fld = type->u.s.fields; fld; fld = fld->next)
3073 {
3074 int skip_p = 0;
3075 const char *desc = NULL;
3076 options_p o;
3077
3078 for (o = fld->opt; o; o = o->next)
3079 if (strcmp (o->name, "skip") == 0)
3080 skip_p = 1;
3081 else if (strcmp (o->name, "desc") == 0)
3082 desc = o->info;
3083 else if (strcmp (o->name, "param_is") == 0)
3084 ;
3085 else
3086 error_at_line (line,
3087 "field `%s' of global `%s' has unknown option `%s'",
3088 fld->name, name, o->name);
3089
3090 if (skip_p)
3091 continue;
3092 else if (desc && fld->type->kind == TYPE_UNION)
3093 {
3094 pair_p validf = NULL;
3095 pair_p ufld;
3096
3097 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3098 {
3099 const char *tag = NULL;
3100 options_p oo;
3101
3102 for (oo = ufld->opt; oo; oo = oo->next)
3103 if (strcmp (oo->name, "tag") == 0)
3104 tag = oo->info;
3105 if (tag == NULL || strcmp (tag, desc) != 0)
3106 continue;
3107 if (validf != NULL)
3108 error_at_line (line,
3109 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3110 name, fld->name, validf->name,
3111 name, fld->name, ufld->name,
3112 tag);
3113 validf = ufld;
3114 }
3115 if (validf != NULL)
3116 {
3117 char *newname;
3118 newname = xasprintf ("%s.%s.%s",
3119 name, fld->name, validf->name);
3120 write_root (f, v, validf->type, newname, 0, line,
3121 if_marked);
3122 free (newname);
3123 }
3124 }
3125 else if (desc)
3126 error_at_line (line,
3127 "global `%s.%s' has `desc' option but is not union",
3128 name, fld->name);
3129 else
3130 {
3131 char *newname;
3132 newname = xasprintf ("%s.%s", name, fld->name);
3133 write_root (f, v, fld->type, newname, 0, line, if_marked);
3134 free (newname);
3135 }
3136 }
3137 }
3138 break;
3139
3140 case TYPE_ARRAY:
3141 {
3142 char *newname;
3143 newname = xasprintf ("%s[0]", name);
3144 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
3145 free (newname);
3146 }
3147 break;
3148
3149 case TYPE_POINTER:
3150 {
3151 type_p ap, tp;
3152
3153 oprintf (f, " {\n");
3154 oprintf (f, " &%s,\n", name);
3155 oprintf (f, " 1");
3156
3157 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3158 if (ap->u.a.len[0])
3159 oprintf (f, " * (%s)", ap->u.a.len);
3160 else if (ap == v->type)
3161 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3162 oprintf (f, ",\n");
3163 oprintf (f, " sizeof (%s", v->name);
3164 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3165 oprintf (f, "[0]");
3166 oprintf (f, "),\n");
3167
3168 tp = type->u.p;
3169
3170 if (! has_length && UNION_OR_STRUCT_P (tp))
3171 {
3172 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
3173 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
3174 }
3175 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3176 {
3177 oprintf (f, " &gt_ggc_m_");
3178 output_mangled_typename (f, tp);
3179 oprintf (f, ",\n &gt_pch_n_");
3180 output_mangled_typename (f, tp);
3181 }
3182 else if (has_length
3183 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3184 {
3185 oprintf (f, " &gt_ggc_ma_%s,\n", name);
3186 oprintf (f, " &gt_pch_na_%s", name);
3187 }
3188 else
3189 {
3190 error_at_line (line,
3191 "global `%s' is pointer to unimplemented type",
3192 name);
3193 }
3194 if (if_marked)
3195 oprintf (f, ",\n &%s", if_marked);
3196 oprintf (f, "\n },\n");
3197 }
3198 break;
3199
3200 case TYPE_STRING:
3201 {
3202 oprintf (f, " {\n");
3203 oprintf (f, " &%s,\n", name);
3204 oprintf (f, " 1, \n");
3205 oprintf (f, " sizeof (%s),\n", v->name);
3206 oprintf (f, " (gt_pointer_walker) &gt_ggc_m_S,\n");
3207 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
3208 oprintf (f, " },\n");
3209 }
3210 break;
3211
3212 case TYPE_SCALAR:
3213 break;
3214
3215 default:
3216 error_at_line (line,
3217 "global `%s' is unimplemented type",
3218 name);
3219 }
3220 }
3221
3222 /* This generates a routine to walk an array. */
3223
3224 static void
3225 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3226 {
3227 struct walk_type_data d;
3228 char *prevval3;
3229
3230 memset (&d, 0, sizeof (d));
3231 d.of = f;
3232 d.cookie = wtd;
3233 d.indent = 2;
3234 d.line = &v->line;
3235 d.opt = v->opt;
3236 d.bitmap = get_lang_bitmap (v->line.file);
3237 d.param = NULL;
3238
3239 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3240
3241 if (wtd->param_prefix)
3242 {
3243 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3244 oprintf (f,
3245 " (void *, void *, gt_pointer_operator, void *);\n");
3246 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3247 wtd->param_prefix, v->name);
3248 oprintf (d.of,
3249 " ATTRIBUTE_UNUSED void *x_p,\n"
3250 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3251 " ATTRIBUTE_UNUSED void * cookie)\n");
3252 oprintf (d.of, "{\n");
3253 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3254 d.process_field = write_types_local_process_field;
3255 walk_type (v->type, &d);
3256 oprintf (f, "}\n\n");
3257 }
3258
3259 d.opt = v->opt;
3260 oprintf (f, "static void gt_%sa_%s (void *);\n",
3261 wtd->prefix, v->name);
3262 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3263 wtd->prefix, v->name);
3264 oprintf (f, "{\n");
3265 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3266 d.process_field = write_types_process_field;
3267 walk_type (v->type, &d);
3268 free (prevval3);
3269 oprintf (f, "}\n\n");
3270 }
3271
3272 /* Output a table describing the locations and types of VARIABLES. */
3273
3274 static void
3275 write_roots (pair_p variables)
3276 {
3277 pair_p v;
3278 struct flist *flp = NULL;
3279
3280 for (v = variables; v; v = v->next)
3281 {
3282 outf_p f = get_output_file_with_visibility (v->line.file);
3283 struct flist *fli;
3284 const char *length = NULL;
3285 int deletable_p = 0;
3286 options_p o;
3287
3288 for (o = v->opt; o; o = o->next)
3289 if (strcmp (o->name, "length") == 0)
3290 length = o->info;
3291 else if (strcmp (o->name, "deletable") == 0)
3292 deletable_p = 1;
3293 else if (strcmp (o->name, "param_is") == 0)
3294 ;
3295 else if (strncmp (o->name, "param", 5) == 0
3296 && ISDIGIT (o->name[5])
3297 && strcmp (o->name + 6, "_is") == 0)
3298 ;
3299 else if (strcmp (o->name, "if_marked") == 0)
3300 ;
3301 else
3302 error_at_line (&v->line,
3303 "global `%s' has unknown option `%s'",
3304 v->name, o->name);
3305
3306 for (fli = flp; fli; fli = fli->next)
3307 if (fli->f == f)
3308 break;
3309 if (fli == NULL)
3310 {
3311 fli = XNEW (struct flist);
3312 fli->f = f;
3313 fli->next = flp;
3314 fli->started_p = 0;
3315 fli->name = v->line.file;
3316 flp = fli;
3317
3318 oprintf (f, "\n/* GC roots. */\n\n");
3319 }
3320
3321 if (! deletable_p
3322 && length
3323 && v->type->kind == TYPE_POINTER
3324 && (v->type->u.p->kind == TYPE_POINTER
3325 || v->type->u.p->kind == TYPE_STRUCT))
3326 {
3327 write_array (f, v, &ggc_wtd);
3328 write_array (f, v, &pch_wtd);
3329 }
3330 }
3331
3332 for (v = variables; v; v = v->next)
3333 {
3334 outf_p f = get_output_file_with_visibility (v->line.file);
3335 struct flist *fli;
3336 int skip_p = 0;
3337 int length_p = 0;
3338 options_p o;
3339
3340 for (o = v->opt; o; o = o->next)
3341 if (strcmp (o->name, "length") == 0)
3342 length_p = 1;
3343 else if (strcmp (o->name, "deletable") == 0
3344 || strcmp (o->name, "if_marked") == 0)
3345 skip_p = 1;
3346
3347 if (skip_p)
3348 continue;
3349
3350 for (fli = flp; fli; fli = fli->next)
3351 if (fli->f == f)
3352 break;
3353 if (! fli->started_p)
3354 {
3355 fli->started_p = 1;
3356
3357 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
3358 put_mangled_filename (f, v->line.file);
3359 oprintf (f, "[] = {\n");
3360 }
3361
3362 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3363 }
3364
3365 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3366 "gt_ggc_rtab");
3367
3368 for (v = variables; v; v = v->next)
3369 {
3370 outf_p f = get_output_file_with_visibility (v->line.file);
3371 struct flist *fli;
3372 int skip_p = 1;
3373 options_p o;
3374
3375 for (o = v->opt; o; o = o->next)
3376 if (strcmp (o->name, "deletable") == 0)
3377 skip_p = 0;
3378 else if (strcmp (o->name, "if_marked") == 0)
3379 skip_p = 1;
3380
3381 if (skip_p)
3382 continue;
3383
3384 for (fli = flp; fli; fli = fli->next)
3385 if (fli->f == f)
3386 break;
3387 if (! fli->started_p)
3388 {
3389 fli->started_p = 1;
3390
3391 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
3392 put_mangled_filename (f, v->line.file);
3393 oprintf (f, "[] = {\n");
3394 }
3395
3396 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3397 v->name, v->name);
3398 }
3399
3400 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3401 "gt_ggc_deletable_rtab");
3402
3403 for (v = variables; v; v = v->next)
3404 {
3405 outf_p f = get_output_file_with_visibility (v->line.file);
3406 struct flist *fli;
3407 const char *if_marked = NULL;
3408 int length_p = 0;
3409 options_p o;
3410
3411 for (o = v->opt; o; o = o->next)
3412 if (strcmp (o->name, "length") == 0)
3413 length_p = 1;
3414 else if (strcmp (o->name, "if_marked") == 0)
3415 if_marked = o->info;
3416
3417 if (if_marked == NULL)
3418 continue;
3419
3420 if (v->type->kind != TYPE_POINTER
3421 || v->type->u.p->kind != TYPE_PARAM_STRUCT
3422 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3423 {
3424 error_at_line (&v->line, "if_marked option used but not hash table");
3425 continue;
3426 }
3427
3428 for (fli = flp; fli; fli = fli->next)
3429 if (fli->f == f)
3430 break;
3431 if (! fli->started_p)
3432 {
3433 fli->started_p = 1;
3434
3435 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
3436 put_mangled_filename (f, v->line.file);
3437 oprintf (f, "[] = {\n");
3438 }
3439
3440 write_root (f, v, v->type->u.p->u.param_struct.param[0],
3441 v->name, length_p, &v->line, if_marked);
3442 }
3443
3444 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3445 "gt_ggc_cache_rtab");
3446
3447 for (v = variables; v; v = v->next)
3448 {
3449 outf_p f = get_output_file_with_visibility (v->line.file);
3450 struct flist *fli;
3451 int length_p = 0;
3452 int if_marked_p = 0;
3453 options_p o;
3454
3455 for (o = v->opt; o; o = o->next)
3456 if (strcmp (o->name, "length") == 0)
3457 length_p = 1;
3458 else if (strcmp (o->name, "if_marked") == 0)
3459 if_marked_p = 1;
3460
3461 if (! if_marked_p)
3462 continue;
3463
3464 for (fli = flp; fli; fli = fli->next)
3465 if (fli->f == f)
3466 break;
3467 if (! fli->started_p)
3468 {
3469 fli->started_p = 1;
3470
3471 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
3472 put_mangled_filename (f, v->line.file);
3473 oprintf (f, "[] = {\n");
3474 }
3475
3476 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3477 }
3478
3479 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3480 "gt_pch_cache_rtab");
3481
3482 for (v = variables; v; v = v->next)
3483 {
3484 outf_p f = get_output_file_with_visibility (v->line.file);
3485 struct flist *fli;
3486 int skip_p = 0;
3487 options_p o;
3488
3489 for (o = v->opt; o; o = o->next)
3490 if (strcmp (o->name, "deletable") == 0
3491 || strcmp (o->name, "if_marked") == 0)
3492 skip_p = 1;
3493
3494 if (skip_p)
3495 continue;
3496
3497 if (! contains_scalar_p (v->type))
3498 continue;
3499
3500 for (fli = flp; fli; fli = fli->next)
3501 if (fli->f == f)
3502 break;
3503 if (! fli->started_p)
3504 {
3505 fli->started_p = 1;
3506
3507 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3508 put_mangled_filename (f, v->line.file);
3509 oprintf (f, "[] = {\n");
3510 }
3511
3512 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3513 v->name, v->name);
3514 }
3515
3516 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3517 "gt_pch_scalar_rtab");
3518 }
3519
3520 /* Record the definition of a generic VEC structure, as if we had expanded
3521 the macros in vec.h:
3522
3523 typedef struct VEC_<type>_base GTY(()) {
3524 unsigned num;
3525 unsigned alloc;
3526 <type> GTY((length ("%h.num"))) vec[1];
3527 } VEC_<type>_base
3528
3529 where the GTY(()) tags are only present if is_scalar is _false_. */
3530
3531 void
3532 note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
3533 {
3534 pair_p fields;
3535 type_p t;
3536 options_p o;
3537 type_p len_ty = create_scalar_type ("unsigned");
3538 const char *name = concat ("VEC_", typename, "_base", (char *)0);
3539
3540 if (is_scalar)
3541 {
3542 t = create_scalar_type (typename);
3543 o = 0;
3544 }
3545 else
3546 {
3547 t = resolve_typedef (typename, pos);
3548 o = create_option (0, "length", "%h.num");
3549 }
3550
3551 /* We assemble the field list in reverse order. */
3552 fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3553 fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3554 fields = create_field_at (fields, len_ty, "num", 0, pos);
3555
3556 do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3557 }
3558
3559 /* Record the definition of an allocation-specific VEC structure, as if
3560 we had expanded the macros in vec.h:
3561
3562 typedef struct VEC_<type>_<astrat> {
3563 VEC_<type>_base base;
3564 } VEC_<type>_<astrat>;
3565 */
3566 void
3567 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3568 {
3569 const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3570 const char *basename = concat ("VEC_", type, "_base", (char *)0);
3571
3572 pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3573 "base", 0, pos);
3574
3575 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3576 }
3577
3578 \f
3579 int
3580 main (int argc, char **argv)
3581 {
3582 size_t i;
3583 static struct fileloc pos = { this_file, 0 };
3584
3585 /* fatal uses this */
3586 progname = "gengtype";
3587
3588 if (argc != 3)
3589 fatal ("usage: gengtype srcdir input-list");
3590
3591 srcdir = argv[1];
3592 srcdir_len = strlen (srcdir);
3593
3594 read_input_list (argv[2]);
3595 if (hit_error)
3596 return 1;
3597
3598 scalar_char.u.scalar_is_char = true;
3599 scalar_nonchar.u.scalar_is_char = false;
3600 gen_rtx_next ();
3601
3602 /* These types are set up with #define or else outside of where
3603 we can see them. */
3604 pos.line = __LINE__ + 1;
3605 do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3606 do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
3607 do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
3608 do_scalar_typedef ("double_int", &pos); pos.line++;
3609 do_scalar_typedef ("uint8", &pos); pos.line++;
3610 do_scalar_typedef ("jword", &pos); pos.line++;
3611 do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3612 do_scalar_typedef ("void", &pos); pos.line++;
3613 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3614
3615 for (i = 0; i < num_gt_files; i++)
3616 parse_file (gt_files[i]);
3617
3618 if (hit_error)
3619 return 1;
3620
3621 set_gc_used (variables);
3622
3623 open_base_files ();
3624 write_enum_defn (structures, param_structs);
3625 write_types (structures, param_structs, &ggc_wtd);
3626 write_types (structures, param_structs, &pch_wtd);
3627 write_local (structures, param_structs);
3628 write_roots (variables);
3629 write_rtx_next ();
3630 close_output_files ();
3631
3632 if (hit_error)
3633 return 1;
3634 return 0;
3635 }