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