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