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