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