]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gengtype.c
gengtype.c (write_root, [...]): Add a emit_pch 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;
9f78bf05 147static size_t nb_plugin_files;
bd117bb6 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 {
9f78bf05 467 size_t i;
bd117bb6
BS
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 {
9f78bf05
BS
1719 int ix= -1;
1720 size_t i;
bd117bb6
BS
1721 for (i = 0; i < nb_plugin_files && ix < 0; i++)
1722 if (strcmp (input_file, plugin_files[i]) == 0)
1723 ix = i;
1724 if (ix < 0)
1725 return NULL;
1726 }
1727
e2500fed
GK
1728 /* Determine the output file name. */
1729 basename = get_file_basename (input_file);
1730
1731 len = strlen (basename);
1732 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1733 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1734 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1735 {
8de8de02 1736 output_name = get_file_gtfilename (input_file);
e03856fe 1737 for_name = basename;
e2500fed 1738 }
ad8c162b
ZL
1739 /* Some headers get used by more than one front-end; hence, it
1740 would be inappropriate to spew them out to a single gtype-<lang>.h
1741 (and gengtype doesn't know how to direct spewage into multiple
1742 gtype-<lang>.h headers at this time). Instead, we pair up these
1743 headers with source files (and their special purpose gt-*.h headers). */
e2500fed 1744 else if (strcmp (basename, "c-common.h") == 0)
e03856fe 1745 output_name = "gt-c-common.h", for_name = "c-common.c";
29cc57cf
RG
1746 else if (strcmp (basename, "c-lang.h") == 0)
1747 output_name = "gt-c-decl.h", for_name = "c-decl.c";
e2500fed 1748 else if (strcmp (basename, "c-tree.h") == 0)
e03856fe 1749 output_name = "gt-c-decl.h", for_name = "c-decl.c";
6e955430
ZL
1750 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1751 && strcmp (basename + 3, "cp-tree.h") == 0)
1752 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1753 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1754 && strcmp (basename + 3, "decl.h") == 0)
1755 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1756 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1757 && strcmp (basename + 3, "name-lookup.h") == 0)
1758 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
ad8c162b
ZL
1759 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1760 && strcmp (basename + 5, "objc-act.h") == 0)
1761 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1762 else
e2500fed 1763 {
8de8de02 1764 int lang_index = get_prefix_langdir_index (basename);
3d7aafde 1765
8de8de02
OH
1766 if (lang_index >= 0)
1767 return base_files[lang_index];
e03856fe
GK
1768
1769 output_name = "gtype-desc.c";
1770 for_name = NULL;
e2500fed
GK
1771 }
1772
1773 /* Look through to see if we've ever seen this output filename before. */
e03856fe
GK
1774 for (r = output_files; r; r = r->next)
1775 if (strcmp (r->name, output_name) == 0)
1776 return r;
e2500fed
GK
1777
1778 /* If not, create it. */
e03856fe 1779 r = create_file (for_name, output_name);
e2500fed 1780
bd117bb6 1781 gcc_assert (r && r->name);
e03856fe 1782 return r;
e2500fed
GK
1783}
1784
9f313342
GK
1785/* The name of an output file, suitable for definitions, that can see
1786 declarations made in INPUT_FILE and is linked into every language
1787 that uses INPUT_FILE. */
1788
e2500fed 1789const char *
3d7aafde 1790get_output_file_name (const char *input_file)
e2500fed 1791{
bd117bb6
BS
1792 outf_p o = get_output_file_with_visibility (input_file);
1793 if (o)
1794 return o->name;
1795 return NULL;
e2500fed
GK
1796}
1797
41e7ac51
BS
1798/* Check if existing file is equal to the in memory buffer. */
1799
1800static bool
1801is_file_equal (outf_p of)
1802{
1803 FILE *newfile = fopen (of->name, "r");
1804 size_t i;
1805 bool equal;
1806 if (newfile == NULL)
1807 return false;
1808
1809 equal = true;
1810 for (i = 0; i < of->bufused; i++)
1811 {
1812 int ch;
1813 ch = fgetc (newfile);
1814 if (ch == EOF || ch != (unsigned char) of->buf[i])
1815 {
1816 equal = false;
1817 break;
1818 }
1819 }
1820 fclose (newfile);
1821 return equal;
1822}
1823
e03856fe 1824/* Copy the output to its final destination,
9f313342
GK
1825 but don't unnecessarily change modification times. */
1826
e2500fed 1827static void
3d7aafde 1828close_output_files (void)
e2500fed 1829{
e03856fe 1830 outf_p of;
3d7aafde 1831
e03856fe 1832 for (of = output_files; of; of = of->next)
e2500fed 1833 {
e2500fed 1834
41e7ac51
BS
1835 if (!is_file_equal(of))
1836 {
1837 FILE *newfile = fopen (of->name, "w");
1838 if (newfile == NULL)
1839 fatal ("opening output file %s: %s", of->name, strerror (errno));
1840 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1841 fatal ("writing output file %s: %s", of->name, strerror (errno));
1842 if (fclose (newfile) != 0)
1843 fatal ("closing output file %s: %s", of->name, strerror (errno));
1844 }
1845 free(of->buf);
1846 of->buf = NULL;
1847 of->bufused = of->buflength = 0;
e2500fed
GK
1848 }
1849}
1850\f
1851struct flist {
1852 struct flist *next;
1853 int started_p;
1854 const char *name;
e03856fe 1855 outf_p f;
e2500fed
GK
1856};
1857
17211ab5
GK
1858struct walk_type_data;
1859
1860/* For scalars and strings, given the item in 'val'.
1861 For structures, given a pointer to the item in 'val'.
1862 For misc. pointers, given the item in 'val'.
1863*/
3d7aafde
AJ
1864typedef void (*process_field_fn)
1865 (type_p f, const struct walk_type_data *p);
17211ab5 1866typedef void (*func_name_fn)
3d7aafde 1867 (type_p s, const struct walk_type_data *p);
17211ab5
GK
1868
1869/* Parameters for write_types. */
1870
3d7aafde 1871struct write_types_data
17211ab5
GK
1872{
1873 const char *prefix;
1874 const char *param_prefix;
1875 const char *subfield_marker_routine;
1876 const char *marker_routine;
1877 const char *reorder_note_routine;
1878 const char *comment;
8d6419b2 1879 int skip_hooks; /* skip hook generation if non zero */
17211ab5
GK
1880};
1881
3d7aafde
AJ
1882static void output_escaped_param (struct walk_type_data *d,
1883 const char *, const char *);
e5cfc29f 1884static void output_mangled_typename (outf_p, const_type_p);
3d7aafde 1885static void walk_type (type_p t, struct walk_type_data *d);
17211ab5 1886static void write_func_for_structure
3d7aafde
AJ
1887 (type_p orig_s, type_p s, type_p * param,
1888 const struct write_types_data *wtd);
1889static void write_types_process_field
1890 (type_p f, const struct walk_type_data *d);
0182d016
BS
1891static void write_types (outf_p output_header,
1892 type_p structures,
3d7aafde
AJ
1893 type_p param_structs,
1894 const struct write_types_data *wtd);
17211ab5 1895static void write_types_local_process_field
3d7aafde 1896 (type_p f, const struct walk_type_data *d);
17211ab5 1897static void write_local_func_for_structure
3d7aafde 1898 (type_p orig_s, type_p s, type_p * param);
0182d016
BS
1899static void write_local (outf_p output_header,
1900 type_p structures,
3d7aafde
AJ
1901 type_p param_structs);
1902static void write_enum_defn (type_p structures, type_p param_structs);
1903static int contains_scalar_p (type_p t);
1904static void put_mangled_filename (outf_p , const char *);
1905static void finish_root_table (struct flist *flp, const char *pfx,
1906 const char *tname, const char *lastname,
1907 const char *name);
1908static void write_root (outf_p , pair_p, type_p, const char *, int,
99be7084 1909 struct fileloc *, const char *, bool);
3d7aafde
AJ
1910static void write_array (outf_p f, pair_p v,
1911 const struct write_types_data *wtd);
99be7084 1912static void write_roots (pair_p, bool);
e2500fed 1913
17211ab5 1914/* Parameters for walk_type. */
e2500fed 1915
17211ab5 1916struct walk_type_data
e2500fed 1917{
17211ab5
GK
1918 process_field_fn process_field;
1919 const void *cookie;
1920 outf_p of;
1921 options_p opt;
1922 const char *val;
1923 const char *prev_val[4];
1924 int indent;
1925 int counter;
1926 struct fileloc *line;
1927 lang_bitmap bitmap;
1928 type_p *param;
1929 int used_length;
1930 type_p orig_s;
1931 const char *reorder_fn;
d8044160
GK
1932 bool needs_cast_p;
1933 bool fn_wants_lvalue;
17211ab5 1934};
36a5eadd
GK
1935
1936/* Print a mangled name representing T to OF. */
1937
1938static void
e5cfc29f 1939output_mangled_typename (outf_p of, const_type_p t)
36a5eadd
GK
1940{
1941 if (t == NULL)
1942 oprintf (of, "Z");
1943 else switch (t->kind)
1944 {
1945 case TYPE_POINTER:
1946 oprintf (of, "P");
1947 output_mangled_typename (of, t->u.p);
1948 break;
1949 case TYPE_SCALAR:
1950 oprintf (of, "I");
1951 break;
1952 case TYPE_STRING:
1953 oprintf (of, "S");
1954 break;
1955 case TYPE_STRUCT:
1956 case TYPE_UNION:
1957 case TYPE_LANG_STRUCT:
6d8dd940 1958 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
36a5eadd
GK
1959 break;
1960 case TYPE_PARAM_STRUCT:
1961 {
1962 int i;
1963 for (i = 0; i < NUM_PARAM; i++)
1964 if (t->u.param_struct.param[i] != NULL)
1965 output_mangled_typename (of, t->u.param_struct.param[i]);
3d7aafde 1966 output_mangled_typename (of, t->u.param_struct.stru);
36a5eadd
GK
1967 }
1968 break;
1969 case TYPE_ARRAY:
b2d59f6f 1970 gcc_unreachable ();
36a5eadd 1971 }
e2500fed
GK
1972}
1973
17211ab5
GK
1974/* Print PARAM to D->OF processing escapes. D->VAL references the
1975 current object, D->PREV_VAL the object containing the current
1976 object, ONAME is the name of the option and D->LINE is used to
1977 print error messages. */
9f313342 1978
e2500fed 1979static void
3d7aafde
AJ
1980output_escaped_param (struct walk_type_data *d, const char *param,
1981 const char *oname)
e2500fed 1982{
17211ab5 1983 const char *p;
3d7aafde 1984
17211ab5
GK
1985 for (p = param; *p; p++)
1986 if (*p != '%')
1987 oprintf (d->of, "%c", *p);
1988 else switch (*++p)
1989 {
1990 case 'h':
1991 oprintf (d->of, "(%s)", d->prev_val[2]);
1992 break;
1993 case '0':
1994 oprintf (d->of, "(%s)", d->prev_val[0]);
1995 break;
1996 case '1':
1997 oprintf (d->of, "(%s)", d->prev_val[1]);
1998 break;
1999 case 'a':
e2500fed 2000 {
17211ab5
GK
2001 const char *pp = d->val + strlen (d->val);
2002 while (pp[-1] == ']')
2003 while (*pp != '[')
2004 pp--;
2005 oprintf (d->of, "%s", pp);
e2500fed 2006 }
17211ab5
GK
2007 break;
2008 default:
2009 error_at_line (d->line, "`%s' option contains bad escape %c%c",
2010 oname, '%', *p);
2011 }
2012}
e2500fed 2013
17211ab5
GK
2014/* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
2015 which is of type T. Write code to D->OF to constrain execution (at
2016 the point that D->PROCESS_FIELD is called) to the appropriate
4da6879c
GK
2017 cases. Call D->PROCESS_FIELD on subobjects before calling it on
2018 pointers to those objects. D->PREV_VAL lists the objects
2019 containing the current object, D->OPT is a list of options to
2020 apply, D->INDENT is the current indentation level, D->LINE is used
2021 to print error messages, D->BITMAP indicates which languages to
2022 print the structure for, and D->PARAM is the current parameter
2023 (from an enclosing param_is option). */
e2500fed 2024
17211ab5 2025static void
3d7aafde 2026walk_type (type_p t, struct walk_type_data *d)
17211ab5
GK
2027{
2028 const char *length = NULL;
2029 const char *desc = NULL;
2030 int maybe_undef_p = 0;
2031 int use_param_num = -1;
2032 int use_params_p = 0;
17211ab5 2033 options_p oo;
b453c95f 2034 const struct nested_ptr_data *nested_ptr_d = NULL;
3d7aafde 2035
d8044160 2036 d->needs_cast_p = false;
17211ab5
GK
2037 for (oo = d->opt; oo; oo = oo->next)
2038 if (strcmp (oo->name, "length") == 0)
9e2878cf 2039 length = oo->info;
17211ab5
GK
2040 else if (strcmp (oo->name, "maybe_undef") == 0)
2041 maybe_undef_p = 1;
2042 else if (strncmp (oo->name, "use_param", 9) == 0
2043 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2044 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
2045 else if (strcmp (oo->name, "use_params") == 0)
2046 use_params_p = 1;
2047 else if (strcmp (oo->name, "desc") == 0)
9e2878cf 2048 desc = oo->info;
8d6419b2
BS
2049 else if (strcmp (oo->name, "mark_hook") == 0)
2050 ;
b453c95f 2051 else if (strcmp (oo->name, "nested_ptr") == 0)
d8044160 2052 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
17211ab5
GK
2053 else if (strcmp (oo->name, "dot") == 0)
2054 ;
2055 else if (strcmp (oo->name, "tag") == 0)
2056 ;
2057 else if (strcmp (oo->name, "special") == 0)
2058 ;
2059 else if (strcmp (oo->name, "skip") == 0)
2060 ;
2061 else if (strcmp (oo->name, "default") == 0)
2062 ;
2063 else if (strcmp (oo->name, "descbits") == 0)
2064 ;
2065 else if (strcmp (oo->name, "param_is") == 0)
2066 ;
084087e1
RH
2067 else if (strncmp (oo->name, "param", 5) == 0
2068 && ISDIGIT (oo->name[5])
2069 && strcmp (oo->name + 6, "_is") == 0)
2070 ;
17211ab5
GK
2071 else if (strcmp (oo->name, "chain_next") == 0)
2072 ;
2073 else if (strcmp (oo->name, "chain_prev") == 0)
2074 ;
623f8e39
JJ
2075 else if (strcmp (oo->name, "chain_circular") == 0)
2076 ;
17211ab5
GK
2077 else if (strcmp (oo->name, "reorder") == 0)
2078 ;
2079 else
2080 error_at_line (d->line, "unknown option `%s'\n", oo->name);
36a5eadd 2081
17211ab5
GK
2082 if (d->used_length)
2083 length = NULL;
36a5eadd 2084
17211ab5
GK
2085 if (use_params_p)
2086 {
2087 int pointer_p = t->kind == TYPE_POINTER;
3d7aafde 2088
17211ab5
GK
2089 if (pointer_p)
2090 t = t->u.p;
2091 if (! UNION_OR_STRUCT_P (t))
2092 error_at_line (d->line, "`use_params' option on unimplemented type");
3d7aafde 2093 else
17211ab5
GK
2094 t = find_param_structure (t, d->param);
2095 if (pointer_p)
2096 t = create_pointer (t);
2097 }
3d7aafde 2098
17211ab5
GK
2099 if (use_param_num != -1)
2100 {
2101 if (d->param != NULL && d->param[use_param_num] != NULL)
e2500fed 2102 {
17211ab5 2103 type_p nt = d->param[use_param_num];
3d7aafde 2104
17211ab5
GK
2105 if (t->kind == TYPE_ARRAY)
2106 nt = create_array (nt, t->u.a.len);
2107 else if (length != NULL && t->kind == TYPE_POINTER)
2108 nt = create_pointer (nt);
f099d360
GK
2109 d->needs_cast_p = (t->kind != TYPE_POINTER
2110 && (nt->kind == TYPE_POINTER
2111 || nt->kind == TYPE_STRING));
17211ab5 2112 t = nt;
e2500fed 2113 }
17211ab5
GK
2114 else
2115 error_at_line (d->line, "no parameter defined for `%s'",
2116 d->val);
2117 }
3d7aafde
AJ
2118
2119 if (maybe_undef_p
17211ab5
GK
2120 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
2121 {
3d7aafde 2122 error_at_line (d->line,
17211ab5
GK
2123 "field `%s' has invalid option `maybe_undef_p'\n",
2124 d->val);
2125 return;
2126 }
3d7aafde 2127
17211ab5
GK
2128 switch (t->kind)
2129 {
2130 case TYPE_SCALAR:
2131 case TYPE_STRING:
2132 d->process_field (t, d);
2133 break;
3d7aafde 2134
17211ab5
GK
2135 case TYPE_POINTER:
2136 {
2137 if (maybe_undef_p
2138 && t->u.p->u.s.line.file == NULL)
2139 {
b2d59f6f 2140 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
17211ab5
GK
2141 break;
2142 }
e2500fed 2143
17211ab5 2144 if (! length)
e2500fed 2145 {
17211ab5
GK
2146 if (! UNION_OR_STRUCT_P (t->u.p)
2147 && t->u.p->kind != TYPE_PARAM_STRUCT)
e2500fed 2148 {
3d7aafde 2149 error_at_line (d->line,
17211ab5
GK
2150 "field `%s' is pointer to unimplemented type",
2151 d->val);
e2500fed
GK
2152 break;
2153 }
3d7aafde 2154
b453c95f
GK
2155 if (nested_ptr_d)
2156 {
2157 const char *oldprevval2 = d->prev_val[2];
2158
2159 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2160 {
2161 error_at_line (d->line,
2162 "field `%s' has invalid "
2163 "option `nested_ptr'\n",
2164 d->val);
2165 return;
2166 }
2167
2168 d->prev_val[2] = d->val;
2169 oprintf (d->of, "%*s{\n", d->indent, "");
2170 d->indent += 2;
2171 d->val = xasprintf ("x%d", d->counter++);
d8044160 2172 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
b453c95f
GK
2173 (nested_ptr_d->type->kind == TYPE_UNION
2174 ? "union" : "struct"),
d8044160
GK
2175 nested_ptr_d->type->u.s.tag,
2176 d->fn_wants_lvalue ? "" : "const ",
2177 d->val);
b453c95f
GK
2178 oprintf (d->of, "%*s", d->indent + 2, "");
2179 output_escaped_param (d, nested_ptr_d->convert_from,
2180 "nested_ptr");
2181 oprintf (d->of, ";\n");
2182
2183 d->process_field (nested_ptr_d->type, d);
2184
d8044160
GK
2185 if (d->fn_wants_lvalue)
2186 {
2187 oprintf (d->of, "%*s%s = ", d->indent, "",
2188 d->prev_val[2]);
2189 d->prev_val[2] = d->val;
2190 output_escaped_param (d, nested_ptr_d->convert_to,
2191 "nested_ptr");
2192 oprintf (d->of, ";\n");
2193 }
b453c95f
GK
2194
2195 d->indent -= 2;
2196 oprintf (d->of, "%*s}\n", d->indent, "");
2197 d->val = d->prev_val[2];
2198 d->prev_val[2] = oldprevval2;
2199 }
2200 else
2201 d->process_field (t->u.p, d);
e2500fed 2202 }
3d7aafde 2203 else
e2500fed 2204 {
17211ab5
GK
2205 int loopcounter = d->counter++;
2206 const char *oldval = d->val;
2207 const char *oldprevval3 = d->prev_val[3];
e2500fed
GK
2208 char *newval;
2209
17211ab5
GK
2210 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2211 d->indent += 2;
2212 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
a62a0172 2213 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
17211ab5
GK
2214 loopcounter, loopcounter);
2215 output_escaped_param (d, length, "length");
2216 oprintf (d->of, "); i%d++) {\n", loopcounter);
2217 d->indent += 2;
2218 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2219 d->used_length = 1;
2220 d->prev_val[3] = oldval;
2221 walk_type (t->u.p, d);
e2500fed 2222 free (newval);
17211ab5
GK
2223 d->val = oldval;
2224 d->prev_val[3] = oldprevval3;
2225 d->used_length = 0;
2226 d->indent -= 2;
2227 oprintf (d->of, "%*s}\n", d->indent, "");
4da6879c 2228 d->process_field(t, d);
17211ab5
GK
2229 d->indent -= 2;
2230 oprintf (d->of, "%*s}\n", d->indent, "");
e2500fed 2231 }
17211ab5
GK
2232 }
2233 break;
e2500fed 2234
17211ab5
GK
2235 case TYPE_ARRAY:
2236 {
2237 int loopcounter = d->counter++;
2238 const char *oldval = d->val;
2239 char *newval;
2240
6356f892 2241 /* If it's an array of scalars, we optimize by not generating
17211ab5
GK
2242 any code. */
2243 if (t->u.a.p->kind == TYPE_SCALAR)
e2500fed 2244 break;
3d7aafde 2245
5039610b
SL
2246 /* When walking an array, compute the length and store it in a
2247 local variable before walking the array elements, instead of
2248 recomputing the length expression each time through the loop.
2249 This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2250 where the length is stored in the first array element,
2251 because otherwise that operand can get overwritten on the
2252 first iteration. */
17211ab5
GK
2253 oprintf (d->of, "%*s{\n", d->indent, "");
2254 d->indent += 2;
2255 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
5039610b
SL
2256 oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2257 d->indent, "", loopcounter);
17211ab5
GK
2258 if (length)
2259 output_escaped_param (d, length, "length");
2260 else
2261 oprintf (d->of, "%s", t->u.a.len);
5039610b
SL
2262 oprintf (d->of, ");\n");
2263
2264 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2265 d->indent, "",
2266 loopcounter, loopcounter, loopcounter, loopcounter);
17211ab5
GK
2267 d->indent += 2;
2268 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2269 d->used_length = 1;
2270 walk_type (t->u.a.p, d);
2271 free (newval);
2272 d->used_length = 0;
2273 d->val = oldval;
2274 d->indent -= 2;
2275 oprintf (d->of, "%*s}\n", d->indent, "");
2276 d->indent -= 2;
2277 oprintf (d->of, "%*s}\n", d->indent, "");
2278 }
2279 break;
3d7aafde 2280
17211ab5
GK
2281 case TYPE_STRUCT:
2282 case TYPE_UNION:
2283 {
2284 pair_p f;
2285 const char *oldval = d->val;
2286 const char *oldprevval1 = d->prev_val[1];
2287 const char *oldprevval2 = d->prev_val[2];
2288 const int union_p = t->kind == TYPE_UNION;
2289 int seen_default_p = 0;
2290 options_p o;
2291
2292 if (! t->u.s.line.file)
2293 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
e2500fed 2294
17211ab5 2295 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
e2500fed 2296 {
17211ab5
GK
2297 error_at_line (d->line,
2298 "structure `%s' defined for mismatching languages",
2299 t->u.s.tag);
2300 error_at_line (&t->u.s.line, "one structure defined here");
2301 }
e2500fed 2302
17211ab5
GK
2303 /* Some things may also be defined in the structure's options. */
2304 for (o = t->u.s.opt; o; o = o->next)
2305 if (! desc && strcmp (o->name, "desc") == 0)
9e2878cf 2306 desc = o->info;
e2500fed 2307
17211ab5
GK
2308 d->prev_val[2] = oldval;
2309 d->prev_val[1] = oldprevval2;
2310 if (union_p)
2311 {
2312 if (desc == NULL)
e2500fed 2313 {
17211ab5
GK
2314 error_at_line (d->line, "missing `desc' option for union `%s'",
2315 t->u.s.tag);
2316 desc = "1";
e2500fed 2317 }
17211ab5
GK
2318 oprintf (d->of, "%*sswitch (", d->indent, "");
2319 output_escaped_param (d, desc, "desc");
2320 oprintf (d->of, ")\n");
2321 d->indent += 2;
2322 oprintf (d->of, "%*s{\n", d->indent, "");
2323 }
2324 for (f = t->u.s.fields; f; f = f->next)
2325 {
2326 options_p oo;
2327 const char *dot = ".";
2328 const char *tagid = NULL;
2329 int skip_p = 0;
2330 int default_p = 0;
2331 int use_param_p = 0;
2332 char *newval;
2333
2334 d->reorder_fn = NULL;
2335 for (oo = f->opt; oo; oo = oo->next)
2336 if (strcmp (oo->name, "dot") == 0)
9e2878cf 2337 dot = oo->info;
17211ab5 2338 else if (strcmp (oo->name, "tag") == 0)
9e2878cf 2339 tagid = oo->info;
17211ab5
GK
2340 else if (strcmp (oo->name, "skip") == 0)
2341 skip_p = 1;
2342 else if (strcmp (oo->name, "default") == 0)
2343 default_p = 1;
2344 else if (strcmp (oo->name, "reorder") == 0)
9e2878cf 2345 d->reorder_fn = oo->info;
17211ab5
GK
2346 else if (strncmp (oo->name, "use_param", 9) == 0
2347 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2348 use_param_p = 1;
2349
2350 if (skip_p)
2351 continue;
2352
2353 if (union_p && tagid)
e2500fed 2354 {
17211ab5
GK
2355 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2356 d->indent += 2;
e2500fed 2357 }
17211ab5 2358 else if (union_p && default_p)
e2500fed 2359 {
17211ab5
GK
2360 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2361 d->indent += 2;
2362 seen_default_p = 1;
e2500fed 2363 }
17211ab5 2364 else if (! union_p && (default_p || tagid))
3d7aafde 2365 error_at_line (d->line,
17211ab5
GK
2366 "can't use `%s' outside a union on field `%s'",
2367 default_p ? "default" : "tag", f->name);
2368 else if (union_p && ! (default_p || tagid)
2369 && f->type->kind == TYPE_SCALAR)
e2500fed 2370 {
17211ab5
GK
2371 fprintf (stderr,
2372 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2373 d->line->file, d->line->line, f->name);
2374 continue;
e2500fed 2375 }
17211ab5 2376 else if (union_p && ! (default_p || tagid))
3d7aafde 2377 error_at_line (d->line,
17211ab5 2378 "field `%s' is missing `tag' or `default' option",
e2500fed 2379 f->name);
3d7aafde 2380
17211ab5
GK
2381 d->line = &f->line;
2382 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2383 d->opt = f->opt;
d8044160 2384 d->used_length = false;
17211ab5
GK
2385
2386 if (union_p && use_param_p && d->param == NULL)
b2d59f6f 2387 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
17211ab5
GK
2388 else
2389 walk_type (f->type, d);
2390
2391 free (newval);
2392
2393 if (union_p)
e2500fed 2394 {
17211ab5
GK
2395 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2396 d->indent -= 2;
e2500fed 2397 }
17211ab5
GK
2398 }
2399 d->reorder_fn = NULL;
e2500fed 2400
17211ab5
GK
2401 d->val = oldval;
2402 d->prev_val[1] = oldprevval1;
2403 d->prev_val[2] = oldprevval2;
2404
2405 if (union_p && ! seen_default_p)
2406 {
2407 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2408 oprintf (d->of, "%*s break;\n", d->indent, "");
2409 }
2410 if (union_p)
2411 {
2412 oprintf (d->of, "%*s}\n", d->indent, "");
2413 d->indent -= 2;
e2500fed 2414 }
17211ab5
GK
2415 }
2416 break;
e2500fed 2417
17211ab5
GK
2418 case TYPE_LANG_STRUCT:
2419 {
2420 type_p nt;
2421 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2422 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2423 break;
2424 if (nt == NULL)
2425 error_at_line (d->line, "structure `%s' differs between languages",
2426 t->u.s.tag);
2427 else
2428 walk_type (nt, d);
2429 }
2430 break;
2431
2432 case TYPE_PARAM_STRUCT:
2433 {
2434 type_p *oldparam = d->param;
3d7aafde 2435
17211ab5
GK
2436 d->param = t->u.param_struct.param;
2437 walk_type (t->u.param_struct.stru, d);
2438 d->param = oldparam;
2439 }
2440 break;
3d7aafde 2441
17211ab5 2442 default:
b2d59f6f 2443 gcc_unreachable ();
e2500fed 2444 }
17211ab5
GK
2445}
2446
2447/* process_field routine for marking routines. */
2448
2449static void
3d7aafde 2450write_types_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
2451{
2452 const struct write_types_data *wtd;
f099d360 2453 const char *cast = d->needs_cast_p ? "(void *)" : "";
17211ab5 2454 wtd = (const struct write_types_data *) d->cookie;
3d7aafde 2455
17211ab5 2456 switch (f->kind)
e2500fed 2457 {
17211ab5 2458 case TYPE_POINTER:
3d7aafde 2459 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
f099d360 2460 wtd->subfield_marker_routine, cast, d->val);
17211ab5 2461 if (wtd->param_prefix)
36a5eadd 2462 {
17211ab5
GK
2463 oprintf (d->of, ", %s", d->prev_val[3]);
2464 if (d->orig_s)
2465 {
2466 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2467 output_mangled_typename (d->of, d->orig_s);
2468 }
2469 else
2470 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
08cee789
DJ
2471
2472 if (f->u.p->kind == TYPE_PARAM_STRUCT
2473 && f->u.p->u.s.line.file != NULL)
2474 {
2475 oprintf (d->of, ", gt_e_");
2476 output_mangled_typename (d->of, f);
2477 }
2478 else if (UNION_OR_STRUCT_P (f)
2479 && f->u.p->u.s.line.file != NULL)
2480 {
2481 oprintf (d->of, ", gt_ggc_e_");
2482 output_mangled_typename (d->of, f);
2483 }
2484 else
2485 oprintf (d->of, ", gt_types_enum_last");
36a5eadd 2486 }
17211ab5
GK
2487 oprintf (d->of, ");\n");
2488 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2489 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
f099d360 2490 wtd->reorder_note_routine, cast, d->val,
17211ab5
GK
2491 d->prev_val[3], d->reorder_fn);
2492 break;
2493
2494 case TYPE_STRING:
17211ab5
GK
2495 case TYPE_STRUCT:
2496 case TYPE_UNION:
2497 case TYPE_LANG_STRUCT:
2498 case TYPE_PARAM_STRUCT:
2499 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2500 output_mangled_typename (d->of, f);
f099d360 2501 oprintf (d->of, " (%s%s);\n", cast, d->val);
17211ab5 2502 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2503 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
f099d360 2504 wtd->reorder_note_routine, cast, d->val, cast, d->val,
17211ab5
GK
2505 d->reorder_fn);
2506 break;
2507
2508 case TYPE_SCALAR:
2509 break;
3d7aafde 2510
17211ab5 2511 default:
b2d59f6f 2512 gcc_unreachable ();
e2500fed
GK
2513 }
2514}
2515
2d82317d
RH
2516/* A subroutine of write_func_for_structure. Write the enum tag for S. */
2517
2518static void
2519output_type_enum (outf_p of, type_p s)
2520{
2521 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2522 {
2523 oprintf (of, ", gt_e_");
2524 output_mangled_typename (of, s);
2525 }
2526 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2527 {
2528 oprintf (of, ", gt_ggc_e_");
2529 output_mangled_typename (of, s);
2530 }
2531 else
2532 oprintf (of, ", gt_types_enum_last");
2533}
2534
17211ab5
GK
2535/* For S, a structure that's part of ORIG_S, and using parameters
2536 PARAM, write out a routine that:
2537 - Takes a parameter, a void * but actually of type *S
2538 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2539 field of S or its substructures and (in some cases) things
2540 that are pointed to by S.
2541*/
9f313342 2542
e2500fed 2543static void
8c80adb7
SB
2544write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2545 const struct write_types_data *wtd)
e2500fed 2546{
36a5eadd
GK
2547 const char *fn = s->u.s.line.file;
2548 int i;
2549 const char *chain_next = NULL;
2550 const char *chain_prev = NULL;
623f8e39 2551 const char *chain_circular = NULL;
8d6419b2 2552 const char *mark_hook_name = NULL;
36a5eadd 2553 options_p opt;
17211ab5 2554 struct walk_type_data d;
3d7aafde 2555
36a5eadd
GK
2556 /* This is a hack, and not the good kind either. */
2557 for (i = NUM_PARAM - 1; i >= 0; i--)
3d7aafde 2558 if (param && param[i] && param[i]->kind == TYPE_POINTER
36a5eadd
GK
2559 && UNION_OR_STRUCT_P (param[i]->u.p))
2560 fn = param[i]->u.p->u.s.line.file;
3d7aafde 2561
17211ab5
GK
2562 memset (&d, 0, sizeof (d));
2563 d.of = get_output_file_with_visibility (fn);
3d7aafde 2564
36a5eadd
GK
2565 for (opt = s->u.s.opt; opt; opt = opt->next)
2566 if (strcmp (opt->name, "chain_next") == 0)
9e2878cf 2567 chain_next = opt->info;
36a5eadd 2568 else if (strcmp (opt->name, "chain_prev") == 0)
9e2878cf 2569 chain_prev = opt->info;
623f8e39
JJ
2570 else if (strcmp (opt->name, "chain_circular") == 0)
2571 chain_circular = opt->info;
8d6419b2
BS
2572 else if (strcmp (opt->name, "mark_hook") == 0)
2573 mark_hook_name = opt->info;
36a5eadd
GK
2574
2575 if (chain_prev != NULL && chain_next == NULL)
2576 error_at_line (&s->u.s.line, "chain_prev without chain_next");
623f8e39
JJ
2577 if (chain_circular != NULL && chain_next != NULL)
2578 error_at_line (&s->u.s.line, "chain_circular with chain_next");
2579 if (chain_circular != NULL)
2580 chain_next = chain_circular;
36a5eadd 2581
17211ab5
GK
2582 d.process_field = write_types_process_field;
2583 d.cookie = wtd;
2584 d.orig_s = orig_s;
2585 d.opt = s->u.s.opt;
2586 d.line = &s->u.s.line;
2587 d.bitmap = s->u.s.bitmap;
2588 d.param = param;
2589 d.prev_val[0] = "*x";
e0a21ab9 2590 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
2591 d.prev_val[3] = "x";
2592 d.val = "(*x)";
2593
2594 oprintf (d.of, "\n");
2595 oprintf (d.of, "void\n");
e2500fed 2596 if (param == NULL)
17211ab5 2597 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
e2500fed 2598 else
36a5eadd 2599 {
17211ab5
GK
2600 oprintf (d.of, "gt_%s_", wtd->prefix);
2601 output_mangled_typename (d.of, orig_s);
36a5eadd 2602 }
6906ba40 2603 oprintf (d.of, " (void *x_p)\n");
17211ab5
GK
2604 oprintf (d.of, "{\n");
2605 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
e2500fed 2606 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
36a5eadd 2607 chain_next == NULL ? "const " : "",
e2500fed 2608 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
36a5eadd 2609 if (chain_next != NULL)
17211ab5 2610 oprintf (d.of, " %s %s * xlimit = x;\n",
36a5eadd
GK
2611 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2612 if (chain_next == NULL)
17211ab5
GK
2613 {
2614 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2615 if (wtd->param_prefix)
2616 {
2617 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2618 output_mangled_typename (d.of, orig_s);
2d82317d 2619 output_type_enum (d.of, orig_s);
17211ab5
GK
2620 }
2621 oprintf (d.of, "))\n");
2622 }
36a5eadd
GK
2623 else
2624 {
623f8e39
JJ
2625 if (chain_circular != NULL)
2626 oprintf (d.of, " if (!%s (xlimit", wtd->marker_routine);
2627 else
2628 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
17211ab5
GK
2629 if (wtd->param_prefix)
2630 {
2631 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2632 output_mangled_typename (d.of, orig_s);
2d82317d 2633 output_type_enum (d.of, orig_s);
17211ab5
GK
2634 }
2635 oprintf (d.of, "))\n");
623f8e39
JJ
2636 if (chain_circular != NULL)
2637 oprintf (d.of, " return;\n do\n");
8d6419b2
BS
2638 if (mark_hook_name && !wtd->skip_hooks)
2639 {
2640 oprintf (d.of, " {\n");
2641 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2642 }
17211ab5
GK
2643 oprintf (d.of, " xlimit = (");
2644 d.prev_val[2] = "*xlimit";
2645 output_escaped_param (&d, chain_next, "chain_next");
2646 oprintf (d.of, ");\n");
8d6419b2
BS
2647 if (mark_hook_name && !wtd->skip_hooks)
2648 oprintf (d.of, " }\n");
36a5eadd
GK
2649 if (chain_prev != NULL)
2650 {
17211ab5
GK
2651 oprintf (d.of, " if (x != xlimit)\n");
2652 oprintf (d.of, " for (;;)\n");
2653 oprintf (d.of, " {\n");
2654 oprintf (d.of, " %s %s * const xprev = (",
36a5eadd 2655 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3d7aafde 2656
17211ab5
GK
2657 d.prev_val[2] = "*x";
2658 output_escaped_param (&d, chain_prev, "chain_prev");
2659 oprintf (d.of, ");\n");
2660 oprintf (d.of, " if (xprev == NULL) break;\n");
2661 oprintf (d.of, " x = xprev;\n");
3d7aafde 2662 oprintf (d.of, " (void) %s (xprev",
17211ab5
GK
2663 wtd->marker_routine);
2664 if (wtd->param_prefix)
2665 {
2666 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2667 output_mangled_typename (d.of, orig_s);
2d82317d 2668 output_type_enum (d.of, orig_s);
17211ab5
GK
2669 }
2670 oprintf (d.of, ");\n");
2671 oprintf (d.of, " }\n");
36a5eadd 2672 }
623f8e39
JJ
2673 if (chain_circular != NULL)
2674 {
2675 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2676 if (wtd->param_prefix)
2677 {
2678 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2679 output_mangled_typename (d.of, orig_s);
2680 output_type_enum (d.of, orig_s);
2681 }
2682 oprintf (d.of, "));\n");
2683 if (mark_hook_name && !wtd->skip_hooks)
2684 oprintf (d.of, " %s (xlimit);\n", mark_hook_name);
2685 oprintf (d.of, " do\n");
2686 }
2687 else
2688 oprintf (d.of, " while (x != xlimit)\n");
36a5eadd 2689 }
17211ab5 2690 oprintf (d.of, " {\n");
8d6419b2
BS
2691 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2692 {
2693 oprintf (d.of, " %s (x);\n", mark_hook_name);
2694 }
17211ab5
GK
2695 d.prev_val[2] = "*x";
2696 d.indent = 6;
2697 walk_type (s, &d);
3d7aafde 2698
36a5eadd
GK
2699 if (chain_next != NULL)
2700 {
17211ab5
GK
2701 oprintf (d.of, " x = (");
2702 output_escaped_param (&d, chain_next, "chain_next");
2703 oprintf (d.of, ");\n");
36a5eadd
GK
2704 }
2705
17211ab5 2706 oprintf (d.of, " }\n");
623f8e39
JJ
2707 if (chain_circular != NULL)
2708 oprintf (d.of, " while (x != xlimit);\n");
17211ab5 2709 oprintf (d.of, "}\n");
e2500fed 2710}
9f313342
GK
2711
2712/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
e2500fed
GK
2713
2714static void
0182d016 2715write_types (outf_p output_header, type_p structures, type_p param_structs,
3d7aafde 2716 const struct write_types_data *wtd)
e2500fed
GK
2717{
2718 type_p s;
3d7aafde 2719
0182d016 2720 oprintf (output_header, "\n/* %s*/\n", wtd->comment);
e2500fed
GK
2721 for (s = structures; s; s = s->next)
2722 if (s->gc_used == GC_POINTED_TO
2723 || s->gc_used == GC_MAYBE_POINTED_TO)
2724 {
2725 options_p opt;
3d7aafde 2726
e2500fed
GK
2727 if (s->gc_used == GC_MAYBE_POINTED_TO
2728 && s->u.s.line.file == NULL)
2729 continue;
2730
0182d016
BS
2731 oprintf (output_header, "#define gt_%s_", wtd->prefix);
2732 output_mangled_typename (output_header, s);
2733 oprintf (output_header, "(X) do { \\\n");
2734 oprintf (output_header,
3d7aafde 2735 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
17211ab5 2736 s->u.s.tag);
0182d016 2737 oprintf (output_header,
e2500fed 2738 " } while (0)\n");
3d7aafde 2739
e2500fed
GK
2740 for (opt = s->u.s.opt; opt; opt = opt->next)
2741 if (strcmp (opt->name, "ptr_alias") == 0)
2742 {
e5cfc29f 2743 const_type_p const t = (const_type_p) opt->info;
3d7aafde 2744 if (t->kind == TYPE_STRUCT
e2500fed
GK
2745 || t->kind == TYPE_UNION
2746 || t->kind == TYPE_LANG_STRUCT)
0182d016 2747 oprintf (output_header,
17211ab5
GK
2748 "#define gt_%sx_%s gt_%sx_%s\n",
2749 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
e2500fed 2750 else
3d7aafde 2751 error_at_line (&s->u.s.line,
e2500fed
GK
2752 "structure alias is not a structure");
2753 break;
2754 }
2755 if (opt)
2756 continue;
2757
2758 /* Declare the marker procedure only once. */
0182d016 2759 oprintf (output_header,
3d7aafde 2760 "extern void gt_%sx_%s (void *);\n",
17211ab5 2761 wtd->prefix, s->u.s.tag);
3d7aafde 2762
e2500fed
GK
2763 if (s->u.s.line.file == NULL)
2764 {
3d7aafde 2765 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2766 s->u.s.tag);
2767 continue;
2768 }
3d7aafde 2769
e2500fed
GK
2770 if (s->kind == TYPE_LANG_STRUCT)
2771 {
2772 type_p ss;
2773 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
17211ab5 2774 write_func_for_structure (s, ss, NULL, wtd);
e2500fed
GK
2775 }
2776 else
17211ab5 2777 write_func_for_structure (s, s, NULL, wtd);
e2500fed
GK
2778 }
2779
2780 for (s = param_structs; s; s = s->next)
2781 if (s->gc_used == GC_POINTED_TO)
2782 {
36a5eadd 2783 type_p * param = s->u.param_struct.param;
e2500fed
GK
2784 type_p stru = s->u.param_struct.stru;
2785
e2500fed 2786 /* Declare the marker procedure. */
0182d016
BS
2787 oprintf (output_header, "extern void gt_%s_", wtd->prefix);
2788 output_mangled_typename (output_header, s);
2789 oprintf (output_header, " (void *);\n");
3d7aafde 2790
e2500fed
GK
2791 if (stru->u.s.line.file == NULL)
2792 {
3d7aafde 2793 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2794 s->u.s.tag);
2795 continue;
2796 }
3d7aafde 2797
e2500fed
GK
2798 if (stru->kind == TYPE_LANG_STRUCT)
2799 {
2800 type_p ss;
2801 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
17211ab5
GK
2802 write_func_for_structure (s, ss, param, wtd);
2803 }
2804 else
2805 write_func_for_structure (s, stru, param, wtd);
2806 }
2807}
2808
2809static const struct write_types_data ggc_wtd =
2810{
2811 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
8d6419b2
BS
2812 "GC marker procedures. ",
2813 FALSE
17211ab5
GK
2814};
2815
2816static const struct write_types_data pch_wtd =
2817{
2818 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2819 "gt_pch_note_reorder",
8d6419b2
BS
2820 "PCH type-walking procedures. ",
2821 TRUE
17211ab5
GK
2822};
2823
2824/* Write out the local pointer-walking routines. */
2825
2826/* process_field routine for local pointer-walking. */
2827
2828static void
3d7aafde 2829write_types_local_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
2830{
2831 switch (f->kind)
2832 {
2833 case TYPE_POINTER:
2834 case TYPE_STRUCT:
2835 case TYPE_UNION:
2836 case TYPE_LANG_STRUCT:
2837 case TYPE_PARAM_STRUCT:
2838 case TYPE_STRING:
2839 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2840 d->prev_val[3]);
2841 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2842 break;
2843
2844 case TYPE_SCALAR:
2845 break;
3d7aafde 2846
17211ab5 2847 default:
b2d59f6f 2848 gcc_unreachable ();
17211ab5
GK
2849 }
2850}
2851
2852/* For S, a structure that's part of ORIG_S, and using parameters
2853 PARAM, write out a routine that:
2854 - Is of type gt_note_pointers
d8044160 2855 - Calls PROCESS_FIELD on each field of S or its substructures.
17211ab5
GK
2856*/
2857
2858static void
3d7aafde 2859write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
17211ab5
GK
2860{
2861 const char *fn = s->u.s.line.file;
2862 int i;
2863 struct walk_type_data d;
3d7aafde 2864
17211ab5
GK
2865 /* This is a hack, and not the good kind either. */
2866 for (i = NUM_PARAM - 1; i >= 0; i--)
3d7aafde 2867 if (param && param[i] && param[i]->kind == TYPE_POINTER
17211ab5
GK
2868 && UNION_OR_STRUCT_P (param[i]->u.p))
2869 fn = param[i]->u.p->u.s.line.file;
3d7aafde 2870
17211ab5
GK
2871 memset (&d, 0, sizeof (d));
2872 d.of = get_output_file_with_visibility (fn);
17211ab5
GK
2873 d.process_field = write_types_local_process_field;
2874 d.opt = s->u.s.opt;
2875 d.line = &s->u.s.line;
2876 d.bitmap = s->u.s.bitmap;
2877 d.param = param;
2878 d.prev_val[0] = d.prev_val[2] = "*x";
e0a21ab9 2879 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
2880 d.prev_val[3] = "x";
2881 d.val = "(*x)";
d8044160 2882 d.fn_wants_lvalue = true;
17211ab5
GK
2883
2884 oprintf (d.of, "\n");
2885 oprintf (d.of, "void\n");
2886 oprintf (d.of, "gt_pch_p_");
2887 output_mangled_typename (d.of, orig_s);
e18476eb
BI
2888 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2889 "\tvoid *x_p,\n"
2890 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2891 "\tATTRIBUTE_UNUSED void *cookie)\n");
17211ab5
GK
2892 oprintf (d.of, "{\n");
2893 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2894 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2895 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2896 d.indent = 2;
2897 walk_type (s, &d);
2898 oprintf (d.of, "}\n");
2899}
2900
2901/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2902
2903static void
0182d016 2904write_local (outf_p output_header, type_p structures, type_p param_structs)
17211ab5
GK
2905{
2906 type_p s;
3d7aafde 2907
0182d016 2908 if (!output_header)
bd117bb6 2909 return;
0182d016 2910 oprintf (output_header, "\n/* Local pointer-walking routines. */\n");
17211ab5
GK
2911 for (s = structures; s; s = s->next)
2912 if (s->gc_used == GC_POINTED_TO
2913 || s->gc_used == GC_MAYBE_POINTED_TO)
2914 {
2915 options_p opt;
3d7aafde 2916
17211ab5
GK
2917 if (s->u.s.line.file == NULL)
2918 continue;
2919
2920 for (opt = s->u.s.opt; opt; opt = opt->next)
2921 if (strcmp (opt->name, "ptr_alias") == 0)
2922 {
e5cfc29f 2923 const_type_p const t = (const_type_p) opt->info;
3d7aafde 2924 if (t->kind == TYPE_STRUCT
17211ab5
GK
2925 || t->kind == TYPE_UNION
2926 || t->kind == TYPE_LANG_STRUCT)
2927 {
0182d016
BS
2928 oprintf (output_header, "#define gt_pch_p_");
2929 output_mangled_typename (output_header, s);
2930 oprintf (output_header, " gt_pch_p_");
2931 output_mangled_typename (output_header, t);
2932 oprintf (output_header, "\n");
17211ab5
GK
2933 }
2934 else
3d7aafde 2935 error_at_line (&s->u.s.line,
17211ab5
GK
2936 "structure alias is not a structure");
2937 break;
2938 }
2939 if (opt)
2940 continue;
2941
2942 /* Declare the marker procedure only once. */
0182d016
BS
2943 oprintf (output_header, "extern void gt_pch_p_");
2944 output_mangled_typename (output_header, s);
2945 oprintf (output_header,
3d7aafde
AJ
2946 "\n (void *, void *, gt_pointer_operator, void *);\n");
2947
17211ab5
GK
2948 if (s->kind == TYPE_LANG_STRUCT)
2949 {
2950 type_p ss;
2951 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2952 write_local_func_for_structure (s, ss, NULL);
2953 }
2954 else
2955 write_local_func_for_structure (s, s, NULL);
2956 }
2957
2958 for (s = param_structs; s; s = s->next)
2959 if (s->gc_used == GC_POINTED_TO)
2960 {
2961 type_p * param = s->u.param_struct.param;
2962 type_p stru = s->u.param_struct.stru;
2963
2964 /* Declare the marker procedure. */
0182d016
BS
2965 oprintf (output_header, "extern void gt_pch_p_");
2966 output_mangled_typename (output_header, s);
2967 oprintf (output_header,
3d7aafde
AJ
2968 "\n (void *, void *, gt_pointer_operator, void *);\n");
2969
17211ab5
GK
2970 if (stru->u.s.line.file == NULL)
2971 {
3d7aafde 2972 fprintf (stderr, "warning: structure `%s' used but not defined\n",
17211ab5
GK
2973 s->u.s.tag);
2974 continue;
2975 }
3d7aafde 2976
17211ab5
GK
2977 if (stru->kind == TYPE_LANG_STRUCT)
2978 {
2979 type_p ss;
2980 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2981 write_local_func_for_structure (s, ss, param);
e2500fed
GK
2982 }
2983 else
17211ab5 2984 write_local_func_for_structure (s, stru, param);
36a5eadd
GK
2985 }
2986}
2987
2988/* Write out the 'enum' definition for gt_types_enum. */
2989
2990static void
8c80adb7 2991write_enum_defn (type_p structures, type_p param_structs)
36a5eadd
GK
2992{
2993 type_p s;
3d7aafde 2994
bd117bb6
BS
2995 if (!header_file)
2996 return;
36a5eadd
GK
2997 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2998 oprintf (header_file, "enum gt_types_enum {\n");
2999 for (s = structures; s; s = s->next)
3000 if (s->gc_used == GC_POINTED_TO
3001 || s->gc_used == GC_MAYBE_POINTED_TO)
3002 {
3003 if (s->gc_used == GC_MAYBE_POINTED_TO
3004 && s->u.s.line.file == NULL)
3005 continue;
3006
3007 oprintf (header_file, " gt_ggc_e_");
3008 output_mangled_typename (header_file, s);
3009 oprintf (header_file, ", \n");
e2500fed 3010 }
36a5eadd
GK
3011 for (s = param_structs; s; s = s->next)
3012 if (s->gc_used == GC_POINTED_TO)
3013 {
3014 oprintf (header_file, " gt_e_");
3015 output_mangled_typename (header_file, s);
3016 oprintf (header_file, ", \n");
3017 }
3018 oprintf (header_file, " gt_types_enum_last\n");
3019 oprintf (header_file, "};\n");
e2500fed
GK
3020}
3021
17211ab5
GK
3022/* Might T contain any non-pointer elements? */
3023
3024static int
3d7aafde 3025contains_scalar_p (type_p t)
17211ab5
GK
3026{
3027 switch (t->kind)
3028 {
3029 case TYPE_STRING:
3030 case TYPE_POINTER:
3031 return 0;
3032 case TYPE_ARRAY:
3033 return contains_scalar_p (t->u.a.p);
3034 default:
3035 /* Could also check for structures that have no non-pointer
3036 fields, but there aren't enough of those to worry about. */
3037 return 1;
3038 }
3039}
36a5eadd 3040
9f313342
GK
3041/* Mangle FN and print it to F. */
3042
e2500fed 3043static void
3d7aafde 3044put_mangled_filename (outf_p f, const char *fn)
e2500fed
GK
3045{
3046 const char *name = get_output_file_name (fn);
bd117bb6
BS
3047 if (!f || !name)
3048 return;
e2500fed 3049 for (; *name != 0; name++)
1f8e4682 3050 if (ISALNUM (*name))
e03856fe 3051 oprintf (f, "%c", *name);
e2500fed 3052 else
e03856fe 3053 oprintf (f, "%c", '_');
e2500fed
GK
3054}
3055
9f313342
GK
3056/* Finish off the currently-created root tables in FLP. PFX, TNAME,
3057 LASTNAME, and NAME are all strings to insert in various places in
3058 the resulting code. */
3059
e2500fed 3060static void
3d7aafde
AJ
3061finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3062 const char *tname, const char *name)
e2500fed
GK
3063{
3064 struct flist *fli2;
3d7aafde 3065
e2500fed
GK
3066 for (fli2 = flp; fli2; fli2 = fli2->next)
3067 if (fli2->started_p)
3068 {
e03856fe
GK
3069 oprintf (fli2->f, " %s\n", lastname);
3070 oprintf (fli2->f, "};\n\n");
e2500fed
GK
3071 }
3072
bd117bb6 3073 for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
e2500fed
GK
3074 if (fli2->started_p)
3075 {
11a67599 3076 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3077 int fnum;
3078
3079 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3080 if (bitmap & 1)
3081 {
e03856fe 3082 oprintf (base_files[fnum],
17211ab5 3083 "extern const struct %s gt_%s_",
e2500fed
GK
3084 tname, pfx);
3085 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3086 oprintf (base_files[fnum], "[];\n");
e2500fed
GK
3087 }
3088 }
3d7aafde 3089
17211ab5
GK
3090 {
3091 size_t fnum;
bd117bb6 3092 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
17211ab5 3093 oprintf (base_files [fnum],
6bc7bc14 3094 "EXPORTED_CONST struct %s * const %s[] = {\n",
17211ab5
GK
3095 tname, name);
3096 }
3d7aafde 3097
e2500fed
GK
3098
3099 for (fli2 = flp; fli2; fli2 = fli2->next)
3100 if (fli2->started_p)
3101 {
11a67599 3102 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3103 int fnum;
3104
3105 fli2->started_p = 0;
3106
bd117bb6 3107 for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
e2500fed
GK
3108 if (bitmap & 1)
3109 {
17211ab5 3110 oprintf (base_files[fnum], " gt_%s_", pfx);
e2500fed 3111 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3112 oprintf (base_files[fnum], ",\n");
e2500fed
GK
3113 }
3114 }
3115
3116 {
17211ab5 3117 size_t fnum;
bd117bb6 3118 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
17211ab5
GK
3119 {
3120 oprintf (base_files[fnum], " NULL\n");
3121 oprintf (base_files[fnum], "};\n");
3122 }
e2500fed
GK
3123 }
3124}
3125
9f313342
GK
3126/* Write out to F the table entry and any marker routines needed to
3127 mark NAME as TYPE. The original variable is V, at LINE.
3128 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
3129 is nonzero iff we are building the root table for hash table caches. */
3130
e2500fed 3131static void
3d7aafde 3132write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
99be7084 3133 struct fileloc *line, const char *if_marked, bool emit_pch)
e2500fed
GK
3134{
3135 switch (type->kind)
3136 {
3137 case TYPE_STRUCT:
3138 {
3139 pair_p fld;
3140 for (fld = type->u.s.fields; fld; fld = fld->next)
3141 {
3142 int skip_p = 0;
3143 const char *desc = NULL;
3144 options_p o;
3d7aafde 3145
e2500fed
GK
3146 for (o = fld->opt; o; o = o->next)
3147 if (strcmp (o->name, "skip") == 0)
3148 skip_p = 1;
3149 else if (strcmp (o->name, "desc") == 0)
9e2878cf 3150 desc = o->info;
69c32ec8
JH
3151 else if (strcmp (o->name, "param_is") == 0)
3152 ;
e2500fed
GK
3153 else
3154 error_at_line (line,
3155 "field `%s' of global `%s' has unknown option `%s'",
3156 fld->name, name, o->name);
3d7aafde 3157
e2500fed
GK
3158 if (skip_p)
3159 continue;
3160 else if (desc && fld->type->kind == TYPE_UNION)
3161 {
3162 pair_p validf = NULL;
3163 pair_p ufld;
3d7aafde 3164
e2500fed
GK
3165 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3166 {
3167 const char *tag = NULL;
3168 options_p oo;
3d7aafde 3169
e2500fed
GK
3170 for (oo = ufld->opt; oo; oo = oo->next)
3171 if (strcmp (oo->name, "tag") == 0)
9e2878cf 3172 tag = oo->info;
e2500fed
GK
3173 if (tag == NULL || strcmp (tag, desc) != 0)
3174 continue;
3175 if (validf != NULL)
3d7aafde 3176 error_at_line (line,
e2500fed
GK
3177 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3178 name, fld->name, validf->name,
3179 name, fld->name, ufld->name,
3180 tag);
3181 validf = ufld;
3182 }
3183 if (validf != NULL)
3184 {
3185 char *newname;
3d7aafde 3186 newname = xasprintf ("%s.%s.%s",
e03856fe 3187 name, fld->name, validf->name);
17211ab5 3188 write_root (f, v, validf->type, newname, 0, line,
99be7084 3189 if_marked, emit_pch);
e2500fed
GK
3190 free (newname);
3191 }
3192 }
3193 else if (desc)
3d7aafde 3194 error_at_line (line,
e2500fed
GK
3195 "global `%s.%s' has `desc' option but is not union",
3196 name, fld->name);
3197 else
3198 {
3199 char *newname;
e03856fe 3200 newname = xasprintf ("%s.%s", name, fld->name);
99be7084
BS
3201 write_root (f, v, fld->type, newname, 0, line, if_marked,
3202 emit_pch);
e2500fed
GK
3203 free (newname);
3204 }
3205 }
3206 }
3207 break;
3208
3209 case TYPE_ARRAY:
3210 {
3211 char *newname;
e03856fe 3212 newname = xasprintf ("%s[0]", name);
99be7084
BS
3213 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
3214 emit_pch);
e2500fed
GK
3215 free (newname);
3216 }
3217 break;
3d7aafde 3218
e2500fed
GK
3219 case TYPE_POINTER:
3220 {
3221 type_p ap, tp;
3d7aafde 3222
e03856fe
GK
3223 oprintf (f, " {\n");
3224 oprintf (f, " &%s,\n", name);
3225 oprintf (f, " 1");
3d7aafde 3226
e2500fed
GK
3227 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3228 if (ap->u.a.len[0])
e03856fe 3229 oprintf (f, " * (%s)", ap->u.a.len);
e2500fed 3230 else if (ap == v->type)
62c71f4b 3231 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
e03856fe
GK
3232 oprintf (f, ",\n");
3233 oprintf (f, " sizeof (%s", v->name);
e2500fed 3234 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
e03856fe
GK
3235 oprintf (f, "[0]");
3236 oprintf (f, "),\n");
3d7aafde 3237
e2500fed 3238 tp = type->u.p;
3d7aafde 3239
e2500fed
GK
3240 if (! has_length && UNION_OR_STRUCT_P (tp))
3241 {
17211ab5 3242 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
99be7084
BS
3243 if (emit_pch)
3244 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
3245 else
3246 oprintf (f, " NULL");
e2500fed
GK
3247 }
3248 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3249 {
36a5eadd
GK
3250 oprintf (f, " &gt_ggc_m_");
3251 output_mangled_typename (f, tp);
99be7084
BS
3252 if (emit_pch)
3253 {
3254 oprintf (f, ",\n &gt_pch_n_");
3255 output_mangled_typename (f, tp);
3256 }
3257 else
3258 oprintf (f, ",\n NULL");
e2500fed
GK
3259 }
3260 else if (has_length
afb0f770 3261 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
e2500fed 3262 {
17211ab5 3263 oprintf (f, " &gt_ggc_ma_%s,\n", name);
99be7084
BS
3264 if (emit_pch)
3265 oprintf (f, " &gt_pch_na_%s", name);
3266 else
3267 oprintf (f, " NULL");
e2500fed
GK
3268 }
3269 else
3270 {
3d7aafde 3271 error_at_line (line,
e2500fed
GK
3272 "global `%s' is pointer to unimplemented type",
3273 name);
3274 }
3275 if (if_marked)
e03856fe
GK
3276 oprintf (f, ",\n &%s", if_marked);
3277 oprintf (f, "\n },\n");
e2500fed
GK
3278 }
3279 break;
3280
e2500fed 3281 case TYPE_STRING:
17211ab5
GK
3282 {
3283 oprintf (f, " {\n");
3284 oprintf (f, " &%s,\n", name);
3285 oprintf (f, " 1, \n");
3286 oprintf (f, " sizeof (%s),\n", v->name);
dae4174e 3287 oprintf (f, " (gt_pointer_walker) &gt_ggc_m_S,\n");
f099d360 3288 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
17211ab5
GK
3289 oprintf (f, " },\n");
3290 }
3291 break;
3d7aafde 3292
17211ab5 3293 case TYPE_SCALAR:
e2500fed 3294 break;
3d7aafde 3295
e2500fed 3296 default:
3d7aafde 3297 error_at_line (line,
e2500fed
GK
3298 "global `%s' is unimplemented type",
3299 name);
3300 }
3301}
3302
17211ab5
GK
3303/* This generates a routine to walk an array. */
3304
3305static void
3d7aafde 3306write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
17211ab5
GK
3307{
3308 struct walk_type_data d;
3309 char *prevval3;
3d7aafde 3310
17211ab5
GK
3311 memset (&d, 0, sizeof (d));
3312 d.of = f;
3313 d.cookie = wtd;
3314 d.indent = 2;
3315 d.line = &v->line;
3316 d.opt = v->opt;
11a67599 3317 d.bitmap = get_lang_bitmap (v->line.file);
17211ab5
GK
3318 d.param = NULL;
3319
3320 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3321
3322 if (wtd->param_prefix)
3323 {
3324 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3d7aafde
AJ
3325 oprintf (f,
3326 " (void *, void *, gt_pointer_operator, void *);\n");
e18476eb 3327 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
17211ab5 3328 wtd->param_prefix, v->name);
e18476eb
BI
3329 oprintf (d.of,
3330 " ATTRIBUTE_UNUSED void *x_p,\n"
3331 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3332 " ATTRIBUTE_UNUSED void * cookie)\n");
17211ab5
GK
3333 oprintf (d.of, "{\n");
3334 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3335 d.process_field = write_types_local_process_field;
3336 walk_type (v->type, &d);
3337 oprintf (f, "}\n\n");
3338 }
3339
3340 d.opt = v->opt;
3d7aafde 3341 oprintf (f, "static void gt_%sa_%s (void *);\n",
17211ab5 3342 wtd->prefix, v->name);
e18476eb 3343 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
17211ab5 3344 wtd->prefix, v->name);
17211ab5
GK
3345 oprintf (f, "{\n");
3346 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3347 d.process_field = write_types_process_field;
3348 walk_type (v->type, &d);
3349 free (prevval3);
3350 oprintf (f, "}\n\n");
3351}
3352
9f313342
GK
3353/* Output a table describing the locations and types of VARIABLES. */
3354
e2500fed 3355static void
99be7084 3356write_roots (pair_p variables, bool emit_pch)
e2500fed
GK
3357{
3358 pair_p v;
3359 struct flist *flp = NULL;
3360
3361 for (v = variables; v; v = v->next)
3362 {
e03856fe 3363 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3364 struct flist *fli;
3365 const char *length = NULL;
3366 int deletable_p = 0;
3367 options_p o;
3368
3369 for (o = v->opt; o; o = o->next)
3370 if (strcmp (o->name, "length") == 0)
9e2878cf 3371 length = o->info;
e2500fed
GK
3372 else if (strcmp (o->name, "deletable") == 0)
3373 deletable_p = 1;
3374 else if (strcmp (o->name, "param_is") == 0)
3375 ;
3d7aafde 3376 else if (strncmp (o->name, "param", 5) == 0
36a5eadd
GK
3377 && ISDIGIT (o->name[5])
3378 && strcmp (o->name + 6, "_is") == 0)
3379 ;
e2500fed
GK
3380 else if (strcmp (o->name, "if_marked") == 0)
3381 ;
3382 else
3d7aafde 3383 error_at_line (&v->line,
e2500fed
GK
3384 "global `%s' has unknown option `%s'",
3385 v->name, o->name);
3386
3387 for (fli = flp; fli; fli = fli->next)
bd117bb6 3388 if (fli->f == f && f)
e2500fed
GK
3389 break;
3390 if (fli == NULL)
3391 {
5d038c4c 3392 fli = XNEW (struct flist);
e2500fed
GK
3393 fli->f = f;
3394 fli->next = flp;
3395 fli->started_p = 0;
3396 fli->name = v->line.file;
bd117bb6 3397 gcc_assert(fli->name);
e2500fed
GK
3398 flp = fli;
3399
e03856fe 3400 oprintf (f, "\n/* GC roots. */\n\n");
e2500fed
GK
3401 }
3402
3403 if (! deletable_p
3404 && length
3405 && v->type->kind == TYPE_POINTER
3406 && (v->type->u.p->kind == TYPE_POINTER
3407 || v->type->u.p->kind == TYPE_STRUCT))
3408 {
17211ab5
GK
3409 write_array (f, v, &ggc_wtd);
3410 write_array (f, v, &pch_wtd);
e2500fed
GK
3411 }
3412 }
3413
3414 for (v = variables; v; v = v->next)
3415 {
e03856fe 3416 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3417 struct flist *fli;
3418 int skip_p = 0;
3419 int length_p = 0;
3420 options_p o;
3d7aafde 3421
e2500fed
GK
3422 for (o = v->opt; o; o = o->next)
3423 if (strcmp (o->name, "length") == 0)
3424 length_p = 1;
3425 else if (strcmp (o->name, "deletable") == 0
3426 || strcmp (o->name, "if_marked") == 0)
3427 skip_p = 1;
3428
3429 if (skip_p)
3430 continue;
3431
3432 for (fli = flp; fli; fli = fli->next)
3433 if (fli->f == f)
3434 break;
3435 if (! fli->started_p)
3436 {
3437 fli->started_p = 1;
3438
6bc7bc14 3439 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
e2500fed 3440 put_mangled_filename (f, v->line.file);
e03856fe 3441 oprintf (f, "[] = {\n");
e2500fed
GK
3442 }
3443
99be7084 3444 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
e2500fed
GK
3445 }
3446
3d7aafde 3447 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3448 "gt_ggc_rtab");
3449
3450 for (v = variables; v; v = v->next)
3451 {
e03856fe 3452 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3453 struct flist *fli;
3454 int skip_p = 1;
3455 options_p o;
3456
3457 for (o = v->opt; o; o = o->next)
3458 if (strcmp (o->name, "deletable") == 0)
3459 skip_p = 0;
3460 else if (strcmp (o->name, "if_marked") == 0)
3461 skip_p = 1;
3462
3463 if (skip_p)
3464 continue;
3465
3466 for (fli = flp; fli; fli = fli->next)
3467 if (fli->f == f)
3468 break;
3469 if (! fli->started_p)
3470 {
3471 fli->started_p = 1;
3472
6bc7bc14 3473 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
e2500fed 3474 put_mangled_filename (f, v->line.file);
e03856fe 3475 oprintf (f, "[] = {\n");
e2500fed 3476 }
3d7aafde 3477
17211ab5 3478 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
e2500fed
GK
3479 v->name, v->name);
3480 }
3d7aafde 3481
17211ab5 3482 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3483 "gt_ggc_deletable_rtab");
3484
3485 for (v = variables; v; v = v->next)
3486 {
e03856fe 3487 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3488 struct flist *fli;
3489 const char *if_marked = NULL;
3490 int length_p = 0;
3491 options_p o;
3d7aafde 3492
e2500fed
GK
3493 for (o = v->opt; o; o = o->next)
3494 if (strcmp (o->name, "length") == 0)
3495 length_p = 1;
3496 else if (strcmp (o->name, "if_marked") == 0)
9e2878cf 3497 if_marked = o->info;
e2500fed
GK
3498
3499 if (if_marked == NULL)
3500 continue;
3501
3502 if (v->type->kind != TYPE_POINTER
3503 || v->type->u.p->kind != TYPE_PARAM_STRUCT
3504 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3505 {
3506 error_at_line (&v->line, "if_marked option used but not hash table");
3507 continue;
3508 }
3509
3510 for (fli = flp; fli; fli = fli->next)
3511 if (fli->f == f)
3512 break;
3513 if (! fli->started_p)
3514 {
3515 fli->started_p = 1;
3516
6bc7bc14 3517 oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
e2500fed 3518 put_mangled_filename (f, v->line.file);
e03856fe 3519 oprintf (f, "[] = {\n");
e2500fed 3520 }
3d7aafde 3521
17211ab5 3522 write_root (f, v, v->type->u.p->u.param_struct.param[0],
99be7084 3523 v->name, length_p, &v->line, if_marked, emit_pch);
e2500fed 3524 }
3d7aafde 3525
17211ab5 3526 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
e2500fed 3527 "gt_ggc_cache_rtab");
17211ab5 3528
99be7084
BS
3529 if (!emit_pch)
3530 return;
3531
17211ab5
GK
3532 for (v = variables; v; v = v->next)
3533 {
3534 outf_p f = get_output_file_with_visibility (v->line.file);
3535 struct flist *fli;
3536 int length_p = 0;
3537 int if_marked_p = 0;
3538 options_p o;
3d7aafde 3539
17211ab5
GK
3540 for (o = v->opt; o; o = o->next)
3541 if (strcmp (o->name, "length") == 0)
3542 length_p = 1;
3543 else if (strcmp (o->name, "if_marked") == 0)
3544 if_marked_p = 1;
3545
3546 if (! if_marked_p)
3547 continue;
3548
3549 for (fli = flp; fli; fli = fli->next)
3550 if (fli->f == f)
3551 break;
3552 if (! fli->started_p)
3553 {
3554 fli->started_p = 1;
3555
6bc7bc14 3556 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
17211ab5
GK
3557 put_mangled_filename (f, v->line.file);
3558 oprintf (f, "[] = {\n");
3559 }
3560
99be7084 3561 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
17211ab5 3562 }
3d7aafde 3563
17211ab5
GK
3564 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3565 "gt_pch_cache_rtab");
3566
3567 for (v = variables; v; v = v->next)
3568 {
3569 outf_p f = get_output_file_with_visibility (v->line.file);
3570 struct flist *fli;
3571 int skip_p = 0;
3572 options_p o;
3573
3574 for (o = v->opt; o; o = o->next)
3575 if (strcmp (o->name, "deletable") == 0
3576 || strcmp (o->name, "if_marked") == 0)
3577 skip_p = 1;
3578
3579 if (skip_p)
3580 continue;
3581
3582 if (! contains_scalar_p (v->type))
3583 continue;
3584
3585 for (fli = flp; fli; fli = fli->next)
3586 if (fli->f == f)
3587 break;
3588 if (! fli->started_p)
3589 {
3590 fli->started_p = 1;
3591
6bc7bc14 3592 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
17211ab5
GK
3593 put_mangled_filename (f, v->line.file);
3594 oprintf (f, "[] = {\n");
3595 }
3d7aafde 3596
17211ab5
GK
3597 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3598 v->name, v->name);
3599 }
3d7aafde 3600
17211ab5
GK
3601 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3602 "gt_pch_scalar_rtab");
e2500fed
GK
3603}
3604
4a399aef
ZW
3605/* Record the definition of a generic VEC structure, as if we had expanded
3606 the macros in vec.h:
3607
3608 typedef struct VEC_<type>_base GTY(()) {
3609 unsigned num;
3610 unsigned alloc;
3611 <type> GTY((length ("%h.num"))) vec[1];
3612 } VEC_<type>_base
3613
3614 where the GTY(()) tags are only present if is_scalar is _false_. */
3615
3616void
8ad97cfc 3617note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
4a399aef 3618{
065ae611 3619 pair_p fields;
4a399aef
ZW
3620 type_p t;
3621 options_p o;
065ae611 3622 type_p len_ty = create_scalar_type ("unsigned");
8ad97cfc 3623 const char *name = concat ("VEC_", type_name, "_base", (char *)0);
4a399aef
ZW
3624
3625 if (is_scalar)
3626 {
8ad97cfc 3627 t = create_scalar_type (type_name);
4a399aef
ZW
3628 o = 0;
3629 }
3630 else
3631 {
8ad97cfc 3632 t = resolve_typedef (type_name, pos);
4a399aef
ZW
3633 o = create_option (0, "length", "%h.num");
3634 }
3635
3636 /* We assemble the field list in reverse order. */
065ae611
ZW
3637 fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3638 fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3639 fields = create_field_at (fields, len_ty, "num", 0, pos);
4a399aef
ZW
3640
3641 do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3642}
3643
3644/* Record the definition of an allocation-specific VEC structure, as if
3645 we had expanded the macros in vec.h:
3646
3647 typedef struct VEC_<type>_<astrat> {
3648 VEC_<type>_base base;
3649 } VEC_<type>_<astrat>;
3650*/
3651void
3652note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3653{
3654 const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3655 const char *basename = concat ("VEC_", type, "_base", (char *)0);
3656
065ae611
ZW
3657 pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3658 "base", 0, pos);
4a399aef
ZW
3659
3660 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3661}
3662
e2500fed 3663\f
3d7aafde 3664int
11a67599 3665main (int argc, char **argv)
e2500fed 3666{
11a67599 3667 size_t i;
01d419ae 3668 static struct fileloc pos = { this_file, 0 };
bd117bb6 3669 char* inputlist = 0;
11a67599
ZW
3670 /* fatal uses this */
3671 progname = "gengtype";
3672
bd117bb6
BS
3673 if (argc >= 5 && !strcmp (argv[1], "-p"))
3674 {
3675 srcdir = argv[2];
3676 inputlist = argv[3];
bd117bb6 3677 nb_plugin_files = argc-4;
9f78bf05
BS
3678 plugin_files = XCNEWVEC (char *, nb_plugin_files);
3679 for (i = 0; i < nb_plugin_files; i++)
3680 {
3681 /* Place an all zero lang_bitmap before the plugin file
3682 name. */
3683 char *name = argv[i + 4];
3684 int len = strlen(name) + 1 + sizeof (lang_bitmap);
3685 plugin_files[i] = XCNEWVEC (char, len) + sizeof (lang_bitmap);
3686 strcpy (plugin_files[i], name);
3687 }
bd117bb6
BS
3688 }
3689 else if (argc == 3)
3690 {
3691 srcdir = argv[1];
3692 inputlist = argv[2];
3693 }
3694 else
3695 fatal ("usage: gengtype [-p] srcdir input-list [file1 file2 ... fileN]");
11a67599 3696
8ac9d31f 3697 srcdir_len = strlen (srcdir);
e2500fed 3698
bd117bb6 3699 read_input_list (inputlist);
11a67599
ZW
3700 if (hit_error)
3701 return 1;
3702
95161faf
ZW
3703 scalar_char.u.scalar_is_char = true;
3704 scalar_nonchar.u.scalar_is_char = false;
95161faf
ZW
3705 gen_rtx_next ();
3706
01d419ae
ZW
3707 /* These types are set up with #define or else outside of where
3708 we can see them. */
3709 pos.line = __LINE__ + 1;
3710 do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3711 do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
1e1ba002 3712 do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
01d419ae 3713 do_scalar_typedef ("double_int", &pos); pos.line++;
c6a21142 3714 do_scalar_typedef ("uint64_t", &pos); pos.line++;
01d419ae
ZW
3715 do_scalar_typedef ("uint8", &pos); pos.line++;
3716 do_scalar_typedef ("jword", &pos); pos.line++;
3717 do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3718 do_scalar_typedef ("void", &pos); pos.line++;
a813c111 3719 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
ed8d2920 3720
11a67599 3721 for (i = 0; i < num_gt_files; i++)
01d419ae 3722 parse_file (gt_files[i]);
e2500fed 3723
01d419ae 3724 if (hit_error)
065ae611 3725 return 1;
e2500fed
GK
3726
3727 set_gc_used (variables);
3728
3729 open_base_files ();
36a5eadd 3730 write_enum_defn (structures, param_structs);
0182d016 3731 write_types (header_file, structures, param_structs, &ggc_wtd);
99be7084
BS
3732 if (plugin_output == NULL)
3733 {
3734 write_types (header_file, structures, param_structs, &pch_wtd);
3735 write_local (header_file, structures, param_structs);
3736 }
3737 write_roots (variables, plugin_output == NULL);
36a5eadd 3738 write_rtx_next ();
e2500fed
GK
3739 close_output_files ();
3740
9f78bf05
BS
3741 if (plugin_files)
3742 {
3743 for (i = 0; i < nb_plugin_files; i++)
3744 free (plugin_files[i] - sizeof (lang_bitmap));
3745 free (plugin_files);
3746 }
3747
01d419ae
ZW
3748 if (hit_error)
3749 return 1;
3750 return 0;
e2500fed 3751}