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