]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gengtype.c
fix changelog error
[thirdparty/gcc.git] / gcc / gengtype.c
CommitLineData
e2500fed 1/* Process source files and output type information.
7ca92787 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
62e5bf5d 3 Free Software Foundation, Inc.
e2500fed 4
9dcd6f09 5 This file is part of GCC.
e2500fed 6
9dcd6f09
NC
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
e2500fed 11
9dcd6f09
NC
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
e2500fed 16
9dcd6f09
NC
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
e2500fed 20
4977bab6 21#include "bconfig.h"
e2500fed 22#include "system.h"
e1b793e7 23#include "errors.h" /* for fatal */
f8ed6dc5 24#include "getopt.h"
df582833 25#include "double-int.h"
f8ed6dc5 26#include "version.h" /* for version_string & pkgversion_string. */
0277fabf 27#include "hashtab.h"
f8ed6dc5 28#include "gengtype.h"
5ba6918e 29
065ae611
ZW
30/* Data types, macros, etc. used only in this file. */
31
32/* Kinds of types we can understand. */
e1b793e7
BS
33enum typekind
34{
065ae611
ZW
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
065ae611
ZW
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
e1b793e7
BS
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};
065ae611
ZW
86
87struct type
88{
89 enum typekind kind;
90 type_p next;
91 type_p pointer_to;
92 enum gc_used_enum gc_used;
e1b793e7
BS
93 union
94 {
065ae611 95 type_p p;
e1b793e7
BS
96 struct
97 {
065ae611
ZW
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;
e1b793e7
BS
106 struct
107 {
065ae611
ZW
108 type_p p;
109 const char *len;
110 } a;
e1b793e7
BS
111 struct
112 {
065ae611
ZW
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) \
f8ed6dc5
JS
121 ((x)->kind == TYPE_UNION || \
122 ((x)->kind == TYPE_LANG_STRUCT \
123 && (x)->u.s.lang_struct->kind == TYPE_UNION))
065ae611 124#define UNION_OR_STRUCT_P(x) \
f8ed6dc5
JS
125 ((x)->kind == TYPE_UNION \
126 || (x)->kind == TYPE_STRUCT \
127 || (x)->kind == TYPE_LANG_STRUCT)
128
065ae611 129
065ae611 130
065ae611
ZW
131const char *get_output_file_name (const char *);
132
065ae611
ZW
133
134/* The list of output files. */
f8ed6dc5
JS
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;
065ae611 144
bd117bb6 145/* The plugin input files and their number; in that case only
c802b1cf 146 a single file is produced. */
e1b793e7 147static char **plugin_files;
9f78bf05 148static size_t nb_plugin_files;
f8ed6dc5
JS
149
150/* The generated plugin output file and name. */
9b39cba9 151static outf_p plugin_output;
f8ed6dc5 152static char *plugin_output_filename;
bd117bb6 153
f8ed6dc5
JS
154/* Our source directory and its length. */
155const char *srcdir;
156size_t srcdir_len;
065ae611 157
f8ed6dc5
JS
158/* Variables used for reading and writing the state. */
159const char *read_state_filename;
160const char *write_state_filename;
065ae611 161
f8ed6dc5
JS
162/* Variables to help debugging. */
163int do_dump;
164int do_debug;
065ae611 165
1d32bbcd
BS
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
065ae611 175static outf_p create_file (const char *, const char *);
8de8de02 176
e1b793e7
BS
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 *);
8de8de02
OH
180
181static int get_prefix_langdir_index (const char *);
e1b793e7 182static const char *get_file_langdir (const char *);
065ae611 183\f
e1b793e7 184
9f313342 185/* Nonzero iff an error has occurred. */
01d419ae 186bool hit_error = false;
9f313342 187
3d7aafde
AJ
188static void gen_rtx_next (void);
189static void write_rtx_next (void);
190static void open_base_files (void);
191static void close_output_files (void);
ef171ead 192
9f313342
GK
193/* Report an error at POS, printing MSG. */
194
e2500fed 195void
0277fabf 196error_at_line (const struct fileloc *pos, const char *msg, ...)
e2500fed 197{
e34d07f2 198 va_list ap;
3d7aafde 199
e34d07f2 200 va_start (ap, msg);
e2500fed
GK
201
202 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
203 vfprintf (stderr, msg, ap);
204 fputc ('\n', stderr);
01d419ae 205 hit_error = true;
e2500fed 206
e34d07f2 207 va_end (ap);
e2500fed
GK
208}
209
065ae611 210/* asprintf, but produces fatal message on out-of-memory. */
01d419ae 211char *
e34d07f2 212xasprintf (const char *format, ...)
e03856fe 213{
065ae611 214 int n;
e03856fe 215 char *result;
e34d07f2 216 va_list ap;
3d7aafde 217
e34d07f2 218 va_start (ap, format);
065ae611
ZW
219 n = vasprintf (&result, format, ap);
220 if (result == NULL || n < 0)
221 fatal ("out of memory");
e34d07f2 222 va_end (ap);
065ae611 223
e03856fe
GK
224 return result;
225}
11a67599
ZW
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
f8ed6dc5
JS
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";
01d419ae 239
11a67599
ZW
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. */
e03856fe 259
11a67599
ZW
260static lang_bitmap
261get_lang_bitmap (const char *gtfile)
262{
01d419ae 263
f8ed6dc5
JS
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 }
01d419ae
ZW
271 else
272 {
273 lang_bitmap n = 0;
274 int i;
275 for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
e1b793e7 276 n = (n << CHAR_BIT) + (unsigned char) gtfile[i];
01d419ae
ZW
277 return n;
278 }
11a67599
ZW
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 {
e1b793e7 289 gtfile[i] = n & ((1U << CHAR_BIT) - 1);
11a67599
ZW
290 n >>= CHAR_BIT;
291 }
292}
293
f8ed6dc5
JS
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
11a67599
ZW
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;
bd117bb6 364 num_gt_files = plugin_files ? nb_plugin_files : 0;
11a67599
ZW
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
e1b793e7 397read_input_line (FILE *list, char **herep, char **linep, struct fileloc *pos)
11a67599
ZW
398{
399 char *here = *herep;
400 char *line;
401 int c = getc (list);
402
1b77ee03
MM
403 /* Read over whitespace. */
404 while (c == '\n' || c == ' ')
405 c = getc (list);
406
11a67599
ZW
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 {
e1b793e7 426 c = getc (list); /* eat what should be a newline */
11a67599
ZW
427 if (c != '\n' && c != EOF)
428 error_at_line (pos, "junk on line after language tag [%s]", line);
429 }
430 else
e1b793e7
BS
431 error_at_line (pos, "missing close bracket for language tag [%s",
432 line);
11a67599
ZW
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)
7ca92787 470 fatal ("cannot open %s: %s", listname, xstrerror (errno));
11a67599
ZW
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 {
e1b793e7
BS
507 error_at_line (&epos, "duplicate language tag [%s]",
508 line);
11a67599
ZW
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)
e1b793e7
BS
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]);
11a67599
ZW
534
535 bmap |= curlangs;
e1b793e7 536 set_lang_bitmap (CONST_CAST (char *, gt_files[i]), bmap);
11a67599
ZW
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
e1b793e7 546 things there are. (We do not bother resizing the arrays down.) */
11a67599 547 num_lang_dirs = langno;
bd117bb6 548 /* Add the plugin files if provided. */
b8698a0f 549 if (plugin_files)
bd117bb6 550 {
9f78bf05 551 size_t i;
bd117bb6
BS
552 for (i = 0; i < nb_plugin_files; i++)
553 gt_files[nfiles++] = plugin_files[i];
554 }
11a67599
ZW
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++)
e1b793e7 574 if ((size_t) (slashpos - basename) == strlen (lang_dir_names[l])
11a67599
ZW
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 }
e1b793e7 584 }
11a67599
ZW
585 }
586 }
587
588 if (ferror (list))
7ca92787 589 fatal ("error reading %s: %s", listname, xstrerror (errno));
11a67599
ZW
590
591 fclose (list);
592}
e1b793e7 593\f
11a67599
ZW
594
595
9f313342
GK
596/* The one and only TYPE_STRING. */
597
95161faf
ZW
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};
e1b793e7 608
95161faf
ZW
609static struct type scalar_char = {
610 TYPE_SCALAR, 0, 0, GC_USED, {0}
3d7aafde 611};
e2500fed 612
9f313342
GK
613/* Lists of various things. */
614
e2500fed
GK
615static pair_p typedefs;
616static type_p structures;
617static type_p param_structs;
618static pair_p variables;
619
e1b793e7 620static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
3d7aafde
AJ
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);
36a5eadd 623
9f313342
GK
624/* Define S as a typedef to T at POS. */
625
e2500fed 626void
3d7aafde 627do_typedef (const char *s, type_p t, struct fileloc *pos)
e2500fed
GK
628{
629 pair_p p;
630
2d593c86
TT
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)
01d419ae
ZW
636 return;
637
e2500fed
GK
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
5d038c4c 649 p = XNEW (struct pair);
e2500fed
GK
650 p->next = typedefs;
651 p->name = s;
652 p->type = t;
653 p->line = *pos;
0277fabf 654 p->opt = NULL;
e2500fed
GK
655 typedefs = p;
656}
657
95161faf
ZW
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). */
36a5eadd 661
95161faf 662void
3d7aafde 663do_scalar_typedef (const char *s, struct fileloc *pos)
36a5eadd 664{
95161faf 665 do_typedef (s, &scalar_nonchar, pos);
36a5eadd
GK
666}
667
e34bb004 668/* Return the type previously defined for S. Use POS to report errors. */
9f313342 669
e2500fed 670type_p
3d7aafde 671resolve_typedef (const char *s, struct fileloc *pos)
e2500fed
GK
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);
e1b793e7 678 return &scalar_nonchar; /* treat as "int" */
e2500fed
GK
679}
680
0f01f026
RS
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. */
9f313342 683
0f01f026 684type_p
3d7aafde
AJ
685new_structure (const char *name, int isunion, struct fileloc *pos,
686 pair_p fields, options_p o)
e2500fed
GK
687{
688 type_p si;
689 type_p s = NULL;
11a67599 690 lang_bitmap bitmap = get_lang_bitmap (pos->file);
e2500fed
GK
691
692 for (si = structures; si != NULL; si = si->next)
e1b793e7 693 if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion)
e2500fed
GK
694 {
695 type_p ls = NULL;
696 if (si->kind == TYPE_LANG_STRUCT)
697 {
698 ls = si;
3d7aafde 699
e2500fed
GK
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;
5d038c4c 707 si = XCNEW (struct type);
e2500fed
GK
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 {
5d038c4c 721 s = XCNEW (struct type);
e2500fed
GK
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 }
3d7aafde 728
e2500fed
GK
729 if (s == NULL)
730 {
5d038c4c 731 s = XCNEW (struct type);
e2500fed
GK
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 {
01d419ae
ZW
739 error_at_line (pos, "duplicate definition of '%s %s'",
740 isunion ? "union" : "struct", s->u.s.tag);
e2500fed
GK
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;
0f01f026 752
e1b793e7 753 return s;
e2500fed
GK
754}
755
9f313342
GK
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
e2500fed 760type_p
3d7aafde 761find_structure (const char *name, int isunion)
e2500fed
GK
762{
763 type_p s;
764
765 for (s = structures; s != NULL; s = s->next)
e1b793e7 766 if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion)
e2500fed
GK
767 return s;
768
5d038c4c 769 s = XCNEW (struct type);
e2500fed
GK
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
272d0bee
KH
778/* Return the previously-defined parameterized structure for structure
779 T and parameters PARAM, or a new parameterized empty structure or
991b6592 780 union if none was defined previously. */
36a5eadd
GK
781
782static type_p
3d7aafde 783find_param_structure (type_p t, type_p param[NUM_PARAM])
36a5eadd
GK
784{
785 type_p res;
3d7aafde 786
36a5eadd
GK
787 for (res = param_structs; res; res = res->next)
788 if (res->u.param_struct.stru == t
3d7aafde 789 && memcmp (res->u.param_struct.param, param,
36a5eadd
GK
790 sizeof (type_p) * NUM_PARAM) == 0)
791 break;
792 if (res == NULL)
793 {
5d038c4c 794 res = XCNEW (struct type);
36a5eadd
GK
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
9f313342
GK
804/* Return a scalar type with name NAME. */
805
e2500fed 806type_p
95161faf 807create_scalar_type (const char *name)
e2500fed 808{
95161faf
ZW
809 if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
810 return &scalar_char;
811 else
812 return &scalar_nonchar;
e2500fed
GK
813}
814
9f313342
GK
815/* Return a pointer to T. */
816
e2500fed 817type_p
3d7aafde 818create_pointer (type_p t)
e2500fed 819{
e1b793e7 820 if (!t->pointer_to)
e2500fed 821 {
5d038c4c 822 type_p r = XCNEW (struct type);
e2500fed
GK
823 r->kind = TYPE_POINTER;
824 r->u.p = t;
825 t->pointer_to = r;
826 }
827 return t->pointer_to;
828}
829
9f313342
GK
830/* Return an array of length LEN. */
831
e2500fed 832type_p
3d7aafde 833create_array (type_p t, const char *len)
e2500fed
GK
834{
835 type_p v;
3d7aafde 836
5d038c4c 837 v = XCNEW (struct type);
e2500fed
GK
838 v->kind = TYPE_ARRAY;
839 v->u.a.p = t;
840 v->u.a.len = len;
841 return v;
842}
843
0f01f026
RS
844/* Return an options structure with name NAME and info INFO. NEXT is the
845 next option in the chain. */
846
1431042e 847options_p
0f01f026 848create_option (options_p next, const char *name, const void *info)
1431042e 849{
5d038c4c 850 options_p o = XNEW (struct options);
0f01f026 851 o->next = next;
1431042e 852 o->name = name;
e1b793e7 853 o->info = (const char *) info;
1431042e
ZW
854 return o;
855}
856
17defa6a
ZW
857/* Return an options structure for a "nested_ptr" option. */
858options_p
065ae611
ZW
859create_nested_ptr_option (options_p next, type_p t,
860 const char *to, const char *from)
17defa6a
ZW
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;
065ae611 867 return create_option (next, "nested_ptr", d);
17defa6a
ZW
868}
869
36a5eadd
GK
870/* Add a variable named S of type T with options O defined at POS,
871 to `variables'. */
872
873void
3d7aafde 874note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
36a5eadd
GK
875{
876 pair_p n;
5d038c4c 877 n = XNEW (struct pair);
36a5eadd
GK
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
065ae611 886/* Most-general structure field creator. */
0f01f026 887static pair_p
065ae611
ZW
888create_field_all (pair_p next, type_p type, const char *name, options_p opt,
889 const char *file, int line)
0f01f026
RS
890{
891 pair_p field;
892
893 field = XNEW (struct pair);
894 field->next = next;
895 field->type = type;
896 field->name = name;
065ae611
ZW
897 field->opt = opt;
898 field->line.file = file;
899 field->line.line = line;
0f01f026
RS
900 return field;
901}
902
065ae611
ZW
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) \
f8ed6dc5 917 create_field_all(next,type,name, 0, this_file, __LINE__)
065ae611 918
aacd3885
RS
919/* Like create_field, but the field is only valid when condition COND
920 is true. */
921
922static pair_p
065ae611
ZW
923create_optional_field_ (pair_p next, type_p type, const char *name,
924 const char *cond, int line)
aacd3885
RS
925{
926 static int id = 1;
065ae611 927 pair_p union_fields;
aacd3885
RS
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. */
065ae611 941 return create_field_all (next, union_type, name,
e1b793e7 942 create_option (0, "desc", cond), this_file, line);
aacd3885 943}
e1b793e7 944
065ae611 945#define create_optional_field(next,type,name,cond) \
f8ed6dc5 946 create_optional_field_(next,type,name,cond,__LINE__)
aacd3885 947
01d419ae
ZW
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}
01d419ae 961\f
e1b793e7 962
9e995780 963/* We don't care how long a CONST_DOUBLE is. */
36a5eadd 964#define CONST_DOUBLE_FORMAT "ww"
9e995780
ZW
965/* We don't want to see codes that are only for generator files. */
966#undef GENERATOR_FILE
967
e1b793e7
BS
968enum rtx_code
969{
9e995780
ZW
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
e1b793e7 976static const char *const rtx_name[NUM_RTX_CODE] = {
9e995780
ZW
977#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
978#include "rtl.def"
979#undef DEF_RTL_EXPR
980};
981
e1b793e7 982static const char *const rtx_format[NUM_RTX_CODE] = {
36a5eadd
GK
983#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
984#include "rtl.def"
985#undef DEF_RTL_EXPR
986};
987
5ba6918e 988static int rtx_next_new[NUM_RTX_CODE];
36a5eadd 989
9e995780
ZW
990/* We also need codes and names for insn notes (not register notes).
991 Note that we do *not* bias the note values here. */
e1b793e7
BS
992enum insn_note
993{
9e995780
ZW
994#define DEF_INSN_NOTE(NAME) NAME,
995#include "insn-notes.def"
996#undef DEF_INSN_NOTE
997
998 NOTE_INSN_MAX
999};
1000
79e4e6a6
JW
1001/* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
1002 default field for line number notes. */
e1b793e7 1003static const char *const note_insn_name[NOTE_INSN_MAX + 1] = {
9e995780
ZW
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
36a5eadd
GK
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
3d7aafde 1016gen_rtx_next (void)
36a5eadd
GK
1017{
1018 int i;
1019 for (i = 0; i < NUM_RTX_CODE; i++)
1020 {
1021 int k;
3d7aafde 1022
5ba6918e 1023 rtx_next_new[i] = -1;
36a5eadd 1024 if (strncmp (rtx_format[i], "iuu", 3) == 0)
5ba6918e 1025 rtx_next_new[i] = 2;
36a5eadd 1026 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
5ba6918e 1027 rtx_next_new[i] = 1;
3d7aafde 1028 else
36a5eadd
GK
1029 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
1030 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
5ba6918e 1031 rtx_next_new[i] = k;
36a5eadd
GK
1032 }
1033}
1034
1035/* Write out the contents of the rtx_next array. */
1036static void
3d7aafde 1037write_rtx_next (void)
36a5eadd
GK
1038{
1039 outf_p f = get_output_file_with_visibility (NULL);
1040 int i;
b8698a0f 1041 if (!f)
bd117bb6 1042 return;
3d7aafde 1043
36a5eadd 1044 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
6bc7bc14 1045 oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
36a5eadd 1046 for (i = 0; i < NUM_RTX_CODE; i++)
5ba6918e 1047 if (rtx_next_new[i] == -1)
36a5eadd
GK
1048 oprintf (f, " 0,\n");
1049 else
3d7aafde 1050 oprintf (f,
e1b793e7 1051 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n", rtx_next_new[i]);
36a5eadd
GK
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
e18476eb 1060adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
36a5eadd
GK
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;
a2c9fe42 1066 type_p basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
36a5eadd 1067
e1de1560 1068 if (t->kind != TYPE_UNION)
36a5eadd 1069 {
3d7aafde 1070 error_at_line (&lexer_line,
e1de1560 1071 "special `rtx_def' must be applied to a union");
36a5eadd
GK
1072 return &string_type;
1073 }
3d7aafde 1074
0f01f026 1075 nodot = create_option (NULL, "dot", "");
36a5eadd
GK
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));
a560d4d4 1081 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
36a5eadd 1082 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
e1b793e7
BS
1083 constant_tp =
1084 create_pointer (find_structure ("constant_descriptor_rtx", 0));
1085 scalar_tp = &scalar_nonchar; /* rtunion int */
36a5eadd
GK
1086
1087 {
1088 pair_p note_flds = NULL;
1089 int c;
5ba6918e 1090
9e995780 1091 for (c = 0; c <= NOTE_INSN_MAX; c++)
36a5eadd 1092 {
5ba6918e
GK
1093 switch (c)
1094 {
5ba6918e 1095 case NOTE_INSN_MAX:
1bcca2c5 1096 case NOTE_INSN_DELETED_LABEL:
0f01f026 1097 note_flds = create_field (note_flds, &string_type, "rt_str");
5ba6918e
GK
1098 break;
1099
1100 case NOTE_INSN_BLOCK_BEG:
1101 case NOTE_INSN_BLOCK_END:
0f01f026 1102 note_flds = create_field (note_flds, tree_tp, "rt_tree");
5ba6918e 1103 break;
3d7aafde 1104
014a1138 1105 case NOTE_INSN_VAR_LOCATION:
0f01f026 1106 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
5ba6918e
GK
1107 break;
1108
1109 default:
0f01f026 1110 note_flds = create_field (note_flds, scalar_tp, "rt_int");
5ba6918e
GK
1111 break;
1112 }
0f01f026
RS
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]);
36a5eadd 1119 }
0f01f026
RS
1120 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1121 &lexer_line, note_flds, NULL);
36a5eadd 1122 }
c185c797
RS
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 }
36a5eadd
GK
1136 for (i = 0; i < NUM_RTX_CODE; i++)
1137 {
36a5eadd
GK
1138 pair_p subfields = NULL;
1139 size_t aindex, nmindex;
1140 const char *sname;
0f01f026 1141 type_p substruct;
36a5eadd
GK
1142 char *ftag;
1143
1144 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1145 {
36a5eadd
GK
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;
9ce88f5e 1156 subname = "rt_int";
36a5eadd
GK
1157 break;
1158
1159 case '0':
1160 if (i == MEM && aindex == 1)
9ce88f5e 1161 t = mem_attrs_tp, subname = "rt_mem";
6fb5fa3c 1162 else if (i == JUMP_INSN && aindex == 8)
9ce88f5e 1163 t = rtx_tp, subname = "rt_rtx";
36a5eadd 1164 else if (i == CODE_LABEL && aindex == 5)
418e920f
BS
1165 t = scalar_tp, subname = "rt_int";
1166 else if (i == CODE_LABEL && aindex == 4)
9ce88f5e 1167 t = rtx_tp, subname = "rt_rtx";
e1b793e7 1168 else if (i == LABEL_REF && (aindex == 1 || aindex == 2))
9ce88f5e 1169 t = rtx_tp, subname = "rt_rtx";
418e920f 1170 else if (i == NOTE && aindex == 4)
0f953f83
JJ
1171 t = note_union_tp, subname = "";
1172 else if (i == NOTE && aindex == 5)
a38e7aa5 1173 t = scalar_tp, subname = "rt_int";
36a5eadd 1174 else if (i == NOTE && aindex >= 7)
9ce88f5e 1175 t = scalar_tp, subname = "rt_int";
36a5eadd 1176 else if (i == ADDR_DIFF_VEC && aindex == 4)
9ce88f5e 1177 t = scalar_tp, subname = "rt_int";
36a5eadd 1178 else if (i == VALUE && aindex == 0)
9ce88f5e 1179 t = scalar_tp, subname = "rt_int";
0ca5af51
AO
1180 else if (i == DEBUG_EXPR && aindex == 0)
1181 t = tree_tp, subname = "rt_tree";
36a5eadd 1182 else if (i == REG && aindex == 1)
9ce88f5e 1183 t = scalar_tp, subname = "rt_int";
a560d4d4 1184 else if (i == REG && aindex == 2)
9ce88f5e 1185 t = reg_attrs_tp, subname = "rt_reg";
36a5eadd 1186 else if (i == SCRATCH && aindex == 0)
9ce88f5e 1187 t = scalar_tp, subname = "rt_int";
52859c77 1188 else if (i == SYMBOL_REF && aindex == 1)
9ce88f5e 1189 t = scalar_tp, subname = "rt_int";
52859c77 1190 else if (i == SYMBOL_REF && aindex == 2)
c185c797 1191 t = symbol_union_tp, subname = "";
36a5eadd 1192 else if (i == BARRIER && aindex >= 3)
9ce88f5e 1193 t = scalar_tp, subname = "rt_int";
36a5eadd
GK
1194 else
1195 {
3d7aafde 1196 error_at_line (&lexer_line,
e1b793e7 1197 "rtx type `%s' has `0' in position %lu, can't handle",
6d8dd940 1198 rtx_name[i], (unsigned long) aindex);
36a5eadd 1199 t = &string_type;
9ce88f5e 1200 subname = "rt_int";
36a5eadd
GK
1201 }
1202 break;
3d7aafde 1203
36a5eadd
GK
1204 case 's':
1205 case 'S':
1206 case 'T':
1207 t = &string_type;
9ce88f5e 1208 subname = "rt_str";
36a5eadd
GK
1209 break;
1210
1211 case 'e':
1212 case 'u':
1213 t = rtx_tp;
9ce88f5e 1214 subname = "rt_rtx";
36a5eadd
GK
1215 break;
1216
1217 case 'E':
1218 case 'V':
1219 t = rtvec_tp;
9ce88f5e 1220 subname = "rt_rtvec";
36a5eadd
GK
1221 break;
1222
1223 case 't':
1224 t = tree_tp;
9ce88f5e 1225 subname = "rt_tree";
36a5eadd
GK
1226 break;
1227
36a5eadd
GK
1228 case 'B':
1229 t = basic_block_tp;
9ce88f5e 1230 subname = "rt_bb";
36a5eadd
GK
1231 break;
1232
1233 default:
3d7aafde 1234 error_at_line (&lexer_line,
e1b793e7 1235 "rtx type `%s' has `%c' in position %lu, can't handle",
36a5eadd 1236 rtx_name[i], rtx_format[i][aindex],
e1b793e7 1237 (unsigned long) aindex);
36a5eadd 1238 t = &string_type;
9ce88f5e 1239 subname = "rt_int";
36a5eadd
GK
1240 break;
1241 }
1242
0f01f026
RS
1243 subfields = create_field (subfields, t,
1244 xasprintf (".fld[%lu].%s",
1245 (unsigned long) aindex,
1246 subname));
1247 subfields->opt = nodot;
36a5eadd 1248 if (t == note_union_tp)
0f01f026 1249 subfields->opt = create_option (subfields->opt, "desc",
a38e7aa5 1250 "NOTE_KIND (&%0)");
c185c797
RS
1251 if (t == symbol_union_tp)
1252 subfields->opt = create_option (subfields->opt, "desc",
1253 "CONSTANT_POOL_ADDRESS_P (&%0)");
36a5eadd
GK
1254 }
1255
aacd3885
RS
1256 if (i == SYMBOL_REF)
1257 {
3fa9c136 1258 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
aacd3885 1259 type_p field_tp = find_structure ("block_symbol", 0);
3fa9c136
RS
1260 subfields
1261 = create_optional_field (subfields, field_tp, "block_sym",
1262 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
aacd3885
RS
1263 }
1264
36a5eadd 1265 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
0f01f026
RS
1266 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1267
36a5eadd
GK
1268 ftag = xstrdup (rtx_name[i]);
1269 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1270 ftag[nmindex] = TOUPPER (ftag[nmindex]);
0f01f026
RS
1271
1272 flds = create_field (flds, substruct, "");
1273 flds->opt = create_option (nodot, "tag", ftag);
36a5eadd
GK
1274 }
1275
0f01f026 1276 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
36a5eadd
GK
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
3d7aafde 1281 pointers to trees, actually sometimes contains pointers to RTL too.
36a5eadd
GK
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
3d7aafde 1286adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
36a5eadd
GK
1287{
1288 pair_p flds;
1289 options_p nodot;
3d7aafde 1290
36a5eadd
GK
1291 if (t->kind != TYPE_ARRAY)
1292 {
3d7aafde 1293 error_at_line (&lexer_line,
36a5eadd
GK
1294 "special `tree_exp' must be applied to an array");
1295 return &string_type;
1296 }
3d7aafde 1297
0f01f026
RS
1298 nodot = create_option (NULL, "dot", "");
1299
1300 flds = create_field (NULL, t, "");
1301 flds->opt = create_option (nodot, "length",
5039610b 1302 "TREE_OPERAND_LENGTH ((tree) &%0)");
0f01f026 1303 flds->opt = create_option (flds->opt, "default", "");
3d7aafde 1304
0f01f026 1305 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
36a5eadd
GK
1306}
1307
9f313342
GK
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
36a5eadd
GK
1314 TYPE_PARAM_STRUCT;
1315 - Handles "special" options.
3d7aafde 1316*/
9f313342 1317
e2500fed 1318type_p
3d7aafde 1319adjust_field_type (type_p t, options_p opt)
e2500fed
GK
1320{
1321 int length_p = 0;
1322 const int pointer_p = t->kind == TYPE_POINTER;
36a5eadd
GK
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;
3d7aafde 1329
e2500fed
GK
1330 for (; opt; opt = opt->next)
1331 if (strcmp (opt->name, "length") == 0)
1332 length_p = 1;
36a5eadd
GK
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))
e2500fed 1337 {
36a5eadd 1338 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
e2500fed 1339
e1b793e7
BS
1340 if (!UNION_OR_STRUCT_P (t)
1341 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
36a5eadd 1342 {
3d7aafde 1343 error_at_line (&lexer_line,
e1b793e7 1344 "option `%s' may only be applied to structures or structure pointers",
36a5eadd
GK
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);
e1b793e7
BS
1352 if (!ISDIGIT (opt->name[5]))
1353 params[num] =
1354 create_pointer (CONST_CAST2 (type_p, const char *, opt->info));
36a5eadd 1355 else
7cbb2a85 1356 params[num] = CONST_CAST2 (type_p, const char *, opt->info);
e2500fed 1357 }
36a5eadd
GK
1358 else if (strcmp (opt->name, "special") == 0)
1359 {
9e2878cf 1360 const char *special_name = opt->info;
36a5eadd
GK
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;
3d7aafde 1372
36a5eadd
GK
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
e1b793e7
BS
1379 if (!length_p
1380 && pointer_p && t->u.p->kind == TYPE_SCALAR && t->u.p->u.scalar_is_char)
e2500fed
GK
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
95161faf 1384 && t->u.a.p->u.p->u.scalar_is_char)
e2500fed
GK
1385 return create_array (&string_type, t->u.a.len);
1386
1387 return t;
1388}
e2500fed 1389\f
e1b793e7 1390
3d7aafde
AJ
1391static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1392static void set_gc_used (pair_p);
e2500fed 1393
9f313342
GK
1394/* Handle OPT for set_gc_used_type. */
1395
e2500fed 1396static void
3d7aafde 1397process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
e1b793e7
BS
1398 int *pass_param, int *length, int *skip,
1399 type_p *nested_ptr)
e2500fed
GK
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)
7cbb2a85
KG
1404 set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
1405 GC_POINTED_TO, NULL);
e2500fed
GK
1406 else if (strcmp (o->name, "maybe_undef") == 0)
1407 *maybe_undef = 1;
36a5eadd
GK
1408 else if (strcmp (o->name, "use_params") == 0)
1409 *pass_param = 1;
1410 else if (strcmp (o->name, "length") == 0)
1411 *length = 1;
5932ca9d
ZW
1412 else if (strcmp (o->name, "skip") == 0)
1413 *skip = 1;
d8044160
GK
1414 else if (strcmp (o->name, "nested_ptr") == 0)
1415 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
e2500fed
GK
1416}
1417
9f313342
GK
1418/* Set the gc_used field of T to LEVEL, and handle the types it references. */
1419
e2500fed 1420static void
3d7aafde 1421set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
e2500fed
GK
1422{
1423 if (t->gc_used >= level)
1424 return;
3d7aafde 1425
e2500fed
GK
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;
d8044160 1435 type_p dummy2;
e2500fed 1436
5932ca9d 1437 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
d8044160 1438 &dummy2);
e2500fed
GK
1439
1440 for (f = t->u.s.fields; f; f = f->next)
1441 {
1442 int maybe_undef = 0;
36a5eadd
GK
1443 int pass_param = 0;
1444 int length = 0;
5932ca9d 1445 int skip = 0;
d8044160 1446 type_p nested_ptr = NULL;
36a5eadd 1447 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
5932ca9d 1448 &length, &skip, &nested_ptr);
3d7aafde 1449
d8044160 1450 if (nested_ptr && f->type->kind == TYPE_POINTER)
b8698a0f 1451 set_gc_used_type (nested_ptr, GC_POINTED_TO,
d8044160
GK
1452 pass_param ? param : NULL);
1453 else if (length && f->type->kind == TYPE_POINTER)
36a5eadd
GK
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);
5932ca9d 1460 else if (skip)
e1b793e7 1461 ; /* target type is not used through this field */
e2500fed 1462 else
36a5eadd 1463 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
e2500fed
GK
1464 }
1465 break;
1466 }
1467
1468 case TYPE_POINTER:
36a5eadd 1469 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
e2500fed
GK
1470 break;
1471
1472 case TYPE_ARRAY:
36a5eadd 1473 set_gc_used_type (t->u.a.p, GC_USED, param);
e2500fed 1474 break;
3d7aafde 1475
e2500fed
GK
1476 case TYPE_LANG_STRUCT:
1477 for (t = t->u.s.lang_struct; t; t = t->next)
36a5eadd 1478 set_gc_used_type (t, level, param);
e2500fed
GK
1479 break;
1480
1481 case TYPE_PARAM_STRUCT:
36a5eadd
GK
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;
3d7aafde 1493 set_gc_used_type (t->u.param_struct.stru, level,
36a5eadd 1494 t->u.param_struct.param);
e2500fed
GK
1495 break;
1496
1497 default:
1498 break;
1499 }
1500}
1501
36a5eadd 1502/* Set the gc_used fields of all the types pointed to by VARIABLES. */
9f313342 1503
e2500fed 1504static void
3d7aafde 1505set_gc_used (pair_p variables)
e2500fed 1506{
1d32bbcd 1507 int nbvars = 0;
e2500fed
GK
1508 pair_p p;
1509 for (p = variables; p; p = p->next)
1d32bbcd
BS
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);
e2500fed
GK
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
065ae611 1522/* Output file handling. */
e2500fed 1523
e03856fe
GK
1524/* Create and return an outf_p for a new file for NAME, to be called
1525 ONAME. */
9f313342 1526
e03856fe 1527static outf_p
3d7aafde 1528create_file (const char *name, const char *oname)
e2500fed
GK
1529{
1530 static const char *const hdr[] = {
bd117bb6 1531 " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
e2500fed
GK
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",
9dcd6f09 1537 "Software Foundation; either version 3, or (at your option) any later\n",
e2500fed
GK
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",
9dcd6f09
NC
1546 "along with GCC; see the file COPYING3. If not see\n",
1547 "<http://www.gnu.org/licenses/>. */\n",
e2500fed
GK
1548 "\n",
1549 "/* This file is machine generated. Do not edit. */\n"
1550 };
e03856fe 1551 outf_p f;
e2500fed 1552 size_t i;
3d7aafde 1553
bd117bb6
BS
1554 gcc_assert (name != NULL);
1555 gcc_assert (oname != NULL);
5d038c4c 1556 f = XCNEW (struct outf);
e03856fe
GK
1557 f->next = output_files;
1558 f->name = oname;
1559 output_files = f;
1560
1561 oprintf (f, "/* Type information for %s.\n", name);
62c71f4b 1562 for (i = 0; i < ARRAY_SIZE (hdr); i++)
e03856fe 1563 oprintf (f, "%s", hdr[i]);
e2500fed
GK
1564 return f;
1565}
1566
b8698a0f 1567/* Print, like fprintf, to O.
311e3ff0
ZW
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. */
3d7aafde 1572void
e34d07f2 1573oprintf (outf_p o, const char *format, ...)
e03856fe 1574{
311e3ff0 1575 char *s;
e03856fe 1576 size_t slength;
311e3ff0 1577 va_list ap;
3d7aafde 1578
bd117bb6
BS
1579 /* In plugin mode, the O could be a NULL pointer, so avoid crashing
1580 in that case. */
b8698a0f 1581 if (!o)
bd117bb6
BS
1582 return;
1583
311e3ff0
ZW
1584 va_start (ap, format);
1585 slength = vasprintf (&s, format, ap);
e1b793e7 1586 if (s == NULL || (int) slength < 0)
311e3ff0
ZW
1587 fatal ("out of memory");
1588 va_end (ap);
e03856fe 1589
311e3ff0 1590 if (o->bufused + slength > o->buflength)
e03856fe
GK
1591 {
1592 size_t new_len = o->buflength;
1593 if (new_len == 0)
1594 new_len = 1024;
e1b793e7
BS
1595 do
1596 {
1597 new_len *= 2;
1598 }
1599 while (o->bufused + slength >= new_len);
cca8ead2 1600 o->buf = XRESIZEVEC (char, o->buf, new_len);
e03856fe
GK
1601 o->buflength = new_len;
1602 }
311e3ff0 1603 memcpy (o->buf + o->bufused, s, slength);
e03856fe 1604 o->bufused += slength;
311e3ff0 1605 free (s);
e03856fe
GK
1606}
1607
9f313342
GK
1608/* Open the global header file and the language-specific header files. */
1609
e2500fed 1610static void
3d7aafde 1611open_base_files (void)
e2500fed
GK
1612{
1613 size_t i;
3d7aafde 1614
bd117bb6
BS
1615 if (nb_plugin_files > 0 && plugin_files)
1616 return;
1617
e03856fe 1618 header_file = create_file ("GCC", "gtype-desc.h");
e2500fed 1619
11a67599
ZW
1620 base_files = XNEWVEC (outf_p, num_lang_dirs);
1621
1622 for (i = 0; i < num_lang_dirs; i++)
3d7aafde 1623 base_files[i] = create_file (lang_dir_names[i],
8ac9d31f 1624 xasprintf ("gtype-%s.h", lang_dir_names[i]));
e03856fe
GK
1625
1626 /* gtype-desc.c is a little special, so we create it here. */
1627 {
1628 /* The order of files here matters very much. */
e1b793e7 1629 static const char *const ifiles[] = {
b6feb796 1630 "config.h", "system.h", "coretypes.h", "tm.h",
e1b793e7 1631 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
7932a3db
NS
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",
1d65f45c 1636 "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
3bd36029 1637 "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h", NULL
e03856fe
GK
1638 };
1639 const char *const *ifp;
1640 outf_p gtype_desc_c;
3d7aafde 1641
e03856fe
GK
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);
5576d6f2
TT
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");
e03856fe 1649 }
e2500fed
GK
1650}
1651
8de8de02
OH
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{
e1b793e7 1658 const char *lastslash = strrchr (f, '/');
b8698a0f 1659
8de8de02
OH
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. */
9f313342 1679
e2500fed 1680static const char *
3d7aafde 1681get_file_basename (const char *f)
e2500fed 1682{
e1b793e7 1683 const char *srcdir_path = get_file_srcdir_relative_path (f);
3d7aafde 1684
8de8de02
OH
1685 return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
1686}
3d7aafde 1687
8de8de02
OH
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. */
3d7aafde 1690
8de8de02
OH
1691static int
1692get_prefix_langdir_index (const char *f)
1693{
1694 size_t f_len = strlen (f);
1695 size_t lang_index;
3d7aafde 1696
8de8de02 1697 for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
8ac9d31f 1698 {
e1b793e7 1699 const char *langdir = lang_dir_names[lang_index];
8de8de02 1700 size_t langdir_len = strlen (langdir);
b8698a0f 1701
8de8de02
OH
1702 if (f_len > langdir_len
1703 && IS_DIR_SEPARATOR (f[langdir_len])
1704 && memcmp (f, langdir, langdir_len) == 0)
1705 return lang_index;
8ac9d31f 1706 }
3d7aafde 1707
8de8de02
OH
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;
e1b793e7
BS
1722 const char *srcdir_relative_path = get_file_srcdir_relative_path (f);
1723 const char *r;
8de8de02
OH
1724
1725 if (!srcdir_relative_path)
1726 return NULL;
1727
1728 lang_index = get_prefix_langdir_index (srcdir_relative_path);
e1b793e7 1729 if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
39dabefd
SB
1730 r = "c-family";
1731 else if (lang_index >= 0)
e1b793e7 1732 r = lang_dir_names[lang_index];
39dabefd
SB
1733 else
1734 r = NULL;
8de8de02 1735
39dabefd 1736 return r;
8de8de02
OH
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);
b8698a0f 1749
e1b793e7 1750 char *result =
8de8de02
OH
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
0277fabf 1755 extension to ".h". We expect the input filename extension was at least
8de8de02
OH
1756 one character long. */
1757
1758 char *s = result;
1759
1760 for (; *s != '.'; s++)
e1b793e7 1761 if (!ISALNUM (*s) && *s != '-')
8de8de02
OH
1762 *s = '-';
1763
1764 memcpy (s, ".h", sizeof (".h"));
1765
1766 return result;
e2500fed
GK
1767}
1768
9f313342
GK
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
e03856fe 1773outf_p
3d7aafde 1774get_output_file_with_visibility (const char *input_file)
e2500fed 1775{
e03856fe 1776 outf_p r;
e2500fed
GK
1777 size_t len;
1778 const char *basename;
e03856fe
GK
1779 const char *for_name;
1780 const char *output_name;
e2500fed 1781
e03856fe
GK
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";
e2500fed 1787
bd117bb6
BS
1788 /* In plugin mode, return NULL unless the input_file is one of the
1789 plugin_files. */
9b39cba9
BS
1790 if (plugin_files)
1791 {
9f78bf05 1792 size_t i;
9b39cba9
BS
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;
bd117bb6
BS
1798 }
1799
e2500fed
GK
1800 /* Determine the output file name. */
1801 basename = get_file_basename (input_file);
1802
1803 len = strlen (basename);
e1b793e7
BS
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))
e2500fed 1807 {
b8698a0f 1808 output_name = get_file_gtfilename (input_file);
e03856fe 1809 for_name = basename;
e2500fed 1810 }
ad8c162b
ZL
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). */
39dabefd
SB
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";
29cc57cf
RG
1820 else if (strcmp (basename, "c-lang.h") == 0)
1821 output_name = "gt-c-decl.h", for_name = "c-decl.c";
e2500fed 1822 else if (strcmp (basename, "c-tree.h") == 0)
e03856fe 1823 output_name = "gt-c-decl.h", for_name = "c-decl.c";
6e955430
ZL
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";
e1b793e7
BS
1833 else if (strncmp (basename, "objc", 4) == 0
1834 && IS_DIR_SEPARATOR (basename[4])
ad8c162b
ZL
1835 && strcmp (basename + 5, "objc-act.h") == 0)
1836 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
b8698a0f 1837 else
e2500fed 1838 {
8de8de02 1839 int lang_index = get_prefix_langdir_index (basename);
3d7aafde 1840
8de8de02
OH
1841 if (lang_index >= 0)
1842 return base_files[lang_index];
e03856fe
GK
1843
1844 output_name = "gtype-desc.c";
1845 for_name = NULL;
e2500fed
GK
1846 }
1847
1848 /* Look through to see if we've ever seen this output filename before. */
e03856fe
GK
1849 for (r = output_files; r; r = r->next)
1850 if (strcmp (r->name, output_name) == 0)
1851 return r;
e2500fed
GK
1852
1853 /* If not, create it. */
e03856fe 1854 r = create_file (for_name, output_name);
e2500fed 1855
bd117bb6 1856 gcc_assert (r && r->name);
e03856fe 1857 return r;
e2500fed
GK
1858}
1859
9f313342
GK
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
e2500fed 1864const char *
3d7aafde 1865get_output_file_name (const char *input_file)
e2500fed 1866{
e1b793e7 1867 outf_p o = get_output_file_with_visibility (input_file);
bd117bb6
BS
1868 if (o)
1869 return o->name;
1870 return NULL;
e2500fed
GK
1871}
1872
41e7ac51
BS
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
e03856fe 1899/* Copy the output to its final destination,
9f313342
GK
1900 but don't unnecessarily change modification times. */
1901
e2500fed 1902static void
3d7aafde 1903close_output_files (void)
e2500fed 1904{
1d32bbcd 1905 int nbwrittenfiles = 0;
e03856fe 1906 outf_p of;
3d7aafde 1907
e03856fe 1908 for (of = output_files; of; of = of->next)
e2500fed 1909 {
e2500fed 1910
e1b793e7
BS
1911 if (!is_file_equal (of))
1912 {
1d32bbcd
BS
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");
e1b793e7
BS
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));
1d32bbcd
BS
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);
e1b793e7
BS
1946 }
1947 free (of->buf);
41e7ac51
BS
1948 of->buf = NULL;
1949 of->bufused = of->buflength = 0;
e2500fed 1950 }
1d32bbcd
BS
1951 if (verbosity_level >= 1)
1952 printf ("%s wrote %d files.\n", progname, nbwrittenfiles);
e2500fed
GK
1953}
1954\f
e1b793e7
BS
1955struct flist
1956{
e2500fed
GK
1957 struct flist *next;
1958 int started_p;
1959 const char *name;
e03856fe 1960 outf_p f;
e2500fed
GK
1961};
1962
17211ab5
GK
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*/
e1b793e7
BS
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);
17211ab5
GK
1971
1972/* Parameters for write_types. */
1973
3d7aafde 1974struct write_types_data
17211ab5
GK
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;
8d6419b2 1982 int skip_hooks; /* skip hook generation if non zero */
17211ab5
GK
1983};
1984
3d7aafde
AJ
1985static void output_escaped_param (struct walk_type_data *d,
1986 const char *, const char *);
e5cfc29f 1987static void output_mangled_typename (outf_p, const_type_p);
3d7aafde 1988static void walk_type (type_p t, struct walk_type_data *d);
e1b793e7 1989static void write_func_for_structure (type_p orig_s, type_p s, type_p *param,
a9429e29 1990 const struct write_types_data *wtd);
3d7aafde 1991static void write_types_process_field
e1b793e7 1992 (type_p f, const struct walk_type_data *d);
0182d016 1993static void write_types (outf_p output_header,
e1b793e7 1994 type_p structures,
3d7aafde
AJ
1995 type_p param_structs,
1996 const struct write_types_data *wtd);
17211ab5 1997static void write_types_local_process_field
e1b793e7 1998 (type_p f, const struct walk_type_data *d);
17211ab5 1999static void write_local_func_for_structure
e1b793e7 2000 (const_type_p orig_s, type_p s, type_p *param);
0182d016 2001static void write_local (outf_p output_header,
e1b793e7 2002 type_p structures, type_p param_structs);
3d7aafde
AJ
2003static void write_enum_defn (type_p structures, type_p param_structs);
2004static int contains_scalar_p (type_p t);
e1b793e7 2005static void put_mangled_filename (outf_p, const char *);
3d7aafde
AJ
2006static void finish_root_table (struct flist *flp, const char *pfx,
2007 const char *tname, const char *lastname,
2008 const char *name);
e1b793e7 2009static void write_root (outf_p, pair_p, type_p, const char *, int,
99be7084 2010 struct fileloc *, const char *, bool);
3d7aafde
AJ
2011static void write_array (outf_p f, pair_p v,
2012 const struct write_types_data *wtd);
99be7084 2013static void write_roots (pair_p, bool);
e2500fed 2014
17211ab5 2015/* Parameters for walk_type. */
e2500fed 2016
17211ab5 2017struct walk_type_data
e2500fed 2018{
17211ab5
GK
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;
0277fabf 2027 const struct fileloc *line;
17211ab5
GK
2028 lang_bitmap bitmap;
2029 type_p *param;
2030 int used_length;
2031 type_p orig_s;
2032 const char *reorder_fn;
d8044160
GK
2033 bool needs_cast_p;
2034 bool fn_wants_lvalue;
17211ab5 2035};
36a5eadd
GK
2036
2037/* Print a mangled name representing T to OF. */
2038
2039static void
e5cfc29f 2040output_mangled_typename (outf_p of, const_type_p t)
36a5eadd
GK
2041{
2042 if (t == NULL)
2043 oprintf (of, "Z");
e1b793e7
BS
2044 else
2045 switch (t->kind)
36a5eadd 2046 {
e1b793e7
BS
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 ();
36a5eadd 2074 }
e2500fed
GK
2075}
2076
17211ab5
GK
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. */
9f313342 2081
e2500fed 2082static void
3d7aafde
AJ
2083output_escaped_param (struct walk_type_data *d, const char *param,
2084 const char *oname)
e2500fed 2085{
17211ab5 2086 const char *p;
3d7aafde 2087
17211ab5
GK
2088 for (p = param; *p; p++)
2089 if (*p != '%')
2090 oprintf (d->of, "%c", *p);
e1b793e7
BS
2091 else
2092 switch (*++p)
e2500fed 2093 {
e1b793e7
BS
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);
e2500fed 2115 }
17211ab5 2116}
e2500fed 2117
17211ab5
GK
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
4da6879c
GK
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). */
e2500fed 2128
17211ab5 2129static void
3d7aafde 2130walk_type (type_p t, struct walk_type_data *d)
17211ab5
GK
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;
17211ab5 2137 options_p oo;
b453c95f 2138 const struct nested_ptr_data *nested_ptr_d = NULL;
3d7aafde 2139
d8044160 2140 d->needs_cast_p = false;
17211ab5
GK
2141 for (oo = d->opt; oo; oo = oo->next)
2142 if (strcmp (oo->name, "length") == 0)
9e2878cf 2143 length = oo->info;
17211ab5
GK
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)
9e2878cf 2152 desc = oo->info;
8d6419b2
BS
2153 else if (strcmp (oo->name, "mark_hook") == 0)
2154 ;
b453c95f 2155 else if (strcmp (oo->name, "nested_ptr") == 0)
d8044160 2156 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
17211ab5
GK
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 ;
17211ab5
GK
2167 else if (strcmp (oo->name, "param_is") == 0)
2168 ;
084087e1 2169 else if (strncmp (oo->name, "param", 5) == 0
e1b793e7 2170 && ISDIGIT (oo->name[5]) && strcmp (oo->name + 6, "_is") == 0)
084087e1 2171 ;
17211ab5
GK
2172 else if (strcmp (oo->name, "chain_next") == 0)
2173 ;
2174 else if (strcmp (oo->name, "chain_prev") == 0)
2175 ;
623f8e39
JJ
2176 else if (strcmp (oo->name, "chain_circular") == 0)
2177 ;
17211ab5
GK
2178 else if (strcmp (oo->name, "reorder") == 0)
2179 ;
a9429e29
LB
2180 else if (strcmp (oo->name, "variable_size") == 0)
2181 ;
17211ab5
GK
2182 else
2183 error_at_line (d->line, "unknown option `%s'\n", oo->name);
36a5eadd 2184
17211ab5
GK
2185 if (d->used_length)
2186 length = NULL;
36a5eadd 2187
17211ab5
GK
2188 if (use_params_p)
2189 {
2190 int pointer_p = t->kind == TYPE_POINTER;
3d7aafde 2191
17211ab5
GK
2192 if (pointer_p)
2193 t = t->u.p;
e1b793e7 2194 if (!UNION_OR_STRUCT_P (t))
17211ab5 2195 error_at_line (d->line, "`use_params' option on unimplemented type");
3d7aafde 2196 else
17211ab5
GK
2197 t = find_param_structure (t, d->param);
2198 if (pointer_p)
2199 t = create_pointer (t);
2200 }
3d7aafde 2201
17211ab5
GK
2202 if (use_param_num != -1)
2203 {
2204 if (d->param != NULL && d->param[use_param_num] != NULL)
e2500fed 2205 {
17211ab5 2206 type_p nt = d->param[use_param_num];
3d7aafde 2207
17211ab5
GK
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);
f099d360
GK
2212 d->needs_cast_p = (t->kind != TYPE_POINTER
2213 && (nt->kind == TYPE_POINTER
2214 || nt->kind == TYPE_STRING));
17211ab5 2215 t = nt;
e2500fed 2216 }
17211ab5 2217 else
e1b793e7 2218 error_at_line (d->line, "no parameter defined for `%s'", d->val);
17211ab5 2219 }
3d7aafde
AJ
2220
2221 if (maybe_undef_p
e1b793e7 2222 && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p)))
17211ab5 2223 {
3d7aafde 2224 error_at_line (d->line,
17211ab5
GK
2225 "field `%s' has invalid option `maybe_undef_p'\n",
2226 d->val);
2227 return;
2228 }
3d7aafde 2229
17211ab5
GK
2230 switch (t->kind)
2231 {
2232 case TYPE_SCALAR:
2233 case TYPE_STRING:
2234 d->process_field (t, d);
2235 break;
3d7aafde 2236
17211ab5
GK
2237 case TYPE_POINTER:
2238 {
e1b793e7 2239 if (maybe_undef_p && t->u.p->u.s.line.file == NULL)
17211ab5 2240 {
b2d59f6f 2241 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
17211ab5
GK
2242 break;
2243 }
e2500fed 2244
e1b793e7 2245 if (!length)
e2500fed 2246 {
e1b793e7 2247 if (!UNION_OR_STRUCT_P (t->u.p)
17211ab5 2248 && t->u.p->kind != TYPE_PARAM_STRUCT)
e2500fed 2249 {
3d7aafde 2250 error_at_line (d->line,
17211ab5
GK
2251 "field `%s' is pointer to unimplemented type",
2252 d->val);
e2500fed
GK
2253 break;
2254 }
3d7aafde 2255
b453c95f
GK
2256 if (nested_ptr_d)
2257 {
2258 const char *oldprevval2 = d->prev_val[2];
2259
e1b793e7 2260 if (!UNION_OR_STRUCT_P (nested_ptr_d->type))
b453c95f
GK
2261 {
2262 error_at_line (d->line,
2263 "field `%s' has invalid "
e1b793e7 2264 "option `nested_ptr'\n", d->val);
b453c95f
GK
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++);
d8044160 2272 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
b8698a0f
L
2273 (nested_ptr_d->type->kind == TYPE_UNION
2274 ? "union" : "struct"),
2275 nested_ptr_d->type->u.s.tag,
e1b793e7 2276 d->fn_wants_lvalue ? "" : "const ", d->val);
b453c95f
GK
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
d8044160
GK
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 }
b453c95f
GK
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);
e2500fed 2301 }
3d7aafde 2302 else
e2500fed 2303 {
17211ab5
GK
2304 int loopcounter = d->counter++;
2305 const char *oldval = d->val;
2306 const char *oldprevval3 = d->prev_val[3];
e2500fed
GK
2307 char *newval;
2308
17211ab5
GK
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);
e1b793e7
BS
2312 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
2313 "", loopcounter, loopcounter);
17211ab5
GK
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);
e2500fed 2321 free (newval);
17211ab5
GK
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, "");
e1b793e7 2327 d->process_field (t, d);
17211ab5
GK
2328 d->indent -= 2;
2329 oprintf (d->of, "%*s}\n", d->indent, "");
e2500fed 2330 }
17211ab5
GK
2331 }
2332 break;
e2500fed 2333
17211ab5
GK
2334 case TYPE_ARRAY:
2335 {
2336 int loopcounter = d->counter++;
2337 const char *oldval = d->val;
2338 char *newval;
2339
6356f892 2340 /* If it's an array of scalars, we optimize by not generating
17211ab5
GK
2341 any code. */
2342 if (t->u.a.p->kind == TYPE_SCALAR)
e2500fed 2343 break;
3d7aafde 2344
5039610b
SL
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. */
17211ab5
GK
2352 oprintf (d->of, "%*s{\n", d->indent, "");
2353 d->indent += 2;
2354 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
5039610b
SL
2355 oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2356 d->indent, "", loopcounter);
17211ab5
GK
2357 if (length)
2358 output_escaped_param (d, length, "length");
2359 else
2360 oprintf (d->of, "%s", t->u.a.len);
5039610b 2361 oprintf (d->of, ");\n");
b8698a0f 2362
5039610b
SL
2363 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2364 d->indent, "",
2365 loopcounter, loopcounter, loopcounter, loopcounter);
17211ab5
GK
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;
3d7aafde 2379
17211ab5
GK
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
e1b793e7 2391 if (!t->u.s.line.file)
17211ab5 2392 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
e2500fed 2393
17211ab5 2394 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
e2500fed 2395 {
17211ab5
GK
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 }
e2500fed 2401
17211ab5
GK
2402 /* Some things may also be defined in the structure's options. */
2403 for (o = t->u.s.opt; o; o = o->next)
e1b793e7 2404 if (!desc && strcmp (o->name, "desc") == 0)
9e2878cf 2405 desc = o->info;
e2500fed 2406
17211ab5
GK
2407 d->prev_val[2] = oldval;
2408 d->prev_val[1] = oldprevval2;
2409 if (union_p)
2410 {
2411 if (desc == NULL)
e2500fed 2412 {
e1b793e7
BS
2413 error_at_line (d->line,
2414 "missing `desc' option for union `%s'",
17211ab5
GK
2415 t->u.s.tag);
2416 desc = "1";
e2500fed 2417 }
17211ab5
GK
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)
9e2878cf 2437 dot = oo->info;
17211ab5 2438 else if (strcmp (oo->name, "tag") == 0)
9e2878cf 2439 tagid = oo->info;
17211ab5
GK
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)
9e2878cf 2445 d->reorder_fn = oo->info;
17211ab5
GK
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)
e2500fed 2454 {
17211ab5
GK
2455 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2456 d->indent += 2;
e2500fed 2457 }
17211ab5 2458 else if (union_p && default_p)
e2500fed 2459 {
17211ab5
GK
2460 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2461 d->indent += 2;
2462 seen_default_p = 1;
e2500fed 2463 }
e1b793e7 2464 else if (!union_p && (default_p || tagid))
3d7aafde 2465 error_at_line (d->line,
17211ab5
GK
2466 "can't use `%s' outside a union on field `%s'",
2467 default_p ? "default" : "tag", f->name);
e1b793e7 2468 else if (union_p && !(default_p || tagid)
17211ab5 2469 && f->type->kind == TYPE_SCALAR)
e2500fed 2470 {
17211ab5 2471 fprintf (stderr,
e1b793e7 2472 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
17211ab5
GK
2473 d->line->file, d->line->line, f->name);
2474 continue;
e2500fed 2475 }
e1b793e7 2476 else if (union_p && !(default_p || tagid))
3d7aafde 2477 error_at_line (d->line,
17211ab5 2478 "field `%s' is missing `tag' or `default' option",
e2500fed 2479 f->name);
3d7aafde 2480
17211ab5
GK
2481 d->line = &f->line;
2482 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2483 d->opt = f->opt;
d8044160 2484 d->used_length = false;
17211ab5
GK
2485
2486 if (union_p && use_param_p && d->param == NULL)
b2d59f6f 2487 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
17211ab5
GK
2488 else
2489 walk_type (f->type, d);
2490
2491 free (newval);
2492
2493 if (union_p)
e2500fed 2494 {
17211ab5
GK
2495 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2496 d->indent -= 2;
e2500fed 2497 }
17211ab5
GK
2498 }
2499 d->reorder_fn = NULL;
e2500fed 2500
17211ab5
GK
2501 d->val = oldval;
2502 d->prev_val[1] = oldprevval1;
2503 d->prev_val[2] = oldprevval2;
2504
e1b793e7 2505 if (union_p && !seen_default_p)
17211ab5
GK
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;
e2500fed 2514 }
17211ab5
GK
2515 }
2516 break;
e2500fed 2517
17211ab5
GK
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;
3d7aafde 2535
17211ab5
GK
2536 d->param = t->u.param_struct.param;
2537 walk_type (t->u.param_struct.stru, d);
2538 d->param = oldparam;
2539 }
2540 break;
3d7aafde 2541
17211ab5 2542 default:
b2d59f6f 2543 gcc_unreachable ();
e2500fed 2544 }
17211ab5
GK
2545}
2546
2547/* process_field routine for marking routines. */
2548
2549static void
3d7aafde 2550write_types_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
2551{
2552 const struct write_types_data *wtd;
f099d360 2553 const char *cast = d->needs_cast_p ? "(void *)" : "";
17211ab5 2554 wtd = (const struct write_types_data *) d->cookie;
3d7aafde 2555
17211ab5 2556 switch (f->kind)
e2500fed 2557 {
17211ab5 2558 case TYPE_POINTER:
3d7aafde 2559 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
f099d360 2560 wtd->subfield_marker_routine, cast, d->val);
17211ab5 2561 if (wtd->param_prefix)
36a5eadd 2562 {
17211ab5
GK
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]);
08cee789
DJ
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 }
e1b793e7 2578 else if (UNION_OR_STRUCT_P (f) && f->u.p->u.s.line.file != NULL)
08cee789
DJ
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");
36a5eadd 2585 }
17211ab5
GK
2586 oprintf (d->of, ");\n");
2587 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2588 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
f099d360 2589 wtd->reorder_note_routine, cast, d->val,
17211ab5
GK
2590 d->prev_val[3], d->reorder_fn);
2591 break;
2592
2593 case TYPE_STRING:
17211ab5
GK
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);
f099d360 2600 oprintf (d->of, " (%s%s);\n", cast, d->val);
17211ab5 2601 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2602 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
f099d360 2603 wtd->reorder_note_routine, cast, d->val, cast, d->val,
17211ab5
GK
2604 d->reorder_fn);
2605 break;
2606
2607 case TYPE_SCALAR:
2608 break;
3d7aafde 2609
17211ab5 2610 default:
b2d59f6f 2611 gcc_unreachable ();
e2500fed
GK
2612 }
2613}
2614
2d82317d
RH
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{
6ba2db5e 2620 if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.file != NULL)
2d82317d
RH
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
0277fabf
LB
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{
90aa3e91 2640 const char *fn;
0277fabf
LB
2641 int i;
2642
90aa3e91
BS
2643 gcc_assert (UNION_OR_STRUCT_P (s));
2644 fn = s->u.s.line.file;
2645
0277fabf
LB
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
17211ab5
GK
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
e1b793e7
BS
2659 field of S or its substructures and (in some cases) things
2660 that are pointed to by S.
17211ab5 2661*/
9f313342 2662
e2500fed 2663static void
8c80adb7
SB
2664write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2665 const struct write_types_data *wtd)
e2500fed 2666{
36a5eadd
GK
2667 const char *chain_next = NULL;
2668 const char *chain_prev = NULL;
623f8e39 2669 const char *chain_circular = NULL;
8d6419b2 2670 const char *mark_hook_name = NULL;
36a5eadd 2671 options_p opt;
17211ab5 2672 struct walk_type_data d;
3d7aafde 2673
17211ab5 2674 memset (&d, 0, sizeof (d));
0277fabf 2675 d.of = get_output_file_for_structure (s, param);
3d7aafde 2676
36a5eadd
GK
2677 for (opt = s->u.s.opt; opt; opt = opt->next)
2678 if (strcmp (opt->name, "chain_next") == 0)
9e2878cf 2679 chain_next = opt->info;
36a5eadd 2680 else if (strcmp (opt->name, "chain_prev") == 0)
9e2878cf 2681 chain_prev = opt->info;
623f8e39
JJ
2682 else if (strcmp (opt->name, "chain_circular") == 0)
2683 chain_circular = opt->info;
8d6419b2
BS
2684 else if (strcmp (opt->name, "mark_hook") == 0)
2685 mark_hook_name = opt->info;
36a5eadd
GK
2686
2687 if (chain_prev != NULL && chain_next == NULL)
2688 error_at_line (&s->u.s.line, "chain_prev without chain_next");
623f8e39
JJ
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;
36a5eadd 2693
17211ab5
GK
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";
e1b793e7 2702 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
2703 d.prev_val[3] = "x";
2704 d.val = "(*x)";
2705
2706 oprintf (d.of, "\n");
2707 oprintf (d.of, "void\n");
e2500fed 2708 if (param == NULL)
17211ab5 2709 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
e2500fed 2710 else
36a5eadd 2711 {
17211ab5
GK
2712 oprintf (d.of, "gt_%s_", wtd->prefix);
2713 output_mangled_typename (d.of, orig_s);
36a5eadd 2714 }
6906ba40 2715 oprintf (d.of, " (void *x_p)\n");
17211ab5
GK
2716 oprintf (d.of, "{\n");
2717 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
e2500fed 2718 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
36a5eadd 2719 chain_next == NULL ? "const " : "",
e2500fed 2720 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
36a5eadd 2721 if (chain_next != NULL)
17211ab5 2722 oprintf (d.of, " %s %s * xlimit = x;\n",
36a5eadd
GK
2723 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2724 if (chain_next == NULL)
17211ab5
GK
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);
2d82317d 2731 output_type_enum (d.of, orig_s);
17211ab5
GK
2732 }
2733 oprintf (d.of, "))\n");
2734 }
36a5eadd
GK
2735 else
2736 {
623f8e39
JJ
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);
17211ab5
GK
2741 if (wtd->param_prefix)
2742 {
2743 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2744 output_mangled_typename (d.of, orig_s);
2d82317d 2745 output_type_enum (d.of, orig_s);
17211ab5
GK
2746 }
2747 oprintf (d.of, "))\n");
623f8e39
JJ
2748 if (chain_circular != NULL)
2749 oprintf (d.of, " return;\n do\n");
8d6419b2
BS
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 }
17211ab5
GK
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");
8d6419b2
BS
2759 if (mark_hook_name && !wtd->skip_hooks)
2760 oprintf (d.of, " }\n");
36a5eadd
GK
2761 if (chain_prev != NULL)
2762 {
17211ab5
GK
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 = (",
36a5eadd 2767 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3d7aafde 2768
17211ab5
GK
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");
e1b793e7 2774 oprintf (d.of, " (void) %s (xprev", wtd->marker_routine);
17211ab5
GK
2775 if (wtd->param_prefix)
2776 {
2777 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2778 output_mangled_typename (d.of, orig_s);
2d82317d 2779 output_type_enum (d.of, orig_s);
17211ab5
GK
2780 }
2781 oprintf (d.of, ");\n");
2782 oprintf (d.of, " }\n");
36a5eadd 2783 }
623f8e39
JJ
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");
36a5eadd 2800 }
17211ab5 2801 oprintf (d.of, " {\n");
8d6419b2
BS
2802 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2803 {
2804 oprintf (d.of, " %s (x);\n", mark_hook_name);
2805 }
17211ab5
GK
2806 d.prev_val[2] = "*x";
2807 d.indent = 6;
2808 walk_type (s, &d);
3d7aafde 2809
36a5eadd
GK
2810 if (chain_next != NULL)
2811 {
17211ab5
GK
2812 oprintf (d.of, " x = (");
2813 output_escaped_param (&d, chain_next, "chain_next");
2814 oprintf (d.of, ");\n");
36a5eadd
GK
2815 }
2816
17211ab5 2817 oprintf (d.of, " }\n");
623f8e39
JJ
2818 if (chain_circular != NULL)
2819 oprintf (d.of, " while (x != xlimit);\n");
17211ab5 2820 oprintf (d.of, "}\n");
e2500fed 2821}
9f313342
GK
2822
2823/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
e2500fed
GK
2824
2825static void
0182d016 2826write_types (outf_p output_header, type_p structures, type_p param_structs,
3d7aafde 2827 const struct write_types_data *wtd)
e2500fed 2828{
1d32bbcd 2829 int nbfun = 0; /* Count the emitted functions. */
e2500fed 2830 type_p s;
3d7aafde 2831
0182d016 2832 oprintf (output_header, "\n/* %s*/\n", wtd->comment);
c802b1cf
BS
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");
e2500fed 2836 for (s = structures; s; s = s->next)
e1b793e7 2837 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
e2500fed
GK
2838 {
2839 options_p opt;
3d7aafde 2840
e1b793e7 2841 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
e2500fed
GK
2842 continue;
2843
0182d016
BS
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,
3d7aafde 2848 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
17211ab5 2849 s->u.s.tag);
e1b793e7 2850 oprintf (output_header, " } while (0)\n");
3d7aafde 2851
e2500fed
GK
2852 for (opt = s->u.s.opt; opt; opt = opt->next)
2853 if (strcmp (opt->name, "ptr_alias") == 0)
2854 {
e5cfc29f 2855 const_type_p const t = (const_type_p) opt->info;
3d7aafde 2856 if (t->kind == TYPE_STRUCT
e1b793e7 2857 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
0182d016 2858 oprintf (output_header,
17211ab5
GK
2859 "#define gt_%sx_%s gt_%sx_%s\n",
2860 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
e2500fed 2861 else
3d7aafde 2862 error_at_line (&s->u.s.line,
e2500fed
GK
2863 "structure alias is not a structure");
2864 break;
2865 }
2866 if (opt)
2867 continue;
2868
2869 /* Declare the marker procedure only once. */
0182d016 2870 oprintf (output_header,
3d7aafde 2871 "extern void gt_%sx_%s (void *);\n",
17211ab5 2872 wtd->prefix, s->u.s.tag);
3d7aafde 2873
e2500fed
GK
2874 if (s->u.s.line.file == NULL)
2875 {
3d7aafde 2876 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2877 s->u.s.tag);
2878 continue;
2879 }
e2500fed
GK
2880 }
2881
2882 for (s = param_structs; s; s = s->next)
2883 if (s->gc_used == GC_POINTED_TO)
2884 {
e2500fed
GK
2885 type_p stru = s->u.param_struct.stru;
2886
e2500fed 2887 /* Declare the marker procedure. */
0182d016
BS
2888 oprintf (output_header, "extern void gt_%s_", wtd->prefix);
2889 output_mangled_typename (output_header, s);
2890 oprintf (output_header, " (void *);\n");
3d7aafde 2891
e2500fed
GK
2892 if (stru->u.s.line.file == NULL)
2893 {
3d7aafde 2894 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2895 s->u.s.tag);
2896 continue;
2897 }
c802b1cf 2898 }
b8698a0f
L
2899
2900 /* At last we emit the functions code. */
c802b1cf
BS
2901 oprintf (output_header, "\n/* functions code */\n");
2902 for (s = structures; s; s = s->next)
e1b793e7 2903 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
c802b1cf
BS
2904 {
2905 options_p opt;
3d7aafde 2906
e1b793e7 2907 if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
c802b1cf
BS
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;
b8698a0f 2914
c802b1cf
BS
2915 if (s->kind == TYPE_LANG_STRUCT)
2916 {
2917 type_p ss;
2918 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
1d32bbcd
BS
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 }
c802b1cf
BS
2925 }
2926 else
1d32bbcd
BS
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 }
c802b1cf 2933 }
1d32bbcd
BS
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
c802b1cf
BS
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;
e2500fed
GK
2949 if (stru->kind == TYPE_LANG_STRUCT)
2950 {
2951 type_p ss;
2952 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
1d32bbcd
BS
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 }
17211ab5
GK
2959 }
2960 else
1d32bbcd
BS
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);
17211ab5 2973 }
1d32bbcd
BS
2974 if (verbosity_level >= 2)
2975 printf ("%s emitted %d routines for %s\n",
2976 progname, nbfun, wtd->comment);
17211ab5
GK
2977}
2978
e1b793e7 2979static const struct write_types_data ggc_wtd = {
17211ab5 2980 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
8d6419b2
BS
2981 "GC marker procedures. ",
2982 FALSE
17211ab5
GK
2983};
2984
e1b793e7 2985static const struct write_types_data pch_wtd = {
17211ab5
GK
2986 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2987 "gt_pch_note_reorder",
8d6419b2
BS
2988 "PCH type-walking procedures. ",
2989 TRUE
17211ab5
GK
2990};
2991
2992/* Write out the local pointer-walking routines. */
2993
2994/* process_field routine for local pointer-walking. */
2995
2996static void
3d7aafde 2997write_types_local_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
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;
3d7aafde 3014
17211ab5 3015 default:
b2d59f6f 3016 gcc_unreachable ();
17211ab5
GK
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
d8044160 3023 - Calls PROCESS_FIELD on each field of S or its substructures.
17211ab5
GK
3024*/
3025
3026static void
0277fabf 3027write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param)
17211ab5 3028{
17211ab5 3029 struct walk_type_data d;
3d7aafde 3030
17211ab5 3031 memset (&d, 0, sizeof (d));
0277fabf 3032 d.of = get_output_file_for_structure (s, param);
17211ab5
GK
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";
e1b793e7 3039 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
3040 d.prev_val[3] = "x";
3041 d.val = "(*x)";
d8044160 3042 d.fn_wants_lvalue = true;
17211ab5
GK
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);
e18476eb
BI
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");
17211ab5
GK
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
0182d016 3064write_local (outf_p output_header, type_p structures, type_p param_structs)
17211ab5
GK
3065{
3066 type_p s;
3d7aafde 3067
b8698a0f 3068 if (!output_header)
bd117bb6 3069 return;
0182d016 3070 oprintf (output_header, "\n/* Local pointer-walking routines. */\n");
17211ab5 3071 for (s = structures; s; s = s->next)
e1b793e7 3072 if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
17211ab5
GK
3073 {
3074 options_p opt;
3d7aafde 3075
17211ab5
GK
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 {
e5cfc29f 3082 const_type_p const t = (const_type_p) opt->info;
3d7aafde 3083 if (t->kind == TYPE_STRUCT
e1b793e7 3084 || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
17211ab5 3085 {
0182d016
BS
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");
17211ab5
GK
3091 }
3092 else
3d7aafde 3093 error_at_line (&s->u.s.line,
17211ab5
GK
3094 "structure alias is not a structure");
3095 break;
3096 }
3097 if (opt)
3098 continue;
3099
3100 /* Declare the marker procedure only once. */
0182d016
BS
3101 oprintf (output_header, "extern void gt_pch_p_");
3102 output_mangled_typename (output_header, s);
3103 oprintf (output_header,
e1b793e7 3104 "\n (void *, void *, gt_pointer_operator, void *);\n");
3d7aafde 3105
17211ab5
GK
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 {
e1b793e7 3119 type_p *param = s->u.param_struct.param;
17211ab5
GK
3120 type_p stru = s->u.param_struct.stru;
3121
3122 /* Declare the marker procedure. */
0182d016
BS
3123 oprintf (output_header, "extern void gt_pch_p_");
3124 output_mangled_typename (output_header, s);
3125 oprintf (output_header,
e1b793e7 3126 "\n (void *, void *, gt_pointer_operator, void *);\n");
3d7aafde 3127
17211ab5
GK
3128 if (stru->u.s.line.file == NULL)
3129 {
3d7aafde 3130 fprintf (stderr, "warning: structure `%s' used but not defined\n",
17211ab5
GK
3131 s->u.s.tag);
3132 continue;
3133 }
3d7aafde 3134
17211ab5
GK
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);
e2500fed
GK
3140 }
3141 else
17211ab5 3142 write_local_func_for_structure (s, stru, param);
36a5eadd
GK
3143 }
3144}
3145
a9429e29
LB
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
36a5eadd
GK
3160/* Write out the 'enum' definition for gt_types_enum. */
3161
3162static void
8c80adb7 3163write_enum_defn (type_p structures, type_p param_structs)
36a5eadd
GK
3164{
3165 type_p s;
1d32bbcd
BS
3166 int nbstruct = 0;
3167 int nbparamstruct = 0;
3d7aafde 3168
b8698a0f 3169 if (!header_file)
bd117bb6 3170 return;
36a5eadd
GK
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)
a9429e29 3174 if (USED_BY_TYPED_GC_P (s))
36a5eadd 3175 {
1d32bbcd
BS
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);
36a5eadd
GK
3182 oprintf (header_file, " gt_ggc_e_");
3183 output_mangled_typename (header_file, s);
a9429e29 3184 oprintf (header_file, ",\n");
e2500fed 3185 }
36a5eadd
GK
3186 for (s = param_structs; s; s = s->next)
3187 if (s->gc_used == GC_POINTED_TO)
3188 {
1d32bbcd
BS
3189 nbparamstruct++;
3190 DBGPRINTF ("write_enum_defn s %p nbparamstruct %d",
3191 (void*) s, nbparamstruct);
36a5eadd
GK
3192 oprintf (header_file, " gt_e_");
3193 output_mangled_typename (header_file, s);
a9429e29 3194 oprintf (header_file, ",\n");
36a5eadd
GK
3195 }
3196 oprintf (header_file, " gt_types_enum_last\n");
3197 oprintf (header_file, "};\n");
1d32bbcd
BS
3198 if (verbosity_level >= 2)
3199 printf ("%s handled %d GTY-ed structures & %d parameterized structures.\n",
3200 progname, nbstruct, nbparamstruct);
3201
e2500fed
GK
3202}
3203
17211ab5
GK
3204/* Might T contain any non-pointer elements? */
3205
3206static int
3d7aafde 3207contains_scalar_p (type_p t)
17211ab5
GK
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
e1b793e7 3218 fields, but there aren't enough of those to worry about. */
17211ab5
GK
3219 return 1;
3220 }
3221}
36a5eadd 3222
9f313342
GK
3223/* Mangle FN and print it to F. */
3224
e2500fed 3225static void
3d7aafde 3226put_mangled_filename (outf_p f, const char *fn)
e2500fed
GK
3227{
3228 const char *name = get_output_file_name (fn);
b8698a0f 3229 if (!f || !name)
bd117bb6 3230 return;
e2500fed 3231 for (; *name != 0; name++)
1f8e4682 3232 if (ISALNUM (*name))
e03856fe 3233 oprintf (f, "%c", *name);
e2500fed 3234 else
e03856fe 3235 oprintf (f, "%c", '_');
e2500fed
GK
3236}
3237
9f313342
GK
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
e2500fed 3242static void
3d7aafde
AJ
3243finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3244 const char *tname, const char *name)
e2500fed
GK
3245{
3246 struct flist *fli2;
3d7aafde 3247
e2500fed
GK
3248 for (fli2 = flp; fli2; fli2 = fli2->next)
3249 if (fli2->started_p)
3250 {
e03856fe
GK
3251 oprintf (fli2->f, " %s\n", lastname);
3252 oprintf (fli2->f, "};\n\n");
e2500fed
GK
3253 }
3254
bd117bb6 3255 for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
e2500fed
GK
3256 if (fli2->started_p)
3257 {
11a67599 3258 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3259 int fnum;
3260
3261 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3262 if (bitmap & 1)
3263 {
e03856fe 3264 oprintf (base_files[fnum],
e1b793e7 3265 "extern const struct %s gt_%s_", tname, pfx);
e2500fed 3266 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3267 oprintf (base_files[fnum], "[];\n");
e2500fed
GK
3268 }
3269 }
3d7aafde 3270
17211ab5
GK
3271 {
3272 size_t fnum;
bd117bb6 3273 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
e1b793e7
BS
3274 oprintf (base_files[fnum],
3275 "EXPORTED_CONST struct %s * const %s[] = {\n", tname, name);
17211ab5 3276 }
3d7aafde 3277
e2500fed
GK
3278
3279 for (fli2 = flp; fli2; fli2 = fli2->next)
3280 if (fli2->started_p)
3281 {
11a67599 3282 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3283 int fnum;
3284
3285 fli2->started_p = 0;
3286
bd117bb6 3287 for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
e2500fed
GK
3288 if (bitmap & 1)
3289 {
17211ab5 3290 oprintf (base_files[fnum], " gt_%s_", pfx);
e2500fed 3291 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3292 oprintf (base_files[fnum], ",\n");
e2500fed
GK
3293 }
3294 }
3295
3296 {
17211ab5 3297 size_t fnum;
bd117bb6 3298 for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
17211ab5
GK
3299 {
3300 oprintf (base_files[fnum], " NULL\n");
3301 oprintf (base_files[fnum], "};\n");
3302 }
e2500fed
GK
3303 }
3304}
3305
b08e0339
RS
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
647565f6
RS
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. */
b08e0339 3352 if (v && type == v->type)
647565f6
RS
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)
b08e0339 3364 v = NULL;
647565f6
RS
3365 write_root (f, v, field_type, ACONCAT ((name, ".", field_name, NULL)),
3366 has_length, line, if_marked, emit_pch);
3367}
3368
9f313342 3369/* Write out to F the table entry and any marker routines needed to
b08e0339
RS
3370 mark NAME as TYPE. V can be one of three values:
3371
f8ed6dc5
JS
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.
b08e0339 3375
f8ed6dc5 3376 - the outermost array that contains NAME, if NAME is part of an array.
b08e0339 3377
f8ed6dc5 3378 - the C variable that contains NAME, if NAME is not part of an array.
b08e0339
RS
3379
3380 LINE is the line of the C source that declares the root variable.
9f313342
GK
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
e2500fed 3384static void
3d7aafde 3385write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
99be7084 3386 struct fileloc *line, const char *if_marked, bool emit_pch)
e2500fed
GK
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;
3d7aafde 3398
e2500fed
GK
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)
9e2878cf 3403 desc = o->info;
69c32ec8
JH
3404 else if (strcmp (o->name, "param_is") == 0)
3405 ;
e2500fed
GK
3406 else
3407 error_at_line (line,
e1b793e7 3408 "field `%s' of global `%s' has unknown option `%s'",
e2500fed 3409 fld->name, name, o->name);
3d7aafde 3410
e2500fed
GK
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;
3d7aafde 3417
e2500fed
GK
3418 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3419 {
3420 const char *tag = NULL;
3421 options_p oo;
3d7aafde 3422
e2500fed
GK
3423 for (oo = ufld->opt; oo; oo = oo->next)
3424 if (strcmp (oo->name, "tag") == 0)
9e2878cf 3425 tag = oo->info;
e2500fed
GK
3426 if (tag == NULL || strcmp (tag, desc) != 0)
3427 continue;
3428 if (validf != NULL)
3d7aafde 3429 error_at_line (line,
e1b793e7 3430 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
e2500fed 3431 name, fld->name, validf->name,
e1b793e7 3432 name, fld->name, ufld->name, tag);
e2500fed
GK
3433 validf = ufld;
3434 }
3435 if (validf != NULL)
647565f6
RS
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)));
e2500fed
GK
3440 }
3441 else if (desc)
3d7aafde 3442 error_at_line (line,
e1b793e7 3443 "global `%s.%s' has `desc' option but is not union",
e2500fed
GK
3444 name, fld->name);
3445 else
647565f6
RS
3446 write_field_root (f, v, type, name, 0, line, if_marked,
3447 emit_pch, fld->type, fld->name);
e2500fed
GK
3448 }
3449 }
3450 break;
3451
3452 case TYPE_ARRAY:
3453 {
3454 char *newname;
e03856fe 3455 newname = xasprintf ("%s[0]", name);
99be7084
BS
3456 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
3457 emit_pch);
e2500fed
GK
3458 free (newname);
3459 }
3460 break;
3d7aafde 3461
e2500fed
GK
3462 case TYPE_POINTER:
3463 {
b08e0339
RS
3464 type_p tp;
3465
3466 if (!start_root_entry (f, v, name, line))
3467 return;
3d7aafde 3468
e2500fed 3469 tp = type->u.p;
3d7aafde 3470
e1b793e7 3471 if (!has_length && UNION_OR_STRUCT_P (tp))
e2500fed 3472 {
17211ab5 3473 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
99be7084
BS
3474 if (emit_pch)
3475 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
3476 else
3477 oprintf (f, " NULL");
e2500fed 3478 }
e1b793e7 3479 else if (!has_length && tp->kind == TYPE_PARAM_STRUCT)
e2500fed 3480 {
36a5eadd
GK
3481 oprintf (f, " &gt_ggc_m_");
3482 output_mangled_typename (f, tp);
99be7084
BS
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");
e2500fed
GK
3490 }
3491 else if (has_length
afb0f770 3492 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
e2500fed 3493 {
17211ab5 3494 oprintf (f, " &gt_ggc_ma_%s,\n", name);
99be7084
BS
3495 if (emit_pch)
3496 oprintf (f, " &gt_pch_na_%s", name);
3497 else
3498 oprintf (f, " NULL");
e2500fed
GK
3499 }
3500 else
3501 {
3d7aafde 3502 error_at_line (line,
e2500fed
GK
3503 "global `%s' is pointer to unimplemented type",
3504 name);
3505 }
3506 if (if_marked)
e03856fe
GK
3507 oprintf (f, ",\n &%s", if_marked);
3508 oprintf (f, "\n },\n");
e2500fed
GK
3509 }
3510 break;
3511
e2500fed 3512 case TYPE_STRING:
17211ab5 3513 {
b08e0339
RS
3514 if (!start_root_entry (f, v, name, line))
3515 return;
3516
dae4174e 3517 oprintf (f, " (gt_pointer_walker) &gt_ggc_m_S,\n");
f099d360 3518 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
17211ab5
GK
3519 oprintf (f, " },\n");
3520 }
3521 break;
3d7aafde 3522
17211ab5 3523 case TYPE_SCALAR:
e2500fed 3524 break;
3d7aafde 3525
e2500fed 3526 default:
e1b793e7 3527 error_at_line (line, "global `%s' is unimplemented type", name);
e2500fed
GK
3528 }
3529}
3530
17211ab5
GK
3531/* This generates a routine to walk an array. */
3532
3533static void
3d7aafde 3534write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
17211ab5
GK
3535{
3536 struct walk_type_data d;
3537 char *prevval3;
3d7aafde 3538
17211ab5
GK
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;
11a67599 3545 d.bitmap = get_lang_bitmap (v->line.file);
17211ab5
GK
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);
e1b793e7 3553 oprintf (f, " (void *, void *, gt_pointer_operator, void *);\n");
e18476eb 3554 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
17211ab5 3555 wtd->param_prefix, v->name);
e18476eb
BI
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");
17211ab5
GK
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;
e1b793e7 3568 oprintf (f, "static void gt_%sa_%s (void *);\n", wtd->prefix, v->name);
e18476eb 3569 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
17211ab5 3570 wtd->prefix, v->name);
17211ab5
GK
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
9f313342
GK
3579/* Output a table describing the locations and types of VARIABLES. */
3580
e2500fed 3581static void
99be7084 3582write_roots (pair_p variables, bool emit_pch)
e2500fed
GK
3583{
3584 pair_p v;
3585 struct flist *flp = NULL;
3586
3587 for (v = variables; v; v = v->next)
3588 {
e03856fe 3589 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
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)
9e2878cf 3597 length = o->info;
e2500fed
GK
3598 else if (strcmp (o->name, "deletable") == 0)
3599 deletable_p = 1;
3600 else if (strcmp (o->name, "param_is") == 0)
3601 ;
3d7aafde 3602 else if (strncmp (o->name, "param", 5) == 0
e1b793e7 3603 && ISDIGIT (o->name[5]) && strcmp (o->name + 6, "_is") == 0)
36a5eadd 3604 ;
e2500fed
GK
3605 else if (strcmp (o->name, "if_marked") == 0)
3606 ;
3607 else
3d7aafde 3608 error_at_line (&v->line,
e2500fed
GK
3609 "global `%s' has unknown option `%s'",
3610 v->name, o->name);
3611
3612 for (fli = flp; fli; fli = fli->next)
bd117bb6 3613 if (fli->f == f && f)
e2500fed
GK
3614 break;
3615 if (fli == NULL)
3616 {
5d038c4c 3617 fli = XNEW (struct flist);
e2500fed
GK
3618 fli->f = f;
3619 fli->next = flp;
3620 fli->started_p = 0;
3621 fli->name = v->line.file;
e1b793e7 3622 gcc_assert (fli->name);
e2500fed
GK
3623 flp = fli;
3624
e03856fe 3625 oprintf (f, "\n/* GC roots. */\n\n");
e2500fed
GK
3626 }
3627
e1b793e7 3628 if (!deletable_p
e2500fed
GK
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 {
17211ab5
GK
3634 write_array (f, v, &ggc_wtd);
3635 write_array (f, v, &pch_wtd);
e2500fed
GK
3636 }
3637 }
3638
3639 for (v = variables; v; v = v->next)
3640 {
e03856fe 3641 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3642 struct flist *fli;
3643 int skip_p = 0;
3644 int length_p = 0;
3645 options_p o;
3d7aafde 3646
e2500fed
GK
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;
e1b793e7 3660 if (!fli->started_p)
e2500fed
GK
3661 {
3662 fli->started_p = 1;
3663
6bc7bc14 3664 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
e2500fed 3665 put_mangled_filename (f, v->line.file);
e03856fe 3666 oprintf (f, "[] = {\n");
e2500fed
GK
3667 }
3668
99be7084 3669 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
e2500fed
GK
3670 }
3671
3d7aafde 3672 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3673 "gt_ggc_rtab");
3674
3675 for (v = variables; v; v = v->next)
3676 {
e03856fe 3677 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
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;
e1b793e7 3694 if (!fli->started_p)
e2500fed
GK
3695 {
3696 fli->started_p = 1;
3697
6bc7bc14 3698 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
e2500fed 3699 put_mangled_filename (f, v->line.file);
e03856fe 3700 oprintf (f, "[] = {\n");
e2500fed 3701 }
3d7aafde 3702
17211ab5 3703 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
e2500fed
GK
3704 v->name, v->name);
3705 }
3d7aafde 3706
17211ab5 3707 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3708 "gt_ggc_deletable_rtab");
3709
3710 for (v = variables; v; v = v->next)
3711 {
e03856fe 3712 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3713 struct flist *fli;
3714 const char *if_marked = NULL;
3715 int length_p = 0;
3716 options_p o;
3d7aafde 3717
e2500fed
GK
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)
9e2878cf 3722 if_marked = o->info;
e2500fed
GK
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 {
e1b793e7
BS
3731 error_at_line (&v->line,
3732 "if_marked option used but not hash table");
e2500fed
GK
3733 continue;
3734 }
3735
3736 for (fli = flp; fli; fli = fli->next)
3737 if (fli->f == f)
3738 break;
e1b793e7 3739 if (!fli->started_p)
e2500fed
GK
3740 {
3741 fli->started_p = 1;
3742
6bc7bc14 3743 oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
e2500fed 3744 put_mangled_filename (f, v->line.file);
e03856fe 3745 oprintf (f, "[] = {\n");
e2500fed 3746 }
3d7aafde 3747
17211ab5 3748 write_root (f, v, v->type->u.p->u.param_struct.param[0],
99be7084 3749 v->name, length_p, &v->line, if_marked, emit_pch);
e2500fed 3750 }
3d7aafde 3751
17211ab5 3752 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
e2500fed 3753 "gt_ggc_cache_rtab");
17211ab5 3754
99be7084
BS
3755 if (!emit_pch)
3756 return;
3757
17211ab5
GK
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;
3d7aafde 3765
17211ab5
GK
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
e1b793e7 3772 if (!if_marked_p)
17211ab5
GK
3773 continue;
3774
3775 for (fli = flp; fli; fli = fli->next)
3776 if (fli->f == f)
3777 break;
e1b793e7 3778 if (!fli->started_p)
17211ab5
GK
3779 {
3780 fli->started_p = 1;
3781
6bc7bc14 3782 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
17211ab5
GK
3783 put_mangled_filename (f, v->line.file);
3784 oprintf (f, "[] = {\n");
3785 }
3786
99be7084 3787 write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
17211ab5 3788 }
3d7aafde 3789
17211ab5
GK
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
e1b793e7 3808 if (!contains_scalar_p (v->type))
17211ab5
GK
3809 continue;
3810
3811 for (fli = flp; fli; fli = fli->next)
3812 if (fli->f == f)
3813 break;
e1b793e7 3814 if (!fli->started_p)
17211ab5
GK
3815 {
3816 fli->started_p = 1;
3817
6bc7bc14 3818 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
17211ab5
GK
3819 put_mangled_filename (f, v->line.file);
3820 oprintf (f, "[] = {\n");
3821 }
3d7aafde 3822
17211ab5
GK
3823 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3824 v->name, v->name);
3825 }
3d7aafde 3826
17211ab5
GK
3827 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3828 "gt_pch_scalar_rtab");
e2500fed
GK
3829}
3830
4a399aef
ZW
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
8ad97cfc 3843note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
4a399aef 3844{
065ae611 3845 pair_p fields;
4a399aef
ZW
3846 type_p t;
3847 options_p o;
065ae611 3848 type_p len_ty = create_scalar_type ("unsigned");
e1b793e7 3849 const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
4a399aef
ZW
3850
3851 if (is_scalar)
3852 {
8ad97cfc 3853 t = create_scalar_type (type_name);
4a399aef
ZW
3854 o = 0;
3855 }
3856 else
3857 {
8ad97cfc 3858 t = resolve_typedef (type_name, pos);
4a399aef
ZW
3859 o = create_option (0, "length", "%h.num");
3860 }
3861
3862 /* We assemble the field list in reverse order. */
065ae611
ZW
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);
4a399aef
ZW
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> {
f8ed6dc5 3874 VEC_<type>_base base;
4a399aef
ZW
3875 } VEC_<type>_<astrat>;
3876*/
3877void
3878note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3879{
e1b793e7
BS
3880 const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0);
3881 const char *basename = concat ("VEC_", type, "_base", (char *) 0);
4a399aef 3882
065ae611
ZW
3883 pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3884 "base", 0, pos);
4a399aef
ZW
3885
3886 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3887}
3888
a9429e29
LB
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
e1b793e7
BS
3914enum alloc_quantity
3915{ single, vector };
3916enum alloc_zone
3917{ any_zone, specific_zone };
a9429e29
LB
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
e1b793e7
BS
3927write_typed_alloc_def (bool variable_size, const char *type_specifier,
3928 const char *type_name, const char *allocator_type,
a9429e29
LB
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
e1b793e7 3935 oprintf (header_file, "#define ggc_alloc_%s%s", allocator_type, type_name);
a9429e29
LB
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
e1b793e7 3957write_typed_struct_alloc_def (const type_p s, const char *allocator_type,
a9429e29
LB
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
e1b793e7 3968write_typed_typedef_alloc_def (const pair_p p, const char *allocator_type,
a9429e29
LB
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++)
e1b793e7
BS
4049 if (t->u.param_struct.param[i] != NULL)
4050 {
4051 output_typename (of, t->u.param_struct.param[i]);
4052 oprintf (of, "_");
4053 }
a9429e29
LB
4054 output_typename (of, t->u.param_struct.stru);
4055 break;
4056 }
4057 default:
e1b793e7 4058 gcc_unreachable ();
a9429e29
LB
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{
90aa3e91 4068 outf_p of = get_output_file_with_visibility (NULL);
a9429e29
LB
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
0277fabf
LB
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 {
e1b793e7
BS
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 ();
0277fabf
LB
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 {
e1b793e7
BS
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 ();
0277fabf
LB
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 {
e1b793e7
BS
4179 printf ("%s:%s ", o->name, o->info);
4180 o = o->next;
0277fabf
LB
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 {
e1b793e7
BS
4210 dump_pair (indent + INDENT, fields);
4211 fields = fields->next;
0277fabf
LB
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
e1b793e7 4274 printf ("%*cType at %p: ", indent, ' ', (void *) t);
0277fabf
LB
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, ' ',
e1b793e7 4286 (void *) t->pointer_to);
0277fabf
LB
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 }
e1b793e7 4314 printf ("%*cEnd of type at %p\n", indent, ' ', (void *) t);
0277fabf
LB
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
e1b793e7 4332dump_pair_list (const char *name, pair_p pp)
0277fabf
LB
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
e1b793e7 4344dump_structures (const char *name, type_p structures)
0277fabf
LB
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}
e2500fed 4363\f
e1b793e7 4364
f8ed6dc5
JS
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'},
1d32bbcd 4370 {"verbose", no_argument, NULL, 'v'},
f8ed6dc5
JS
4371 {"dump", no_argument, NULL, 'd'},
4372 {"debug", no_argument, NULL, 'D'},
4373 {"plugin", required_argument, NULL, 'P'},
4374 {"srcdir", required_argument, NULL, 'S'},
1d32bbcd 4375 {"backupdir", required_argument, NULL, 'B'},
f8ed6dc5
JS
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");
1d32bbcd 4392 printf ("\t -v | --verbose \t# Increase verbosity. Can be given several times.\n");
f8ed6dc5
JS
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");
1d32bbcd
BS
4398 printf ("\t -B | --backupdir <directory> "
4399 " \t# Specify the backup directory for updated files.\n");
f8ed6dc5
JS
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;
1d32bbcd 4418 while ((opt = getopt_long (argc, argv, "hVvdP:S:B:I:w:r:D",
f8ed6dc5
JS
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;
1d32bbcd
BS
4435 case 'v': /* --verbose */
4436 verbosity_level++;
4437 break;
f8ed6dc5
JS
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;
1d32bbcd
BS
4451 case 'B': /* --backupdir */
4452 if (optarg)
4453 backup_dir = optarg;
4454 else
4455 fatal ("missing backup directory");
4456 break;
f8ed6dc5
JS
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;
dad22268 4490 plugin_files = XNEWVEC (char*, nb_plugin_files);
f8ed6dc5
JS
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
3d7aafde 4500int
11a67599 4501main (int argc, char **argv)
e2500fed 4502{
11a67599 4503 size_t i;
f8ed6dc5 4504 static struct fileloc pos = { NULL, 0 };
9b39cba9 4505 outf_p output_header;
11a67599 4506
f8ed6dc5
JS
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)
0277fabf 4517 {
f8ed6dc5
JS
4518 time_t now = (time_t) 0;
4519 time (&now);
4520 DBGPRINTF ("gengtype started pid %d at %s",
4521 (int) getpid (), ctime (&now));
0277fabf 4522 }
f8ed6dc5 4523#endif /* ENABLE_CHECKING */
0277fabf 4524
f8ed6dc5
JS
4525 /* Parse the input list and the input files. */
4526 DBGPRINTF ("inputlist %s", inputlist);
4527 if (read_state_filename)
bd117bb6 4528 {
f8ed6dc5
JS
4529 fatal ("read state %s not implemented yet", read_state_filename);
4530 /* TODO: implement read state. */
bd117bb6 4531 }
f8ed6dc5 4532 else if (inputlist)
bd117bb6 4533 {
f8ed6dc5
JS
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. */
b1d2d6b1
BS
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
f8ed6dc5
JS
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 }
1d32bbcd
BS
4558 if (verbosity_level >= 1)
4559 printf ("%s parsed %d files\n", progname, (int) num_gt_files);
4560
f8ed6dc5
JS
4561 DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
4562 DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
4563
b8698a0f 4564 }
bd117bb6 4565 else
f8ed6dc5 4566 fatal ("either an input list or a read state file should be given");
11a67599
ZW
4567 if (hit_error)
4568 return 1;
4569
95161faf 4570
f8ed6dc5
JS
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
dad22268 4580 if (nb_plugin_files == 0 || !plugin_files)
f8ed6dc5
JS
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;
e2500fed 4590
f8ed6dc5
JS
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 }
01d419ae 4600 if (hit_error)
065ae611 4601 return 1;
e2500fed 4602
f8ed6dc5
JS
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. */
e2500fed
GK
4607 set_gc_used (variables);
4608
f8ed6dc5
JS
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
e2500fed 4617 open_base_files ();
f8ed6dc5 4618
36a5eadd 4619 write_enum_defn (structures, param_structs);
a9429e29 4620 write_typed_alloc_defns (structures, typedefs);
9b39cba9 4621 output_header = plugin_output ? plugin_output : header_file;
f8ed6dc5
JS
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
9b39cba9 4627 write_types (output_header, structures, param_structs, &ggc_wtd);
ea2ca633 4628 if (plugin_files == NULL)
99be7084 4629 {
f8ed6dc5
JS
4630 DBGPRINT_COUNT_TYPE ("structures before write_types headerfil",
4631 structures);
4632 DBGPRINT_COUNT_TYPE ("param_structs before write_types headerfil",
4633 param_structs);
99be7084
BS
4634 write_types (header_file, structures, param_structs, &pch_wtd);
4635 write_local (header_file, structures, param_structs);
4636 }
a9429e29 4637 write_splay_tree_allocators (param_structs);
ea2ca633 4638 write_roots (variables, plugin_files == NULL);
36a5eadd 4639 write_rtx_next ();
e2500fed
GK
4640 close_output_files ();
4641
0277fabf
LB
4642 if (do_dump)
4643 dump_everything ();
4644
f8ed6dc5 4645 /* Don't bother about free-ing any input or plugin file, etc. */
9f78bf05 4646
01d419ae
ZW
4647 if (hit_error)
4648 return 1;
4649 return 0;
e2500fed 4650}