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