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