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