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