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