]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gengtype.c
2010-11-08 Basile Starynkevitch <basile@starynkevitch.net>
[thirdparty/gcc.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 "errors.h" /* for fatal */
24 #include "getopt.h"
25 #include "double-int.h"
26 #include "version.h" /* for version_string & pkgversion_string. */
27 #include "hashtab.h"
28 #include "gengtype.h"
29
30 /* Data types, macros, etc. used only in this file. */
31
32 /* Kinds of types we can understand. */
33 enum typekind
34 {
35 TYPE_SCALAR,
36 TYPE_STRING,
37 TYPE_STRUCT,
38 TYPE_UNION,
39 TYPE_POINTER,
40 TYPE_ARRAY,
41 TYPE_LANG_STRUCT,
42 TYPE_PARAM_STRUCT
43 };
44
45
46 /* A way to pass data through to the output end. */
47 struct options
48 {
49 struct options *next;
50 const char *name;
51 const char *info;
52 };
53
54 /* Option data for the 'nested_ptr' option. */
55 struct nested_ptr_data
56 {
57 type_p type;
58 const char *convert_to;
59 const char *convert_from;
60 };
61
62 /* A name and a type. */
63 struct pair
64 {
65 pair_p next;
66 const char *name;
67 type_p type;
68 struct fileloc line;
69 options_p opt;
70 };
71
72 #define NUM_PARAM 10
73
74 /* A description of a type. */
75 enum gc_used_enum
76 {
77 GC_UNUSED = 0,
78 GC_USED,
79 /* Used for structures whose definitions we haven't seen so far when
80 we encounter a pointer to it that is annotated with ``maybe_undef''.
81 If after reading in everything we don't have source file
82 information for it, we assume that it never has been defined. */
83 GC_MAYBE_POINTED_TO,
84 GC_POINTED_TO
85 };
86
87 struct type
88 {
89 enum typekind kind;
90 type_p next;
91 type_p pointer_to;
92 enum gc_used_enum gc_used;
93 union
94 {
95 type_p p;
96 struct
97 {
98 const char *tag;
99 struct fileloc line;
100 pair_p fields;
101 options_p opt;
102 lang_bitmap bitmap;
103 type_p lang_struct;
104 } s;
105 bool scalar_is_char;
106 struct
107 {
108 type_p p;
109 const char *len;
110 } a;
111 struct
112 {
113 type_p stru;
114 type_p param[NUM_PARAM];
115 struct fileloc line;
116 } param_struct;
117 } u;
118 };
119
120 #define UNION_P(x) \
121 ((x)->kind == TYPE_UNION || \
122 ((x)->kind == TYPE_LANG_STRUCT \
123 && (x)->u.s.lang_struct->kind == TYPE_UNION))
124 #define UNION_OR_STRUCT_P(x) \
125 ((x)->kind == TYPE_UNION \
126 || (x)->kind == TYPE_STRUCT \
127 || (x)->kind == TYPE_LANG_STRUCT)
128
129
130
131 const char *get_output_file_name (const char *);
132
133
134 /* The list of output files. */
135 outf_p output_files;
136
137 /* The output header file that is included into pretty much every
138 source file. */
139 outf_p header_file;
140
141
142 /* The name of the file containing the list of input files. */
143 static char *inputlist;
144
145 /* The plugin input files and their number; in that case only
146 a single file is produced. */
147 static char **plugin_files;
148 static size_t nb_plugin_files;
149
150 /* The generated plugin output file and name. */
151 static outf_p plugin_output;
152 static char *plugin_output_filename;
153
154 /* Our source directory and its length. */
155 const char *srcdir;
156 size_t srcdir_len;
157
158 /* Variables used for reading and writing the state. */
159 const char *read_state_filename;
160 const char *write_state_filename;
161
162 /* Variables to help debugging. */
163 int do_dump;
164 int do_debug;
165
166 /* Level for verbose messages. */
167 int verbosity_level;
168
169 /* The backup directory should be in the same file system as the
170 generated files, otherwise the rename(2) system call would fail.
171 If NULL, no backup is made when overwriting a generated file. */
172 static const char* backup_dir; /* (-B) program option. */
173
174
175 static outf_p create_file (const char *, const char *);
176
177 static const char *get_file_basename (const char *);
178 static const char *get_file_realbasename (const char *);
179 static const char *get_file_srcdir_relative_path (const char *);
180
181 static int get_prefix_langdir_index (const char *);
182 static const char *get_file_langdir (const char *);
183 \f
184
185 /* Nonzero iff an error has occurred. */
186 bool hit_error = false;
187
188 static void gen_rtx_next (void);
189 static void write_rtx_next (void);
190 static void open_base_files (void);
191 static void close_output_files (void);
192
193 /* Report an error at POS, printing MSG. */
194
195 void
196 error_at_line (const struct fileloc *pos, const char *msg, ...)
197 {
198 va_list ap;
199
200 va_start (ap, msg);
201
202 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
203 vfprintf (stderr, msg, ap);
204 fputc ('\n', stderr);
205 hit_error = true;
206
207 va_end (ap);
208 }
209
210 /* asprintf, but produces fatal message on out-of-memory. */
211 char *
212 xasprintf (const char *format, ...)
213 {
214 int n;
215 char *result;
216 va_list ap;
217
218 va_start (ap, format);
219 n = vasprintf (&result, format, ap);
220 if (result == NULL || n < 0)
221 fatal ("out of memory");
222 va_end (ap);
223
224 return result;
225 }
226 \f
227 /* Input file handling. */
228
229 /* Table of all input files. */
230 static const char **gt_files;
231 static size_t num_gt_files;
232
233 /* A number of places use the name of this "gengtype.h" file for a
234 location for things that we can't rely on the source to define.
235 Make sure we can still use pointer comparison on filenames. */
236 const char this_file[] = __FILE__;
237 /* The "system.h" file is likewise specially useful. */
238 const char system_h_file[] = "system.h";
239
240 /* Vector of per-language directories. */
241 static const char **lang_dir_names;
242 static size_t num_lang_dirs;
243
244 /* An array of output files suitable for definitions. There is one
245 BASE_FILES entry for each language. */
246 static outf_p *base_files;
247
248 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
249 INPUT_FILE is used by <lang>.
250
251 This function should be written to assume that a file _is_ used
252 if the situation is unclear. If it wrongly assumes a file _is_ used,
253 a linker error will result. If it wrongly assumes a file _is not_ used,
254 some GC roots may be missed, which is a much harder-to-debug problem.
255
256 The relevant bitmap is stored immediately before the file's name in the
257 buffer set up by read_input_list. It may be unaligned, so we have to
258 read it byte-by-byte. */
259
260 static lang_bitmap
261 get_lang_bitmap (const char *gtfile)
262 {
263
264 if (gtfile == this_file || gtfile == system_h_file)
265 {
266 /* Things defined in this "gengtype.c" file or in "system.h" are
267 universal (and there is no space for their lang_bitmap before
268 their file names). */
269 return (((lang_bitmap) 1) << num_lang_dirs) - 1;
270 }
271 else
272 {
273 lang_bitmap n = 0;
274 int i;
275 for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
276 n = (n << CHAR_BIT) + (unsigned char) gtfile[i];
277 return n;
278 }
279 }
280
281 /* Set the bitmap returned by get_lang_bitmap. The only legitimate
282 caller of this function is read_input_list. */
283 static void
284 set_lang_bitmap (char *gtfile, lang_bitmap n)
285 {
286 int i;
287 for (i = -1; i >= -(int) sizeof (lang_bitmap); i--)
288 {
289 gtfile[i] = n & ((1U << CHAR_BIT) - 1);
290 n >>= CHAR_BIT;
291 }
292 }
293
294
295 #if ENABLE_CHECKING
296 /* Utility debugging function, printing the various type counts within
297 a list of types. Called thru the DBGPRINT_COUNT_TYPE macro. */
298 void
299 dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
300 {
301 int nb_types = 0, nb_scalar = 0, nb_string = 0;
302 int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0;
303 int nb_lang_struct = 0, nb_param_struct = 0;
304 type_p p = NULL;
305 for (p = t; p; p = p->next)
306 {
307 nb_types++;
308 switch (p->kind)
309 {
310 case TYPE_SCALAR:
311 nb_scalar++;
312 break;
313 case TYPE_STRING:
314 nb_string++;
315 break;
316 case TYPE_STRUCT:
317 nb_struct++;
318 break;
319 case TYPE_UNION:
320 nb_union++;
321 break;
322 case TYPE_POINTER:
323 nb_pointer++;
324 break;
325 case TYPE_ARRAY:
326 nb_array++;
327 break;
328 case TYPE_LANG_STRUCT:
329 nb_lang_struct++;
330 break;
331 case TYPE_PARAM_STRUCT:
332 nb_param_struct++;
333 break;
334 default:
335 gcc_unreachable ();
336 }
337 }
338 fprintf (stderr, "\n" "%s:%d: %s: @@%%@@ %d types ::\n",
339 lbasename (fil), lin, msg, nb_types);
340 if (nb_scalar > 0 || nb_string > 0)
341 fprintf (stderr, "@@%%@@ %d scalars, %d strings\n", nb_scalar, nb_string);
342 if (nb_struct > 0 || nb_union > 0)
343 fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union);
344 if (nb_pointer > 0 || nb_array > 0)
345 fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array);
346 if (nb_lang_struct > 0 || nb_param_struct > 0)
347 fprintf (stderr, "@@%%@@ %d lang_structs, %d param_structs\n",
348 nb_lang_struct, nb_param_struct);
349 fprintf (stderr, "\n");
350 }
351 #endif /* ENABLE_CHECKING */
352
353 /* Scan the input file, LIST, and determine how much space we need to
354 store strings in. Also, count the number of language directories
355 and files. The numbers returned are overestimates as they does not
356 consider repeated files. */
357 static size_t
358 measure_input_list (FILE *list)
359 {
360 size_t n = 0;
361 int c;
362 bool atbol = true;
363 num_lang_dirs = 0;
364 num_gt_files = plugin_files ? nb_plugin_files : 0;
365 while ((c = getc (list)) != EOF)
366 {
367 n++;
368 if (atbol)
369 {
370 if (c == '[')
371 num_lang_dirs++;
372 else
373 {
374 /* Add space for a lang_bitmap before the input file name. */
375 n += sizeof (lang_bitmap);
376 num_gt_files++;
377 }
378 atbol = false;
379 }
380
381 if (c == '\n')
382 atbol = true;
383 }
384
385 rewind (list);
386 return n;
387 }
388
389 /* Read one input line from LIST to HEREP (which is updated). A
390 pointer to the string is returned via LINEP. If it was a language
391 subdirectory in square brackets, strip off the square brackets and
392 return true. Otherwise, leave space before the string for a
393 lang_bitmap, and return false. At EOF, returns false, does not
394 touch *HEREP, and sets *LINEP to NULL. POS is used for
395 diagnostics. */
396 static bool
397 read_input_line (FILE *list, char **herep, char **linep, struct fileloc *pos)
398 {
399 char *here = *herep;
400 char *line;
401 int c = getc (list);
402
403 /* Read over whitespace. */
404 while (c == '\n' || c == ' ')
405 c = getc (list);
406
407 if (c == EOF)
408 {
409 *linep = 0;
410 return false;
411 }
412 else if (c == '[')
413 {
414 /* No space for a lang_bitmap is necessary. Discard the '['. */
415 c = getc (list);
416 line = here;
417 while (c != ']' && c != '\n' && c != EOF)
418 {
419 *here++ = c;
420 c = getc (list);
421 }
422 *here++ = '\0';
423
424 if (c == ']')
425 {
426 c = getc (list); /* eat what should be a newline */
427 if (c != '\n' && c != EOF)
428 error_at_line (pos, "junk on line after language tag [%s]", line);
429 }
430 else
431 error_at_line (pos, "missing close bracket for language tag [%s",
432 line);
433
434 *herep = here;
435 *linep = line;
436 return true;
437 }
438 else
439 {
440 /* Leave space for a lang_bitmap. */
441 memset (here, 0, sizeof (lang_bitmap));
442 here += sizeof (lang_bitmap);
443 line = here;
444 do
445 {
446 *here++ = c;
447 c = getc (list);
448 }
449 while (c != EOF && c != '\n');
450 *here++ = '\0';
451 *herep = here;
452 *linep = line;
453 return false;
454 }
455 }
456
457 /* Read the list of input files from LIST and compute all of the
458 relevant tables. There is one file per line of the list. At
459 first, all the files on the list are language-generic, but
460 eventually a line will appear which is the name of a language
461 subdirectory in square brackets, like this: [cp]. All subsequent
462 files are specific to that language, until another language
463 subdirectory tag appears. Files can appear more than once, if
464 they apply to more than one language. */
465 static void
466 read_input_list (const char *listname)
467 {
468 FILE *list = fopen (listname, "r");
469 if (!list)
470 fatal ("cannot open %s: %s", listname, xstrerror (errno));
471 else
472 {
473 struct fileloc epos;
474 size_t bufsz = measure_input_list (list);
475 char *buf = XNEWVEC (char, bufsz);
476 char *here = buf;
477 char *committed = buf;
478 char *limit = buf + bufsz;
479 char *line;
480 bool is_language;
481 size_t langno = 0;
482 size_t nfiles = 0;
483 lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
484
485 epos.file = listname;
486 epos.line = 0;
487
488 lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
489 gt_files = XNEWVEC (const char *, num_gt_files);
490
491 for (;;)
492 {
493 next_line:
494 epos.line++;
495 committed = here;
496 is_language = read_input_line (list, &here, &line, &epos);
497 gcc_assert (here <= limit);
498 if (line == 0)
499 break;
500 else if (is_language)
501 {
502 size_t i;
503 gcc_assert (langno <= num_lang_dirs);
504 for (i = 0; i < langno; i++)
505 if (strcmp (lang_dir_names[i], line) == 0)
506 {
507 error_at_line (&epos, "duplicate language tag [%s]",
508 line);
509 curlangs = 1 << i;
510 here = committed;
511 goto next_line;
512 }
513
514 curlangs = 1 << langno;
515 lang_dir_names[langno++] = line;
516 }
517 else
518 {
519 size_t i;
520 gcc_assert (nfiles <= num_gt_files);
521 for (i = 0; i < nfiles; i++)
522 if (strcmp (gt_files[i], line) == 0)
523 {
524 /* Throw away the string we just read, and add the
525 current language to the existing string's bitmap. */
526 lang_bitmap bmap = get_lang_bitmap (gt_files[i]);
527 if (bmap & curlangs)
528 error_at_line (&epos,
529 "file %s specified more than once "
530 "for language %s", line,
531 langno ==
532 0 ? "(all)" : lang_dir_names[langno -
533 1]);
534
535 bmap |= curlangs;
536 set_lang_bitmap (CONST_CAST (char *, gt_files[i]), bmap);
537 here = committed;
538 goto next_line;
539 }
540
541 set_lang_bitmap (line, curlangs);
542 gt_files[nfiles++] = line;
543 }
544 }
545 /* Update the global counts now that we know accurately how many
546 things there are. (We do not bother resizing the arrays down.) */
547 num_lang_dirs = langno;
548 /* Add the plugin files if provided. */
549 if (plugin_files)
550 {
551 size_t i;
552 for (i = 0; i < nb_plugin_files; i++)
553 gt_files[nfiles++] = plugin_files[i];
554 }
555 num_gt_files = nfiles;
556 }
557
558 /* Sanity check: any file that resides in a language subdirectory
559 (e.g. 'cp') ought to belong to the corresponding language.
560 ??? Still true if for instance ObjC++ is enabled and C++ isn't?
561 (Can you even do that? Should you be allowed to?) */
562 {
563 size_t f;
564 for (f = 0; f < num_gt_files; f++)
565 {
566 lang_bitmap bitmap = get_lang_bitmap (gt_files[f]);
567 const char *basename = get_file_basename (gt_files[f]);
568 const char *slashpos = strchr (basename, '/');
569
570 if (slashpos)
571 {
572 size_t l;
573 for (l = 0; l < num_lang_dirs; l++)
574 if ((size_t) (slashpos - basename) == strlen (lang_dir_names[l])
575 && memcmp (basename, lang_dir_names[l],
576 strlen (lang_dir_names[l])) == 0)
577 {
578 if (!(bitmap & (1 << l)))
579 error ("%s is in language directory '%s' but is not "
580 "tagged for that language",
581 basename, lang_dir_names[l]);
582 break;
583 }
584 }
585 }
586 }
587
588 if (ferror (list))
589 fatal ("error reading %s: %s", listname, xstrerror (errno));
590
591 fclose (list);
592 }
593 \f
594
595
596 /* The one and only TYPE_STRING. */
597
598 static struct type string_type = {
599 TYPE_STRING, 0, 0, GC_USED, {0}
600 };
601
602 /* The two and only TYPE_SCALARs. Their u.scalar_is_char flags are
603 set to appropriate values at the beginning of main. */
604
605 static struct type scalar_nonchar = {
606 TYPE_SCALAR, 0, 0, GC_USED, {0}
607 };
608
609 static struct type scalar_char = {
610 TYPE_SCALAR, 0, 0, GC_USED, {0}
611 };
612
613 /* Lists of various things. */
614
615 static pair_p typedefs;
616 static type_p structures;
617 static type_p param_structs;
618 static pair_p variables;
619
620 static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
621 static type_p adjust_field_tree_exp (type_p t, options_p opt);
622 static type_p adjust_field_rtx_def (type_p t, options_p opt);
623
624 /* Define S as a typedef to T at POS. */
625
626 void
627 do_typedef (const char *s, type_p t, struct fileloc *pos)
628 {
629 pair_p p;
630
631 /* temporary kludge - gengtype doesn't handle conditionals or
632 macros. Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
633 is coming from this file (main() sets them up with safe dummy
634 definitions). */
635 if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
636 return;
637
638 for (p = typedefs; p != NULL; p = p->next)
639 if (strcmp (p->name, s) == 0)
640 {
641 if (p->type != t)
642 {
643 error_at_line (pos, "type `%s' previously defined", s);
644 error_at_line (&p->line, "previously defined here");
645 }
646 return;
647 }
648
649 p = XNEW (struct pair);
650 p->next = typedefs;
651 p->name = s;
652 p->type = t;
653 p->line = *pos;
654 p->opt = NULL;
655 typedefs = p;
656 }
657
658 /* Define S as a typename of a scalar. Cannot be used to define
659 typedefs of 'char'. Note: is also used for pointer-to-function
660 typedefs (which are therefore not treated as pointers). */
661
662 void
663 do_scalar_typedef (const char *s, struct fileloc *pos)
664 {
665 do_typedef (s, &scalar_nonchar, pos);
666 }
667
668 /* Return the type previously defined for S. Use POS to report errors. */
669
670 type_p
671 resolve_typedef (const char *s, struct fileloc *pos)
672 {
673 pair_p p;
674 for (p = typedefs; p != NULL; p = p->next)
675 if (strcmp (p->name, s) == 0)
676 return p->type;
677 error_at_line (pos, "unidentified type `%s'", s);
678 return &scalar_nonchar; /* treat as "int" */
679 }
680
681 /* Create and return a new structure with tag NAME (or a union iff
682 ISUNION is nonzero), at POS with fields FIELDS and options O. */
683
684 type_p
685 new_structure (const char *name, int isunion, struct fileloc *pos,
686 pair_p fields, options_p o)
687 {
688 type_p si;
689 type_p s = NULL;
690 lang_bitmap bitmap = get_lang_bitmap (pos->file);
691
692 for (si = structures; si != NULL; si = si->next)
693 if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion)
694 {
695 type_p ls = NULL;
696 if (si->kind == TYPE_LANG_STRUCT)
697 {
698 ls = si;
699
700 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
701 if (si->u.s.bitmap == bitmap)
702 s = si;
703 }
704 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
705 {
706 ls = si;
707 si = XCNEW (struct type);
708 memcpy (si, ls, sizeof (struct type));
709 ls->kind = TYPE_LANG_STRUCT;
710 ls->u.s.lang_struct = si;
711 ls->u.s.fields = NULL;
712 si->next = NULL;
713 si->pointer_to = NULL;
714 si->u.s.lang_struct = ls;
715 }
716 else
717 s = si;
718
719 if (ls != NULL && s == NULL)
720 {
721 s = XCNEW (struct type);
722 s->next = ls->u.s.lang_struct;
723 ls->u.s.lang_struct = s;
724 s->u.s.lang_struct = ls;
725 }
726 break;
727 }
728
729 if (s == NULL)
730 {
731 s = XCNEW (struct type);
732 s->next = structures;
733 structures = s;
734 }
735
736 if (s->u.s.line.file != NULL
737 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
738 {
739 error_at_line (pos, "duplicate definition of '%s %s'",
740 isunion ? "union" : "struct", s->u.s.tag);
741 error_at_line (&s->u.s.line, "previous definition here");
742 }
743
744 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
745 s->u.s.tag = name;
746 s->u.s.line = *pos;
747 s->u.s.fields = fields;
748 s->u.s.opt = o;
749 s->u.s.bitmap = bitmap;
750 if (s->u.s.lang_struct)
751 s->u.s.lang_struct->u.s.bitmap |= bitmap;
752
753 return s;
754 }
755
756 /* Return the previously-defined structure with tag NAME (or a union
757 iff ISUNION is nonzero), or a new empty structure or union if none
758 was defined previously. */
759
760 type_p
761 find_structure (const char *name, int isunion)
762 {
763 type_p s;
764
765 for (s = structures; s != NULL; s = s->next)
766 if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion)
767 return s;
768
769 s = XCNEW (struct type);
770 s->next = structures;
771 structures = s;
772 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
773 s->u.s.tag = name;
774 structures = s;
775 return s;
776 }
777
778 /* Return the previously-defined parameterized structure for structure
779 T and parameters PARAM, or a new parameterized empty structure or
780 union if none was defined previously. */
781
782 static type_p
783 find_param_structure (type_p t, type_p param[NUM_PARAM])
784 {
785 type_p res;
786
787 for (res = param_structs; res; res = res->next)
788 if (res->u.param_struct.stru == t
789 && memcmp (res->u.param_struct.param, param,
790 sizeof (type_p) * NUM_PARAM) == 0)
791 break;
792 if (res == NULL)
793 {
794 res = XCNEW (struct type);
795 res->kind = TYPE_PARAM_STRUCT;
796 res->next = param_structs;
797 param_structs = res;
798 res->u.param_struct.stru = t;
799 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
800 }
801 return res;
802 }
803
804 /* Return a scalar type with name NAME. */
805
806 type_p
807 create_scalar_type (const char *name)
808 {
809 if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
810 return &scalar_char;
811 else
812 return &scalar_nonchar;
813 }
814
815 /* Return a pointer to T. */
816
817 type_p
818 create_pointer (type_p t)
819 {
820 if (!t->pointer_to)
821 {
822 type_p r = XCNEW (struct type);
823 r->kind = TYPE_POINTER;
824 r->u.p = t;
825 t->pointer_to = r;
826 }
827 return t->pointer_to;
828 }
829
830 /* Return an array of length LEN. */
831
832 type_p
833 create_array (type_p t, const char *len)
834 {
835 type_p v;
836
837 v = XCNEW (struct type);
838 v->kind = TYPE_ARRAY;
839 v->u.a.p = t;
840 v->u.a.len = len;
841 return v;
842 }
843
844 /* Return an options structure with name NAME and info INFO. NEXT is the
845 next option in the chain. */
846
847 options_p
848 create_option (options_p next, const char *name, const void *info)
849 {
850 options_p o = XNEW (struct options);
851 o->next = next;
852 o->name = name;
853 o->info = (const char *) info;
854 return o;
855 }
856
857 /* Return an options structure for a "nested_ptr" option. */
858 options_p
859 create_nested_ptr_option (options_p next, type_p t,
860 const char *to, const char *from)
861 {
862 struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
863
864 d->type = adjust_field_type (t, 0);
865 d->convert_to = to;
866 d->convert_from = from;
867 return create_option (next, "nested_ptr", d);
868 }
869
870 /* Add a variable named S of type T with options O defined at POS,
871 to `variables'. */
872
873 void
874 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
875 {
876 pair_p n;
877 n = XNEW (struct pair);
878 n->name = s;
879 n->type = t;
880 n->line = *pos;
881 n->opt = o;
882 n->next = variables;
883 variables = n;
884 }
885
886 /* Most-general structure field creator. */
887 static pair_p
888 create_field_all (pair_p next, type_p type, const char *name, options_p opt,
889 const char *file, int line)
890 {
891 pair_p field;
892
893 field = XNEW (struct pair);
894 field->next = next;
895 field->type = type;
896 field->name = name;
897 field->opt = opt;
898 field->line.file = file;
899 field->line.line = line;
900 return field;
901 }
902
903 /* Create a field that came from the source code we are scanning,
904 i.e. we have a 'struct fileloc', and possibly options; also,
905 adjust_field_type should be called. */
906 pair_p
907 create_field_at (pair_p next, type_p type, const char *name, options_p opt,
908 struct fileloc *pos)
909 {
910 return create_field_all (next, adjust_field_type (type, opt),
911 name, opt, pos->file, pos->line);
912 }
913
914 /* Create a fake field with the given type and name. NEXT is the next
915 field in the chain. */
916 #define create_field(next,type,name) \
917 create_field_all(next,type,name, 0, this_file, __LINE__)
918
919 /* Like create_field, but the field is only valid when condition COND
920 is true. */
921
922 static pair_p
923 create_optional_field_ (pair_p next, type_p type, const char *name,
924 const char *cond, int line)
925 {
926 static int id = 1;
927 pair_p union_fields;
928 type_p union_type;
929
930 /* Create a fake union type with a single nameless field of type TYPE.
931 The field has a tag of "1". This allows us to make the presence
932 of a field of type TYPE depend on some boolean "desc" being true. */
933 union_fields = create_field (NULL, type, "");
934 union_fields->opt = create_option (union_fields->opt, "dot", "");
935 union_fields->opt = create_option (union_fields->opt, "tag", "1");
936 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
937 &lexer_line, union_fields, NULL);
938
939 /* Create the field and give it the new fake union type. Add a "desc"
940 tag that specifies the condition under which the field is valid. */
941 return create_field_all (next, union_type, name,
942 create_option (0, "desc", cond), this_file, line);
943 }
944
945 #define create_optional_field(next,type,name,cond) \
946 create_optional_field_(next,type,name,cond,__LINE__)
947
948 /* Reverse a linked list of 'struct pair's in place. */
949 pair_p
950 nreverse_pairs (pair_p list)
951 {
952 pair_p prev = 0, p, next;
953 for (p = list; p; p = next)
954 {
955 next = p->next;
956 p->next = prev;
957 prev = p;
958 }
959 return prev;
960 }
961 \f
962
963 /* We don't care how long a CONST_DOUBLE is. */
964 #define CONST_DOUBLE_FORMAT "ww"
965 /* We don't want to see codes that are only for generator files. */
966 #undef GENERATOR_FILE
967
968 enum rtx_code
969 {
970 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
971 #include "rtl.def"
972 #undef DEF_RTL_EXPR
973 NUM_RTX_CODE
974 };
975
976 static const char *const rtx_name[NUM_RTX_CODE] = {
977 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
978 #include "rtl.def"
979 #undef DEF_RTL_EXPR
980 };
981
982 static const char *const rtx_format[NUM_RTX_CODE] = {
983 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
984 #include "rtl.def"
985 #undef DEF_RTL_EXPR
986 };
987
988 static int rtx_next_new[NUM_RTX_CODE];
989
990 /* We also need codes and names for insn notes (not register notes).
991 Note that we do *not* bias the note values here. */
992 enum insn_note
993 {
994 #define DEF_INSN_NOTE(NAME) NAME,
995 #include "insn-notes.def"
996 #undef DEF_INSN_NOTE
997
998 NOTE_INSN_MAX
999 };
1000
1001 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
1002 default field for line number notes. */
1003 static const char *const note_insn_name[NOTE_INSN_MAX + 1] = {
1004 #define DEF_INSN_NOTE(NAME) #NAME,
1005 #include "insn-notes.def"
1006 #undef DEF_INSN_NOTE
1007 };
1008
1009 #undef CONST_DOUBLE_FORMAT
1010 #define GENERATOR_FILE
1011
1012 /* Generate the contents of the rtx_next array. This really doesn't belong
1013 in gengtype at all, but it's needed for adjust_field_rtx_def. */
1014
1015 static void
1016 gen_rtx_next (void)
1017 {
1018 int i;
1019 for (i = 0; i < NUM_RTX_CODE; i++)
1020 {
1021 int k;
1022
1023 rtx_next_new[i] = -1;
1024 if (strncmp (rtx_format[i], "iuu", 3) == 0)
1025 rtx_next_new[i] = 2;
1026 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
1027 rtx_next_new[i] = 1;
1028 else
1029 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
1030 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
1031 rtx_next_new[i] = k;
1032 }
1033 }
1034
1035 /* Write out the contents of the rtx_next array. */
1036 static void
1037 write_rtx_next (void)
1038 {
1039 outf_p f = get_output_file_with_visibility (NULL);
1040 int i;
1041 if (!f)
1042 return;
1043
1044 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
1045 oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
1046 for (i = 0; i < NUM_RTX_CODE; i++)
1047 if (rtx_next_new[i] == -1)
1048 oprintf (f, " 0,\n");
1049 else
1050 oprintf (f,
1051 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n", rtx_next_new[i]);
1052 oprintf (f, "};\n");
1053 }
1054
1055 /* Handle `special("rtx_def")'. This is a special case for field
1056 `fld' of struct rtx_def, which is an array of unions whose values
1057 are based in a complex way on the type of RTL. */
1058
1059 static type_p
1060 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
1061 {
1062 pair_p flds = NULL;
1063 options_p nodot;
1064 int i;
1065 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
1066 type_p basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
1067
1068 if (t->kind != TYPE_UNION)
1069 {
1070 error_at_line (&lexer_line,
1071 "special `rtx_def' must be applied to a union");
1072 return &string_type;
1073 }
1074
1075 nodot = create_option (NULL, "dot", "");
1076
1077 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
1078 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
1079 tree_tp = create_pointer (find_structure ("tree_node", 1));
1080 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
1081 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
1082 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
1083 constant_tp =
1084 create_pointer (find_structure ("constant_descriptor_rtx", 0));
1085 scalar_tp = &scalar_nonchar; /* rtunion int */
1086
1087 {
1088 pair_p note_flds = NULL;
1089 int c;
1090
1091 for (c = 0; c <= NOTE_INSN_MAX; c++)
1092 {
1093 switch (c)
1094 {
1095 case NOTE_INSN_MAX:
1096 case NOTE_INSN_DELETED_LABEL:
1097 note_flds = create_field (note_flds, &string_type, "rt_str");
1098 break;
1099
1100 case NOTE_INSN_BLOCK_BEG:
1101 case NOTE_INSN_BLOCK_END:
1102 note_flds = create_field (note_flds, tree_tp, "rt_tree");
1103 break;
1104
1105 case NOTE_INSN_VAR_LOCATION:
1106 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
1107 break;
1108
1109 default:
1110 note_flds = create_field (note_flds, scalar_tp, "rt_int");
1111 break;
1112 }
1113 /* NOTE_INSN_MAX is used as the default field for line
1114 number notes. */
1115 if (c == NOTE_INSN_MAX)
1116 note_flds->opt = create_option (nodot, "default", "");
1117 else
1118 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
1119 }
1120 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1121 &lexer_line, note_flds, NULL);
1122 }
1123 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
1124 {
1125 pair_p sym_flds;
1126
1127 sym_flds = create_field (NULL, tree_tp, "rt_tree");
1128 sym_flds->opt = create_option (nodot, "default", "");
1129
1130 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
1131 sym_flds->opt = create_option (nodot, "tag", "1");
1132
1133 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
1134 &lexer_line, sym_flds, NULL);
1135 }
1136 for (i = 0; i < NUM_RTX_CODE; i++)
1137 {
1138 pair_p subfields = NULL;
1139 size_t aindex, nmindex;
1140 const char *sname;
1141 type_p substruct;
1142 char *ftag;
1143
1144 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1145 {
1146 type_p t;
1147 const char *subname;
1148
1149 switch (rtx_format[i][aindex])
1150 {
1151 case '*':
1152 case 'i':
1153 case 'n':
1154 case 'w':
1155 t = scalar_tp;
1156 subname = "rt_int";
1157 break;
1158
1159 case '0':
1160 if (i == MEM && aindex == 1)
1161 t = mem_attrs_tp, subname = "rt_mem";
1162 else if (i == JUMP_INSN && aindex == 8)
1163 t = rtx_tp, subname = "rt_rtx";
1164 else if (i == CODE_LABEL && aindex == 5)
1165 t = scalar_tp, subname = "rt_int";
1166 else if (i == CODE_LABEL && aindex == 4)
1167 t = rtx_tp, subname = "rt_rtx";
1168 else if (i == LABEL_REF && (aindex == 1 || aindex == 2))
1169 t = rtx_tp, subname = "rt_rtx";
1170 else if (i == NOTE && aindex == 4)
1171 t = note_union_tp, subname = "";
1172 else if (i == NOTE && aindex == 5)
1173 t = scalar_tp, subname = "rt_int";
1174 else if (i == NOTE && aindex >= 7)
1175 t = scalar_tp, subname = "rt_int";
1176 else if (i == ADDR_DIFF_VEC && aindex == 4)
1177 t = scalar_tp, subname = "rt_int";
1178 else if (i == VALUE && aindex == 0)
1179 t = scalar_tp, subname = "rt_int";
1180 else if (i == DEBUG_EXPR && aindex == 0)
1181 t = tree_tp, subname = "rt_tree";
1182 else if (i == REG && aindex == 1)
1183 t = scalar_tp, subname = "rt_int";
1184 else if (i == REG && aindex == 2)
1185 t = reg_attrs_tp, subname = "rt_reg";
1186 else if (i == SCRATCH && aindex == 0)
1187 t = scalar_tp, subname = "rt_int";
1188 else if (i == SYMBOL_REF && aindex == 1)
1189 t = scalar_tp, subname = "rt_int";
1190 else if (i == SYMBOL_REF && aindex == 2)
1191 t = symbol_union_tp, subname = "";
1192 else if (i == BARRIER && aindex >= 3)
1193 t = scalar_tp, subname = "rt_int";
1194 else
1195 {
1196 error_at_line (&lexer_line,
1197 "rtx type `%s' has `0' in position %lu, can't handle",
1198 rtx_name[i], (unsigned long) aindex);
1199 t = &string_type;
1200 subname = "rt_int";
1201 }
1202 break;
1203
1204 case 's':
1205 case 'S':
1206 case 'T':
1207 t = &string_type;
1208 subname = "rt_str";
1209 break;
1210
1211 case 'e':
1212 case 'u':
1213 t = rtx_tp;
1214 subname = "rt_rtx";
1215 break;
1216
1217 case 'E':
1218 case 'V':
1219 t = rtvec_tp;
1220 subname = "rt_rtvec";
1221 break;
1222
1223 case 't':
1224 t = tree_tp;
1225 subname = "rt_tree";
1226 break;
1227
1228 case 'B':
1229 t = basic_block_tp;
1230 subname = "rt_bb";
1231 break;
1232
1233 default:
1234 error_at_line (&lexer_line,
1235 "rtx type `%s' has `%c' in position %lu, can't handle",
1236 rtx_name[i], rtx_format[i][aindex],
1237 (unsigned long) aindex);
1238 t = &string_type;
1239 subname = "rt_int";
1240 break;
1241 }
1242
1243 subfields = create_field (subfields, t,
1244 xasprintf (".fld[%lu].%s",
1245 (unsigned long) aindex,
1246 subname));
1247 subfields->opt = nodot;
1248 if (t == note_union_tp)
1249 subfields->opt = create_option (subfields->opt, "desc",
1250 "NOTE_KIND (&%0)");
1251 if (t == symbol_union_tp)
1252 subfields->opt = create_option (subfields->opt, "desc",
1253 "CONSTANT_POOL_ADDRESS_P (&%0)");
1254 }
1255
1256 if (i == SYMBOL_REF)
1257 {
1258 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
1259 type_p field_tp = find_structure ("block_symbol", 0);
1260 subfields
1261 = create_optional_field (subfields, field_tp, "block_sym",
1262 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
1263 }
1264
1265 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
1266 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1267
1268 ftag = xstrdup (rtx_name[i]);
1269 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1270 ftag[nmindex] = TOUPPER (ftag[nmindex]);
1271
1272 flds = create_field (flds, substruct, "");
1273 flds->opt = create_option (nodot, "tag", ftag);
1274 }
1275
1276 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
1277 }
1278
1279 /* Handle `special("tree_exp")'. This is a special case for
1280 field `operands' of struct tree_exp, which although it claims to contain
1281 pointers to trees, actually sometimes contains pointers to RTL too.
1282 Passed T, the old type of the field, and OPT its options. Returns
1283 a new type for the field. */
1284
1285 static type_p
1286 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
1287 {
1288 pair_p flds;
1289 options_p nodot;
1290
1291 if (t->kind != TYPE_ARRAY)
1292 {
1293 error_at_line (&lexer_line,
1294 "special `tree_exp' must be applied to an array");
1295 return &string_type;
1296 }
1297
1298 nodot = create_option (NULL, "dot", "");
1299
1300 flds = create_field (NULL, t, "");
1301 flds->opt = create_option (nodot, "length",
1302 "TREE_OPERAND_LENGTH ((tree) &%0)");
1303 flds->opt = create_option (flds->opt, "default", "");
1304
1305 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
1306 }
1307
1308 /* Perform any special processing on a type T, about to become the type
1309 of a field. Return the appropriate type for the field.
1310 At present:
1311 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
1312 - Similarly for arrays of pointer-to-char;
1313 - Converts structures for which a parameter is provided to
1314 TYPE_PARAM_STRUCT;
1315 - Handles "special" options.
1316 */
1317
1318 type_p
1319 adjust_field_type (type_p t, options_p opt)
1320 {
1321 int length_p = 0;
1322 const int pointer_p = t->kind == TYPE_POINTER;
1323 type_p params[NUM_PARAM];
1324 int params_p = 0;
1325 int i;
1326
1327 for (i = 0; i < NUM_PARAM; i++)
1328 params[i] = NULL;
1329
1330 for (; opt; opt = opt->next)
1331 if (strcmp (opt->name, "length") == 0)
1332 length_p = 1;
1333 else if (strcmp (opt->name, "param_is") == 0
1334 || (strncmp (opt->name, "param", 5) == 0
1335 && ISDIGIT (opt->name[5])
1336 && strcmp (opt->name + 6, "_is") == 0))
1337 {
1338 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
1339
1340 if (!UNION_OR_STRUCT_P (t)
1341 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
1342 {
1343 error_at_line (&lexer_line,
1344 "option `%s' may only be applied to structures or structure pointers",
1345 opt->name);
1346 return t;
1347 }
1348
1349 params_p = 1;
1350 if (params[num] != NULL)
1351 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
1352 if (!ISDIGIT (opt->name[5]))
1353 params[num] =
1354 create_pointer (CONST_CAST2 (type_p, const char *, opt->info));
1355 else
1356 params[num] = CONST_CAST2 (type_p, const char *, opt->info);
1357 }
1358 else if (strcmp (opt->name, "special") == 0)
1359 {
1360 const char *special_name = opt->info;
1361 if (strcmp (special_name, "tree_exp") == 0)
1362 t = adjust_field_tree_exp (t, opt);
1363 else if (strcmp (special_name, "rtx_def") == 0)
1364 t = adjust_field_rtx_def (t, opt);
1365 else
1366 error_at_line (&lexer_line, "unknown special `%s'", special_name);
1367 }
1368
1369 if (params_p)
1370 {
1371 type_p realt;
1372
1373 if (pointer_p)
1374 t = t->u.p;
1375 realt = find_param_structure (t, params);
1376 t = pointer_p ? create_pointer (realt) : realt;
1377 }
1378
1379 if (!length_p
1380 && pointer_p && t->u.p->kind == TYPE_SCALAR && t->u.p->u.scalar_is_char)
1381 return &string_type;
1382 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
1383 && t->u.a.p->u.p->kind == TYPE_SCALAR
1384 && t->u.a.p->u.p->u.scalar_is_char)
1385 return create_array (&string_type, t->u.a.len);
1386
1387 return t;
1388 }
1389 \f
1390
1391 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1392 static void set_gc_used (pair_p);
1393
1394 /* Handle OPT for set_gc_used_type. */
1395
1396 static void
1397 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
1398 int *pass_param, int *length, int *skip,
1399 type_p *nested_ptr)
1400 {
1401 options_p o;
1402 for (o = opt; o; o = o->next)
1403 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
1404 set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
1405 GC_POINTED_TO, NULL);
1406 else if (strcmp (o->name, "maybe_undef") == 0)
1407 *maybe_undef = 1;
1408 else if (strcmp (o->name, "use_params") == 0)
1409 *pass_param = 1;
1410 else if (strcmp (o->name, "length") == 0)
1411 *length = 1;
1412 else if (strcmp (o->name, "skip") == 0)
1413 *skip = 1;
1414 else if (strcmp (o->name, "nested_ptr") == 0)
1415 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
1416 }
1417
1418 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
1419
1420 static void
1421 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
1422 {
1423 if (t->gc_used >= level)
1424 return;
1425
1426 t->gc_used = level;
1427
1428 switch (t->kind)
1429 {
1430 case TYPE_STRUCT:
1431 case TYPE_UNION:
1432 {
1433 pair_p f;
1434 int dummy;
1435 type_p dummy2;
1436
1437 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
1438 &dummy2);
1439
1440 for (f = t->u.s.fields; f; f = f->next)
1441 {
1442 int maybe_undef = 0;
1443 int pass_param = 0;
1444 int length = 0;
1445 int skip = 0;
1446 type_p nested_ptr = NULL;
1447 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
1448 &length, &skip, &nested_ptr);
1449
1450 if (nested_ptr && f->type->kind == TYPE_POINTER)
1451 set_gc_used_type (nested_ptr, GC_POINTED_TO,
1452 pass_param ? param : NULL);
1453 else if (length && f->type->kind == TYPE_POINTER)
1454 set_gc_used_type (f->type->u.p, GC_USED, NULL);
1455 else if (maybe_undef && f->type->kind == TYPE_POINTER)
1456 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
1457 else if (pass_param && f->type->kind == TYPE_POINTER && param)
1458 set_gc_used_type (find_param_structure (f->type->u.p, param),
1459 GC_POINTED_TO, NULL);
1460 else if (skip)
1461 ; /* target type is not used through this field */
1462 else
1463 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
1464 }
1465 break;
1466 }
1467
1468 case TYPE_POINTER:
1469 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
1470 break;
1471
1472 case TYPE_ARRAY:
1473 set_gc_used_type (t->u.a.p, GC_USED, param);
1474 break;
1475
1476 case TYPE_LANG_STRUCT:
1477 for (t = t->u.s.lang_struct; t; t = t->next)
1478 set_gc_used_type (t, level, param);
1479 break;
1480
1481 case TYPE_PARAM_STRUCT:
1482 {
1483 int i;
1484 for (i = 0; i < NUM_PARAM; i++)
1485 if (t->u.param_struct.param[i] != 0)
1486 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
1487 }
1488 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
1489 level = GC_POINTED_TO;
1490 else
1491 level = GC_USED;
1492 t->u.param_struct.stru->gc_used = GC_UNUSED;
1493 set_gc_used_type (t->u.param_struct.stru, level,
1494 t->u.param_struct.param);
1495 break;
1496
1497 default:
1498 break;
1499 }
1500 }
1501
1502 /* Set the gc_used fields of all the types pointed to by VARIABLES. */
1503
1504 static void
1505 set_gc_used (pair_p variables)
1506 {
1507 int nbvars = 0;
1508 pair_p p;
1509 for (p = variables; p; p = p->next)
1510 {
1511 set_gc_used_type (p->type, GC_USED, NULL);
1512 nbvars++;
1513 };
1514 if (verbosity_level >= 2)
1515 printf ("%s used %d GTY-ed variables\n", progname, nbvars);
1516 }
1517 \f
1518 /* File mapping routines. For each input file, there is one output .c file
1519 (but some output files have many input files), and there is one .h file
1520 for the whole build. */
1521
1522 /* Output file handling. */
1523
1524 /* Create and return an outf_p for a new file for NAME, to be called
1525 ONAME. */
1526
1527 static outf_p
1528 create_file (const char *name, const char *oname)
1529 {
1530 static const char *const hdr[] = {
1531 " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
1532 "\n",
1533 "This file is part of GCC.\n",
1534 "\n",
1535 "GCC is free software; you can redistribute it and/or modify it under\n",
1536 "the terms of the GNU General Public License as published by the Free\n",
1537 "Software Foundation; either version 3, or (at your option) any later\n",
1538 "version.\n",
1539 "\n",
1540 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1541 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1542 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1543 "for more details.\n",
1544 "\n",
1545 "You should have received a copy of the GNU General Public License\n",
1546 "along with GCC; see the file COPYING3. If not see\n",
1547 "<http://www.gnu.org/licenses/>. */\n",
1548 "\n",
1549 "/* This file is machine generated. Do not edit. */\n"
1550 };
1551 outf_p f;
1552 size_t i;
1553
1554 gcc_assert (name != NULL);
1555 gcc_assert (oname != NULL);
1556 f = XCNEW (struct outf);
1557 f->next = output_files;
1558 f->name = oname;
1559 output_files = f;
1560
1561 oprintf (f, "/* Type information for %s.\n", name);
1562 for (i = 0; i < ARRAY_SIZE (hdr); i++)
1563 oprintf (f, "%s", hdr[i]);
1564 return f;
1565 }
1566
1567 /* Print, like fprintf, to O.
1568 N.B. You might think this could be implemented more efficiently
1569 with vsnprintf(). Unfortunately, there are C libraries that
1570 provide that function but without the C99 semantics for its return
1571 value, making it impossible to know how much space is required. */
1572 void
1573 oprintf (outf_p o, const char *format, ...)
1574 {
1575 char *s;
1576 size_t slength;
1577 va_list ap;
1578
1579 /* In plugin mode, the O could be a NULL pointer, so avoid crashing
1580 in that case. */
1581 if (!o)
1582 return;
1583
1584 va_start (ap, format);
1585 slength = vasprintf (&s, format, ap);
1586 if (s == NULL || (int) slength < 0)
1587 fatal ("out of memory");
1588 va_end (ap);
1589
1590 if (o->bufused + slength > o->buflength)
1591 {
1592 size_t new_len = o->buflength;
1593 if (new_len == 0)
1594 new_len = 1024;
1595 do
1596 {
1597 new_len *= 2;
1598 }
1599 while (o->bufused + slength >= new_len);
1600 o->buf = XRESIZEVEC (char, o->buf, new_len);
1601 o->buflength = new_len;
1602 }
1603 memcpy (o->buf + o->bufused, s, slength);
1604 o->bufused += slength;
1605 free (s);
1606 }
1607
1608 /* Open the global header file and the language-specific header files. */
1609
1610 static void
1611 open_base_files (void)
1612 {
1613 size_t i;
1614
1615 if (nb_plugin_files > 0 && plugin_files)
1616 return;
1617
1618 header_file = create_file ("GCC", "gtype-desc.h");
1619
1620 base_files = XNEWVEC (outf_p, num_lang_dirs);
1621
1622 for (i = 0; i < num_lang_dirs; i++)
1623 base_files[i] = create_file (lang_dir_names[i],
1624 xasprintf ("gtype-%s.h", lang_dir_names[i]));
1625
1626 /* gtype-desc.c is a little special, so we create it here. */
1627 {
1628 /* The order of files here matters very much. */
1629 static const char *const ifiles[] = {
1630 "config.h", "system.h", "coretypes.h", "tm.h",
1631 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1632 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1633 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1634 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1635 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1636 "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
1637 "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h", NULL
1638 };
1639 const char *const *ifp;
1640 outf_p gtype_desc_c;
1641
1642 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1643 for (ifp = ifiles; *ifp; ifp++)
1644 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1645
1646 /* Make sure we handle "cfun" specially. */
1647 oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n");
1648 oprintf (gtype_desc_c, "#undef cfun\n");
1649 }
1650 }
1651
1652 /* For F a filename, return the real basename of F, with all the directory
1653 components skipped. */
1654
1655 static const char *
1656 get_file_realbasename (const char *f)
1657 {
1658 const char *lastslash = strrchr (f, '/');
1659
1660 return (lastslash != NULL) ? lastslash + 1 : f;
1661 }
1662
1663 /* For F a filename, return the relative path to F from $(srcdir) if the
1664 latter is a prefix in F, NULL otherwise. */
1665
1666 static const char *
1667 get_file_srcdir_relative_path (const char *f)
1668 {
1669 if (strlen (f) > srcdir_len
1670 && IS_DIR_SEPARATOR (f[srcdir_len])
1671 && memcmp (f, srcdir, srcdir_len) == 0)
1672 return f + srcdir_len + 1;
1673 else
1674 return NULL;
1675 }
1676
1677 /* For F a filename, return the relative path to F from $(srcdir) if the
1678 latter is a prefix in F, or the real basename of F otherwise. */
1679
1680 static const char *
1681 get_file_basename (const char *f)
1682 {
1683 const char *srcdir_path = get_file_srcdir_relative_path (f);
1684
1685 return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
1686 }
1687
1688 /* For F a filename, return the lang_dir_names relative index of the language
1689 directory that is a prefix in F, if any, -1 otherwise. */
1690
1691 static int
1692 get_prefix_langdir_index (const char *f)
1693 {
1694 size_t f_len = strlen (f);
1695 size_t lang_index;
1696
1697 for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
1698 {
1699 const char *langdir = lang_dir_names[lang_index];
1700 size_t langdir_len = strlen (langdir);
1701
1702 if (f_len > langdir_len
1703 && IS_DIR_SEPARATOR (f[langdir_len])
1704 && memcmp (f, langdir, langdir_len) == 0)
1705 return lang_index;
1706 }
1707
1708 return -1;
1709 }
1710
1711 /* For F a filename, return the name of language directory where F is located,
1712 if any, NULL otherwise. */
1713
1714 static const char *
1715 get_file_langdir (const char *f)
1716 {
1717 /* Get the relative path to F from $(srcdir) and find the language by
1718 comparing the prefix with language directory names. If F is not even
1719 srcdir relative, no point in looking further. */
1720
1721 int lang_index;
1722 const char *srcdir_relative_path = get_file_srcdir_relative_path (f);
1723 const char *r;
1724
1725 if (!srcdir_relative_path)
1726 return NULL;
1727
1728 lang_index = get_prefix_langdir_index (srcdir_relative_path);
1729 if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
1730 r = "c-family";
1731 else if (lang_index >= 0)
1732 r = lang_dir_names[lang_index];
1733 else
1734 r = NULL;
1735
1736 return r;
1737 }
1738
1739 /* The gt- output file name for F. */
1740
1741 static const char *
1742 get_file_gtfilename (const char *f)
1743 {
1744 /* Cook up an initial version of the gt- file name from the file real
1745 basename and the language name, if any. */
1746
1747 const char *basename = get_file_realbasename (f);
1748 const char *langdir = get_file_langdir (f);
1749
1750 char *result =
1751 (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
1752 : xasprintf ("gt-%s", basename));
1753
1754 /* Then replace all non alphanumerics characters by '-' and change the
1755 extension to ".h". We expect the input filename extension was at least
1756 one character long. */
1757
1758 char *s = result;
1759
1760 for (; *s != '.'; s++)
1761 if (!ISALNUM (*s) && *s != '-')
1762 *s = '-';
1763
1764 memcpy (s, ".h", sizeof (".h"));
1765
1766 return result;
1767 }
1768
1769 /* An output file, suitable for definitions, that can see declarations
1770 made in INPUT_FILE and is linked into every language that uses
1771 INPUT_FILE. */
1772
1773 outf_p
1774 get_output_file_with_visibility (const char *input_file)
1775 {
1776 outf_p r;
1777 size_t len;
1778 const char *basename;
1779 const char *for_name;
1780 const char *output_name;
1781
1782 /* This can happen when we need a file with visibility on a
1783 structure that we've never seen. We have to just hope that it's
1784 globally visible. */
1785 if (input_file == NULL)
1786 input_file = "system.h";
1787
1788 /* In plugin mode, return NULL unless the input_file is one of the
1789 plugin_files. */
1790 if (plugin_files)
1791 {
1792 size_t i;
1793 for (i = 0; i < nb_plugin_files; i++)
1794 if (strcmp (input_file, plugin_files[i]) == 0)
1795 return plugin_output;
1796
1797 return NULL;
1798 }
1799
1800 /* Determine the output file name. */
1801 basename = get_file_basename (input_file);
1802
1803 len = strlen (basename);
1804 if ((len > 2 && memcmp (basename + len - 2, ".c", 2) == 0)
1805 || (len > 2 && memcmp (basename + len - 2, ".y", 2) == 0)
1806 || (len > 3 && memcmp (basename + len - 3, ".in", 3) == 0))
1807 {
1808 output_name = get_file_gtfilename (input_file);
1809 for_name = basename;
1810 }
1811 /* Some headers get used by more than one front-end; hence, it
1812 would be inappropriate to spew them out to a single gtype-<lang>.h
1813 (and gengtype doesn't know how to direct spewage into multiple
1814 gtype-<lang>.h headers at this time). Instead, we pair up these
1815 headers with source files (and their special purpose gt-*.h headers). */
1816 else if (strncmp (basename, "c-family", 8) == 0
1817 && IS_DIR_SEPARATOR (basename[8])
1818 && strcmp (basename + 9, "c-common.h") == 0)
1819 output_name = "gt-c-family-c-common.h", for_name = "c-family/c-common.c";
1820 else if (strcmp (basename, "c-lang.h") == 0)
1821 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1822 else if (strcmp (basename, "c-tree.h") == 0)
1823 output_name = "gt-c-decl.h", for_name = "c-decl.c";
1824 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1825 && strcmp (basename + 3, "cp-tree.h") == 0)
1826 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1827 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1828 && strcmp (basename + 3, "decl.h") == 0)
1829 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1830 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1831 && strcmp (basename + 3, "name-lookup.h") == 0)
1832 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1833 else if (strncmp (basename, "objc", 4) == 0
1834 && IS_DIR_SEPARATOR (basename[4])
1835 && strcmp (basename + 5, "objc-act.h") == 0)
1836 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1837 else
1838 {
1839 int lang_index = get_prefix_langdir_index (basename);
1840
1841 if (lang_index >= 0)
1842 return base_files[lang_index];
1843
1844 output_name = "gtype-desc.c";
1845 for_name = NULL;
1846 }
1847
1848 /* Look through to see if we've ever seen this output filename before. */
1849 for (r = output_files; r; r = r->next)
1850 if (strcmp (r->name, output_name) == 0)
1851 return r;
1852
1853 /* If not, create it. */
1854 r = create_file (for_name, output_name);
1855
1856 gcc_assert (r && r->name);
1857 return r;
1858 }
1859
1860 /* The name of an output file, suitable for definitions, that can see
1861 declarations made in INPUT_FILE and is linked into every language
1862 that uses INPUT_FILE. */
1863
1864 const char *
1865 get_output_file_name (const char *input_file)
1866 {
1867 outf_p o = get_output_file_with_visibility (input_file);
1868 if (o)
1869 return o->name;
1870 return NULL;
1871 }
1872
1873 /* Check if existing file is equal to the in memory buffer. */
1874
1875 static bool
1876 is_file_equal (outf_p of)
1877 {
1878 FILE *newfile = fopen (of->name, "r");
1879 size_t i;
1880 bool equal;
1881 if (newfile == NULL)
1882 return false;
1883
1884 equal = true;
1885 for (i = 0; i < of->bufused; i++)
1886 {
1887 int ch;
1888 ch = fgetc (newfile);
1889 if (ch == EOF || ch != (unsigned char) of->buf[i])
1890 {
1891 equal = false;
1892 break;
1893 }
1894 }
1895 fclose (newfile);
1896 return equal;
1897 }
1898
1899 /* Copy the output to its final destination,
1900 but don't unnecessarily change modification times. */
1901
1902 static void
1903 close_output_files (void)
1904 {
1905 int nbwrittenfiles = 0;
1906 outf_p of;
1907
1908 for (of = output_files; of; of = of->next)
1909 {
1910
1911 if (!is_file_equal (of))
1912 {
1913 FILE *newfile = NULL;
1914 char *backupname = NULL;
1915 /* Back up the old version of the output file gt-FOO.c as
1916 BACKUPDIR/gt-FOO.c~ if we have a backup directory. */
1917 if (backup_dir)
1918 {
1919 backupname = concat (backup_dir, "/",
1920 lbasename (of->name), "~", NULL);
1921 if (!access (of->name, F_OK) && rename (of->name, backupname))
1922 fatal ("failed to back up %s as %s: %s",
1923 of->name, backupname, xstrerror (errno));
1924 }
1925
1926 newfile = fopen (of->name, "w");
1927 if (newfile == NULL)
1928 fatal ("opening output file %s: %s", of->name, xstrerror (errno));
1929 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1930 fatal ("writing output file %s: %s", of->name, xstrerror (errno));
1931 if (fclose (newfile) != 0)
1932 fatal ("closing output file %s: %s", of->name, xstrerror (errno));
1933 nbwrittenfiles++;
1934 if (verbosity_level >= 2 && backupname)
1935 printf ("%s wrote #%-3d %s backed-up in %s\n",
1936 progname, nbwrittenfiles, of->name, backupname);
1937 else if (verbosity_level >= 1)
1938 printf ("%s write #%-3d %s\n", progname, nbwrittenfiles, of->name);
1939 free (backupname);
1940 }
1941 else
1942 {
1943 /* output file remains unchanged. */
1944 if (verbosity_level >= 2)
1945 printf ("%s keep %s\n", progname, of->name);
1946 }
1947 free (of->buf);
1948 of->buf = NULL;
1949 of->bufused = of->buflength = 0;
1950 }
1951 if (verbosity_level >= 1)
1952 printf ("%s wrote %d files.\n", progname, nbwrittenfiles);
1953 }
1954 \f
1955 struct flist
1956 {
1957 struct flist *next;
1958 int started_p;
1959 const char *name;
1960 outf_p f;
1961 };
1962
1963 struct walk_type_data;
1964
1965 /* For scalars and strings, given the item in 'val'.
1966 For structures, given a pointer to the item in 'val'.
1967 For misc. pointers, given the item in 'val'.
1968 */
1969 typedef void (*process_field_fn) (type_p f, const struct walk_type_data * p);
1970 typedef void (*func_name_fn) (type_p s, const struct walk_type_data * p);
1971
1972 /* Parameters for write_types. */
1973
1974 struct write_types_data
1975 {
1976 const char *prefix;
1977 const char *param_prefix;
1978 const char *subfield_marker_routine;
1979 const char *marker_routine;
1980 const char *reorder_note_routine;
1981 const char *comment;
1982 int skip_hooks; /* skip hook generation if non zero */
1983 };
1984
1985 static void output_escaped_param (struct walk_type_data *d,
1986 const char *, const char *);
1987 static void output_mangled_typename (outf_p, const_type_p);
1988 static void walk_type (type_p t, struct walk_type_data *d);
1989 static void write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1990 const struct write_types_data *wtd);
1991 static void write_types_process_field
1992 (type_p f, const struct walk_type_data *d);
1993 static void write_types (outf_p output_header,
1994 type_p structures,
1995 type_p param_structs,
1996 const struct write_types_data *wtd);
1997 static void write_types_local_process_field
1998 (type_p f, const struct walk_type_data *d);
1999 static void write_local_func_for_structure
2000 (const_type_p orig_s, type_p s, type_p *param);
2001 static void write_local (outf_p output_header,
2002 type_p structures, type_p param_structs);
2003 static void write_enum_defn (type_p structures, type_p param_structs);
2004 static int contains_scalar_p (type_p t);
2005 static void put_mangled_filename (outf_p, const char *);
2006 static void finish_root_table (struct flist *flp, const char *pfx,
2007 const char *tname, const char *lastname,
2008 const char *name);
2009 static void write_root (outf_p, pair_p, type_p, const char *, int,
2010 struct fileloc *, const char *, bool);
2011 static void write_array (outf_p f, pair_p v,
2012 const struct write_types_data *wtd);
2013 static void write_roots (pair_p, bool);
2014
2015 /* Parameters for walk_type. */
2016
2017 struct walk_type_data
2018 {
2019 process_field_fn process_field;
2020 const void *cookie;
2021 outf_p of;
2022 options_p opt;
2023 const char *val;
2024 const char *prev_val[4];
2025 int indent;
2026 int counter;
2027 const struct fileloc *line;
2028 lang_bitmap bitmap;
2029 type_p *param;
2030 int used_length;
2031 type_p orig_s;
2032 const char *reorder_fn;
2033 bool needs_cast_p;
2034 bool fn_wants_lvalue;
2035 };
2036
2037 /* Print a mangled name representing T to OF. */
2038
2039 static void
2040 output_mangled_typename (outf_p of, const_type_p t)
2041 {
2042 if (t == NULL)
2043 oprintf (of, "Z");
2044 else
2045 switch (t->kind)
2046 {
2047 case TYPE_POINTER:
2048 oprintf (of, "P");
2049 output_mangled_typename (of, t->u.p);
2050 break;
2051 case TYPE_SCALAR:
2052 oprintf (of, "I");
2053 break;
2054 case TYPE_STRING:
2055 oprintf (of, "S");
2056 break;
2057 case TYPE_STRUCT:
2058 case TYPE_UNION:
2059 case TYPE_LANG_STRUCT:
2060 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
2061 t->u.s.tag);
2062 break;
2063 case TYPE_PARAM_STRUCT:
2064 {
2065 int i;
2066 for (i = 0; i < NUM_PARAM; i++)
2067 if (t->u.param_struct.param[i] != NULL)
2068 output_mangled_typename (of, t->u.param_struct.param[i]);
2069 output_mangled_typename (of, t->u.param_struct.stru);
2070 }
2071 break;
2072 case TYPE_ARRAY:
2073 gcc_unreachable ();
2074 }
2075 }
2076
2077 /* Print PARAM to D->OF processing escapes. D->VAL references the
2078 current object, D->PREV_VAL the object containing the current
2079 object, ONAME is the name of the option and D->LINE is used to
2080 print error messages. */
2081
2082 static void
2083 output_escaped_param (struct walk_type_data *d, const char *param,
2084 const char *oname)
2085 {
2086 const char *p;
2087
2088 for (p = param; *p; p++)
2089 if (*p != '%')
2090 oprintf (d->of, "%c", *p);
2091 else
2092 switch (*++p)
2093 {
2094 case 'h':
2095 oprintf (d->of, "(%s)", d->prev_val[2]);
2096 break;
2097 case '0':
2098 oprintf (d->of, "(%s)", d->prev_val[0]);
2099 break;
2100 case '1':
2101 oprintf (d->of, "(%s)", d->prev_val[1]);
2102 break;
2103 case 'a':
2104 {
2105 const char *pp = d->val + strlen (d->val);
2106 while (pp[-1] == ']')
2107 while (*pp != '[')
2108 pp--;
2109 oprintf (d->of, "%s", pp);
2110 }
2111 break;
2112 default:
2113 error_at_line (d->line, "`%s' option contains bad escape %c%c",
2114 oname, '%', *p);
2115 }
2116 }
2117
2118 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
2119 which is of type T. Write code to D->OF to constrain execution (at
2120 the point that D->PROCESS_FIELD is called) to the appropriate
2121 cases. Call D->PROCESS_FIELD on subobjects before calling it on
2122 pointers to those objects. D->PREV_VAL lists the objects
2123 containing the current object, D->OPT is a list of options to
2124 apply, D->INDENT is the current indentation level, D->LINE is used
2125 to print error messages, D->BITMAP indicates which languages to
2126 print the structure for, and D->PARAM is the current parameter
2127 (from an enclosing param_is option). */
2128
2129 static void
2130 walk_type (type_p t, struct walk_type_data *d)
2131 {
2132 const char *length = NULL;
2133 const char *desc = NULL;
2134 int maybe_undef_p = 0;
2135 int use_param_num = -1;
2136 int use_params_p = 0;
2137 options_p oo;
2138 const struct nested_ptr_data *nested_ptr_d = NULL;
2139
2140 d->needs_cast_p = false;
2141 for (oo = d->opt; oo; oo = oo->next)
2142 if (strcmp (oo->name, "length") == 0)
2143 length = oo->info;
2144 else if (strcmp (oo->name, "maybe_undef") == 0)
2145 maybe_undef_p = 1;
2146 else if (strncmp (oo->name, "use_param", 9) == 0
2147 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2148 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
2149 else if (strcmp (oo->name, "use_params") == 0)
2150 use_params_p = 1;
2151 else if (strcmp (oo->name, "desc") == 0)
2152 desc = oo->info;
2153 else if (strcmp (oo->name, "mark_hook") == 0)
2154 ;
2155 else if (strcmp (oo->name, "nested_ptr") == 0)
2156 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
2157 else if (strcmp (oo->name, "dot") == 0)
2158 ;
2159 else if (strcmp (oo->name, "tag") == 0)
2160 ;
2161 else if (strcmp (oo->name, "special") == 0)
2162 ;
2163 else if (strcmp (oo->name, "skip") == 0)
2164 ;
2165 else if (strcmp (oo->name, "default") == 0)
2166 ;
2167 else if (strcmp (oo->name, "param_is") == 0)
2168 ;
2169 else if (strncmp (oo->name, "param", 5) == 0
2170 && ISDIGIT (oo->name[5]) && strcmp (oo->name + 6, "_is") == 0)
2171 ;
2172 else if (strcmp (oo->name, "chain_next") == 0)
2173 ;
2174 else if (strcmp (oo->name, "chain_prev") == 0)
2175 ;
2176 else if (strcmp (oo->name, "chain_circular") == 0)
2177 ;
2178 else if (strcmp (oo->name, "reorder") == 0)
2179 ;
2180 else if (strcmp (oo->name, "variable_size") == 0)
2181 ;
2182 else
2183 error_at_line (d->line, "unknown option `%s'\n", oo->name);
2184
2185 if (d->used_length)
2186 length = NULL;
2187
2188 if (use_params_p)
2189 {
2190 int pointer_p = t->kind == TYPE_POINTER;
2191
2192 if (pointer_p)
2193 t = t->u.p;
2194 if (!UNION_OR_STRUCT_P (t))
2195 error_at_line (d->line, "`use_params' option on unimplemented type");
2196 else
2197 t = find_param_structure (t, d->param);
2198 if (pointer_p)
2199 t = create_pointer (t);
2200 }
2201
2202 if (use_param_num != -1)
2203 {
2204 if (d->param != NULL && d->param[use_param_num] != NULL)
2205 {
2206 type_p nt = d->param[use_param_num];
2207
2208 if (t->kind == TYPE_ARRAY)
2209 nt = create_array (nt, t->u.a.len);
2210 else if (length != NULL && t->kind == TYPE_POINTER)
2211 nt = create_pointer (nt);
2212 d->needs_cast_p = (t->kind != TYPE_POINTER
2213 && (nt->kind == TYPE_POINTER
2214 || nt->kind == TYPE_STRING));
2215 t = nt;
2216 }
2217 else
2218 error_at_line (d->line, "no parameter defined for `%s'", d->val);
2219 }
2220
2221 if (maybe_undef_p
2222 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
2223 {
2224 error_at_line (d->line,
2225 "field `%s' has invalid option `maybe_undef_p'\n",
2226 d->val);
2227 return;
2228 }
2229
2230 switch (t->kind)
2231 {
2232 case TYPE_SCALAR:
2233 case TYPE_STRING:
2234 d->process_field (t, d);
2235 break;
2236
2237 case TYPE_POINTER:
2238 {
2239 if (maybe_undef_p && t->u.p->u.s.line.file == NULL)
2240 {
2241 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2242 break;
2243 }
2244
2245 if (!length)
2246 {
2247 if (!UNION_OR_STRUCT_P (t->u.p)
2248 && t->u.p->kind != TYPE_PARAM_STRUCT)
2249 {
2250 error_at_line (d->line,
2251 "field `%s' is pointer to unimplemented type",
2252 d->val);
2253 break;
2254 }
2255
2256 if (nested_ptr_d)
2257 {
2258 const char *oldprevval2 = d->prev_val[2];
2259
2260 if (!UNION_OR_STRUCT_P (nested_ptr_d->type))
2261 {
2262 error_at_line (d->line,
2263 "field `%s' has invalid "
2264 "option `nested_ptr'\n", d->val);
2265 return;
2266 }
2267
2268 d->prev_val[2] = d->val;
2269 oprintf (d->of, "%*s{\n", d->indent, "");
2270 d->indent += 2;
2271 d->val = xasprintf ("x%d", d->counter++);
2272 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2273 (nested_ptr_d->type->kind == TYPE_UNION
2274 ? "union" : "struct"),
2275 nested_ptr_d->type->u.s.tag,
2276 d->fn_wants_lvalue ? "" : "const ", d->val);
2277 oprintf (d->of, "%*s", d->indent + 2, "");
2278 output_escaped_param (d, nested_ptr_d->convert_from,
2279 "nested_ptr");
2280 oprintf (d->of, ";\n");
2281
2282 d->process_field (nested_ptr_d->type, d);
2283
2284 if (d->fn_wants_lvalue)
2285 {
2286 oprintf (d->of, "%*s%s = ", d->indent, "",
2287 d->prev_val[2]);
2288 d->prev_val[2] = d->val;
2289 output_escaped_param (d, nested_ptr_d->convert_to,
2290 "nested_ptr");
2291 oprintf (d->of, ";\n");
2292 }
2293
2294 d->indent -= 2;
2295 oprintf (d->of, "%*s}\n", d->indent, "");
2296 d->val = d->prev_val[2];
2297 d->prev_val[2] = oldprevval2;
2298 }
2299 else
2300 d->process_field (t->u.p, d);
2301 }
2302 else
2303 {
2304 int loopcounter = d->counter++;
2305 const char *oldval = d->val;
2306 const char *oldprevval3 = d->prev_val[3];
2307 char *newval;
2308
2309 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2310 d->indent += 2;
2311 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2312 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
2313 "", loopcounter, loopcounter);
2314 output_escaped_param (d, length, "length");
2315 oprintf (d->of, "); i%d++) {\n", loopcounter);
2316 d->indent += 2;
2317 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2318 d->used_length = 1;
2319 d->prev_val[3] = oldval;
2320 walk_type (t->u.p, d);
2321 free (newval);
2322 d->val = oldval;
2323 d->prev_val[3] = oldprevval3;
2324 d->used_length = 0;
2325 d->indent -= 2;
2326 oprintf (d->of, "%*s}\n", d->indent, "");
2327 d->process_field (t, d);
2328 d->indent -= 2;
2329 oprintf (d->of, "%*s}\n", d->indent, "");
2330 }
2331 }
2332 break;
2333
2334 case TYPE_ARRAY:
2335 {
2336 int loopcounter = d->counter++;
2337 const char *oldval = d->val;
2338 char *newval;
2339
2340 /* If it's an array of scalars, we optimize by not generating
2341 any code. */
2342 if (t->u.a.p->kind == TYPE_SCALAR)
2343 break;
2344
2345 /* When walking an array, compute the length and store it in a
2346 local variable before walking the array elements, instead of
2347 recomputing the length expression each time through the loop.
2348 This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2349 where the length is stored in the first array element,
2350 because otherwise that operand can get overwritten on the
2351 first iteration. */
2352 oprintf (d->of, "%*s{\n", d->indent, "");
2353 d->indent += 2;
2354 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2355 oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2356 d->indent, "", loopcounter);
2357 if (length)
2358 output_escaped_param (d, length, "length");
2359 else
2360 oprintf (d->of, "%s", t->u.a.len);
2361 oprintf (d->of, ");\n");
2362
2363 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2364 d->indent, "",
2365 loopcounter, loopcounter, loopcounter, loopcounter);
2366 d->indent += 2;
2367 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2368 d->used_length = 1;
2369 walk_type (t->u.a.p, d);
2370 free (newval);
2371 d->used_length = 0;
2372 d->val = oldval;
2373 d->indent -= 2;
2374 oprintf (d->of, "%*s}\n", d->indent, "");
2375 d->indent -= 2;
2376 oprintf (d->of, "%*s}\n", d->indent, "");
2377 }
2378 break;
2379
2380 case TYPE_STRUCT:
2381 case TYPE_UNION:
2382 {
2383 pair_p f;
2384 const char *oldval = d->val;
2385 const char *oldprevval1 = d->prev_val[1];
2386 const char *oldprevval2 = d->prev_val[2];
2387 const int union_p = t->kind == TYPE_UNION;
2388 int seen_default_p = 0;
2389 options_p o;
2390
2391 if (!t->u.s.line.file)
2392 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2393
2394 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2395 {
2396 error_at_line (d->line,
2397 "structure `%s' defined for mismatching languages",
2398 t->u.s.tag);
2399 error_at_line (&t->u.s.line, "one structure defined here");
2400 }
2401
2402 /* Some things may also be defined in the structure's options. */
2403 for (o = t->u.s.opt; o; o = o->next)
2404 if (!desc && strcmp (o->name, "desc") == 0)
2405 desc = o->info;
2406
2407 d->prev_val[2] = oldval;
2408 d->prev_val[1] = oldprevval2;
2409 if (union_p)
2410 {
2411 if (desc == NULL)
2412 {
2413 error_at_line (d->line,
2414 "missing `desc' option for union `%s'",
2415 t->u.s.tag);
2416 desc = "1";
2417 }
2418 oprintf (d->of, "%*sswitch (", d->indent, "");
2419 output_escaped_param (d, desc, "desc");
2420 oprintf (d->of, ")\n");
2421 d->indent += 2;
2422 oprintf (d->of, "%*s{\n", d->indent, "");
2423 }
2424 for (f = t->u.s.fields; f; f = f->next)
2425 {
2426 options_p oo;
2427 const char *dot = ".";
2428 const char *tagid = NULL;
2429 int skip_p = 0;
2430 int default_p = 0;
2431 int use_param_p = 0;
2432 char *newval;
2433
2434 d->reorder_fn = NULL;
2435 for (oo = f->opt; oo; oo = oo->next)
2436 if (strcmp (oo->name, "dot") == 0)
2437 dot = oo->info;
2438 else if (strcmp (oo->name, "tag") == 0)
2439 tagid = oo->info;
2440 else if (strcmp (oo->name, "skip") == 0)
2441 skip_p = 1;
2442 else if (strcmp (oo->name, "default") == 0)
2443 default_p = 1;
2444 else if (strcmp (oo->name, "reorder") == 0)
2445 d->reorder_fn = oo->info;
2446 else if (strncmp (oo->name, "use_param", 9) == 0
2447 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2448 use_param_p = 1;
2449
2450 if (skip_p)
2451 continue;
2452
2453 if (union_p && tagid)
2454 {
2455 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2456 d->indent += 2;
2457 }
2458 else if (union_p && default_p)
2459 {
2460 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2461 d->indent += 2;
2462 seen_default_p = 1;
2463 }
2464 else if (!union_p && (default_p || tagid))
2465 error_at_line (d->line,
2466 "can't use `%s' outside a union on field `%s'",
2467 default_p ? "default" : "tag", f->name);
2468 else if (union_p && !(default_p || tagid)
2469 && f->type->kind == TYPE_SCALAR)
2470 {
2471 fprintf (stderr,
2472 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2473 d->line->file, d->line->line, f->name);
2474 continue;
2475 }
2476 else if (union_p && !(default_p || tagid))
2477 error_at_line (d->line,
2478 "field `%s' is missing `tag' or `default' option",
2479 f->name);
2480
2481 d->line = &f->line;
2482 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2483 d->opt = f->opt;
2484 d->used_length = false;
2485
2486 if (union_p && use_param_p && d->param == NULL)
2487 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2488 else
2489 walk_type (f->type, d);
2490
2491 free (newval);
2492
2493 if (union_p)
2494 {
2495 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2496 d->indent -= 2;
2497 }
2498 }
2499 d->reorder_fn = NULL;
2500
2501 d->val = oldval;
2502 d->prev_val[1] = oldprevval1;
2503 d->prev_val[2] = oldprevval2;
2504
2505 if (union_p && !seen_default_p)
2506 {
2507 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2508 oprintf (d->of, "%*s break;\n", d->indent, "");
2509 }
2510 if (union_p)
2511 {
2512 oprintf (d->of, "%*s}\n", d->indent, "");
2513 d->indent -= 2;
2514 }
2515 }
2516 break;
2517
2518 case TYPE_LANG_STRUCT:
2519 {
2520 type_p nt;
2521 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2522 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2523 break;
2524 if (nt == NULL)
2525 error_at_line (d->line, "structure `%s' differs between languages",
2526 t->u.s.tag);
2527 else
2528 walk_type (nt, d);
2529 }
2530 break;
2531
2532 case TYPE_PARAM_STRUCT:
2533 {
2534 type_p *oldparam = d->param;
2535
2536 d->param = t->u.param_struct.param;
2537 walk_type (t->u.param_struct.stru, d);
2538 d->param = oldparam;
2539 }
2540 break;
2541
2542 default:
2543 gcc_unreachable ();
2544 }
2545 }
2546
2547 /* process_field routine for marking routines. */
2548
2549 static void
2550 write_types_process_field (type_p f, const struct walk_type_data *d)
2551 {
2552 const struct write_types_data *wtd;
2553 const char *cast = d->needs_cast_p ? "(void *)" : "";
2554 wtd = (const struct write_types_data *) d->cookie;
2555
2556 switch (f->kind)
2557 {
2558 case TYPE_POINTER:
2559 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2560 wtd->subfield_marker_routine, cast, d->val);
2561 if (wtd->param_prefix)
2562 {
2563 oprintf (d->of, ", %s", d->prev_val[3]);
2564 if (d->orig_s)
2565 {
2566 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2567 output_mangled_typename (d->of, d->orig_s);
2568 }
2569 else
2570 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2571
2572 if (f->u.p->kind == TYPE_PARAM_STRUCT
2573 && f->u.p->u.s.line.file != NULL)
2574 {
2575 oprintf (d->of, ", gt_e_");
2576 output_mangled_typename (d->of, f);
2577 }
2578 else if (UNION_OR_STRUCT_P (f) && f->u.p->u.s.line.file != NULL)
2579 {
2580 oprintf (d->of, ", gt_ggc_e_");
2581 output_mangled_typename (d->of, f);
2582 }
2583 else
2584 oprintf (d->of, ", gt_types_enum_last");
2585 }
2586 oprintf (d->of, ");\n");
2587 if (d->reorder_fn && wtd->reorder_note_routine)
2588 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2589 wtd->reorder_note_routine, cast, d->val,
2590 d->prev_val[3], d->reorder_fn);
2591 break;
2592
2593 case TYPE_STRING:
2594 case TYPE_STRUCT:
2595 case TYPE_UNION:
2596 case TYPE_LANG_STRUCT:
2597 case TYPE_PARAM_STRUCT:
2598 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2599 output_mangled_typename (d->of, f);
2600 oprintf (d->of, " (%s%s);\n", cast, d->val);
2601 if (d->reorder_fn && wtd->reorder_note_routine)
2602 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2603 wtd->reorder_note_routine, cast, d->val, cast, d->val,
2604 d->reorder_fn);
2605 break;
2606
2607 case TYPE_SCALAR:
2608 break;
2609
2610 default:
2611 gcc_unreachable ();
2612 }
2613 }
2614
2615 /* A subroutine of write_func_for_structure. Write the enum tag for S. */
2616
2617 static void
2618 output_type_enum (outf_p of, type_p s)
2619 {
2620 if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.file != NULL)
2621 {
2622 oprintf (of, ", gt_e_");
2623 output_mangled_typename (of, s);
2624 }
2625 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2626 {
2627 oprintf (of, ", gt_ggc_e_");
2628 output_mangled_typename (of, s);
2629 }
2630 else
2631 oprintf (of, ", gt_types_enum_last");
2632 }
2633
2634 /* Return an output file that is suitable for definitions which can
2635 reference struct S */
2636
2637 static outf_p
2638 get_output_file_for_structure (const_type_p s, type_p *param)
2639 {
2640 const char *fn = s->u.s.line.file;
2641 int i;
2642
2643 /* This is a hack, and not the good kind either. */
2644 for (i = NUM_PARAM - 1; i >= 0; i--)
2645 if (param && param[i] && param[i]->kind == TYPE_POINTER
2646 && UNION_OR_STRUCT_P (param[i]->u.p))
2647 fn = param[i]->u.p->u.s.line.file;
2648
2649 return get_output_file_with_visibility (fn);
2650 }
2651
2652 /* For S, a structure that's part of ORIG_S, and using parameters
2653 PARAM, write out a routine that:
2654 - Takes a parameter, a void * but actually of type *S
2655 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2656 field of S or its substructures and (in some cases) things
2657 that are pointed to by S.
2658 */
2659
2660 static void
2661 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2662 const struct write_types_data *wtd)
2663 {
2664 const char *chain_next = NULL;
2665 const char *chain_prev = NULL;
2666 const char *chain_circular = NULL;
2667 const char *mark_hook_name = NULL;
2668 options_p opt;
2669 struct walk_type_data d;
2670
2671 memset (&d, 0, sizeof (d));
2672 d.of = get_output_file_for_structure (s, param);
2673
2674 for (opt = s->u.s.opt; opt; opt = opt->next)
2675 if (strcmp (opt->name, "chain_next") == 0)
2676 chain_next = opt->info;
2677 else if (strcmp (opt->name, "chain_prev") == 0)
2678 chain_prev = opt->info;
2679 else if (strcmp (opt->name, "chain_circular") == 0)
2680 chain_circular = opt->info;
2681 else if (strcmp (opt->name, "mark_hook") == 0)
2682 mark_hook_name = opt->info;
2683
2684 if (chain_prev != NULL && chain_next == NULL)
2685 error_at_line (&s->u.s.line, "chain_prev without chain_next");
2686 if (chain_circular != NULL && chain_next != NULL)
2687 error_at_line (&s->u.s.line, "chain_circular with chain_next");
2688 if (chain_circular != NULL)
2689 chain_next = chain_circular;
2690
2691 d.process_field = write_types_process_field;
2692 d.cookie = wtd;
2693 d.orig_s = orig_s;
2694 d.opt = s->u.s.opt;
2695 d.line = &s->u.s.line;
2696 d.bitmap = s->u.s.bitmap;
2697 d.param = param;
2698 d.prev_val[0] = "*x";
2699 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2700 d.prev_val[3] = "x";
2701 d.val = "(*x)";
2702
2703 oprintf (d.of, "\n");
2704 oprintf (d.of, "void\n");
2705 if (param == NULL)
2706 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2707 else
2708 {
2709 oprintf (d.of, "gt_%s_", wtd->prefix);
2710 output_mangled_typename (d.of, orig_s);
2711 }
2712 oprintf (d.of, " (void *x_p)\n");
2713 oprintf (d.of, "{\n");
2714 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
2715 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2716 chain_next == NULL ? "const " : "",
2717 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2718 if (chain_next != NULL)
2719 oprintf (d.of, " %s %s * xlimit = x;\n",
2720 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2721 if (chain_next == NULL)
2722 {
2723 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2724 if (wtd->param_prefix)
2725 {
2726 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2727 output_mangled_typename (d.of, orig_s);
2728 output_type_enum (d.of, orig_s);
2729 }
2730 oprintf (d.of, "))\n");
2731 }
2732 else
2733 {
2734 if (chain_circular != NULL)
2735 oprintf (d.of, " if (!%s (xlimit", wtd->marker_routine);
2736 else
2737 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2738 if (wtd->param_prefix)
2739 {
2740 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2741 output_mangled_typename (d.of, orig_s);
2742 output_type_enum (d.of, orig_s);
2743 }
2744 oprintf (d.of, "))\n");
2745 if (chain_circular != NULL)
2746 oprintf (d.of, " return;\n do\n");
2747 if (mark_hook_name && !wtd->skip_hooks)
2748 {
2749 oprintf (d.of, " {\n");
2750 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2751 }
2752 oprintf (d.of, " xlimit = (");
2753 d.prev_val[2] = "*xlimit";
2754 output_escaped_param (&d, chain_next, "chain_next");
2755 oprintf (d.of, ");\n");
2756 if (mark_hook_name && !wtd->skip_hooks)
2757 oprintf (d.of, " }\n");
2758 if (chain_prev != NULL)
2759 {
2760 oprintf (d.of, " if (x != xlimit)\n");
2761 oprintf (d.of, " for (;;)\n");
2762 oprintf (d.of, " {\n");
2763 oprintf (d.of, " %s %s * const xprev = (",
2764 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2765
2766 d.prev_val[2] = "*x";
2767 output_escaped_param (&d, chain_prev, "chain_prev");
2768 oprintf (d.of, ");\n");
2769 oprintf (d.of, " if (xprev == NULL) break;\n");
2770 oprintf (d.of, " x = xprev;\n");
2771 oprintf (d.of, " (void) %s (xprev", wtd->marker_routine);
2772 if (wtd->param_prefix)
2773 {
2774 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2775 output_mangled_typename (d.of, orig_s);
2776 output_type_enum (d.of, orig_s);
2777 }
2778 oprintf (d.of, ");\n");
2779 oprintf (d.of, " }\n");
2780 }
2781 if (chain_circular != NULL)
2782 {
2783 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2784 if (wtd->param_prefix)
2785 {
2786 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2787 output_mangled_typename (d.of, orig_s);
2788 output_type_enum (d.of, orig_s);
2789 }
2790 oprintf (d.of, "));\n");
2791 if (mark_hook_name && !wtd->skip_hooks)
2792 oprintf (d.of, " %s (xlimit);\n", mark_hook_name);
2793 oprintf (d.of, " do\n");
2794 }
2795 else
2796 oprintf (d.of, " while (x != xlimit)\n");
2797 }
2798 oprintf (d.of, " {\n");
2799 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2800 {
2801 oprintf (d.of, " %s (x);\n", mark_hook_name);
2802 }
2803 d.prev_val[2] = "*x";
2804 d.indent = 6;
2805 walk_type (s, &d);
2806
2807 if (chain_next != NULL)
2808 {
2809 oprintf (d.of, " x = (");
2810 output_escaped_param (&d, chain_next, "chain_next");
2811 oprintf (d.of, ");\n");
2812 }
2813
2814 oprintf (d.of, " }\n");
2815 if (chain_circular != NULL)
2816 oprintf (d.of, " while (x != xlimit);\n");
2817 oprintf (d.of, "}\n");
2818 }
2819
2820 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2821
2822 static void
2823 write_types (outf_p output_header, type_p structures, type_p param_structs,
2824 const struct write_types_data *wtd)
2825 {
2826 int nbfun = 0; /* Count the emitted functions. */
2827 type_p s;
2828
2829 oprintf (output_header, "\n/* %s*/\n", wtd->comment);
2830 /* We first emit the macros and the declarations. Functions' code is
2831 emitted afterwards. This is needed in plugin mode. */
2832 oprintf (output_header, "/* macros and declarations */\n");
2833 for (s = structures; s; s = s->next)
2834 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
2835 {
2836 options_p opt;
2837
2838 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
2839 continue;
2840
2841 oprintf (output_header, "#define gt_%s_", wtd->prefix);
2842 output_mangled_typename (output_header, s);
2843 oprintf (output_header, "(X) do { \\\n");
2844 oprintf (output_header,
2845 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2846 s->u.s.tag);
2847 oprintf (output_header, " } while (0)\n");
2848
2849 for (opt = s->u.s.opt; opt; opt = opt->next)
2850 if (strcmp (opt->name, "ptr_alias") == 0)
2851 {
2852 const_type_p const t = (const_type_p) opt->info;
2853 if (t->kind == TYPE_STRUCT
2854 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
2855 oprintf (output_header,
2856 "#define gt_%sx_%s gt_%sx_%s\n",
2857 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2858 else
2859 error_at_line (&s->u.s.line,
2860 "structure alias is not a structure");
2861 break;
2862 }
2863 if (opt)
2864 continue;
2865
2866 /* Declare the marker procedure only once. */
2867 oprintf (output_header,
2868 "extern void gt_%sx_%s (void *);\n",
2869 wtd->prefix, s->u.s.tag);
2870
2871 if (s->u.s.line.file == NULL)
2872 {
2873 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2874 s->u.s.tag);
2875 continue;
2876 }
2877 }
2878
2879 for (s = param_structs; s; s = s->next)
2880 if (s->gc_used == GC_POINTED_TO)
2881 {
2882 type_p stru = s->u.param_struct.stru;
2883
2884 /* Declare the marker procedure. */
2885 oprintf (output_header, "extern void gt_%s_", wtd->prefix);
2886 output_mangled_typename (output_header, s);
2887 oprintf (output_header, " (void *);\n");
2888
2889 if (stru->u.s.line.file == NULL)
2890 {
2891 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2892 s->u.s.tag);
2893 continue;
2894 }
2895 }
2896
2897 /* At last we emit the functions code. */
2898 oprintf (output_header, "\n/* functions code */\n");
2899 for (s = structures; s; s = s->next)
2900 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
2901 {
2902 options_p opt;
2903
2904 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
2905 continue;
2906 for (opt = s->u.s.opt; opt; opt = opt->next)
2907 if (strcmp (opt->name, "ptr_alias") == 0)
2908 break;
2909 if (opt)
2910 continue;
2911
2912 if (s->kind == TYPE_LANG_STRUCT)
2913 {
2914 type_p ss;
2915 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2916 {
2917 nbfun++;
2918 DBGPRINTF ("writing func #%d lang_struct ss @ %p '%s'",
2919 nbfun, (void*) ss, ss->u.s.tag);
2920 write_func_for_structure (s, ss, NULL, wtd);
2921 }
2922 }
2923 else
2924 {
2925 nbfun++;
2926 DBGPRINTF ("writing func #%d struct s @ %p '%s'",
2927 nbfun, (void*) s, s->u.s.tag);
2928 write_func_for_structure (s, s, NULL, wtd);
2929 }
2930 }
2931 else
2932 {
2933 /* Structure s is not possibly pointed to, so can be ignored. */
2934 DBGPRINTF ("ignored s @ %p '%s' gc_used#%d",
2935 (void*)s, s->u.s.tag,
2936 (int) s->gc_used);
2937 }
2938
2939 for (s = param_structs; s; s = s->next)
2940 if (s->gc_used == GC_POINTED_TO)
2941 {
2942 type_p *param = s->u.param_struct.param;
2943 type_p stru = s->u.param_struct.stru;
2944 if (stru->u.s.line.file == NULL)
2945 continue;
2946 if (stru->kind == TYPE_LANG_STRUCT)
2947 {
2948 type_p ss;
2949 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2950 {
2951 nbfun++;
2952 DBGPRINTF ("writing func #%d param lang_struct ss @ %p '%s'",
2953 nbfun, (void*) ss, ss->u.s.tag);
2954 write_func_for_structure (s, ss, param, wtd);
2955 }
2956 }
2957 else
2958 {
2959 nbfun++;
2960 DBGPRINTF ("writing func #%d param struct s @ %p stru @ %p '%s'",
2961 nbfun, (void*) s,
2962 (void*) stru, stru->u.s.tag);
2963 write_func_for_structure (s, stru, param, wtd);
2964 }
2965 }
2966 else
2967 {
2968 /* Param structure s is not pointed to, so should be ignored. */
2969 DBGPRINTF ("ignored s @ %p", (void*)s);
2970 }
2971 if (verbosity_level >= 2)
2972 printf ("%s emitted %d routines for %s\n",
2973 progname, nbfun, wtd->comment);
2974 }
2975
2976 static const struct write_types_data ggc_wtd = {
2977 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2978 "GC marker procedures. ",
2979 FALSE
2980 };
2981
2982 static const struct write_types_data pch_wtd = {
2983 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2984 "gt_pch_note_reorder",
2985 "PCH type-walking procedures. ",
2986 TRUE
2987 };
2988
2989 /* Write out the local pointer-walking routines. */
2990
2991 /* process_field routine for local pointer-walking. */
2992
2993 static void
2994 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2995 {
2996 switch (f->kind)
2997 {
2998 case TYPE_POINTER:
2999 case TYPE_STRUCT:
3000 case TYPE_UNION:
3001 case TYPE_LANG_STRUCT:
3002 case TYPE_PARAM_STRUCT:
3003 case TYPE_STRING:
3004 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
3005 d->prev_val[3]);
3006 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
3007 break;
3008
3009 case TYPE_SCALAR:
3010 break;
3011
3012 default:
3013 gcc_unreachable ();
3014 }
3015 }
3016
3017 /* For S, a structure that's part of ORIG_S, and using parameters
3018 PARAM, write out a routine that:
3019 - Is of type gt_note_pointers
3020 - Calls PROCESS_FIELD on each field of S or its substructures.
3021 */
3022
3023 static void
3024 write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param)
3025 {
3026 struct walk_type_data d;
3027
3028 memset (&d, 0, sizeof (d));
3029 d.of = get_output_file_for_structure (s, param);
3030 d.process_field = write_types_local_process_field;
3031 d.opt = s->u.s.opt;
3032 d.line = &s->u.s.line;
3033 d.bitmap = s->u.s.bitmap;
3034 d.param = param;
3035 d.prev_val[0] = d.prev_val[2] = "*x";
3036 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
3037 d.prev_val[3] = "x";
3038 d.val = "(*x)";
3039 d.fn_wants_lvalue = true;
3040
3041 oprintf (d.of, "\n");
3042 oprintf (d.of, "void\n");
3043 oprintf (d.of, "gt_pch_p_");
3044 output_mangled_typename (d.of, orig_s);
3045 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
3046 "\tvoid *x_p,\n"
3047 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3048 "\tATTRIBUTE_UNUSED void *cookie)\n");
3049 oprintf (d.of, "{\n");
3050 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
3051 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
3052 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3053 d.indent = 2;
3054 walk_type (s, &d);
3055 oprintf (d.of, "}\n");
3056 }
3057
3058 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
3059
3060 static void
3061 write_local (outf_p output_header, type_p structures, type_p param_structs)
3062 {
3063 type_p s;
3064
3065 if (!output_header)
3066 return;
3067 oprintf (output_header, "\n/* Local pointer-walking routines. */\n");
3068 for (s = structures; s; s = s->next)
3069 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
3070 {
3071 options_p opt;
3072
3073 if (s->u.s.line.file == NULL)
3074 continue;
3075
3076 for (opt = s->u.s.opt; opt; opt = opt->next)
3077 if (strcmp (opt->name, "ptr_alias") == 0)
3078 {
3079 const_type_p const t = (const_type_p) opt->info;
3080 if (t->kind == TYPE_STRUCT
3081 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
3082 {
3083 oprintf (output_header, "#define gt_pch_p_");
3084 output_mangled_typename (output_header, s);
3085 oprintf (output_header, " gt_pch_p_");
3086 output_mangled_typename (output_header, t);
3087 oprintf (output_header, "\n");
3088 }
3089 else
3090 error_at_line (&s->u.s.line,
3091 "structure alias is not a structure");
3092 break;
3093 }
3094 if (opt)
3095 continue;
3096
3097 /* Declare the marker procedure only once. */
3098 oprintf (output_header, "extern void gt_pch_p_");
3099 output_mangled_typename (output_header, s);
3100 oprintf (output_header,
3101 "\n (void *, void *, gt_pointer_operator, void *);\n");
3102
3103 if (s->kind == TYPE_LANG_STRUCT)
3104 {
3105 type_p ss;
3106 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
3107 write_local_func_for_structure (s, ss, NULL);
3108 }
3109 else
3110 write_local_func_for_structure (s, s, NULL);
3111 }
3112
3113 for (s = param_structs; s; s = s->next)
3114 if (s->gc_used == GC_POINTED_TO)
3115 {
3116 type_p *param = s->u.param_struct.param;
3117 type_p stru = s->u.param_struct.stru;
3118
3119 /* Declare the marker procedure. */
3120 oprintf (output_header, "extern void gt_pch_p_");
3121 output_mangled_typename (output_header, s);
3122 oprintf (output_header,
3123 "\n (void *, void *, gt_pointer_operator, void *);\n");
3124
3125 if (stru->u.s.line.file == NULL)
3126 {
3127 fprintf (stderr, "warning: structure `%s' used but not defined\n",
3128 s->u.s.tag);
3129 continue;
3130 }
3131
3132 if (stru->kind == TYPE_LANG_STRUCT)
3133 {
3134 type_p ss;
3135 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
3136 write_local_func_for_structure (s, ss, param);
3137 }
3138 else
3139 write_local_func_for_structure (s, stru, param);
3140 }
3141 }
3142
3143 /* Nonzero if S is a type for which typed GC allocators should be output. */
3144
3145 #define USED_BY_TYPED_GC_P(s) \
3146 (((s->kind == TYPE_POINTER) \
3147 && ((s->u.p->gc_used == GC_POINTED_TO) \
3148 || (s->u.p->gc_used == GC_USED))) \
3149 || (UNION_OR_STRUCT_P (s) && \
3150 (((s)->gc_used == GC_POINTED_TO) \
3151 || ((s)->gc_used == GC_MAYBE_POINTED_TO \
3152 && s->u.s.line.file != NULL) \
3153 || ((s)->gc_used == GC_USED \
3154 && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))))))
3155
3156
3157 /* Write out the 'enum' definition for gt_types_enum. */
3158
3159 static void
3160 write_enum_defn (type_p structures, type_p param_structs)
3161 {
3162 type_p s;
3163 int nbstruct = 0;
3164 int nbparamstruct = 0;
3165
3166 if (!header_file)
3167 return;
3168 oprintf (header_file, "\n/* Enumeration of types known. */\n");
3169 oprintf (header_file, "enum gt_types_enum {\n");
3170 for (s = structures; s; s = s->next)
3171 if (USED_BY_TYPED_GC_P (s))
3172 {
3173 nbstruct++;
3174 DBGPRINTF ("write_enum_defn s @ %p nbstruct %d",
3175 (void*) s, nbstruct);
3176 if (UNION_OR_STRUCT_P (s))
3177 DBGPRINTF ("write_enum_defn s %p #%d is unionorstruct tagged %s",
3178 (void*) s, nbstruct, s->u.s.tag);
3179 oprintf (header_file, " gt_ggc_e_");
3180 output_mangled_typename (header_file, s);
3181 oprintf (header_file, ",\n");
3182 }
3183 for (s = param_structs; s; s = s->next)
3184 if (s->gc_used == GC_POINTED_TO)
3185 {
3186 nbparamstruct++;
3187 DBGPRINTF ("write_enum_defn s %p nbparamstruct %d",
3188 (void*) s, nbparamstruct);
3189 oprintf (header_file, " gt_e_");
3190 output_mangled_typename (header_file, s);
3191 oprintf (header_file, ",\n");
3192 }
3193 oprintf (header_file, " gt_types_enum_last\n");
3194 oprintf (header_file, "};\n");
3195 if (verbosity_level >= 2)
3196 printf ("%s handled %d GTY-ed structures & %d parameterized structures.\n",
3197 progname, nbstruct, nbparamstruct);
3198
3199 }
3200
3201 /* Might T contain any non-pointer elements? */
3202
3203 static int
3204 contains_scalar_p (type_p t)
3205 {
3206 switch (t->kind)
3207 {
3208 case TYPE_STRING:
3209 case TYPE_POINTER:
3210 return 0;
3211 case TYPE_ARRAY:
3212 return contains_scalar_p (t->u.a.p);
3213 default:
3214 /* Could also check for structures that have no non-pointer
3215 fields, but there aren't enough of those to worry about. */
3216 return 1;
3217 }
3218 }
3219
3220 /* Mangle FN and print it to F. */
3221
3222 static void
3223 put_mangled_filename (outf_p f, const char *fn)
3224 {
3225 const char *name = get_output_file_name (fn);
3226 if (!f || !name)
3227 return;
3228 for (; *name != 0; name++)
3229 if (ISALNUM (*name))
3230 oprintf (f, "%c", *name);
3231 else
3232 oprintf (f, "%c", '_');
3233 }
3234
3235 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
3236 LASTNAME, and NAME are all strings to insert in various places in
3237 the resulting code. */
3238
3239 static void
3240 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3241 const char *tname, const char *name)
3242 {
3243 struct flist *fli2;
3244
3245 for (fli2 = flp; fli2; fli2 = fli2->next)
3246 if (fli2->started_p)
3247 {
3248 oprintf (fli2->f, " %s\n", lastname);
3249 oprintf (fli2->f, "};\n\n");
3250 }
3251
3252 for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
3253 if (fli2->started_p)
3254 {
3255 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3256 int fnum;
3257
3258 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3259 if (bitmap & 1)
3260 {
3261 oprintf (base_files[fnum],
3262 "extern const struct %s gt_%s_", tname, pfx);
3263 put_mangled_filename (base_files[fnum], fli2->name);
3264 oprintf (base_files[fnum], "[];\n");
3265 }
3266 }
3267
3268 {
3269 size_t fnum;
3270 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3271 oprintf (base_files[fnum],
3272 "EXPORTED_CONST struct %s * const %s[] = {\n", tname, name);
3273 }
3274
3275
3276 for (fli2 = flp; fli2; fli2 = fli2->next)
3277 if (fli2->started_p)
3278 {
3279 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3280 int fnum;
3281
3282 fli2->started_p = 0;
3283
3284 for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
3285 if (bitmap & 1)
3286 {
3287 oprintf (base_files[fnum], " gt_%s_", pfx);
3288 put_mangled_filename (base_files[fnum], fli2->name);
3289 oprintf (base_files[fnum], ",\n");
3290 }
3291 }
3292
3293 {
3294 size_t fnum;
3295 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3296 {
3297 oprintf (base_files[fnum], " NULL\n");
3298 oprintf (base_files[fnum], "};\n");
3299 }
3300 }
3301 }
3302
3303 /* Write the first three fields (pointer, count and stride) for
3304 root NAME to F. V and LINE are as for write_root.
3305
3306 Return true if the entry could be written; return false on error. */
3307
3308 static bool
3309 start_root_entry (outf_p f, pair_p v, const char *name, struct fileloc *line)
3310 {
3311 type_p ap;
3312
3313 if (!v)
3314 {
3315 error_at_line (line, "`%s' is too complex to be a root", name);
3316 return false;
3317 }
3318
3319 oprintf (f, " {\n");
3320 oprintf (f, " &%s,\n", name);
3321 oprintf (f, " 1");
3322
3323 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3324 if (ap->u.a.len[0])
3325 oprintf (f, " * (%s)", ap->u.a.len);
3326 else if (ap == v->type)
3327 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3328 oprintf (f, ",\n");
3329 oprintf (f, " sizeof (%s", v->name);
3330 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3331 oprintf (f, "[0]");
3332 oprintf (f, "),\n");
3333 return true;
3334 }
3335
3336 /* A subroutine of write_root for writing the roots for field FIELD_NAME,
3337 which has type FIELD_TYPE. Parameters F to EMIT_PCH are the parameters
3338 of the caller. */
3339
3340 static void
3341 write_field_root (outf_p f, pair_p v, type_p type, const char *name,
3342 int has_length, struct fileloc *line, const char *if_marked,
3343 bool emit_pch, type_p field_type, const char *field_name)
3344 {
3345 /* If the field reference is relative to V, rather than to some
3346 subcomponent of V, we can mark any subarrays with a single stride.
3347 We're effectively treating the field as a global variable in its
3348 own right. */
3349 if (v && type == v->type)
3350 {
3351 struct pair newv;
3352
3353 newv = *v;
3354 newv.type = field_type;
3355 newv.name = ACONCAT ((v->name, ".", field_name, NULL));
3356 v = &newv;
3357 }
3358 /* Otherwise, any arrays nested in the structure are too complex to
3359 handle. */
3360 else if (field_type->kind == TYPE_ARRAY)
3361 v = NULL;
3362 write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)),
3363 has_length, line, if_marked, emit_pch);
3364 }
3365
3366 /* Write out to F the table entry and any marker routines needed to
3367 mark NAME as TYPE. V can be one of three values:
3368
3369 - null, if NAME is too complex to represent using a single
3370 count and stride. In this case, it is an error for NAME to
3371 contain any gc-ed data.
3372
3373 - the outermost array that contains NAME, if NAME is part of an array.
3374
3375 - the C variable that contains NAME, if NAME is not part of an array.
3376
3377 LINE is the line of the C source that declares the root variable.
3378 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
3379 is nonzero iff we are building the root table for hash table caches. */
3380
3381 static void
3382 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3383 struct fileloc *line, const char *if_marked, bool emit_pch)
3384 {
3385 switch (type->kind)
3386 {
3387 case TYPE_STRUCT:
3388 {
3389 pair_p fld;
3390 for (fld = type->u.s.fields; fld; fld = fld->next)
3391 {
3392 int skip_p = 0;
3393 const char *desc = NULL;
3394 options_p o;
3395
3396 for (o = fld->opt; o; o = o->next)
3397 if (strcmp (o->name, "skip") == 0)
3398 skip_p = 1;
3399 else if (strcmp (o->name, "desc") == 0)
3400 desc = o->info;
3401 else if (strcmp (o->name, "param_is") == 0)
3402 ;
3403 else
3404 error_at_line (line,
3405 "field `%s' of global `%s' has unknown option `%s'",
3406 fld->name, name, o->name);
3407
3408 if (skip_p)
3409 continue;
3410 else if (desc && fld->type->kind == TYPE_UNION)
3411 {
3412 pair_p validf = NULL;
3413 pair_p ufld;
3414
3415 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3416 {
3417 const char *tag = NULL;
3418 options_p oo;
3419
3420 for (oo = ufld->opt; oo; oo = oo->next)
3421 if (strcmp (oo->name, "tag") == 0)
3422 tag = oo->info;
3423 if (tag == NULL || strcmp (tag, desc) != 0)
3424 continue;
3425 if (validf != NULL)
3426 error_at_line (line,
3427 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3428 name, fld->name, validf->name,
3429 name, fld->name, ufld->name, tag);
3430 validf = ufld;
3431 }
3432 if (validf != NULL)
3433 write_field_root (f, v, type, name, 0, line, if_marked,
3434 emit_pch, validf->type,
3435 ACONCAT ((fld->name, ".",
3436 validf->name, NULL)));
3437 }
3438 else if (desc)
3439 error_at_line (line,
3440 "global `%s.%s' has `desc' option but is not union",
3441 name, fld->name);
3442 else
3443 write_field_root (f, v, type, name, 0, line, if_marked,
3444 emit_pch, fld->type, fld->name);
3445 }
3446 }
3447 break;
3448
3449 case TYPE_ARRAY:
3450 {
3451 char *newname;
3452 newname = xasprintf ("%s[0]", name);
3453 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
3454 emit_pch);
3455 free (newname);
3456 }
3457 break;
3458
3459 case TYPE_POINTER:
3460 {
3461 type_p tp;
3462
3463 if (!start_root_entry (f, v, name, line))
3464 return;
3465
3466 tp = type->u.p;
3467
3468 if (!has_length && UNION_OR_STRUCT_P (tp))
3469 {
3470 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
3471 if (emit_pch)
3472 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
3473 else
3474 oprintf (f, " NULL");
3475 }
3476 else if (!has_length && tp->kind == TYPE_PARAM_STRUCT)
3477 {
3478 oprintf (f, " &gt_ggc_m_");
3479 output_mangled_typename (f, tp);
3480 if (emit_pch)
3481 {
3482 oprintf (f, ",\n &gt_pch_n_");
3483 output_mangled_typename (f, tp);
3484 }
3485 else
3486 oprintf (f, ",\n NULL");
3487 }
3488 else if (has_length
3489 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3490 {
3491 oprintf (f, " &gt_ggc_ma_%s,\n", name);
3492 if (emit_pch)
3493 oprintf (f, " &gt_pch_na_%s", name);
3494 else
3495 oprintf (f, " NULL");
3496 }
3497 else
3498 {
3499 error_at_line (line,
3500 "global `%s' is pointer to unimplemented type",
3501 name);
3502 }
3503 if (if_marked)
3504 oprintf (f, ",\n &%s", if_marked);
3505 oprintf (f, "\n },\n");
3506 }
3507 break;
3508
3509 case TYPE_STRING:
3510 {
3511 if (!start_root_entry (f, v, name, line))
3512 return;
3513
3514 oprintf (f, " (gt_pointer_walker) &gt_ggc_m_S,\n");
3515 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
3516 oprintf (f, " },\n");
3517 }
3518 break;
3519
3520 case TYPE_SCALAR:
3521 break;
3522
3523 default:
3524 error_at_line (line, "global `%s' is unimplemented type", name);
3525 }
3526 }
3527
3528 /* This generates a routine to walk an array. */
3529
3530 static void
3531 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3532 {
3533 struct walk_type_data d;
3534 char *prevval3;
3535
3536 memset (&d, 0, sizeof (d));
3537 d.of = f;
3538 d.cookie = wtd;
3539 d.indent = 2;
3540 d.line = &v->line;
3541 d.opt = v->opt;
3542 d.bitmap = get_lang_bitmap (v->line.file);
3543 d.param = NULL;
3544
3545 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3546
3547 if (wtd->param_prefix)
3548 {
3549 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3550 oprintf (f, " (void *, void *, gt_pointer_operator, void *);\n");
3551 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3552 wtd->param_prefix, v->name);
3553 oprintf (d.of,
3554 " ATTRIBUTE_UNUSED void *x_p,\n"
3555 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3556 " ATTRIBUTE_UNUSED void * cookie)\n");
3557 oprintf (d.of, "{\n");
3558 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3559 d.process_field = write_types_local_process_field;
3560 walk_type (v->type, &d);
3561 oprintf (f, "}\n\n");
3562 }
3563
3564 d.opt = v->opt;
3565 oprintf (f, "static void gt_%sa_%s (void *);\n", wtd->prefix, v->name);
3566 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3567 wtd->prefix, v->name);
3568 oprintf (f, "{\n");
3569 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3570 d.process_field = write_types_process_field;
3571 walk_type (v->type, &d);
3572 free (prevval3);
3573 oprintf (f, "}\n\n");
3574 }
3575
3576 /* Output a table describing the locations and types of VARIABLES. */
3577
3578 static void
3579 write_roots (pair_p variables, bool emit_pch)
3580 {
3581 pair_p v;
3582 struct flist *flp = NULL;
3583
3584 for (v = variables; v; v = v->next)
3585 {
3586 outf_p f = get_output_file_with_visibility (v->line.file);
3587 struct flist *fli;
3588 const char *length = NULL;
3589 int deletable_p = 0;
3590 options_p o;
3591
3592 for (o = v->opt; o; o = o->next)
3593 if (strcmp (o->name, "length") == 0)
3594 length = o->info;
3595 else if (strcmp (o->name, "deletable") == 0)
3596 deletable_p = 1;
3597 else if (strcmp (o->name, "param_is") == 0)
3598 ;
3599 else if (strncmp (o->name, "param", 5) == 0
3600 && ISDIGIT (o->name[5]) && strcmp (o->name + 6, "_is") == 0)
3601 ;
3602 else if (strcmp (o->name, "if_marked") == 0)
3603 ;
3604 else
3605 error_at_line (&v->line,
3606 "global `%s' has unknown option `%s'",
3607 v->name, o->name);
3608
3609 for (fli = flp; fli; fli = fli->next)
3610 if (fli->f == f && f)
3611 break;
3612 if (fli == NULL)
3613 {
3614 fli = XNEW (struct flist);
3615 fli->f = f;
3616 fli->next = flp;
3617 fli->started_p = 0;
3618 fli->name = v->line.file;
3619 gcc_assert (fli->name);
3620 flp = fli;
3621
3622 oprintf (f, "\n/* GC roots. */\n\n");
3623 }
3624
3625 if (!deletable_p
3626 && length
3627 && v->type->kind == TYPE_POINTER
3628 && (v->type->u.p->kind == TYPE_POINTER
3629 || v->type->u.p->kind == TYPE_STRUCT))
3630 {
3631 write_array (f, v, &ggc_wtd);
3632 write_array (f, v, &pch_wtd);
3633 }
3634 }
3635
3636 for (v = variables; v; v = v->next)
3637 {
3638 outf_p f = get_output_file_with_visibility (v->line.file);
3639 struct flist *fli;
3640 int skip_p = 0;
3641 int length_p = 0;
3642 options_p o;
3643
3644 for (o = v->opt; o; o = o->next)
3645 if (strcmp (o->name, "length") == 0)
3646 length_p = 1;
3647 else if (strcmp (o->name, "deletable") == 0
3648 || strcmp (o->name, "if_marked") == 0)
3649 skip_p = 1;
3650
3651 if (skip_p)
3652 continue;
3653
3654 for (fli = flp; fli; fli = fli->next)
3655 if (fli->f == f)
3656 break;
3657 if (!fli->started_p)
3658 {
3659 fli->started_p = 1;
3660
3661 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
3662 put_mangled_filename (f, v->line.file);
3663 oprintf (f, "[] = {\n");
3664 }
3665
3666 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
3667 }
3668
3669 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3670 "gt_ggc_rtab");
3671
3672 for (v = variables; v; v = v->next)
3673 {
3674 outf_p f = get_output_file_with_visibility (v->line.file);
3675 struct flist *fli;
3676 int skip_p = 1;
3677 options_p o;
3678
3679 for (o = v->opt; o; o = o->next)
3680 if (strcmp (o->name, "deletable") == 0)
3681 skip_p = 0;
3682 else if (strcmp (o->name, "if_marked") == 0)
3683 skip_p = 1;
3684
3685 if (skip_p)
3686 continue;
3687
3688 for (fli = flp; fli; fli = fli->next)
3689 if (fli->f == f)
3690 break;
3691 if (!fli->started_p)
3692 {
3693 fli->started_p = 1;
3694
3695 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
3696 put_mangled_filename (f, v->line.file);
3697 oprintf (f, "[] = {\n");
3698 }
3699
3700 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3701 v->name, v->name);
3702 }
3703
3704 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3705 "gt_ggc_deletable_rtab");
3706
3707 for (v = variables; v; v = v->next)
3708 {
3709 outf_p f = get_output_file_with_visibility (v->line.file);
3710 struct flist *fli;
3711 const char *if_marked = NULL;
3712 int length_p = 0;
3713 options_p o;
3714
3715 for (o = v->opt; o; o = o->next)
3716 if (strcmp (o->name, "length") == 0)
3717 length_p = 1;
3718 else if (strcmp (o->name, "if_marked") == 0)
3719 if_marked = o->info;
3720
3721 if (if_marked == NULL)
3722 continue;
3723
3724 if (v->type->kind != TYPE_POINTER
3725 || v->type->u.p->kind != TYPE_PARAM_STRUCT
3726 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3727 {
3728 error_at_line (&v->line,
3729 "if_marked option used but not hash table");
3730 continue;
3731 }
3732
3733 for (fli = flp; fli; fli = fli->next)
3734 if (fli->f == f)
3735 break;
3736 if (!fli->started_p)
3737 {
3738 fli->started_p = 1;
3739
3740 oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
3741 put_mangled_filename (f, v->line.file);
3742 oprintf (f, "[] = {\n");
3743 }
3744
3745 write_root (f, v, v->type->u.p->u.param_struct.param[0],
3746 v->name, length_p, &v->line, if_marked, emit_pch);
3747 }
3748
3749 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3750 "gt_ggc_cache_rtab");
3751
3752 if (!emit_pch)
3753 return;
3754
3755 for (v = variables; v; v = v->next)
3756 {
3757 outf_p f = get_output_file_with_visibility (v->line.file);
3758 struct flist *fli;
3759 int length_p = 0;
3760 int if_marked_p = 0;
3761 options_p o;
3762
3763 for (o = v->opt; o; o = o->next)
3764 if (strcmp (o->name, "length") == 0)
3765 length_p = 1;
3766 else if (strcmp (o->name, "if_marked") == 0)
3767 if_marked_p = 1;
3768
3769 if (!if_marked_p)
3770 continue;
3771
3772 for (fli = flp; fli; fli = fli->next)
3773 if (fli->f == f)
3774 break;
3775 if (!fli->started_p)
3776 {
3777 fli->started_p = 1;
3778
3779 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
3780 put_mangled_filename (f, v->line.file);
3781 oprintf (f, "[] = {\n");
3782 }
3783
3784 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
3785 }
3786
3787 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3788 "gt_pch_cache_rtab");
3789
3790 for (v = variables; v; v = v->next)
3791 {
3792 outf_p f = get_output_file_with_visibility (v->line.file);
3793 struct flist *fli;
3794 int skip_p = 0;
3795 options_p o;
3796
3797 for (o = v->opt; o; o = o->next)
3798 if (strcmp (o->name, "deletable") == 0
3799 || strcmp (o->name, "if_marked") == 0)
3800 skip_p = 1;
3801
3802 if (skip_p)
3803 continue;
3804
3805 if (!contains_scalar_p (v->type))
3806 continue;
3807
3808 for (fli = flp; fli; fli = fli->next)
3809 if (fli->f == f)
3810 break;
3811 if (!fli->started_p)
3812 {
3813 fli->started_p = 1;
3814
3815 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
3816 put_mangled_filename (f, v->line.file);
3817 oprintf (f, "[] = {\n");
3818 }
3819
3820 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3821 v->name, v->name);
3822 }
3823
3824 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3825 "gt_pch_scalar_rtab");
3826 }
3827
3828 /* Record the definition of a generic VEC structure, as if we had expanded
3829 the macros in vec.h:
3830
3831 typedef struct VEC_<type>_base GTY(()) {
3832 unsigned num;
3833 unsigned alloc;
3834 <type> GTY((length ("%h.num"))) vec[1];
3835 } VEC_<type>_base
3836
3837 where the GTY(()) tags are only present if is_scalar is _false_. */
3838
3839 void
3840 note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
3841 {
3842 pair_p fields;
3843 type_p t;
3844 options_p o;
3845 type_p len_ty = create_scalar_type ("unsigned");
3846 const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
3847
3848 if (is_scalar)
3849 {
3850 t = create_scalar_type (type_name);
3851 o = 0;
3852 }
3853 else
3854 {
3855 t = resolve_typedef (type_name, pos);
3856 o = create_option (0, "length", "%h.num");
3857 }
3858
3859 /* We assemble the field list in reverse order. */
3860 fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3861 fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3862 fields = create_field_at (fields, len_ty, "num", 0, pos);
3863
3864 do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3865 }
3866
3867 /* Record the definition of an allocation-specific VEC structure, as if
3868 we had expanded the macros in vec.h:
3869
3870 typedef struct VEC_<type>_<astrat> {
3871 VEC_<type>_base base;
3872 } VEC_<type>_<astrat>;
3873 */
3874 void
3875 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3876 {
3877 const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0);
3878 const char *basename = concat ("VEC_", type, "_base", (char *) 0);
3879
3880 pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3881 "base", 0, pos);
3882
3883 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3884 }
3885
3886 /* Returns the specifier keyword for a string or union type S, empty string
3887 otherwise. */
3888
3889 static const char *
3890 get_type_specifier (const type_p s)
3891 {
3892 if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT)
3893 return "struct ";
3894 if (s->kind == TYPE_UNION)
3895 return "union ";
3896 return "";
3897 }
3898
3899 /* TRUE if type S has the GTY variable_size annotation. */
3900
3901 static bool
3902 variable_size_p (const type_p s)
3903 {
3904 options_p o;
3905 for (o = s->u.s.opt; o; o = o->next)
3906 if (strcmp (o->name, "variable_size") == 0)
3907 return true;
3908 return false;
3909 }
3910
3911 enum alloc_quantity
3912 { single, vector };
3913 enum alloc_zone
3914 { any_zone, specific_zone };
3915
3916 /* Writes one typed allocator definition for type identifier TYPE_NAME with
3917 optional type specifier TYPE_SPECIFIER. The allocator name will contain
3918 ALLOCATOR_TYPE. If VARIABLE_SIZE is true, the allocator will have an extra
3919 parameter specifying number of bytes to allocate. If QUANTITY is set to
3920 VECTOR, a vector allocator will be output, if ZONE is set to SPECIFIC_ZONE,
3921 the allocator will be zone-specific. */
3922
3923 static void
3924 write_typed_alloc_def (bool variable_size, const char *type_specifier,
3925 const char *type_name, const char *allocator_type,
3926 enum alloc_quantity quantity, enum alloc_zone zone)
3927 {
3928 bool two_args = variable_size && (quantity == vector);
3929 bool third_arg = ((zone == specific_zone)
3930 && (variable_size || (quantity == vector)));
3931
3932 oprintf (header_file, "#define ggc_alloc_%s%s", allocator_type, type_name);
3933 oprintf (header_file, "(%s%s%s%s%s) ",
3934 (variable_size ? "SIZE" : ""),
3935 (two_args ? ", " : ""),
3936 (quantity == vector) ? "n" : "",
3937 (third_arg ? ", " : ""), (zone == specific_zone) ? "z" : "");
3938 oprintf (header_file, "((%s%s *)", type_specifier, type_name);
3939 oprintf (header_file, "(ggc_internal_%salloc_stat (", allocator_type);
3940 if (zone == specific_zone)
3941 oprintf (header_file, "z, ");
3942 if (variable_size)
3943 oprintf (header_file, "SIZE");
3944 else
3945 oprintf (header_file, "sizeof (%s%s)", type_specifier, type_name);
3946 if (quantity == vector)
3947 oprintf (header_file, ", n");
3948 oprintf (header_file, " MEM_STAT_INFO)))\n");
3949 }
3950
3951 /* Writes a typed allocator definition for a struct or union S. */
3952
3953 static void
3954 write_typed_struct_alloc_def (const type_p s, const char *allocator_type,
3955 enum alloc_quantity quantity,
3956 enum alloc_zone zone)
3957 {
3958 write_typed_alloc_def (variable_size_p (s), get_type_specifier (s),
3959 s->u.s.tag, allocator_type, quantity, zone);
3960 }
3961
3962 /* Writes a typed allocator definition for a typedef P. */
3963
3964 static void
3965 write_typed_typedef_alloc_def (const pair_p p, const char *allocator_type,
3966 enum alloc_quantity quantity,
3967 enum alloc_zone zone)
3968 {
3969 write_typed_alloc_def (variable_size_p (p->type), "", p->name,
3970 allocator_type, quantity, zone);
3971 }
3972
3973 /* Writes typed allocator definitions for the types in STRUCTURES and
3974 TYPEDEFS that are used by GC. */
3975
3976 static void
3977 write_typed_alloc_defns (const type_p structures, const pair_p typedefs)
3978 {
3979 type_p s;
3980 pair_p p;
3981
3982 oprintf (header_file,
3983 "\n/* Allocators for known structs and unions. */\n\n");
3984 for (s = structures; s; s = s->next)
3985 {
3986 if (!USED_BY_TYPED_GC_P (s))
3987 continue;
3988 write_typed_struct_alloc_def (s, "", single, any_zone);
3989 write_typed_struct_alloc_def (s, "cleared_", single, any_zone);
3990 write_typed_struct_alloc_def (s, "vec_", vector, any_zone);
3991 write_typed_struct_alloc_def (s, "cleared_vec_", vector, any_zone);
3992 write_typed_struct_alloc_def (s, "zone_", single, specific_zone);
3993 write_typed_struct_alloc_def (s, "zone_cleared_", single,
3994 specific_zone);
3995 write_typed_struct_alloc_def (s, "zone_vec_", vector, specific_zone);
3996 write_typed_struct_alloc_def (s, "zone_cleared_vec_", vector,
3997 specific_zone);
3998 }
3999
4000 oprintf (header_file, "\n/* Allocators for known typedefs. */\n");
4001 for (p = typedefs; p; p = p->next)
4002 {
4003 s = p->type;
4004 if (!USED_BY_TYPED_GC_P (s) || (strcmp (p->name, s->u.s.tag) == 0))
4005 continue;
4006 write_typed_typedef_alloc_def (p, "", single, any_zone);
4007 write_typed_typedef_alloc_def (p, "cleared_", single, any_zone);
4008 write_typed_typedef_alloc_def (p, "vec_", vector, any_zone);
4009 write_typed_typedef_alloc_def (p, "cleared_vec_", vector, any_zone);
4010 write_typed_typedef_alloc_def (p, "zone_", single, specific_zone);
4011 write_typed_typedef_alloc_def (p, "zone_cleared_", single,
4012 specific_zone);
4013 write_typed_typedef_alloc_def (p, "zone_cleared_vec_", vector,
4014 specific_zone);
4015 }
4016 }
4017
4018 /* Prints not-as-ugly version of a typename of T to OF. Trades the uniquness
4019 guaranteee for somewhat increased readability. If name conflicts do happen,
4020 this funcion will have to be adjusted to be more like
4021 output_mangled_typename. */
4022
4023 static void
4024 output_typename (outf_p of, const_type_p t)
4025 {
4026 switch (t->kind)
4027 {
4028 case TYPE_STRING:
4029 oprintf (of, "str");
4030 break;
4031 case TYPE_SCALAR:
4032 oprintf (of, "scalar");
4033 break;
4034 case TYPE_POINTER:
4035 output_typename (of, t->u.p);
4036 break;
4037 case TYPE_STRUCT:
4038 case TYPE_UNION:
4039 case TYPE_LANG_STRUCT:
4040 oprintf (of, "%s", t->u.s.tag);
4041 break;
4042 case TYPE_PARAM_STRUCT:
4043 {
4044 int i;
4045 for (i = 0; i < NUM_PARAM; i++)
4046 if (t->u.param_struct.param[i] != NULL)
4047 {
4048 output_typename (of, t->u.param_struct.param[i]);
4049 oprintf (of, "_");
4050 }
4051 output_typename (of, t->u.param_struct.stru);
4052 break;
4053 }
4054 default:
4055 gcc_unreachable ();
4056 }
4057 }
4058
4059 /* Writes a typed GC allocator for type S that is suitable as a callback for
4060 the splay tree implementation in libiberty. */
4061
4062 static void
4063 write_splay_tree_allocator_def (const_type_p s)
4064 {
4065 outf_p of = get_output_file_for_structure (s, NULL);
4066 oprintf (of, "void * ggc_alloc_splay_tree_");
4067 output_typename (of, s);
4068 oprintf (of, " (int sz, void * nl)\n");
4069 oprintf (of, "{\n");
4070 oprintf (of, " return ggc_splay_alloc (");
4071 oprintf (of, "gt_e_");
4072 output_mangled_typename (of, s);
4073 oprintf (of, ", sz, nl);\n");
4074 oprintf (of, "}\n\n");
4075 }
4076
4077 /* Writes typed GC allocators for PARAM_STRUCTS that are suitable as callbacks
4078 for the splay tree implementation in libiberty. */
4079
4080 static void
4081 write_splay_tree_allocators (const_type_p param_structs)
4082 {
4083 const_type_p s;
4084
4085 oprintf (header_file, "\n/* Splay tree callback allocators. */\n");
4086 for (s = param_structs; s; s = s->next)
4087 if (s->gc_used == GC_POINTED_TO)
4088 {
4089 oprintf (header_file, "extern void * ggc_alloc_splay_tree_");
4090 output_typename (header_file, s);
4091 oprintf (header_file, " (int, void *);\n");
4092 write_splay_tree_allocator_def (s);
4093 }
4094 }
4095
4096 static void dump_pair (int indent, pair_p p);
4097 static void dump_type (int indent, type_p p);
4098 static void dump_type_list (int indent, type_p p);
4099
4100 #define INDENT 2
4101
4102 /* Dumps the value of typekind KIND. */
4103
4104 static void
4105 dump_typekind (int indent, enum typekind kind)
4106 {
4107 printf ("%*ckind = ", indent, ' ');
4108 switch (kind)
4109 {
4110 case TYPE_SCALAR:
4111 printf ("TYPE_SCALAR");
4112 break;
4113 case TYPE_STRING:
4114 printf ("TYPE_STRING");
4115 break;
4116 case TYPE_STRUCT:
4117 printf ("TYPE_STRUCT");
4118 break;
4119 case TYPE_UNION:
4120 printf ("TYPE_UNION");
4121 break;
4122 case TYPE_POINTER:
4123 printf ("TYPE_POINTER");
4124 break;
4125 case TYPE_ARRAY:
4126 printf ("TYPE_ARRAY");
4127 break;
4128 case TYPE_LANG_STRUCT:
4129 printf ("TYPE_LANG_STRUCT");
4130 break;
4131 case TYPE_PARAM_STRUCT:
4132 printf ("TYPE_PARAM_STRUCT");
4133 break;
4134 default:
4135 gcc_unreachable ();
4136 }
4137 printf ("\n");
4138 }
4139
4140 /* Dumps the value of GC_USED flag. */
4141
4142 static void
4143 dump_gc_used (int indent, enum gc_used_enum gc_used)
4144 {
4145 printf ("%*cgc_used = ", indent, ' ');
4146 switch (gc_used)
4147 {
4148 case GC_UNUSED:
4149 printf ("GC_UNUSED");
4150 break;
4151 case GC_USED:
4152 printf ("GC_USED");
4153 break;
4154 case GC_MAYBE_POINTED_TO:
4155 printf ("GC_MAYBE_POINTED_TO");
4156 break;
4157 case GC_POINTED_TO:
4158 printf ("GC_POINTED_TO");
4159 break;
4160 default:
4161 gcc_unreachable ();
4162 }
4163 printf ("\n");
4164 }
4165
4166 /* Dumps the type options OPT. */
4167
4168 static void
4169 dump_options (int indent, options_p opt)
4170 {
4171 options_p o;
4172 printf ("%*coptions = ", indent, ' ');
4173 o = opt;
4174 while (o)
4175 {
4176 printf ("%s:%s ", o->name, o->info);
4177 o = o->next;
4178 }
4179 printf ("\n");
4180 }
4181
4182 /* Dumps the source file location in LINE. */
4183
4184 static void
4185 dump_fileloc (int indent, struct fileloc line)
4186 {
4187 printf ("%*cfileloc: file = %s, line = %d\n", indent, ' ', line.file,
4188 line.line);
4189 }
4190
4191 /* Recursively dumps the struct, union, or a language-specific
4192 struct T. */
4193
4194 static void
4195 dump_type_u_s (int indent, type_p t)
4196 {
4197 pair_p fields;
4198
4199 gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION
4200 || t->kind == TYPE_LANG_STRUCT);
4201 printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag);
4202 dump_fileloc (indent, t->u.s.line);
4203 printf ("%*cu.s.fields =\n", indent, ' ');
4204 fields = t->u.s.fields;
4205 while (fields)
4206 {
4207 dump_pair (indent + INDENT, fields);
4208 fields = fields->next;
4209 }
4210 printf ("%*cend of fields of type %p\n", indent, ' ', (void *) t);
4211 dump_options (indent, t->u.s.opt);
4212 printf ("%*cu.s.bitmap = %X\n", indent, ' ', t->u.s.bitmap);
4213 if (t->kind == TYPE_LANG_STRUCT)
4214 {
4215 printf ("%*cu.s.lang_struct:\n", indent, ' ');
4216 dump_type_list (indent + INDENT, t->u.s.lang_struct);
4217 }
4218 }
4219
4220 /* Recursively dumps the array T. */
4221
4222 static void
4223 dump_type_u_a (int indent, type_p t)
4224 {
4225 gcc_assert (t->kind == TYPE_ARRAY);
4226 printf ("%*clen = %s, u.a.p:\n", indent, ' ', t->u.a.len);
4227 dump_type_list (indent + INDENT, t->u.a.p);
4228 }
4229
4230 /* Recursively dumps the parameterized struct T. */
4231
4232 static void
4233 dump_type_u_param_struct (int indent, type_p t)
4234 {
4235 int i;
4236 gcc_assert (t->kind == TYPE_PARAM_STRUCT);
4237 printf ("%*cu.param_struct.stru:\n", indent, ' ');
4238 dump_type_list (indent, t->u.param_struct.stru);
4239 dump_fileloc (indent, t->u.param_struct.line);
4240 for (i = 0; i < NUM_PARAM; i++)
4241 {
4242 if (t->u.param_struct.param[i] == NULL)
4243 continue;
4244 printf ("%*cu.param_struct.param[%d]:\n", indent, ' ', i);
4245 dump_type (indent + INDENT, t->u.param_struct.param[i]);
4246 }
4247 }
4248
4249 /* Recursively dumps the type list T. */
4250
4251 static void
4252 dump_type_list (int indent, type_p t)
4253 {
4254 type_p p = t;
4255 while (p)
4256 {
4257 dump_type (indent, p);
4258 p = p->next;
4259 }
4260 }
4261
4262 static htab_t seen_types;
4263
4264 /* Recursively dumps the type T if it was not dumped previously. */
4265
4266 static void
4267 dump_type (int indent, type_p t)
4268 {
4269 PTR *slot;
4270
4271 printf ("%*cType at %p: ", indent, ' ', (void *) t);
4272 slot = htab_find_slot (seen_types, t, INSERT);
4273 if (*slot != NULL)
4274 {
4275 printf ("already seen.\n");
4276 return;
4277 }
4278 *slot = t;
4279 printf ("\n");
4280
4281 dump_typekind (indent, t->kind);
4282 printf ("%*cpointer_to = %p\n", indent + INDENT, ' ',
4283 (void *) t->pointer_to);
4284 dump_gc_used (indent + INDENT, t->gc_used);
4285 switch (t->kind)
4286 {
4287 case TYPE_SCALAR:
4288 printf ("%*cscalar_is_char = %s\n", indent + INDENT, ' ',
4289 t->u.scalar_is_char ? "true" : "false");
4290 break;
4291 case TYPE_STRING:
4292 break;
4293 case TYPE_STRUCT:
4294 case TYPE_UNION:
4295 case TYPE_LANG_STRUCT:
4296 dump_type_u_s (indent + INDENT, t);
4297 break;
4298 case TYPE_POINTER:
4299 printf ("%*cp:\n", indent + INDENT, ' ');
4300 dump_type (indent + INDENT, t->u.p);
4301 break;
4302 case TYPE_ARRAY:
4303 dump_type_u_a (indent + INDENT, t);
4304 break;
4305 case TYPE_PARAM_STRUCT:
4306 dump_type_u_param_struct (indent + INDENT, t);
4307 break;
4308 default:
4309 gcc_unreachable ();
4310 }
4311 printf ("%*cEnd of type at %p\n", indent, ' ', (void *) t);
4312 }
4313
4314 /* Dumps the pair P. */
4315
4316 static void
4317 dump_pair (int indent, pair_p p)
4318 {
4319 printf ("%*cpair: name = %s\n", indent, ' ', p->name);
4320 dump_type (indent, p->type);
4321 dump_fileloc (indent, p->line);
4322 dump_options (indent, p->opt);
4323 printf ("%*cEnd of pair %s\n", indent, ' ', p->name);
4324 }
4325
4326 /* Dumps the list of pairs PP. */
4327
4328 static void
4329 dump_pair_list (const char *name, pair_p pp)
4330 {
4331 pair_p p;
4332 printf ("%s:\n", name);
4333 for (p = pp; p != NULL; p = p->next)
4334 dump_pair (0, p);
4335 printf ("End of %s\n\n", name);
4336 }
4337
4338 /* Dumps the STRUCTURES. */
4339
4340 static void
4341 dump_structures (const char *name, type_p structures)
4342 {
4343 printf ("%s:\n", name);
4344 dump_type_list (0, structures);
4345 printf ("End of %s\n\n", name);
4346 }
4347
4348 /* Dumps the internal structures of gengtype. */
4349
4350 static void
4351 dump_everything (void)
4352 {
4353 seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL);
4354 dump_pair_list ("typedefs", typedefs);
4355 dump_structures ("structures", structures);
4356 dump_structures ("param_structs", param_structs);
4357 dump_pair_list ("variables", variables);
4358 htab_delete (seen_types);
4359 }
4360 \f
4361
4362
4363 /* Option specification for getopt_long. */
4364 static const struct option gengtype_long_options[] = {
4365 {"help", no_argument, NULL, 'h'},
4366 {"version", no_argument, NULL, 'V'},
4367 {"verbose", no_argument, NULL, 'v'},
4368 {"dump", no_argument, NULL, 'd'},
4369 {"debug", no_argument, NULL, 'D'},
4370 {"plugin", required_argument, NULL, 'P'},
4371 {"srcdir", required_argument, NULL, 'S'},
4372 {"backupdir", required_argument, NULL, 'B'},
4373 {"inputs", required_argument, NULL, 'I'},
4374 {"read-state", required_argument, NULL, 'r'},
4375 {"write-state", required_argument, NULL, 'w'},
4376 /* Terminating NULL placeholder. */
4377 {NULL, no_argument, NULL, 0},
4378 };
4379
4380
4381 static void
4382 print_usage (void)
4383 {
4384 printf ("Usage: %s\n", progname);
4385 printf ("\t -h | --help " " \t# Give this help.\n");
4386 printf ("\t -D | --debug "
4387 " \t# Give debug output to debug %s itself.\n", progname);
4388 printf ("\t -V | --version " " \t# Give version information.\n");
4389 printf ("\t -v | --verbose \t# Increase verbosity. Can be given several times.\n");
4390 printf ("\t -d | --dump " " \t# Dump state for debugging.\n");
4391 printf ("\t -P | --plugin <output-file> <plugin-src> ... "
4392 " \t# Generate for plugin.\n");
4393 printf ("\t -S | --srcdir <GCC-directory> "
4394 " \t# Specify the GCC source directory.\n");
4395 printf ("\t -B | --backupdir <directory> "
4396 " \t# Specify the backup directory for updated files.\n");
4397 printf ("\t -I | --inputs <input-list> "
4398 " \t# Specify the file with source files list.\n");
4399 printf ("\t -w | --write-state <state-file> " " \t# Write a state file.\n");
4400 printf ("\t -r | --read-state <state-file> " " \t# Read a state file.\n");
4401 }
4402
4403 static void
4404 print_version (void)
4405 {
4406 printf ("%s %s%s\n", progname, pkgversion_string, version_string);
4407 printf ("Report bugs: %s\n", bug_report_url);
4408 }
4409
4410 /* Parse the program options using getopt_long... */
4411 static void
4412 parse_program_options (int argc, char **argv)
4413 {
4414 int opt = -1;
4415 while ((opt = getopt_long (argc, argv, "hVvdP:S:B:I:w:r:D",
4416 gengtype_long_options, NULL)) >= 0)
4417 {
4418 switch (opt)
4419 {
4420 case 'h': /* --help */
4421 print_usage ();
4422 break;
4423 case 'V': /* --version */
4424 print_version ();
4425 break;
4426 case 'd': /* --dump */
4427 do_dump = 1;
4428 break;
4429 case 'D': /* --debug */
4430 do_debug = 1;
4431 break;
4432 case 'v': /* --verbose */
4433 verbosity_level++;
4434 break;
4435 case 'P': /* --plugin */
4436 if (optarg)
4437 plugin_output_filename = optarg;
4438 else
4439 fatal ("missing plugin output file name");
4440 break;
4441 case 'S': /* --srcdir */
4442 if (optarg)
4443 srcdir = optarg;
4444 else
4445 fatal ("missing source directory");
4446 srcdir_len = strlen (srcdir);
4447 break;
4448 case 'B': /* --backupdir */
4449 if (optarg)
4450 backup_dir = optarg;
4451 else
4452 fatal ("missing backup directory");
4453 break;
4454 case 'I': /* --inputs */
4455 if (optarg)
4456 inputlist = optarg;
4457 else
4458 fatal ("missing input list");
4459 break;
4460 case 'r': /* --read-state */
4461 if (optarg)
4462 read_state_filename = optarg;
4463 else
4464 fatal ("missing read state file");
4465 DBGPRINTF ("read state %s\n", optarg);
4466 break;
4467 case 'w': /* --write-state */
4468 DBGPRINTF ("write state %s\n", optarg);
4469 if (optarg)
4470 write_state_filename = optarg;
4471 else
4472 fatal ("missing write state file");
4473 break;
4474 default:
4475 fprintf (stderr, "%s: unknown flag '%c'\n", progname, opt);
4476 print_usage ();
4477 fatal ("unexpected flag");
4478 }
4479 };
4480 if (plugin_output_filename)
4481 {
4482 /* In plugin mode we require some input files. */
4483 int i = 0;
4484 if (optind >= argc)
4485 fatal ("no source files given in plugin mode");
4486 nb_plugin_files = argc - optind;
4487 plugin_files = XNEWVEC (char*, nb_plugin_files);
4488 for (i = 0; i < (int) nb_plugin_files; i++)
4489 {
4490 char *name = argv[i + optind];
4491 plugin_files[i] = name;
4492 }
4493 }
4494 }
4495
4496
4497 int
4498 main (int argc, char **argv)
4499 {
4500 size_t i;
4501 static struct fileloc pos = { NULL, 0 };
4502 outf_p output_header;
4503
4504 /* Mandatory common initializations. */
4505 progname = "gengtype"; /* For fatal and messages. */
4506 /* Set the scalar_is_char union number for predefined scalar types. */
4507 scalar_nonchar.u.scalar_is_char = FALSE;
4508 scalar_char.u.scalar_is_char = TRUE;
4509
4510 parse_program_options (argc, argv);
4511
4512 #if ENABLE_CHECKING
4513 if (do_debug)
4514 {
4515 time_t now = (time_t) 0;
4516 time (&now);
4517 DBGPRINTF ("gengtype started pid %d at %s",
4518 (int) getpid (), ctime (&now));
4519 }
4520 #endif /* ENABLE_CHECKING */
4521
4522 /* Parse the input list and the input files. */
4523 DBGPRINTF ("inputlist %s", inputlist);
4524 if (read_state_filename)
4525 {
4526 fatal ("read state %s not implemented yet", read_state_filename);
4527 /* TODO: implement read state. */
4528 }
4529 else if (inputlist)
4530 {
4531 /* These types are set up with #define or else outside of where
4532 we can see them. We should initialize them before calling
4533 read_input_list. */
4534 #define POS_HERE(Call) do { pos.file = this_file; pos.line = __LINE__; \
4535 Call;} while(0)
4536 POS_HERE (do_scalar_typedef ("CUMULATIVE_ARGS", &pos));
4537 POS_HERE (do_scalar_typedef ("REAL_VALUE_TYPE", &pos));
4538 POS_HERE (do_scalar_typedef ("FIXED_VALUE_TYPE", &pos));
4539 POS_HERE (do_scalar_typedef ("double_int", &pos));
4540 POS_HERE (do_scalar_typedef ("uint64_t", &pos));
4541 POS_HERE (do_scalar_typedef ("uint8", &pos));
4542 POS_HERE (do_scalar_typedef ("jword", &pos));
4543 POS_HERE (do_scalar_typedef ("JCF_u2", &pos));
4544 POS_HERE (do_scalar_typedef ("void", &pos));
4545 POS_HERE (do_typedef ("PTR",
4546 create_pointer (resolve_typedef ("void", &pos)),
4547 &pos));
4548 #undef POS_HERE
4549 read_input_list (inputlist);
4550 for (i = 0; i < num_gt_files; i++)
4551 {
4552 parse_file (gt_files[i]);
4553 DBGPRINTF ("parsed file #%d %s", (int) i, gt_files[i]);
4554 }
4555 if (verbosity_level >= 1)
4556 printf ("%s parsed %d files\n", progname, (int) num_gt_files);
4557
4558 DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
4559 DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
4560
4561 }
4562 else
4563 fatal ("either an input list or a read state file should be given");
4564 if (hit_error)
4565 return 1;
4566
4567
4568 if (plugin_output_filename)
4569 {
4570 size_t ix = 0;
4571 /* In plugin mode, we should have read a state file, and have
4572 given at least one plugin file. */
4573 if (!read_state_filename)
4574 fatal ("No read state given in plugin mode for %s",
4575 plugin_output_filename);
4576
4577 if (nb_plugin_files == 0 || !plugin_files)
4578 fatal ("No plugin files given in plugin mode for %s",
4579 plugin_output_filename);
4580
4581 /* Parse our plugin files. */
4582 for (ix = 0; ix < nb_plugin_files; ix++)
4583 parse_file (plugin_files[ix]);
4584
4585 if (hit_error)
4586 return 1;
4587
4588 plugin_output = create_file ("GCC", plugin_output_filename);
4589 DBGPRINTF ("created plugin_output %p named %s",
4590 (void *) plugin_output, plugin_output->name);
4591 }
4592 else
4593 { /* No plugin files, we are in normal mode. */
4594 if (!srcdir)
4595 fatal ("gengtype needs a source directory in normal mode");
4596 }
4597 if (hit_error)
4598 return 1;
4599
4600 gen_rtx_next ();
4601
4602 /* The call to set_gc_used may indirectly call find_param_structure
4603 hence enlarge the param_structs list of types. */
4604 set_gc_used (variables);
4605
4606 /* We should write the state here, but it is not yet implemented. */
4607 if (write_state_filename)
4608 {
4609 fatal ("write state %s in not yet implemented", write_state_filename);
4610 /* TODO: implement write state. */
4611 }
4612
4613
4614 open_base_files ();
4615
4616 write_enum_defn (structures, param_structs);
4617 write_typed_alloc_defns (structures, typedefs);
4618 output_header = plugin_output ? plugin_output : header_file;
4619 DBGPRINT_COUNT_TYPE ("structures before write_types outputheader",
4620 structures);
4621 DBGPRINT_COUNT_TYPE ("param_structs before write_types outputheader",
4622 param_structs);
4623
4624 write_types (output_header, structures, param_structs, &ggc_wtd);
4625 if (plugin_files == NULL)
4626 {
4627 DBGPRINT_COUNT_TYPE ("structures before write_types headerfil",
4628 structures);
4629 DBGPRINT_COUNT_TYPE ("param_structs before write_types headerfil",
4630 param_structs);
4631 write_types (header_file, structures, param_structs, &pch_wtd);
4632 write_local (header_file, structures, param_structs);
4633 }
4634 write_splay_tree_allocators (param_structs);
4635 write_roots (variables, plugin_files == NULL);
4636 write_rtx_next ();
4637 close_output_files ();
4638
4639 if (do_dump)
4640 dump_everything ();
4641
4642 /* Don't bother about free-ing any input or plugin file, etc. */
4643
4644 if (hit_error)
4645 return 1;
4646 return 0;
4647 }