]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gengtype.c
df-problems.c (df_simulate_one_insn_forwards): Fix braces in switch.
[thirdparty/gcc.git] / gcc / gengtype.c
CommitLineData
e2500fed 1/* Process source files and output type information.
6bc7bc14 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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"
e2500fed 23#include "gengtype.h"
4a399aef 24#include "errors.h" /* for fatal */
df582833 25#include "double-int.h"
5ba6918e 26
065ae611
ZW
27/* Data types, macros, etc. used only in this file. */
28
29/* Kinds of types we can understand. */
30enum typekind {
31 TYPE_SCALAR,
32 TYPE_STRING,
33 TYPE_STRUCT,
34 TYPE_UNION,
35 TYPE_POINTER,
36 TYPE_ARRAY,
37 TYPE_LANG_STRUCT,
38 TYPE_PARAM_STRUCT
39};
40
41typedef unsigned lang_bitmap;
42
43/* A way to pass data through to the output end. */
44struct options
45{
46 struct options *next;
47 const char *name;
48 const char *info;
49};
50
51/* Option data for the 'nested_ptr' option. */
52struct nested_ptr_data
53{
54 type_p type;
55 const char *convert_to;
56 const char *convert_from;
57};
58
59/* A name and a type. */
60struct pair
61{
62 pair_p next;
63 const char *name;
64 type_p type;
65 struct fileloc line;
66 options_p opt;
67};
68
69#define NUM_PARAM 10
70
71/* A description of a type. */
72enum gc_used_enum
73 {
74 GC_UNUSED = 0,
75 GC_USED,
76 GC_MAYBE_POINTED_TO,
77 GC_POINTED_TO
78 };
79
80struct type
81{
82 enum typekind kind;
83 type_p next;
84 type_p pointer_to;
85 enum gc_used_enum gc_used;
86 union {
87 type_p p;
88 struct {
89 const char *tag;
90 struct fileloc line;
91 pair_p fields;
92 options_p opt;
93 lang_bitmap bitmap;
94 type_p lang_struct;
95 } s;
96 bool scalar_is_char;
97 struct {
98 type_p p;
99 const char *len;
100 } a;
101 struct {
102 type_p stru;
103 type_p param[NUM_PARAM];
104 struct fileloc line;
105 } param_struct;
106 } u;
107};
108
109#define UNION_P(x) \
110 ((x)->kind == TYPE_UNION || \
111 ((x)->kind == TYPE_LANG_STRUCT \
112 && (x)->u.s.lang_struct->kind == TYPE_UNION))
113#define UNION_OR_STRUCT_P(x) \
114 ((x)->kind == TYPE_UNION \
115 || (x)->kind == TYPE_STRUCT \
116 || (x)->kind == TYPE_LANG_STRUCT)
117
118/* Structure representing an output file. */
119struct outf
120{
121 struct outf *next;
122 const char *name;
123 size_t buflength;
124 size_t bufused;
125 char *buf;
126};
127typedef struct outf * outf_p;
128
129/* An output file, suitable for definitions, that can see declarations
130 made in INPUT_FILE and is linked into every language that uses
131 INPUT_FILE. */
132extern outf_p get_output_file_with_visibility
133 (const char *input_file);
134const char *get_output_file_name (const char *);
135
065ae611
ZW
136/* Print, like fprintf, to O. */
137static void oprintf (outf_p o, const char *S, ...)
138 ATTRIBUTE_PRINTF_2;
139
140/* The list of output files. */
141static outf_p output_files;
142
143/* The output header file that is included into pretty much every
144 source file. */
145static outf_p header_file;
146
11a67599
ZW
147/* Source directory. */
148static const char *srcdir;
065ae611
ZW
149
150/* Length of srcdir name. */
8de8de02 151static size_t srcdir_len = 0;
065ae611 152
065ae611 153static outf_p create_file (const char *, const char *);
8de8de02 154
065ae611 155static const char * get_file_basename (const char *);
8de8de02
OH
156static const char * get_file_realbasename (const char *);
157static const char * get_file_srcdir_relative_path (const char *);
158
159static int get_prefix_langdir_index (const char *);
160static const char * get_file_langdir (const char *);
065ae611
ZW
161
162\f
9f313342 163/* Nonzero iff an error has occurred. */
01d419ae 164bool hit_error = false;
9f313342 165
3d7aafde
AJ
166static void gen_rtx_next (void);
167static void write_rtx_next (void);
168static void open_base_files (void);
169static void close_output_files (void);
ef171ead 170
9f313342
GK
171/* Report an error at POS, printing MSG. */
172
e2500fed 173void
e34d07f2 174error_at_line (struct fileloc *pos, const char *msg, ...)
e2500fed 175{
e34d07f2 176 va_list ap;
3d7aafde 177
e34d07f2 178 va_start (ap, msg);
e2500fed
GK
179
180 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
181 vfprintf (stderr, msg, ap);
182 fputc ('\n', stderr);
01d419ae 183 hit_error = true;
e2500fed 184
e34d07f2 185 va_end (ap);
e2500fed
GK
186}
187
065ae611 188/* asprintf, but produces fatal message on out-of-memory. */
01d419ae 189char *
e34d07f2 190xasprintf (const char *format, ...)
e03856fe 191{
065ae611 192 int n;
e03856fe 193 char *result;
e34d07f2 194 va_list ap;
3d7aafde 195
e34d07f2 196 va_start (ap, format);
065ae611
ZW
197 n = vasprintf (&result, format, ap);
198 if (result == NULL || n < 0)
199 fatal ("out of memory");
e34d07f2 200 va_end (ap);
065ae611 201
e03856fe
GK
202 return result;
203}
11a67599
ZW
204\f
205/* Input file handling. */
206
207/* Table of all input files. */
208static const char **gt_files;
209static size_t num_gt_files;
210
01d419ae
ZW
211/* A number of places use the name of this file for a location for
212 things that we can't rely on the source to define. Make sure we
213 can still use pointer comparison on filenames. */
214static const char this_file[] = __FILE__;
215
11a67599
ZW
216/* Vector of per-language directories. */
217static const char **lang_dir_names;
218static size_t num_lang_dirs;
219
220/* An array of output files suitable for definitions. There is one
221 BASE_FILES entry for each language. */
222static outf_p *base_files;
223
224/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
225 INPUT_FILE is used by <lang>.
226
227 This function should be written to assume that a file _is_ used
228 if the situation is unclear. If it wrongly assumes a file _is_ used,
229 a linker error will result. If it wrongly assumes a file _is not_ used,
230 some GC roots may be missed, which is a much harder-to-debug problem.
231
232 The relevant bitmap is stored immediately before the file's name in the
233 buffer set up by read_input_list. It may be unaligned, so we have to
234 read it byte-by-byte. */
e03856fe 235
11a67599
ZW
236static lang_bitmap
237get_lang_bitmap (const char *gtfile)
238{
01d419ae
ZW
239
240 if (gtfile == this_file)
241 /* Things defined in this file are universal. */
242 return (((lang_bitmap)1) << num_lang_dirs) - 1;
243 else
244 {
245 lang_bitmap n = 0;
246 int i;
247 for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
248 n = (n << CHAR_BIT) + (unsigned char)gtfile[i];
249 return n;
250 }
11a67599
ZW
251}
252
253/* Set the bitmap returned by get_lang_bitmap. The only legitimate
254 caller of this function is read_input_list. */
255static void
256set_lang_bitmap (char *gtfile, lang_bitmap n)
257{
258 int i;
259 for (i = -1; i >= -(int) sizeof (lang_bitmap); i--)
260 {
261 gtfile[i] = n & ((1U << CHAR_BIT)-1);
262 n >>= CHAR_BIT;
263 }
264}
265
266/* Scan the input file, LIST, and determine how much space we need to
267 store strings in. Also, count the number of language directories
268 and files. The numbers returned are overestimates as they does not
269 consider repeated files. */
270static size_t
271measure_input_list (FILE *list)
272{
273 size_t n = 0;
274 int c;
275 bool atbol = true;
276 num_lang_dirs = 0;
277 num_gt_files = 0;
278 while ((c = getc (list)) != EOF)
279 {
280 n++;
281 if (atbol)
282 {
283 if (c == '[')
284 num_lang_dirs++;
285 else
286 {
287 /* Add space for a lang_bitmap before the input file name. */
288 n += sizeof (lang_bitmap);
289 num_gt_files++;
290 }
291 atbol = false;
292 }
293
294 if (c == '\n')
295 atbol = true;
296 }
297
298 rewind (list);
299 return n;
300}
301
302/* Read one input line from LIST to HEREP (which is updated). A
303 pointer to the string is returned via LINEP. If it was a language
304 subdirectory in square brackets, strip off the square brackets and
305 return true. Otherwise, leave space before the string for a
306 lang_bitmap, and return false. At EOF, returns false, does not
307 touch *HEREP, and sets *LINEP to NULL. POS is used for
308 diagnostics. */
309static bool
310read_input_line (FILE *list, char **herep, char **linep,
311 struct fileloc *pos)
312{
313 char *here = *herep;
314 char *line;
315 int c = getc (list);
316
1b77ee03
MM
317 /* Read over whitespace. */
318 while (c == '\n' || c == ' ')
319 c = getc (list);
320
11a67599
ZW
321 if (c == EOF)
322 {
323 *linep = 0;
324 return false;
325 }
326 else if (c == '[')
327 {
328 /* No space for a lang_bitmap is necessary. Discard the '['. */
329 c = getc (list);
330 line = here;
331 while (c != ']' && c != '\n' && c != EOF)
332 {
333 *here++ = c;
334 c = getc (list);
335 }
336 *here++ = '\0';
337
338 if (c == ']')
339 {
340 c = getc (list); /* eat what should be a newline */
341 if (c != '\n' && c != EOF)
342 error_at_line (pos, "junk on line after language tag [%s]", line);
343 }
344 else
345 error_at_line (pos, "missing close bracket for language tag [%s", line);
346
347 *herep = here;
348 *linep = line;
349 return true;
350 }
351 else
352 {
353 /* Leave space for a lang_bitmap. */
354 memset (here, 0, sizeof (lang_bitmap));
355 here += sizeof (lang_bitmap);
356 line = here;
357 do
358 {
359 *here++ = c;
360 c = getc (list);
361 }
362 while (c != EOF && c != '\n');
363 *here++ = '\0';
364 *herep = here;
365 *linep = line;
366 return false;
367 }
368}
369
370/* Read the list of input files from LIST and compute all of the
371 relevant tables. There is one file per line of the list. At
372 first, all the files on the list are language-generic, but
373 eventually a line will appear which is the name of a language
374 subdirectory in square brackets, like this: [cp]. All subsequent
375 files are specific to that language, until another language
376 subdirectory tag appears. Files can appear more than once, if
377 they apply to more than one language. */
378static void
379read_input_list (const char *listname)
380{
381 FILE *list = fopen (listname, "r");
382 if (!list)
383 fatal ("cannot open %s: %s", listname, strerror (errno));
384 else
385 {
386 struct fileloc epos;
387 size_t bufsz = measure_input_list (list);
388 char *buf = XNEWVEC (char, bufsz);
389 char *here = buf;
390 char *committed = buf;
391 char *limit = buf + bufsz;
392 char *line;
393 bool is_language;
394 size_t langno = 0;
395 size_t nfiles = 0;
396 lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
397
398 epos.file = listname;
399 epos.line = 0;
400
401 lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
402 gt_files = XNEWVEC (const char *, num_gt_files);
403
404 for (;;)
405 {
406 next_line:
407 epos.line++;
408 committed = here;
409 is_language = read_input_line (list, &here, &line, &epos);
410 gcc_assert (here <= limit);
411 if (line == 0)
412 break;
413 else if (is_language)
414 {
415 size_t i;
416 gcc_assert (langno <= num_lang_dirs);
417 for (i = 0; i < langno; i++)
418 if (strcmp (lang_dir_names[i], line) == 0)
419 {
420 error_at_line (&epos, "duplicate language tag [%s]", line);
421 curlangs = 1 << i;
422 here = committed;
423 goto next_line;
424 }
425
426 curlangs = 1 << langno;
427 lang_dir_names[langno++] = line;
428 }
429 else
430 {
431 size_t i;
432 gcc_assert (nfiles <= num_gt_files);
433 for (i = 0; i < nfiles; i++)
434 if (strcmp (gt_files[i], line) == 0)
435 {
436 /* Throw away the string we just read, and add the
437 current language to the existing string's bitmap. */
438 lang_bitmap bmap = get_lang_bitmap (gt_files[i]);
439 if (bmap & curlangs)
440 error_at_line (&epos, "file %s specified more than once "
441 "for language %s", line, langno == 0
442 ? "(all)"
443 : lang_dir_names[langno - 1]);
444
445 bmap |= curlangs;
7cbb2a85 446 set_lang_bitmap (CONST_CAST(char *, gt_files[i]), bmap);
11a67599
ZW
447 here = committed;
448 goto next_line;
449 }
450
451 set_lang_bitmap (line, curlangs);
452 gt_files[nfiles++] = line;
453 }
454 }
455 /* Update the global counts now that we know accurately how many
456 things there are. (We do not bother resizing the arrays down.) */
457 num_lang_dirs = langno;
458 num_gt_files = nfiles;
459 }
460
461 /* Sanity check: any file that resides in a language subdirectory
462 (e.g. 'cp') ought to belong to the corresponding language.
463 ??? Still true if for instance ObjC++ is enabled and C++ isn't?
464 (Can you even do that? Should you be allowed to?) */
465 {
466 size_t f;
467 for (f = 0; f < num_gt_files; f++)
468 {
469 lang_bitmap bitmap = get_lang_bitmap (gt_files[f]);
470 const char *basename = get_file_basename (gt_files[f]);
471 const char *slashpos = strchr (basename, '/');
472
473 if (slashpos)
474 {
475 size_t l;
476 for (l = 0; l < num_lang_dirs; l++)
477 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [l])
478 && memcmp (basename, lang_dir_names[l],
479 strlen (lang_dir_names[l])) == 0)
480 {
481 if (!(bitmap & (1 << l)))
482 error ("%s is in language directory '%s' but is not "
483 "tagged for that language",
484 basename, lang_dir_names[l]);
485 break;
486 }
487 }
488 }
489 }
490
491 if (ferror (list))
492 fatal ("error reading %s: %s", listname, strerror (errno));
493
494 fclose (list);
495}
496
497
498\f
9f313342
GK
499/* The one and only TYPE_STRING. */
500
95161faf
ZW
501static struct type string_type = {
502 TYPE_STRING, 0, 0, GC_USED, {0}
503};
504
505/* The two and only TYPE_SCALARs. Their u.scalar_is_char flags are
506 set to appropriate values at the beginning of main. */
507
508static struct type scalar_nonchar = {
509 TYPE_SCALAR, 0, 0, GC_USED, {0}
510};
511static struct type scalar_char = {
512 TYPE_SCALAR, 0, 0, GC_USED, {0}
3d7aafde 513};
e2500fed 514
9f313342
GK
515/* Lists of various things. */
516
e2500fed
GK
517static pair_p typedefs;
518static type_p structures;
519static type_p param_structs;
520static pair_p variables;
521
3d7aafde
AJ
522static type_p find_param_structure
523 (type_p t, type_p param[NUM_PARAM]);
524static type_p adjust_field_tree_exp (type_p t, options_p opt);
525static type_p adjust_field_rtx_def (type_p t, options_p opt);
36a5eadd 526
9f313342
GK
527/* Define S as a typedef to T at POS. */
528
e2500fed 529void
3d7aafde 530do_typedef (const char *s, type_p t, struct fileloc *pos)
e2500fed
GK
531{
532 pair_p p;
533
2d593c86
TT
534 /* temporary kludge - gengtype doesn't handle conditionals or
535 macros. Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
536 is coming from this file (main() sets them up with safe dummy
537 definitions). */
538 if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
01d419ae
ZW
539 return;
540
e2500fed
GK
541 for (p = typedefs; p != NULL; p = p->next)
542 if (strcmp (p->name, s) == 0)
543 {
544 if (p->type != t)
545 {
546 error_at_line (pos, "type `%s' previously defined", s);
547 error_at_line (&p->line, "previously defined here");
548 }
549 return;
550 }
551
5d038c4c 552 p = XNEW (struct pair);
e2500fed
GK
553 p->next = typedefs;
554 p->name = s;
555 p->type = t;
556 p->line = *pos;
557 typedefs = p;
558}
559
95161faf
ZW
560/* Define S as a typename of a scalar. Cannot be used to define
561 typedefs of 'char'. Note: is also used for pointer-to-function
562 typedefs (which are therefore not treated as pointers). */
36a5eadd 563
95161faf 564void
3d7aafde 565do_scalar_typedef (const char *s, struct fileloc *pos)
36a5eadd 566{
95161faf 567 do_typedef (s, &scalar_nonchar, pos);
36a5eadd
GK
568}
569
e34bb004 570/* Return the type previously defined for S. Use POS to report errors. */
9f313342 571
e2500fed 572type_p
3d7aafde 573resolve_typedef (const char *s, struct fileloc *pos)
e2500fed
GK
574{
575 pair_p p;
576 for (p = typedefs; p != NULL; p = p->next)
577 if (strcmp (p->name, s) == 0)
578 return p->type;
579 error_at_line (pos, "unidentified type `%s'", s);
95161faf 580 return &scalar_nonchar; /* treat as "int" */
e2500fed
GK
581}
582
0f01f026
RS
583/* Create and return a new structure with tag NAME (or a union iff
584 ISUNION is nonzero), at POS with fields FIELDS and options O. */
9f313342 585
0f01f026 586type_p
3d7aafde
AJ
587new_structure (const char *name, int isunion, struct fileloc *pos,
588 pair_p fields, options_p o)
e2500fed
GK
589{
590 type_p si;
591 type_p s = NULL;
11a67599 592 lang_bitmap bitmap = get_lang_bitmap (pos->file);
e2500fed 593
01d419ae
ZW
594 /* temporary kludge - gengtype doesn't handle conditionals or
595 macros. Ignore any attempt to define struct location_s, unless
596 it is coming from this file (main() sets it up safely). */
597 if (!strcmp (name, "location_s") && !isunion
598 && pos->file != this_file)
599 return find_structure (name, 0);
600
e2500fed 601 for (si = structures; si != NULL; si = si->next)
3d7aafde 602 if (strcmp (name, si->u.s.tag) == 0
e2500fed
GK
603 && UNION_P (si) == isunion)
604 {
605 type_p ls = NULL;
606 if (si->kind == TYPE_LANG_STRUCT)
607 {
608 ls = si;
3d7aafde 609
e2500fed
GK
610 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
611 if (si->u.s.bitmap == bitmap)
612 s = si;
613 }
614 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
615 {
616 ls = si;
5d038c4c 617 si = XCNEW (struct type);
e2500fed
GK
618 memcpy (si, ls, sizeof (struct type));
619 ls->kind = TYPE_LANG_STRUCT;
620 ls->u.s.lang_struct = si;
621 ls->u.s.fields = NULL;
622 si->next = NULL;
623 si->pointer_to = NULL;
624 si->u.s.lang_struct = ls;
625 }
626 else
627 s = si;
628
629 if (ls != NULL && s == NULL)
630 {
5d038c4c 631 s = XCNEW (struct type);
e2500fed
GK
632 s->next = ls->u.s.lang_struct;
633 ls->u.s.lang_struct = s;
634 s->u.s.lang_struct = ls;
635 }
636 break;
637 }
3d7aafde 638
e2500fed
GK
639 if (s == NULL)
640 {
5d038c4c 641 s = XCNEW (struct type);
e2500fed
GK
642 s->next = structures;
643 structures = s;
644 }
645
646 if (s->u.s.line.file != NULL
647 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
648 {
01d419ae
ZW
649 error_at_line (pos, "duplicate definition of '%s %s'",
650 isunion ? "union" : "struct", s->u.s.tag);
e2500fed
GK
651 error_at_line (&s->u.s.line, "previous definition here");
652 }
653
654 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
655 s->u.s.tag = name;
656 s->u.s.line = *pos;
657 s->u.s.fields = fields;
658 s->u.s.opt = o;
659 s->u.s.bitmap = bitmap;
660 if (s->u.s.lang_struct)
661 s->u.s.lang_struct->u.s.bitmap |= bitmap;
0f01f026 662
01d419ae
ZW
663 /* Reset location_s's location to input.h so that we know where to
664 write out its mark routine. */
665 if (!strcmp (name, "location_s") && !isunion
666 && pos->file == this_file)
667 {
668 size_t n;
669 for (n = 0; n < num_gt_files; n++)
670 if (!strcmp (gt_files[n] + strlen (gt_files[n]) - strlen ("input.h"),
671 "input.h"))
672 {
673 s->u.s.line.file = gt_files[n];
674 break;
675 }
676 }
677
678 return s;
e2500fed
GK
679}
680
9f313342
GK
681/* Return the previously-defined structure with tag NAME (or a union
682 iff ISUNION is nonzero), or a new empty structure or union if none
683 was defined previously. */
684
e2500fed 685type_p
3d7aafde 686find_structure (const char *name, int isunion)
e2500fed
GK
687{
688 type_p s;
689
690 for (s = structures; s != NULL; s = s->next)
3d7aafde 691 if (strcmp (name, s->u.s.tag) == 0
e2500fed
GK
692 && UNION_P (s) == isunion)
693 return s;
694
5d038c4c 695 s = XCNEW (struct type);
e2500fed
GK
696 s->next = structures;
697 structures = s;
698 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
699 s->u.s.tag = name;
700 structures = s;
701 return s;
702}
703
272d0bee
KH
704/* Return the previously-defined parameterized structure for structure
705 T and parameters PARAM, or a new parameterized empty structure or
991b6592 706 union if none was defined previously. */
36a5eadd
GK
707
708static type_p
3d7aafde 709find_param_structure (type_p t, type_p param[NUM_PARAM])
36a5eadd
GK
710{
711 type_p res;
3d7aafde 712
36a5eadd
GK
713 for (res = param_structs; res; res = res->next)
714 if (res->u.param_struct.stru == t
3d7aafde 715 && memcmp (res->u.param_struct.param, param,
36a5eadd
GK
716 sizeof (type_p) * NUM_PARAM) == 0)
717 break;
718 if (res == NULL)
719 {
5d038c4c 720 res = XCNEW (struct type);
36a5eadd
GK
721 res->kind = TYPE_PARAM_STRUCT;
722 res->next = param_structs;
723 param_structs = res;
724 res->u.param_struct.stru = t;
725 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
726 }
727 return res;
728}
729
9f313342
GK
730/* Return a scalar type with name NAME. */
731
e2500fed 732type_p
95161faf 733create_scalar_type (const char *name)
e2500fed 734{
95161faf
ZW
735 if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
736 return &scalar_char;
737 else
738 return &scalar_nonchar;
e2500fed
GK
739}
740
9f313342
GK
741/* Return a pointer to T. */
742
e2500fed 743type_p
3d7aafde 744create_pointer (type_p t)
e2500fed
GK
745{
746 if (! t->pointer_to)
747 {
5d038c4c 748 type_p r = XCNEW (struct type);
e2500fed
GK
749 r->kind = TYPE_POINTER;
750 r->u.p = t;
751 t->pointer_to = r;
752 }
753 return t->pointer_to;
754}
755
9f313342
GK
756/* Return an array of length LEN. */
757
e2500fed 758type_p
3d7aafde 759create_array (type_p t, const char *len)
e2500fed
GK
760{
761 type_p v;
3d7aafde 762
5d038c4c 763 v = XCNEW (struct type);
e2500fed
GK
764 v->kind = TYPE_ARRAY;
765 v->u.a.p = t;
766 v->u.a.len = len;
767 return v;
768}
769
0f01f026
RS
770/* Return an options structure with name NAME and info INFO. NEXT is the
771 next option in the chain. */
772
1431042e 773options_p
0f01f026 774create_option (options_p next, const char *name, const void *info)
1431042e 775{
5d038c4c 776 options_p o = XNEW (struct options);
0f01f026 777 o->next = next;
1431042e 778 o->name = name;
9e2878cf 779 o->info = (const char*) info;
1431042e
ZW
780 return o;
781}
782
17defa6a
ZW
783/* Return an options structure for a "nested_ptr" option. */
784options_p
065ae611
ZW
785create_nested_ptr_option (options_p next, type_p t,
786 const char *to, const char *from)
17defa6a
ZW
787{
788 struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
789
790 d->type = adjust_field_type (t, 0);
791 d->convert_to = to;
792 d->convert_from = from;
065ae611 793 return create_option (next, "nested_ptr", d);
17defa6a
ZW
794}
795
36a5eadd
GK
796/* Add a variable named S of type T with options O defined at POS,
797 to `variables'. */
798
799void
3d7aafde 800note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
36a5eadd
GK
801{
802 pair_p n;
5d038c4c 803 n = XNEW (struct pair);
36a5eadd
GK
804 n->name = s;
805 n->type = t;
806 n->line = *pos;
807 n->opt = o;
808 n->next = variables;
809 variables = n;
810}
811
065ae611 812/* Most-general structure field creator. */
0f01f026 813static pair_p
065ae611
ZW
814create_field_all (pair_p next, type_p type, const char *name, options_p opt,
815 const char *file, int line)
0f01f026
RS
816{
817 pair_p field;
818
819 field = XNEW (struct pair);
820 field->next = next;
821 field->type = type;
822 field->name = name;
065ae611
ZW
823 field->opt = opt;
824 field->line.file = file;
825 field->line.line = line;
0f01f026
RS
826 return field;
827}
828
065ae611
ZW
829/* Create a field that came from the source code we are scanning,
830 i.e. we have a 'struct fileloc', and possibly options; also,
831 adjust_field_type should be called. */
832pair_p
833create_field_at (pair_p next, type_p type, const char *name, options_p opt,
834 struct fileloc *pos)
835{
836 return create_field_all (next, adjust_field_type (type, opt),
837 name, opt, pos->file, pos->line);
838}
839
840/* Create a fake field with the given type and name. NEXT is the next
841 field in the chain. */
842#define create_field(next,type,name) \
01d419ae 843 create_field_all(next,type,name, 0, this_file, __LINE__)
065ae611 844
aacd3885
RS
845/* Like create_field, but the field is only valid when condition COND
846 is true. */
847
848static pair_p
065ae611
ZW
849create_optional_field_ (pair_p next, type_p type, const char *name,
850 const char *cond, int line)
aacd3885
RS
851{
852 static int id = 1;
065ae611 853 pair_p union_fields;
aacd3885
RS
854 type_p union_type;
855
856 /* Create a fake union type with a single nameless field of type TYPE.
857 The field has a tag of "1". This allows us to make the presence
858 of a field of type TYPE depend on some boolean "desc" being true. */
859 union_fields = create_field (NULL, type, "");
860 union_fields->opt = create_option (union_fields->opt, "dot", "");
861 union_fields->opt = create_option (union_fields->opt, "tag", "1");
862 union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
863 &lexer_line, union_fields, NULL);
864
865 /* Create the field and give it the new fake union type. Add a "desc"
866 tag that specifies the condition under which the field is valid. */
065ae611
ZW
867 return create_field_all (next, union_type, name,
868 create_option (0, "desc", cond),
01d419ae 869 this_file, line);
aacd3885 870}
065ae611
ZW
871#define create_optional_field(next,type,name,cond) \
872 create_optional_field_(next,type,name,cond,__LINE__)
aacd3885 873
01d419ae
ZW
874/* Reverse a linked list of 'struct pair's in place. */
875pair_p
876nreverse_pairs (pair_p list)
877{
878 pair_p prev = 0, p, next;
879 for (p = list; p; p = next)
880 {
881 next = p->next;
882 p->next = prev;
883 prev = p;
884 }
885 return prev;
886}
887
888\f
9e995780 889/* We don't care how long a CONST_DOUBLE is. */
36a5eadd 890#define CONST_DOUBLE_FORMAT "ww"
9e995780
ZW
891/* We don't want to see codes that are only for generator files. */
892#undef GENERATOR_FILE
893
894enum rtx_code {
895#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
896#include "rtl.def"
897#undef DEF_RTL_EXPR
898 NUM_RTX_CODE
899};
900
901static const char * const rtx_name[NUM_RTX_CODE] = {
902#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
903#include "rtl.def"
904#undef DEF_RTL_EXPR
905};
906
907static const char * const rtx_format[NUM_RTX_CODE] = {
36a5eadd
GK
908#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
909#include "rtl.def"
910#undef DEF_RTL_EXPR
911};
912
5ba6918e 913static int rtx_next_new[NUM_RTX_CODE];
36a5eadd 914
9e995780
ZW
915/* We also need codes and names for insn notes (not register notes).
916 Note that we do *not* bias the note values here. */
917enum insn_note {
918#define DEF_INSN_NOTE(NAME) NAME,
919#include "insn-notes.def"
920#undef DEF_INSN_NOTE
921
922 NOTE_INSN_MAX
923};
924
79e4e6a6
JW
925/* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
926 default field for line number notes. */
927static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
9e995780
ZW
928#define DEF_INSN_NOTE(NAME) #NAME,
929#include "insn-notes.def"
930#undef DEF_INSN_NOTE
931};
932
933#undef CONST_DOUBLE_FORMAT
934#define GENERATOR_FILE
935
36a5eadd
GK
936/* Generate the contents of the rtx_next array. This really doesn't belong
937 in gengtype at all, but it's needed for adjust_field_rtx_def. */
938
939static void
3d7aafde 940gen_rtx_next (void)
36a5eadd
GK
941{
942 int i;
943 for (i = 0; i < NUM_RTX_CODE; i++)
944 {
945 int k;
3d7aafde 946
5ba6918e 947 rtx_next_new[i] = -1;
36a5eadd 948 if (strncmp (rtx_format[i], "iuu", 3) == 0)
5ba6918e 949 rtx_next_new[i] = 2;
36a5eadd 950 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
5ba6918e 951 rtx_next_new[i] = 1;
3d7aafde 952 else
36a5eadd
GK
953 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
954 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
5ba6918e 955 rtx_next_new[i] = k;
36a5eadd
GK
956 }
957}
958
959/* Write out the contents of the rtx_next array. */
960static void
3d7aafde 961write_rtx_next (void)
36a5eadd
GK
962{
963 outf_p f = get_output_file_with_visibility (NULL);
964 int i;
3d7aafde 965
36a5eadd 966 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
6bc7bc14 967 oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
36a5eadd 968 for (i = 0; i < NUM_RTX_CODE; i++)
5ba6918e 969 if (rtx_next_new[i] == -1)
36a5eadd
GK
970 oprintf (f, " 0,\n");
971 else
3d7aafde 972 oprintf (f,
e1de1560 973 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
5ba6918e 974 rtx_next_new[i]);
36a5eadd
GK
975 oprintf (f, "};\n");
976}
977
978/* Handle `special("rtx_def")'. This is a special case for field
979 `fld' of struct rtx_def, which is an array of unions whose values
980 are based in a complex way on the type of RTL. */
981
982static type_p
e18476eb 983adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
36a5eadd
GK
984{
985 pair_p flds = NULL;
986 options_p nodot;
987 int i;
988 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
c185c797 989 type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
36a5eadd 990
e1de1560 991 if (t->kind != TYPE_UNION)
36a5eadd 992 {
3d7aafde 993 error_at_line (&lexer_line,
e1de1560 994 "special `rtx_def' must be applied to a union");
36a5eadd
GK
995 return &string_type;
996 }
3d7aafde 997
0f01f026 998 nodot = create_option (NULL, "dot", "");
36a5eadd
GK
999
1000 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
1001 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
1002 tree_tp = create_pointer (find_structure ("tree_node", 1));
1003 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
a560d4d4 1004 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
36a5eadd
GK
1005 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
1006 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
c185c797 1007 constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
95161faf 1008 scalar_tp = &scalar_nonchar; /* rtunion int */
36a5eadd
GK
1009
1010 {
1011 pair_p note_flds = NULL;
1012 int c;
5ba6918e 1013
9e995780 1014 for (c = 0; c <= NOTE_INSN_MAX; c++)
36a5eadd 1015 {
5ba6918e
GK
1016 switch (c)
1017 {
5ba6918e 1018 case NOTE_INSN_MAX:
1bcca2c5 1019 case NOTE_INSN_DELETED_LABEL:
0f01f026 1020 note_flds = create_field (note_flds, &string_type, "rt_str");
5ba6918e
GK
1021 break;
1022
1023 case NOTE_INSN_BLOCK_BEG:
1024 case NOTE_INSN_BLOCK_END:
0f01f026 1025 note_flds = create_field (note_flds, tree_tp, "rt_tree");
5ba6918e 1026 break;
3d7aafde 1027
014a1138 1028 case NOTE_INSN_VAR_LOCATION:
0f01f026 1029 note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
5ba6918e
GK
1030 break;
1031
1032 default:
0f01f026 1033 note_flds = create_field (note_flds, scalar_tp, "rt_int");
5ba6918e
GK
1034 break;
1035 }
0f01f026
RS
1036 /* NOTE_INSN_MAX is used as the default field for line
1037 number notes. */
1038 if (c == NOTE_INSN_MAX)
1039 note_flds->opt = create_option (nodot, "default", "");
1040 else
1041 note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
36a5eadd 1042 }
0f01f026
RS
1043 note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1044 &lexer_line, note_flds, NULL);
36a5eadd 1045 }
c185c797
RS
1046 /* Create a type to represent the various forms of SYMBOL_REF_DATA. */
1047 {
1048 pair_p sym_flds;
1049
1050 sym_flds = create_field (NULL, tree_tp, "rt_tree");
1051 sym_flds->opt = create_option (nodot, "default", "");
1052
1053 sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
1054 sym_flds->opt = create_option (nodot, "tag", "1");
1055
1056 symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
1057 &lexer_line, sym_flds, NULL);
1058 }
36a5eadd
GK
1059 for (i = 0; i < NUM_RTX_CODE; i++)
1060 {
36a5eadd
GK
1061 pair_p subfields = NULL;
1062 size_t aindex, nmindex;
1063 const char *sname;
0f01f026 1064 type_p substruct;
36a5eadd
GK
1065 char *ftag;
1066
1067 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1068 {
36a5eadd
GK
1069 type_p t;
1070 const char *subname;
1071
1072 switch (rtx_format[i][aindex])
1073 {
1074 case '*':
1075 case 'i':
1076 case 'n':
1077 case 'w':
1078 t = scalar_tp;
9ce88f5e 1079 subname = "rt_int";
36a5eadd
GK
1080 break;
1081
1082 case '0':
1083 if (i == MEM && aindex == 1)
9ce88f5e 1084 t = mem_attrs_tp, subname = "rt_mem";
6fb5fa3c 1085 else if (i == JUMP_INSN && aindex == 8)
9ce88f5e 1086 t = rtx_tp, subname = "rt_rtx";
36a5eadd 1087 else if (i == CODE_LABEL && aindex == 4)
9ce88f5e 1088 t = scalar_tp, subname = "rt_int";
36a5eadd 1089 else if (i == CODE_LABEL && aindex == 5)
9ce88f5e 1090 t = rtx_tp, subname = "rt_rtx";
36a5eadd
GK
1091 else if (i == LABEL_REF
1092 && (aindex == 1 || aindex == 2))
9ce88f5e 1093 t = rtx_tp, subname = "rt_rtx";
36a5eadd
GK
1094 else if (i == NOTE && aindex == 4)
1095 t = note_union_tp, subname = "";
a38e7aa5
JH
1096 else if (i == NOTE && aindex == 5)
1097 t = scalar_tp, subname = "rt_int";
36a5eadd 1098 else if (i == NOTE && aindex >= 7)
9ce88f5e 1099 t = scalar_tp, subname = "rt_int";
36a5eadd 1100 else if (i == ADDR_DIFF_VEC && aindex == 4)
9ce88f5e 1101 t = scalar_tp, subname = "rt_int";
36a5eadd 1102 else if (i == VALUE && aindex == 0)
9ce88f5e 1103 t = scalar_tp, subname = "rt_int";
36a5eadd 1104 else if (i == REG && aindex == 1)
9ce88f5e 1105 t = scalar_tp, subname = "rt_int";
a560d4d4 1106 else if (i == REG && aindex == 2)
9ce88f5e 1107 t = reg_attrs_tp, subname = "rt_reg";
36a5eadd 1108 else if (i == SCRATCH && aindex == 0)
9ce88f5e 1109 t = scalar_tp, subname = "rt_int";
52859c77 1110 else if (i == SYMBOL_REF && aindex == 1)
9ce88f5e 1111 t = scalar_tp, subname = "rt_int";
52859c77 1112 else if (i == SYMBOL_REF && aindex == 2)
c185c797 1113 t = symbol_union_tp, subname = "";
36a5eadd 1114 else if (i == BARRIER && aindex >= 3)
9ce88f5e 1115 t = scalar_tp, subname = "rt_int";
36a5eadd
GK
1116 else
1117 {
3d7aafde 1118 error_at_line (&lexer_line,
6d8dd940
AJ
1119 "rtx type `%s' has `0' in position %lu, can't handle",
1120 rtx_name[i], (unsigned long) aindex);
36a5eadd 1121 t = &string_type;
9ce88f5e 1122 subname = "rt_int";
36a5eadd
GK
1123 }
1124 break;
3d7aafde 1125
36a5eadd
GK
1126 case 's':
1127 case 'S':
1128 case 'T':
1129 t = &string_type;
9ce88f5e 1130 subname = "rt_str";
36a5eadd
GK
1131 break;
1132
1133 case 'e':
1134 case 'u':
1135 t = rtx_tp;
9ce88f5e 1136 subname = "rt_rtx";
36a5eadd
GK
1137 break;
1138
1139 case 'E':
1140 case 'V':
1141 t = rtvec_tp;
9ce88f5e 1142 subname = "rt_rtvec";
36a5eadd
GK
1143 break;
1144
1145 case 't':
1146 t = tree_tp;
9ce88f5e 1147 subname = "rt_tree";
36a5eadd
GK
1148 break;
1149
1150 case 'b':
1151 t = bitmap_tp;
9ce88f5e 1152 subname = "rt_bit";
36a5eadd
GK
1153 break;
1154
1155 case 'B':
1156 t = basic_block_tp;
9ce88f5e 1157 subname = "rt_bb";
36a5eadd
GK
1158 break;
1159
1160 default:
3d7aafde 1161 error_at_line (&lexer_line,
6d8dd940 1162 "rtx type `%s' has `%c' in position %lu, can't handle",
36a5eadd 1163 rtx_name[i], rtx_format[i][aindex],
6d8dd940 1164 (unsigned long)aindex);
36a5eadd 1165 t = &string_type;
9ce88f5e 1166 subname = "rt_int";
36a5eadd
GK
1167 break;
1168 }
1169
0f01f026
RS
1170 subfields = create_field (subfields, t,
1171 xasprintf (".fld[%lu].%s",
1172 (unsigned long) aindex,
1173 subname));
1174 subfields->opt = nodot;
36a5eadd 1175 if (t == note_union_tp)
0f01f026 1176 subfields->opt = create_option (subfields->opt, "desc",
a38e7aa5 1177 "NOTE_KIND (&%0)");
c185c797
RS
1178 if (t == symbol_union_tp)
1179 subfields->opt = create_option (subfields->opt, "desc",
1180 "CONSTANT_POOL_ADDRESS_P (&%0)");
36a5eadd
GK
1181 }
1182
aacd3885
RS
1183 if (i == SYMBOL_REF)
1184 {
3fa9c136 1185 /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
aacd3885 1186 type_p field_tp = find_structure ("block_symbol", 0);
3fa9c136
RS
1187 subfields
1188 = create_optional_field (subfields, field_tp, "block_sym",
1189 "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
aacd3885
RS
1190 }
1191
36a5eadd 1192 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
0f01f026
RS
1193 substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1194
36a5eadd
GK
1195 ftag = xstrdup (rtx_name[i]);
1196 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1197 ftag[nmindex] = TOUPPER (ftag[nmindex]);
0f01f026
RS
1198
1199 flds = create_field (flds, substruct, "");
1200 flds->opt = create_option (nodot, "tag", ftag);
36a5eadd
GK
1201 }
1202
0f01f026 1203 return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
36a5eadd
GK
1204}
1205
1206/* Handle `special("tree_exp")'. This is a special case for
1207 field `operands' of struct tree_exp, which although it claims to contain
3d7aafde 1208 pointers to trees, actually sometimes contains pointers to RTL too.
36a5eadd
GK
1209 Passed T, the old type of the field, and OPT its options. Returns
1210 a new type for the field. */
1211
1212static type_p
3d7aafde 1213adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
36a5eadd
GK
1214{
1215 pair_p flds;
1216 options_p nodot;
3d7aafde 1217
36a5eadd
GK
1218 if (t->kind != TYPE_ARRAY)
1219 {
3d7aafde 1220 error_at_line (&lexer_line,
36a5eadd
GK
1221 "special `tree_exp' must be applied to an array");
1222 return &string_type;
1223 }
3d7aafde 1224
0f01f026
RS
1225 nodot = create_option (NULL, "dot", "");
1226
1227 flds = create_field (NULL, t, "");
1228 flds->opt = create_option (nodot, "length",
5039610b 1229 "TREE_OPERAND_LENGTH ((tree) &%0)");
0f01f026 1230 flds->opt = create_option (flds->opt, "default", "");
3d7aafde 1231
0f01f026 1232 return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
36a5eadd
GK
1233}
1234
9f313342
GK
1235/* Perform any special processing on a type T, about to become the type
1236 of a field. Return the appropriate type for the field.
1237 At present:
1238 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
1239 - Similarly for arrays of pointer-to-char;
1240 - Converts structures for which a parameter is provided to
36a5eadd
GK
1241 TYPE_PARAM_STRUCT;
1242 - Handles "special" options.
3d7aafde 1243*/
9f313342 1244
e2500fed 1245type_p
3d7aafde 1246adjust_field_type (type_p t, options_p opt)
e2500fed
GK
1247{
1248 int length_p = 0;
1249 const int pointer_p = t->kind == TYPE_POINTER;
36a5eadd
GK
1250 type_p params[NUM_PARAM];
1251 int params_p = 0;
1252 int i;
1253
1254 for (i = 0; i < NUM_PARAM; i++)
1255 params[i] = NULL;
3d7aafde 1256
e2500fed
GK
1257 for (; opt; opt = opt->next)
1258 if (strcmp (opt->name, "length") == 0)
1259 length_p = 1;
36a5eadd
GK
1260 else if (strcmp (opt->name, "param_is") == 0
1261 || (strncmp (opt->name, "param", 5) == 0
1262 && ISDIGIT (opt->name[5])
1263 && strcmp (opt->name + 6, "_is") == 0))
e2500fed 1264 {
36a5eadd 1265 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
e2500fed 1266
36a5eadd
GK
1267 if (! UNION_OR_STRUCT_P (t)
1268 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1269 {
3d7aafde 1270 error_at_line (&lexer_line,
36a5eadd
GK
1271 "option `%s' may only be applied to structures or structure pointers",
1272 opt->name);
1273 return t;
1274 }
1275
1276 params_p = 1;
1277 if (params[num] != NULL)
1278 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
1279 if (! ISDIGIT (opt->name[5]))
7cbb2a85 1280 params[num] = create_pointer (CONST_CAST2(type_p, const char *, opt->info));
36a5eadd 1281 else
7cbb2a85 1282 params[num] = CONST_CAST2 (type_p, const char *, opt->info);
e2500fed 1283 }
36a5eadd
GK
1284 else if (strcmp (opt->name, "special") == 0)
1285 {
9e2878cf 1286 const char *special_name = opt->info;
36a5eadd
GK
1287 if (strcmp (special_name, "tree_exp") == 0)
1288 t = adjust_field_tree_exp (t, opt);
1289 else if (strcmp (special_name, "rtx_def") == 0)
1290 t = adjust_field_rtx_def (t, opt);
1291 else
1292 error_at_line (&lexer_line, "unknown special `%s'", special_name);
1293 }
1294
1295 if (params_p)
1296 {
1297 type_p realt;
3d7aafde 1298
36a5eadd
GK
1299 if (pointer_p)
1300 t = t->u.p;
1301 realt = find_param_structure (t, params);
1302 t = pointer_p ? create_pointer (realt) : realt;
1303 }
1304
e2500fed
GK
1305 if (! length_p
1306 && pointer_p
1307 && t->u.p->kind == TYPE_SCALAR
95161faf 1308 && t->u.p->u.scalar_is_char)
e2500fed
GK
1309 return &string_type;
1310 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
1311 && t->u.a.p->u.p->kind == TYPE_SCALAR
95161faf 1312 && t->u.a.p->u.p->u.scalar_is_char)
e2500fed
GK
1313 return create_array (&string_type, t->u.a.len);
1314
1315 return t;
1316}
1317
e2500fed 1318\f
3d7aafde
AJ
1319static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1320static void set_gc_used (pair_p);
e2500fed 1321
9f313342
GK
1322/* Handle OPT for set_gc_used_type. */
1323
e2500fed 1324static void
3d7aafde 1325process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
5932ca9d 1326 int *pass_param, int *length, int *skip, type_p *nested_ptr)
e2500fed
GK
1327{
1328 options_p o;
1329 for (o = opt; o; o = o->next)
1330 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
7cbb2a85
KG
1331 set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
1332 GC_POINTED_TO, NULL);
e2500fed
GK
1333 else if (strcmp (o->name, "maybe_undef") == 0)
1334 *maybe_undef = 1;
36a5eadd
GK
1335 else if (strcmp (o->name, "use_params") == 0)
1336 *pass_param = 1;
1337 else if (strcmp (o->name, "length") == 0)
1338 *length = 1;
5932ca9d
ZW
1339 else if (strcmp (o->name, "skip") == 0)
1340 *skip = 1;
d8044160
GK
1341 else if (strcmp (o->name, "nested_ptr") == 0)
1342 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
e2500fed
GK
1343}
1344
9f313342
GK
1345/* Set the gc_used field of T to LEVEL, and handle the types it references. */
1346
e2500fed 1347static void
3d7aafde 1348set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
e2500fed
GK
1349{
1350 if (t->gc_used >= level)
1351 return;
3d7aafde 1352
e2500fed
GK
1353 t->gc_used = level;
1354
1355 switch (t->kind)
1356 {
1357 case TYPE_STRUCT:
1358 case TYPE_UNION:
1359 {
1360 pair_p f;
1361 int dummy;
d8044160 1362 type_p dummy2;
e2500fed 1363
5932ca9d 1364 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
d8044160 1365 &dummy2);
e2500fed
GK
1366
1367 for (f = t->u.s.fields; f; f = f->next)
1368 {
1369 int maybe_undef = 0;
36a5eadd
GK
1370 int pass_param = 0;
1371 int length = 0;
5932ca9d 1372 int skip = 0;
d8044160 1373 type_p nested_ptr = NULL;
36a5eadd 1374 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
5932ca9d 1375 &length, &skip, &nested_ptr);
3d7aafde 1376
d8044160
GK
1377 if (nested_ptr && f->type->kind == TYPE_POINTER)
1378 set_gc_used_type (nested_ptr, GC_POINTED_TO,
1379 pass_param ? param : NULL);
1380 else if (length && f->type->kind == TYPE_POINTER)
36a5eadd
GK
1381 set_gc_used_type (f->type->u.p, GC_USED, NULL);
1382 else if (maybe_undef && f->type->kind == TYPE_POINTER)
1383 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
1384 else if (pass_param && f->type->kind == TYPE_POINTER && param)
1385 set_gc_used_type (find_param_structure (f->type->u.p, param),
1386 GC_POINTED_TO, NULL);
5932ca9d
ZW
1387 else if (skip)
1388 ; /* target type is not used through this field */
e2500fed 1389 else
36a5eadd 1390 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
e2500fed
GK
1391 }
1392 break;
1393 }
1394
1395 case TYPE_POINTER:
36a5eadd 1396 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
e2500fed
GK
1397 break;
1398
1399 case TYPE_ARRAY:
36a5eadd 1400 set_gc_used_type (t->u.a.p, GC_USED, param);
e2500fed 1401 break;
3d7aafde 1402
e2500fed
GK
1403 case TYPE_LANG_STRUCT:
1404 for (t = t->u.s.lang_struct; t; t = t->next)
36a5eadd 1405 set_gc_used_type (t, level, param);
e2500fed
GK
1406 break;
1407
1408 case TYPE_PARAM_STRUCT:
36a5eadd
GK
1409 {
1410 int i;
1411 for (i = 0; i < NUM_PARAM; i++)
1412 if (t->u.param_struct.param[i] != 0)
1413 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
1414 }
1415 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
1416 level = GC_POINTED_TO;
1417 else
1418 level = GC_USED;
1419 t->u.param_struct.stru->gc_used = GC_UNUSED;
3d7aafde 1420 set_gc_used_type (t->u.param_struct.stru, level,
36a5eadd 1421 t->u.param_struct.param);
e2500fed
GK
1422 break;
1423
1424 default:
1425 break;
1426 }
1427}
1428
36a5eadd 1429/* Set the gc_used fields of all the types pointed to by VARIABLES. */
9f313342 1430
e2500fed 1431static void
3d7aafde 1432set_gc_used (pair_p variables)
e2500fed
GK
1433{
1434 pair_p p;
1435 for (p = variables; p; p = p->next)
36a5eadd 1436 set_gc_used_type (p->type, GC_USED, NULL);
e2500fed
GK
1437}
1438\f
1439/* File mapping routines. For each input file, there is one output .c file
1440 (but some output files have many input files), and there is one .h file
1441 for the whole build. */
1442
065ae611 1443/* Output file handling. */
e2500fed 1444
e03856fe
GK
1445/* Create and return an outf_p for a new file for NAME, to be called
1446 ONAME. */
9f313342 1447
e03856fe 1448static outf_p
3d7aafde 1449create_file (const char *name, const char *oname)
e2500fed
GK
1450{
1451 static const char *const hdr[] = {
9dcd6f09 1452 " Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
e2500fed
GK
1453 "\n",
1454 "This file is part of GCC.\n",
1455 "\n",
1456 "GCC is free software; you can redistribute it and/or modify it under\n",
1457 "the terms of the GNU General Public License as published by the Free\n",
9dcd6f09 1458 "Software Foundation; either version 3, or (at your option) any later\n",
e2500fed
GK
1459 "version.\n",
1460 "\n",
1461 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1462 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1463 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
1464 "for more details.\n",
1465 "\n",
1466 "You should have received a copy of the GNU General Public License\n",
9dcd6f09
NC
1467 "along with GCC; see the file COPYING3. If not see\n",
1468 "<http://www.gnu.org/licenses/>. */\n",
e2500fed
GK
1469 "\n",
1470 "/* This file is machine generated. Do not edit. */\n"
1471 };
e03856fe 1472 outf_p f;
e2500fed 1473 size_t i;
3d7aafde 1474
5d038c4c 1475 f = XCNEW (struct outf);
e03856fe
GK
1476 f->next = output_files;
1477 f->name = oname;
1478 output_files = f;
1479
1480 oprintf (f, "/* Type information for %s.\n", name);
62c71f4b 1481 for (i = 0; i < ARRAY_SIZE (hdr); i++)
e03856fe 1482 oprintf (f, "%s", hdr[i]);
e2500fed
GK
1483 return f;
1484}
1485
311e3ff0
ZW
1486/* Print, like fprintf, to O.
1487 N.B. You might think this could be implemented more efficiently
1488 with vsnprintf(). Unfortunately, there are C libraries that
1489 provide that function but without the C99 semantics for its return
1490 value, making it impossible to know how much space is required. */
3d7aafde 1491void
e34d07f2 1492oprintf (outf_p o, const char *format, ...)
e03856fe 1493{
311e3ff0 1494 char *s;
e03856fe 1495 size_t slength;
311e3ff0 1496 va_list ap;
3d7aafde 1497
311e3ff0
ZW
1498 va_start (ap, format);
1499 slength = vasprintf (&s, format, ap);
1500 if (s == NULL || (int)slength < 0)
1501 fatal ("out of memory");
1502 va_end (ap);
e03856fe 1503
311e3ff0 1504 if (o->bufused + slength > o->buflength)
e03856fe
GK
1505 {
1506 size_t new_len = o->buflength;
1507 if (new_len == 0)
1508 new_len = 1024;
1509 do {
1510 new_len *= 2;
1511 } while (o->bufused + slength >= new_len);
cca8ead2 1512 o->buf = XRESIZEVEC (char, o->buf, new_len);
e03856fe
GK
1513 o->buflength = new_len;
1514 }
311e3ff0 1515 memcpy (o->buf + o->bufused, s, slength);
e03856fe 1516 o->bufused += slength;
311e3ff0 1517 free (s);
e03856fe
GK
1518}
1519
9f313342
GK
1520/* Open the global header file and the language-specific header files. */
1521
e2500fed 1522static void
3d7aafde 1523open_base_files (void)
e2500fed
GK
1524{
1525 size_t i;
3d7aafde 1526
e03856fe 1527 header_file = create_file ("GCC", "gtype-desc.h");
e2500fed 1528
11a67599
ZW
1529 base_files = XNEWVEC (outf_p, num_lang_dirs);
1530
1531 for (i = 0; i < num_lang_dirs; i++)
3d7aafde 1532 base_files[i] = create_file (lang_dir_names[i],
8ac9d31f 1533 xasprintf ("gtype-%s.h", lang_dir_names[i]));
e03856fe
GK
1534
1535 /* gtype-desc.c is a little special, so we create it here. */
1536 {
1537 /* The order of files here matters very much. */
1538 static const char *const ifiles [] = {
6de9cd9a 1539 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
7932a3db
NS
1540 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
1541 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1542 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1543 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1544 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
726a989a 1545 "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h", NULL
e03856fe
GK
1546 };
1547 const char *const *ifp;
1548 outf_p gtype_desc_c;
3d7aafde 1549
e03856fe
GK
1550 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1551 for (ifp = ifiles; *ifp; ifp++)
1552 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
5576d6f2
TT
1553
1554 /* Make sure we handle "cfun" specially. */
1555 oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n");
1556 oprintf (gtype_desc_c, "#undef cfun\n");
e03856fe 1557 }
e2500fed
GK
1558}
1559
8de8de02
OH
1560/* For F a filename, return the real basename of F, with all the directory
1561 components skipped. */
1562
1563static const char *
1564get_file_realbasename (const char *f)
1565{
1566 const char * lastslash = strrchr (f, '/');
1567
1568 return (lastslash != NULL) ? lastslash + 1 : f;
1569}
1570
1571/* For F a filename, return the relative path to F from $(srcdir) if the
1572 latter is a prefix in F, NULL otherwise. */
1573
1574static const char *
1575get_file_srcdir_relative_path (const char *f)
1576{
1577 if (strlen (f) > srcdir_len
1578 && IS_DIR_SEPARATOR (f[srcdir_len])
1579 && memcmp (f, srcdir, srcdir_len) == 0)
1580 return f + srcdir_len + 1;
1581 else
1582 return NULL;
1583}
1584
1585/* For F a filename, return the relative path to F from $(srcdir) if the
1586 latter is a prefix in F, or the real basename of F otherwise. */
9f313342 1587
e2500fed 1588static const char *
3d7aafde 1589get_file_basename (const char *f)
e2500fed 1590{
8de8de02 1591 const char * srcdir_path = get_file_srcdir_relative_path (f);
3d7aafde 1592
8de8de02
OH
1593 return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
1594}
3d7aafde 1595
8de8de02
OH
1596/* For F a filename, return the lang_dir_names relative index of the language
1597 directory that is a prefix in F, if any, -1 otherwise. */
3d7aafde 1598
8de8de02
OH
1599static int
1600get_prefix_langdir_index (const char *f)
1601{
1602 size_t f_len = strlen (f);
1603 size_t lang_index;
3d7aafde 1604
8de8de02 1605 for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
8ac9d31f 1606 {
8de8de02
OH
1607 const char * langdir = lang_dir_names [lang_index];
1608 size_t langdir_len = strlen (langdir);
1609
1610 if (f_len > langdir_len
1611 && IS_DIR_SEPARATOR (f[langdir_len])
1612 && memcmp (f, langdir, langdir_len) == 0)
1613 return lang_index;
8ac9d31f 1614 }
3d7aafde 1615
8de8de02
OH
1616 return -1;
1617}
1618
1619/* For F a filename, return the name of language directory where F is located,
1620 if any, NULL otherwise. */
1621
1622static const char *
1623get_file_langdir (const char *f)
1624{
1625 /* Get the relative path to F from $(srcdir) and find the language by
1626 comparing the prefix with language directory names. If F is not even
1627 srcdir relative, no point in looking further. */
1628
1629 int lang_index;
1630 const char * srcdir_relative_path = get_file_srcdir_relative_path (f);
1631
1632 if (!srcdir_relative_path)
1633 return NULL;
1634
1635 lang_index = get_prefix_langdir_index (srcdir_relative_path);
1636
1637 return (lang_index >= 0) ? lang_dir_names [lang_index] : NULL;
1638}
1639
1640/* The gt- output file name for F. */
1641
1642static const char *
1643get_file_gtfilename (const char *f)
1644{
1645 /* Cook up an initial version of the gt- file name from the file real
1646 basename and the language name, if any. */
1647
1648 const char *basename = get_file_realbasename (f);
1649 const char *langdir = get_file_langdir (f);
1650
1651 char * result =
1652 (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
1653 : xasprintf ("gt-%s", basename));
1654
1655 /* Then replace all non alphanumerics characters by '-' and change the
1656 extenstion to ".h". We expect the input filename extension was at least
1657 one character long. */
1658
1659 char *s = result;
1660
1661 for (; *s != '.'; s++)
1662 if (! ISALNUM (*s) && *s != '-')
1663 *s = '-';
1664
1665 memcpy (s, ".h", sizeof (".h"));
1666
1667 return result;
e2500fed
GK
1668}
1669
9f313342
GK
1670/* An output file, suitable for definitions, that can see declarations
1671 made in INPUT_FILE and is linked into every language that uses
1672 INPUT_FILE. */
1673
e03856fe 1674outf_p
3d7aafde 1675get_output_file_with_visibility (const char *input_file)
e2500fed 1676{
e03856fe 1677 outf_p r;
e2500fed
GK
1678 size_t len;
1679 const char *basename;
e03856fe
GK
1680 const char *for_name;
1681 const char *output_name;
e2500fed 1682
e03856fe
GK
1683 /* This can happen when we need a file with visibility on a
1684 structure that we've never seen. We have to just hope that it's
1685 globally visible. */
1686 if (input_file == NULL)
1687 input_file = "system.h";
e2500fed 1688
e2500fed
GK
1689 /* Determine the output file name. */
1690 basename = get_file_basename (input_file);
1691
1692 len = strlen (basename);
1693 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1694 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1695 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1696 {
8de8de02 1697 output_name = get_file_gtfilename (input_file);
e03856fe 1698 for_name = basename;
e2500fed 1699 }
ad8c162b
ZL
1700 /* Some headers get used by more than one front-end; hence, it
1701 would be inappropriate to spew them out to a single gtype-<lang>.h
1702 (and gengtype doesn't know how to direct spewage into multiple
1703 gtype-<lang>.h headers at this time). Instead, we pair up these
1704 headers with source files (and their special purpose gt-*.h headers). */
e2500fed 1705 else if (strcmp (basename, "c-common.h") == 0)
e03856fe 1706 output_name = "gt-c-common.h", for_name = "c-common.c";
e2500fed 1707 else if (strcmp (basename, "c-tree.h") == 0)
e03856fe 1708 output_name = "gt-c-decl.h", for_name = "c-decl.c";
6e955430
ZL
1709 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1710 && strcmp (basename + 3, "cp-tree.h") == 0)
1711 output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1712 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1713 && strcmp (basename + 3, "decl.h") == 0)
1714 output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1715 else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1716 && strcmp (basename + 3, "name-lookup.h") == 0)
1717 output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
ad8c162b
ZL
1718 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1719 && strcmp (basename + 5, "objc-act.h") == 0)
1720 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1721 else
e2500fed 1722 {
8de8de02 1723 int lang_index = get_prefix_langdir_index (basename);
3d7aafde 1724
8de8de02
OH
1725 if (lang_index >= 0)
1726 return base_files[lang_index];
e03856fe
GK
1727
1728 output_name = "gtype-desc.c";
1729 for_name = NULL;
e2500fed
GK
1730 }
1731
1732 /* Look through to see if we've ever seen this output filename before. */
e03856fe
GK
1733 for (r = output_files; r; r = r->next)
1734 if (strcmp (r->name, output_name) == 0)
1735 return r;
e2500fed
GK
1736
1737 /* If not, create it. */
e03856fe 1738 r = create_file (for_name, output_name);
e2500fed 1739
e03856fe 1740 return r;
e2500fed
GK
1741}
1742
9f313342
GK
1743/* The name of an output file, suitable for definitions, that can see
1744 declarations made in INPUT_FILE and is linked into every language
1745 that uses INPUT_FILE. */
1746
e2500fed 1747const char *
3d7aafde 1748get_output_file_name (const char *input_file)
e2500fed 1749{
e03856fe 1750 return get_output_file_with_visibility (input_file)->name;
e2500fed
GK
1751}
1752
e03856fe 1753/* Copy the output to its final destination,
9f313342
GK
1754 but don't unnecessarily change modification times. */
1755
e2500fed 1756static void
3d7aafde 1757close_output_files (void)
e2500fed 1758{
e03856fe 1759 outf_p of;
3d7aafde 1760
e03856fe 1761 for (of = output_files; of; of = of->next)
e2500fed 1762 {
e03856fe
GK
1763 FILE * newfile;
1764
1765 newfile = fopen (of->name, "r");
1766 if (newfile != NULL )
e2500fed 1767 {
e03856fe
GK
1768 int no_write_p;
1769 size_t i;
e2500fed 1770
e03856fe
GK
1771 for (i = 0; i < of->bufused; i++)
1772 {
1773 int ch;
1774 ch = fgetc (newfile);
1775 if (ch == EOF || ch != (unsigned char) of->buf[i])
1776 break;
1777 }
1778 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
e2500fed 1779 fclose (newfile);
e03856fe
GK
1780
1781 if (no_write_p)
1782 continue;
e2500fed
GK
1783 }
1784
e03856fe 1785 newfile = fopen (of->name, "w");
e2500fed 1786 if (newfile == NULL)
065ae611 1787 fatal ("opening output file %s: %s", of->name, strerror (errno));
e03856fe 1788 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
065ae611 1789 fatal ("writing output file %s: %s", of->name, strerror (errno));
e03856fe 1790 if (fclose (newfile) != 0)
065ae611 1791 fatal ("closing output file %s: %s", of->name, strerror (errno));
e2500fed
GK
1792 }
1793}
1794\f
1795struct flist {
1796 struct flist *next;
1797 int started_p;
1798 const char *name;
e03856fe 1799 outf_p f;
e2500fed
GK
1800};
1801
17211ab5
GK
1802struct walk_type_data;
1803
1804/* For scalars and strings, given the item in 'val'.
1805 For structures, given a pointer to the item in 'val'.
1806 For misc. pointers, given the item in 'val'.
1807*/
3d7aafde
AJ
1808typedef void (*process_field_fn)
1809 (type_p f, const struct walk_type_data *p);
17211ab5 1810typedef void (*func_name_fn)
3d7aafde 1811 (type_p s, const struct walk_type_data *p);
17211ab5
GK
1812
1813/* Parameters for write_types. */
1814
3d7aafde 1815struct write_types_data
17211ab5
GK
1816{
1817 const char *prefix;
1818 const char *param_prefix;
1819 const char *subfield_marker_routine;
1820 const char *marker_routine;
1821 const char *reorder_note_routine;
1822 const char *comment;
8d6419b2 1823 int skip_hooks; /* skip hook generation if non zero */
17211ab5
GK
1824};
1825
3d7aafde
AJ
1826static void output_escaped_param (struct walk_type_data *d,
1827 const char *, const char *);
e5cfc29f 1828static void output_mangled_typename (outf_p, const_type_p);
3d7aafde 1829static void walk_type (type_p t, struct walk_type_data *d);
17211ab5 1830static void write_func_for_structure
3d7aafde
AJ
1831 (type_p orig_s, type_p s, type_p * param,
1832 const struct write_types_data *wtd);
1833static void write_types_process_field
1834 (type_p f, const struct walk_type_data *d);
1835static void write_types (type_p structures,
1836 type_p param_structs,
1837 const struct write_types_data *wtd);
17211ab5 1838static void write_types_local_process_field
3d7aafde 1839 (type_p f, const struct walk_type_data *d);
17211ab5 1840static void write_local_func_for_structure
3d7aafde
AJ
1841 (type_p orig_s, type_p s, type_p * param);
1842static void write_local (type_p structures,
1843 type_p param_structs);
1844static void write_enum_defn (type_p structures, type_p param_structs);
1845static int contains_scalar_p (type_p t);
1846static void put_mangled_filename (outf_p , const char *);
1847static void finish_root_table (struct flist *flp, const char *pfx,
1848 const char *tname, const char *lastname,
1849 const char *name);
1850static void write_root (outf_p , pair_p, type_p, const char *, int,
1851 struct fileloc *, const char *);
1852static void write_array (outf_p f, pair_p v,
1853 const struct write_types_data *wtd);
1854static void write_roots (pair_p);
e2500fed 1855
17211ab5 1856/* Parameters for walk_type. */
e2500fed 1857
17211ab5 1858struct walk_type_data
e2500fed 1859{
17211ab5
GK
1860 process_field_fn process_field;
1861 const void *cookie;
1862 outf_p of;
1863 options_p opt;
1864 const char *val;
1865 const char *prev_val[4];
1866 int indent;
1867 int counter;
1868 struct fileloc *line;
1869 lang_bitmap bitmap;
1870 type_p *param;
1871 int used_length;
1872 type_p orig_s;
1873 const char *reorder_fn;
d8044160
GK
1874 bool needs_cast_p;
1875 bool fn_wants_lvalue;
17211ab5 1876};
36a5eadd
GK
1877
1878/* Print a mangled name representing T to OF. */
1879
1880static void
e5cfc29f 1881output_mangled_typename (outf_p of, const_type_p t)
36a5eadd
GK
1882{
1883 if (t == NULL)
1884 oprintf (of, "Z");
1885 else switch (t->kind)
1886 {
1887 case TYPE_POINTER:
1888 oprintf (of, "P");
1889 output_mangled_typename (of, t->u.p);
1890 break;
1891 case TYPE_SCALAR:
1892 oprintf (of, "I");
1893 break;
1894 case TYPE_STRING:
1895 oprintf (of, "S");
1896 break;
1897 case TYPE_STRUCT:
1898 case TYPE_UNION:
1899 case TYPE_LANG_STRUCT:
6d8dd940 1900 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
36a5eadd
GK
1901 break;
1902 case TYPE_PARAM_STRUCT:
1903 {
1904 int i;
1905 for (i = 0; i < NUM_PARAM; i++)
1906 if (t->u.param_struct.param[i] != NULL)
1907 output_mangled_typename (of, t->u.param_struct.param[i]);
3d7aafde 1908 output_mangled_typename (of, t->u.param_struct.stru);
36a5eadd
GK
1909 }
1910 break;
1911 case TYPE_ARRAY:
b2d59f6f 1912 gcc_unreachable ();
36a5eadd 1913 }
e2500fed
GK
1914}
1915
17211ab5
GK
1916/* Print PARAM to D->OF processing escapes. D->VAL references the
1917 current object, D->PREV_VAL the object containing the current
1918 object, ONAME is the name of the option and D->LINE is used to
1919 print error messages. */
9f313342 1920
e2500fed 1921static void
3d7aafde
AJ
1922output_escaped_param (struct walk_type_data *d, const char *param,
1923 const char *oname)
e2500fed 1924{
17211ab5 1925 const char *p;
3d7aafde 1926
17211ab5
GK
1927 for (p = param; *p; p++)
1928 if (*p != '%')
1929 oprintf (d->of, "%c", *p);
1930 else switch (*++p)
1931 {
1932 case 'h':
1933 oprintf (d->of, "(%s)", d->prev_val[2]);
1934 break;
1935 case '0':
1936 oprintf (d->of, "(%s)", d->prev_val[0]);
1937 break;
1938 case '1':
1939 oprintf (d->of, "(%s)", d->prev_val[1]);
1940 break;
1941 case 'a':
e2500fed 1942 {
17211ab5
GK
1943 const char *pp = d->val + strlen (d->val);
1944 while (pp[-1] == ']')
1945 while (*pp != '[')
1946 pp--;
1947 oprintf (d->of, "%s", pp);
e2500fed 1948 }
17211ab5
GK
1949 break;
1950 default:
1951 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1952 oname, '%', *p);
1953 }
1954}
e2500fed 1955
17211ab5
GK
1956/* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1957 which is of type T. Write code to D->OF to constrain execution (at
1958 the point that D->PROCESS_FIELD is called) to the appropriate
4da6879c
GK
1959 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1960 pointers to those objects. D->PREV_VAL lists the objects
1961 containing the current object, D->OPT is a list of options to
1962 apply, D->INDENT is the current indentation level, D->LINE is used
1963 to print error messages, D->BITMAP indicates which languages to
1964 print the structure for, and D->PARAM is the current parameter
1965 (from an enclosing param_is option). */
e2500fed 1966
17211ab5 1967static void
3d7aafde 1968walk_type (type_p t, struct walk_type_data *d)
17211ab5
GK
1969{
1970 const char *length = NULL;
1971 const char *desc = NULL;
1972 int maybe_undef_p = 0;
1973 int use_param_num = -1;
1974 int use_params_p = 0;
17211ab5 1975 options_p oo;
b453c95f 1976 const struct nested_ptr_data *nested_ptr_d = NULL;
3d7aafde 1977
d8044160 1978 d->needs_cast_p = false;
17211ab5
GK
1979 for (oo = d->opt; oo; oo = oo->next)
1980 if (strcmp (oo->name, "length") == 0)
9e2878cf 1981 length = oo->info;
17211ab5
GK
1982 else if (strcmp (oo->name, "maybe_undef") == 0)
1983 maybe_undef_p = 1;
1984 else if (strncmp (oo->name, "use_param", 9) == 0
1985 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1986 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1987 else if (strcmp (oo->name, "use_params") == 0)
1988 use_params_p = 1;
1989 else if (strcmp (oo->name, "desc") == 0)
9e2878cf 1990 desc = oo->info;
8d6419b2
BS
1991 else if (strcmp (oo->name, "mark_hook") == 0)
1992 ;
b453c95f 1993 else if (strcmp (oo->name, "nested_ptr") == 0)
d8044160 1994 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
17211ab5
GK
1995 else if (strcmp (oo->name, "dot") == 0)
1996 ;
1997 else if (strcmp (oo->name, "tag") == 0)
1998 ;
1999 else if (strcmp (oo->name, "special") == 0)
2000 ;
2001 else if (strcmp (oo->name, "skip") == 0)
2002 ;
2003 else if (strcmp (oo->name, "default") == 0)
2004 ;
2005 else if (strcmp (oo->name, "descbits") == 0)
2006 ;
2007 else if (strcmp (oo->name, "param_is") == 0)
2008 ;
084087e1
RH
2009 else if (strncmp (oo->name, "param", 5) == 0
2010 && ISDIGIT (oo->name[5])
2011 && strcmp (oo->name + 6, "_is") == 0)
2012 ;
17211ab5
GK
2013 else if (strcmp (oo->name, "chain_next") == 0)
2014 ;
2015 else if (strcmp (oo->name, "chain_prev") == 0)
2016 ;
623f8e39
JJ
2017 else if (strcmp (oo->name, "chain_circular") == 0)
2018 ;
17211ab5
GK
2019 else if (strcmp (oo->name, "reorder") == 0)
2020 ;
2021 else
2022 error_at_line (d->line, "unknown option `%s'\n", oo->name);
36a5eadd 2023
17211ab5
GK
2024 if (d->used_length)
2025 length = NULL;
36a5eadd 2026
17211ab5
GK
2027 if (use_params_p)
2028 {
2029 int pointer_p = t->kind == TYPE_POINTER;
3d7aafde 2030
17211ab5
GK
2031 if (pointer_p)
2032 t = t->u.p;
2033 if (! UNION_OR_STRUCT_P (t))
2034 error_at_line (d->line, "`use_params' option on unimplemented type");
3d7aafde 2035 else
17211ab5
GK
2036 t = find_param_structure (t, d->param);
2037 if (pointer_p)
2038 t = create_pointer (t);
2039 }
3d7aafde 2040
17211ab5
GK
2041 if (use_param_num != -1)
2042 {
2043 if (d->param != NULL && d->param[use_param_num] != NULL)
e2500fed 2044 {
17211ab5 2045 type_p nt = d->param[use_param_num];
3d7aafde 2046
17211ab5
GK
2047 if (t->kind == TYPE_ARRAY)
2048 nt = create_array (nt, t->u.a.len);
2049 else if (length != NULL && t->kind == TYPE_POINTER)
2050 nt = create_pointer (nt);
f099d360
GK
2051 d->needs_cast_p = (t->kind != TYPE_POINTER
2052 && (nt->kind == TYPE_POINTER
2053 || nt->kind == TYPE_STRING));
17211ab5 2054 t = nt;
e2500fed 2055 }
17211ab5
GK
2056 else
2057 error_at_line (d->line, "no parameter defined for `%s'",
2058 d->val);
2059 }
3d7aafde
AJ
2060
2061 if (maybe_undef_p
17211ab5
GK
2062 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
2063 {
3d7aafde 2064 error_at_line (d->line,
17211ab5
GK
2065 "field `%s' has invalid option `maybe_undef_p'\n",
2066 d->val);
2067 return;
2068 }
3d7aafde 2069
17211ab5
GK
2070 switch (t->kind)
2071 {
2072 case TYPE_SCALAR:
2073 case TYPE_STRING:
2074 d->process_field (t, d);
2075 break;
3d7aafde 2076
17211ab5
GK
2077 case TYPE_POINTER:
2078 {
2079 if (maybe_undef_p
2080 && t->u.p->u.s.line.file == NULL)
2081 {
b2d59f6f 2082 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
17211ab5
GK
2083 break;
2084 }
e2500fed 2085
17211ab5 2086 if (! length)
e2500fed 2087 {
17211ab5
GK
2088 if (! UNION_OR_STRUCT_P (t->u.p)
2089 && t->u.p->kind != TYPE_PARAM_STRUCT)
e2500fed 2090 {
3d7aafde 2091 error_at_line (d->line,
17211ab5
GK
2092 "field `%s' is pointer to unimplemented type",
2093 d->val);
e2500fed
GK
2094 break;
2095 }
3d7aafde 2096
b453c95f
GK
2097 if (nested_ptr_d)
2098 {
2099 const char *oldprevval2 = d->prev_val[2];
2100
2101 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2102 {
2103 error_at_line (d->line,
2104 "field `%s' has invalid "
2105 "option `nested_ptr'\n",
2106 d->val);
2107 return;
2108 }
2109
2110 d->prev_val[2] = d->val;
2111 oprintf (d->of, "%*s{\n", d->indent, "");
2112 d->indent += 2;
2113 d->val = xasprintf ("x%d", d->counter++);
d8044160 2114 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
b453c95f
GK
2115 (nested_ptr_d->type->kind == TYPE_UNION
2116 ? "union" : "struct"),
d8044160
GK
2117 nested_ptr_d->type->u.s.tag,
2118 d->fn_wants_lvalue ? "" : "const ",
2119 d->val);
b453c95f
GK
2120 oprintf (d->of, "%*s", d->indent + 2, "");
2121 output_escaped_param (d, nested_ptr_d->convert_from,
2122 "nested_ptr");
2123 oprintf (d->of, ";\n");
2124
2125 d->process_field (nested_ptr_d->type, d);
2126
d8044160
GK
2127 if (d->fn_wants_lvalue)
2128 {
2129 oprintf (d->of, "%*s%s = ", d->indent, "",
2130 d->prev_val[2]);
2131 d->prev_val[2] = d->val;
2132 output_escaped_param (d, nested_ptr_d->convert_to,
2133 "nested_ptr");
2134 oprintf (d->of, ";\n");
2135 }
b453c95f
GK
2136
2137 d->indent -= 2;
2138 oprintf (d->of, "%*s}\n", d->indent, "");
2139 d->val = d->prev_val[2];
2140 d->prev_val[2] = oldprevval2;
2141 }
2142 else
2143 d->process_field (t->u.p, d);
e2500fed 2144 }
3d7aafde 2145 else
e2500fed 2146 {
17211ab5
GK
2147 int loopcounter = d->counter++;
2148 const char *oldval = d->val;
2149 const char *oldprevval3 = d->prev_val[3];
e2500fed
GK
2150 char *newval;
2151
17211ab5
GK
2152 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2153 d->indent += 2;
2154 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
a62a0172 2155 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
17211ab5
GK
2156 loopcounter, loopcounter);
2157 output_escaped_param (d, length, "length");
2158 oprintf (d->of, "); i%d++) {\n", loopcounter);
2159 d->indent += 2;
2160 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2161 d->used_length = 1;
2162 d->prev_val[3] = oldval;
2163 walk_type (t->u.p, d);
e2500fed 2164 free (newval);
17211ab5
GK
2165 d->val = oldval;
2166 d->prev_val[3] = oldprevval3;
2167 d->used_length = 0;
2168 d->indent -= 2;
2169 oprintf (d->of, "%*s}\n", d->indent, "");
4da6879c 2170 d->process_field(t, d);
17211ab5
GK
2171 d->indent -= 2;
2172 oprintf (d->of, "%*s}\n", d->indent, "");
e2500fed 2173 }
17211ab5
GK
2174 }
2175 break;
e2500fed 2176
17211ab5
GK
2177 case TYPE_ARRAY:
2178 {
2179 int loopcounter = d->counter++;
2180 const char *oldval = d->val;
2181 char *newval;
2182
6356f892 2183 /* If it's an array of scalars, we optimize by not generating
17211ab5
GK
2184 any code. */
2185 if (t->u.a.p->kind == TYPE_SCALAR)
e2500fed 2186 break;
3d7aafde 2187
5039610b
SL
2188 /* When walking an array, compute the length and store it in a
2189 local variable before walking the array elements, instead of
2190 recomputing the length expression each time through the loop.
2191 This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2192 where the length is stored in the first array element,
2193 because otherwise that operand can get overwritten on the
2194 first iteration. */
17211ab5
GK
2195 oprintf (d->of, "%*s{\n", d->indent, "");
2196 d->indent += 2;
2197 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
5039610b
SL
2198 oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2199 d->indent, "", loopcounter);
17211ab5
GK
2200 if (length)
2201 output_escaped_param (d, length, "length");
2202 else
2203 oprintf (d->of, "%s", t->u.a.len);
5039610b
SL
2204 oprintf (d->of, ");\n");
2205
2206 oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2207 d->indent, "",
2208 loopcounter, loopcounter, loopcounter, loopcounter);
17211ab5
GK
2209 d->indent += 2;
2210 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2211 d->used_length = 1;
2212 walk_type (t->u.a.p, d);
2213 free (newval);
2214 d->used_length = 0;
2215 d->val = oldval;
2216 d->indent -= 2;
2217 oprintf (d->of, "%*s}\n", d->indent, "");
2218 d->indent -= 2;
2219 oprintf (d->of, "%*s}\n", d->indent, "");
2220 }
2221 break;
3d7aafde 2222
17211ab5
GK
2223 case TYPE_STRUCT:
2224 case TYPE_UNION:
2225 {
2226 pair_p f;
2227 const char *oldval = d->val;
2228 const char *oldprevval1 = d->prev_val[1];
2229 const char *oldprevval2 = d->prev_val[2];
2230 const int union_p = t->kind == TYPE_UNION;
2231 int seen_default_p = 0;
2232 options_p o;
2233
2234 if (! t->u.s.line.file)
2235 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
e2500fed 2236
17211ab5 2237 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
e2500fed 2238 {
17211ab5
GK
2239 error_at_line (d->line,
2240 "structure `%s' defined for mismatching languages",
2241 t->u.s.tag);
2242 error_at_line (&t->u.s.line, "one structure defined here");
2243 }
e2500fed 2244
17211ab5
GK
2245 /* Some things may also be defined in the structure's options. */
2246 for (o = t->u.s.opt; o; o = o->next)
2247 if (! desc && strcmp (o->name, "desc") == 0)
9e2878cf 2248 desc = o->info;
e2500fed 2249
17211ab5
GK
2250 d->prev_val[2] = oldval;
2251 d->prev_val[1] = oldprevval2;
2252 if (union_p)
2253 {
2254 if (desc == NULL)
e2500fed 2255 {
17211ab5
GK
2256 error_at_line (d->line, "missing `desc' option for union `%s'",
2257 t->u.s.tag);
2258 desc = "1";
e2500fed 2259 }
17211ab5
GK
2260 oprintf (d->of, "%*sswitch (", d->indent, "");
2261 output_escaped_param (d, desc, "desc");
2262 oprintf (d->of, ")\n");
2263 d->indent += 2;
2264 oprintf (d->of, "%*s{\n", d->indent, "");
2265 }
2266 for (f = t->u.s.fields; f; f = f->next)
2267 {
2268 options_p oo;
2269 const char *dot = ".";
2270 const char *tagid = NULL;
2271 int skip_p = 0;
2272 int default_p = 0;
2273 int use_param_p = 0;
2274 char *newval;
2275
2276 d->reorder_fn = NULL;
2277 for (oo = f->opt; oo; oo = oo->next)
2278 if (strcmp (oo->name, "dot") == 0)
9e2878cf 2279 dot = oo->info;
17211ab5 2280 else if (strcmp (oo->name, "tag") == 0)
9e2878cf 2281 tagid = oo->info;
17211ab5
GK
2282 else if (strcmp (oo->name, "skip") == 0)
2283 skip_p = 1;
2284 else if (strcmp (oo->name, "default") == 0)
2285 default_p = 1;
2286 else if (strcmp (oo->name, "reorder") == 0)
9e2878cf 2287 d->reorder_fn = oo->info;
17211ab5
GK
2288 else if (strncmp (oo->name, "use_param", 9) == 0
2289 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2290 use_param_p = 1;
2291
2292 if (skip_p)
2293 continue;
2294
2295 if (union_p && tagid)
e2500fed 2296 {
17211ab5
GK
2297 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2298 d->indent += 2;
e2500fed 2299 }
17211ab5 2300 else if (union_p && default_p)
e2500fed 2301 {
17211ab5
GK
2302 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2303 d->indent += 2;
2304 seen_default_p = 1;
e2500fed 2305 }
17211ab5 2306 else if (! union_p && (default_p || tagid))
3d7aafde 2307 error_at_line (d->line,
17211ab5
GK
2308 "can't use `%s' outside a union on field `%s'",
2309 default_p ? "default" : "tag", f->name);
2310 else if (union_p && ! (default_p || tagid)
2311 && f->type->kind == TYPE_SCALAR)
e2500fed 2312 {
17211ab5
GK
2313 fprintf (stderr,
2314 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2315 d->line->file, d->line->line, f->name);
2316 continue;
e2500fed 2317 }
17211ab5 2318 else if (union_p && ! (default_p || tagid))
3d7aafde 2319 error_at_line (d->line,
17211ab5 2320 "field `%s' is missing `tag' or `default' option",
e2500fed 2321 f->name);
3d7aafde 2322
17211ab5
GK
2323 d->line = &f->line;
2324 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2325 d->opt = f->opt;
d8044160 2326 d->used_length = false;
17211ab5
GK
2327
2328 if (union_p && use_param_p && d->param == NULL)
b2d59f6f 2329 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
17211ab5
GK
2330 else
2331 walk_type (f->type, d);
2332
2333 free (newval);
2334
2335 if (union_p)
e2500fed 2336 {
17211ab5
GK
2337 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2338 d->indent -= 2;
e2500fed 2339 }
17211ab5
GK
2340 }
2341 d->reorder_fn = NULL;
e2500fed 2342
17211ab5
GK
2343 d->val = oldval;
2344 d->prev_val[1] = oldprevval1;
2345 d->prev_val[2] = oldprevval2;
2346
2347 if (union_p && ! seen_default_p)
2348 {
2349 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2350 oprintf (d->of, "%*s break;\n", d->indent, "");
2351 }
2352 if (union_p)
2353 {
2354 oprintf (d->of, "%*s}\n", d->indent, "");
2355 d->indent -= 2;
e2500fed 2356 }
17211ab5
GK
2357 }
2358 break;
e2500fed 2359
17211ab5
GK
2360 case TYPE_LANG_STRUCT:
2361 {
2362 type_p nt;
2363 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2364 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2365 break;
2366 if (nt == NULL)
2367 error_at_line (d->line, "structure `%s' differs between languages",
2368 t->u.s.tag);
2369 else
2370 walk_type (nt, d);
2371 }
2372 break;
2373
2374 case TYPE_PARAM_STRUCT:
2375 {
2376 type_p *oldparam = d->param;
3d7aafde 2377
17211ab5
GK
2378 d->param = t->u.param_struct.param;
2379 walk_type (t->u.param_struct.stru, d);
2380 d->param = oldparam;
2381 }
2382 break;
3d7aafde 2383
17211ab5 2384 default:
b2d59f6f 2385 gcc_unreachable ();
e2500fed 2386 }
17211ab5
GK
2387}
2388
2389/* process_field routine for marking routines. */
2390
2391static void
3d7aafde 2392write_types_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
2393{
2394 const struct write_types_data *wtd;
f099d360 2395 const char *cast = d->needs_cast_p ? "(void *)" : "";
17211ab5 2396 wtd = (const struct write_types_data *) d->cookie;
3d7aafde 2397
17211ab5 2398 switch (f->kind)
e2500fed 2399 {
17211ab5 2400 case TYPE_POINTER:
3d7aafde 2401 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
f099d360 2402 wtd->subfield_marker_routine, cast, d->val);
17211ab5 2403 if (wtd->param_prefix)
36a5eadd 2404 {
17211ab5
GK
2405 oprintf (d->of, ", %s", d->prev_val[3]);
2406 if (d->orig_s)
2407 {
2408 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2409 output_mangled_typename (d->of, d->orig_s);
2410 }
2411 else
2412 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
08cee789
DJ
2413
2414 if (f->u.p->kind == TYPE_PARAM_STRUCT
2415 && f->u.p->u.s.line.file != NULL)
2416 {
2417 oprintf (d->of, ", gt_e_");
2418 output_mangled_typename (d->of, f);
2419 }
2420 else if (UNION_OR_STRUCT_P (f)
2421 && f->u.p->u.s.line.file != NULL)
2422 {
2423 oprintf (d->of, ", gt_ggc_e_");
2424 output_mangled_typename (d->of, f);
2425 }
2426 else
2427 oprintf (d->of, ", gt_types_enum_last");
36a5eadd 2428 }
17211ab5
GK
2429 oprintf (d->of, ");\n");
2430 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2431 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
f099d360 2432 wtd->reorder_note_routine, cast, d->val,
17211ab5
GK
2433 d->prev_val[3], d->reorder_fn);
2434 break;
2435
2436 case TYPE_STRING:
17211ab5
GK
2437 case TYPE_STRUCT:
2438 case TYPE_UNION:
2439 case TYPE_LANG_STRUCT:
2440 case TYPE_PARAM_STRUCT:
2441 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2442 output_mangled_typename (d->of, f);
f099d360 2443 oprintf (d->of, " (%s%s);\n", cast, d->val);
17211ab5 2444 if (d->reorder_fn && wtd->reorder_note_routine)
3d7aafde 2445 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
f099d360 2446 wtd->reorder_note_routine, cast, d->val, cast, d->val,
17211ab5
GK
2447 d->reorder_fn);
2448 break;
2449
2450 case TYPE_SCALAR:
2451 break;
3d7aafde 2452
17211ab5 2453 default:
b2d59f6f 2454 gcc_unreachable ();
e2500fed
GK
2455 }
2456}
2457
2d82317d
RH
2458/* A subroutine of write_func_for_structure. Write the enum tag for S. */
2459
2460static void
2461output_type_enum (outf_p of, type_p s)
2462{
2463 if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2464 {
2465 oprintf (of, ", gt_e_");
2466 output_mangled_typename (of, s);
2467 }
2468 else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2469 {
2470 oprintf (of, ", gt_ggc_e_");
2471 output_mangled_typename (of, s);
2472 }
2473 else
2474 oprintf (of, ", gt_types_enum_last");
2475}
2476
17211ab5
GK
2477/* For S, a structure that's part of ORIG_S, and using parameters
2478 PARAM, write out a routine that:
2479 - Takes a parameter, a void * but actually of type *S
2480 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2481 field of S or its substructures and (in some cases) things
2482 that are pointed to by S.
2483*/
9f313342 2484
e2500fed 2485static void
8c80adb7
SB
2486write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2487 const struct write_types_data *wtd)
e2500fed 2488{
36a5eadd
GK
2489 const char *fn = s->u.s.line.file;
2490 int i;
2491 const char *chain_next = NULL;
2492 const char *chain_prev = NULL;
623f8e39 2493 const char *chain_circular = NULL;
8d6419b2 2494 const char *mark_hook_name = NULL;
36a5eadd 2495 options_p opt;
17211ab5 2496 struct walk_type_data d;
3d7aafde 2497
36a5eadd
GK
2498 /* This is a hack, and not the good kind either. */
2499 for (i = NUM_PARAM - 1; i >= 0; i--)
3d7aafde 2500 if (param && param[i] && param[i]->kind == TYPE_POINTER
36a5eadd
GK
2501 && UNION_OR_STRUCT_P (param[i]->u.p))
2502 fn = param[i]->u.p->u.s.line.file;
3d7aafde 2503
17211ab5
GK
2504 memset (&d, 0, sizeof (d));
2505 d.of = get_output_file_with_visibility (fn);
3d7aafde 2506
36a5eadd
GK
2507 for (opt = s->u.s.opt; opt; opt = opt->next)
2508 if (strcmp (opt->name, "chain_next") == 0)
9e2878cf 2509 chain_next = opt->info;
36a5eadd 2510 else if (strcmp (opt->name, "chain_prev") == 0)
9e2878cf 2511 chain_prev = opt->info;
623f8e39
JJ
2512 else if (strcmp (opt->name, "chain_circular") == 0)
2513 chain_circular = opt->info;
8d6419b2
BS
2514 else if (strcmp (opt->name, "mark_hook") == 0)
2515 mark_hook_name = opt->info;
36a5eadd
GK
2516
2517 if (chain_prev != NULL && chain_next == NULL)
2518 error_at_line (&s->u.s.line, "chain_prev without chain_next");
623f8e39
JJ
2519 if (chain_circular != NULL && chain_next != NULL)
2520 error_at_line (&s->u.s.line, "chain_circular with chain_next");
2521 if (chain_circular != NULL)
2522 chain_next = chain_circular;
36a5eadd 2523
17211ab5
GK
2524 d.process_field = write_types_process_field;
2525 d.cookie = wtd;
2526 d.orig_s = orig_s;
2527 d.opt = s->u.s.opt;
2528 d.line = &s->u.s.line;
2529 d.bitmap = s->u.s.bitmap;
2530 d.param = param;
2531 d.prev_val[0] = "*x";
e0a21ab9 2532 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
2533 d.prev_val[3] = "x";
2534 d.val = "(*x)";
2535
2536 oprintf (d.of, "\n");
2537 oprintf (d.of, "void\n");
e2500fed 2538 if (param == NULL)
17211ab5 2539 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
e2500fed 2540 else
36a5eadd 2541 {
17211ab5
GK
2542 oprintf (d.of, "gt_%s_", wtd->prefix);
2543 output_mangled_typename (d.of, orig_s);
36a5eadd 2544 }
6906ba40 2545 oprintf (d.of, " (void *x_p)\n");
17211ab5
GK
2546 oprintf (d.of, "{\n");
2547 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
e2500fed 2548 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
36a5eadd 2549 chain_next == NULL ? "const " : "",
e2500fed 2550 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
36a5eadd 2551 if (chain_next != NULL)
17211ab5 2552 oprintf (d.of, " %s %s * xlimit = x;\n",
36a5eadd
GK
2553 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2554 if (chain_next == NULL)
17211ab5
GK
2555 {
2556 oprintf (d.of, " if (%s (x", wtd->marker_routine);
2557 if (wtd->param_prefix)
2558 {
2559 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2560 output_mangled_typename (d.of, orig_s);
2d82317d 2561 output_type_enum (d.of, orig_s);
17211ab5
GK
2562 }
2563 oprintf (d.of, "))\n");
2564 }
36a5eadd
GK
2565 else
2566 {
623f8e39
JJ
2567 if (chain_circular != NULL)
2568 oprintf (d.of, " if (!%s (xlimit", wtd->marker_routine);
2569 else
2570 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
17211ab5
GK
2571 if (wtd->param_prefix)
2572 {
2573 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2574 output_mangled_typename (d.of, orig_s);
2d82317d 2575 output_type_enum (d.of, orig_s);
17211ab5
GK
2576 }
2577 oprintf (d.of, "))\n");
623f8e39
JJ
2578 if (chain_circular != NULL)
2579 oprintf (d.of, " return;\n do\n");
8d6419b2
BS
2580 if (mark_hook_name && !wtd->skip_hooks)
2581 {
2582 oprintf (d.of, " {\n");
2583 oprintf (d.of, " %s (xlimit);\n ", mark_hook_name);
2584 }
17211ab5
GK
2585 oprintf (d.of, " xlimit = (");
2586 d.prev_val[2] = "*xlimit";
2587 output_escaped_param (&d, chain_next, "chain_next");
2588 oprintf (d.of, ");\n");
8d6419b2
BS
2589 if (mark_hook_name && !wtd->skip_hooks)
2590 oprintf (d.of, " }\n");
36a5eadd
GK
2591 if (chain_prev != NULL)
2592 {
17211ab5
GK
2593 oprintf (d.of, " if (x != xlimit)\n");
2594 oprintf (d.of, " for (;;)\n");
2595 oprintf (d.of, " {\n");
2596 oprintf (d.of, " %s %s * const xprev = (",
36a5eadd 2597 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
3d7aafde 2598
17211ab5
GK
2599 d.prev_val[2] = "*x";
2600 output_escaped_param (&d, chain_prev, "chain_prev");
2601 oprintf (d.of, ");\n");
2602 oprintf (d.of, " if (xprev == NULL) break;\n");
2603 oprintf (d.of, " x = xprev;\n");
3d7aafde 2604 oprintf (d.of, " (void) %s (xprev",
17211ab5
GK
2605 wtd->marker_routine);
2606 if (wtd->param_prefix)
2607 {
2608 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2609 output_mangled_typename (d.of, orig_s);
2d82317d 2610 output_type_enum (d.of, orig_s);
17211ab5
GK
2611 }
2612 oprintf (d.of, ");\n");
2613 oprintf (d.of, " }\n");
36a5eadd 2614 }
623f8e39
JJ
2615 if (chain_circular != NULL)
2616 {
2617 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
2618 if (wtd->param_prefix)
2619 {
2620 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2621 output_mangled_typename (d.of, orig_s);
2622 output_type_enum (d.of, orig_s);
2623 }
2624 oprintf (d.of, "));\n");
2625 if (mark_hook_name && !wtd->skip_hooks)
2626 oprintf (d.of, " %s (xlimit);\n", mark_hook_name);
2627 oprintf (d.of, " do\n");
2628 }
2629 else
2630 oprintf (d.of, " while (x != xlimit)\n");
36a5eadd 2631 }
17211ab5 2632 oprintf (d.of, " {\n");
8d6419b2
BS
2633 if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2634 {
2635 oprintf (d.of, " %s (x);\n", mark_hook_name);
2636 }
17211ab5
GK
2637 d.prev_val[2] = "*x";
2638 d.indent = 6;
2639 walk_type (s, &d);
3d7aafde 2640
36a5eadd
GK
2641 if (chain_next != NULL)
2642 {
17211ab5
GK
2643 oprintf (d.of, " x = (");
2644 output_escaped_param (&d, chain_next, "chain_next");
2645 oprintf (d.of, ");\n");
36a5eadd
GK
2646 }
2647
17211ab5 2648 oprintf (d.of, " }\n");
623f8e39
JJ
2649 if (chain_circular != NULL)
2650 oprintf (d.of, " while (x != xlimit);\n");
17211ab5 2651 oprintf (d.of, "}\n");
e2500fed 2652}
9f313342
GK
2653
2654/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
e2500fed
GK
2655
2656static void
3d7aafde
AJ
2657write_types (type_p structures, type_p param_structs,
2658 const struct write_types_data *wtd)
e2500fed
GK
2659{
2660 type_p s;
3d7aafde 2661
17211ab5 2662 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
e2500fed
GK
2663 for (s = structures; s; s = s->next)
2664 if (s->gc_used == GC_POINTED_TO
2665 || s->gc_used == GC_MAYBE_POINTED_TO)
2666 {
2667 options_p opt;
3d7aafde 2668
e2500fed
GK
2669 if (s->gc_used == GC_MAYBE_POINTED_TO
2670 && s->u.s.line.file == NULL)
2671 continue;
2672
17211ab5 2673 oprintf (header_file, "#define gt_%s_", wtd->prefix);
36a5eadd
GK
2674 output_mangled_typename (header_file, s);
2675 oprintf (header_file, "(X) do { \\\n");
e03856fe 2676 oprintf (header_file,
3d7aafde 2677 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
17211ab5 2678 s->u.s.tag);
e03856fe 2679 oprintf (header_file,
e2500fed 2680 " } while (0)\n");
3d7aafde 2681
e2500fed
GK
2682 for (opt = s->u.s.opt; opt; opt = opt->next)
2683 if (strcmp (opt->name, "ptr_alias") == 0)
2684 {
e5cfc29f 2685 const_type_p const t = (const_type_p) opt->info;
3d7aafde 2686 if (t->kind == TYPE_STRUCT
e2500fed
GK
2687 || t->kind == TYPE_UNION
2688 || t->kind == TYPE_LANG_STRUCT)
e03856fe 2689 oprintf (header_file,
17211ab5
GK
2690 "#define gt_%sx_%s gt_%sx_%s\n",
2691 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
e2500fed 2692 else
3d7aafde 2693 error_at_line (&s->u.s.line,
e2500fed
GK
2694 "structure alias is not a structure");
2695 break;
2696 }
2697 if (opt)
2698 continue;
2699
2700 /* Declare the marker procedure only once. */
3d7aafde
AJ
2701 oprintf (header_file,
2702 "extern void gt_%sx_%s (void *);\n",
17211ab5 2703 wtd->prefix, s->u.s.tag);
3d7aafde 2704
e2500fed
GK
2705 if (s->u.s.line.file == NULL)
2706 {
3d7aafde 2707 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2708 s->u.s.tag);
2709 continue;
2710 }
3d7aafde 2711
e2500fed
GK
2712 if (s->kind == TYPE_LANG_STRUCT)
2713 {
2714 type_p ss;
2715 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
17211ab5 2716 write_func_for_structure (s, ss, NULL, wtd);
e2500fed
GK
2717 }
2718 else
17211ab5 2719 write_func_for_structure (s, s, NULL, wtd);
e2500fed
GK
2720 }
2721
2722 for (s = param_structs; s; s = s->next)
2723 if (s->gc_used == GC_POINTED_TO)
2724 {
36a5eadd 2725 type_p * param = s->u.param_struct.param;
e2500fed
GK
2726 type_p stru = s->u.param_struct.stru;
2727
e2500fed 2728 /* Declare the marker procedure. */
17211ab5 2729 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
36a5eadd 2730 output_mangled_typename (header_file, s);
3d7aafde
AJ
2731 oprintf (header_file, " (void *);\n");
2732
e2500fed
GK
2733 if (stru->u.s.line.file == NULL)
2734 {
3d7aafde 2735 fprintf (stderr, "warning: structure `%s' used but not defined\n",
e2500fed
GK
2736 s->u.s.tag);
2737 continue;
2738 }
3d7aafde 2739
e2500fed
GK
2740 if (stru->kind == TYPE_LANG_STRUCT)
2741 {
2742 type_p ss;
2743 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
17211ab5
GK
2744 write_func_for_structure (s, ss, param, wtd);
2745 }
2746 else
2747 write_func_for_structure (s, stru, param, wtd);
2748 }
2749}
2750
2751static const struct write_types_data ggc_wtd =
2752{
2753 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
8d6419b2
BS
2754 "GC marker procedures. ",
2755 FALSE
17211ab5
GK
2756};
2757
2758static const struct write_types_data pch_wtd =
2759{
2760 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2761 "gt_pch_note_reorder",
8d6419b2
BS
2762 "PCH type-walking procedures. ",
2763 TRUE
17211ab5
GK
2764};
2765
2766/* Write out the local pointer-walking routines. */
2767
2768/* process_field routine for local pointer-walking. */
2769
2770static void
3d7aafde 2771write_types_local_process_field (type_p f, const struct walk_type_data *d)
17211ab5
GK
2772{
2773 switch (f->kind)
2774 {
2775 case TYPE_POINTER:
2776 case TYPE_STRUCT:
2777 case TYPE_UNION:
2778 case TYPE_LANG_STRUCT:
2779 case TYPE_PARAM_STRUCT:
2780 case TYPE_STRING:
2781 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2782 d->prev_val[3]);
2783 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2784 break;
2785
2786 case TYPE_SCALAR:
2787 break;
3d7aafde 2788
17211ab5 2789 default:
b2d59f6f 2790 gcc_unreachable ();
17211ab5
GK
2791 }
2792}
2793
2794/* For S, a structure that's part of ORIG_S, and using parameters
2795 PARAM, write out a routine that:
2796 - Is of type gt_note_pointers
d8044160 2797 - Calls PROCESS_FIELD on each field of S or its substructures.
17211ab5
GK
2798*/
2799
2800static void
3d7aafde 2801write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
17211ab5
GK
2802{
2803 const char *fn = s->u.s.line.file;
2804 int i;
2805 struct walk_type_data d;
3d7aafde 2806
17211ab5
GK
2807 /* This is a hack, and not the good kind either. */
2808 for (i = NUM_PARAM - 1; i >= 0; i--)
3d7aafde 2809 if (param && param[i] && param[i]->kind == TYPE_POINTER
17211ab5
GK
2810 && UNION_OR_STRUCT_P (param[i]->u.p))
2811 fn = param[i]->u.p->u.s.line.file;
3d7aafde 2812
17211ab5
GK
2813 memset (&d, 0, sizeof (d));
2814 d.of = get_output_file_with_visibility (fn);
3d7aafde 2815
17211ab5
GK
2816 d.process_field = write_types_local_process_field;
2817 d.opt = s->u.s.opt;
2818 d.line = &s->u.s.line;
2819 d.bitmap = s->u.s.bitmap;
2820 d.param = param;
2821 d.prev_val[0] = d.prev_val[2] = "*x";
e0a21ab9 2822 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
17211ab5
GK
2823 d.prev_val[3] = "x";
2824 d.val = "(*x)";
d8044160 2825 d.fn_wants_lvalue = true;
17211ab5
GK
2826
2827 oprintf (d.of, "\n");
2828 oprintf (d.of, "void\n");
2829 oprintf (d.of, "gt_pch_p_");
2830 output_mangled_typename (d.of, orig_s);
e18476eb
BI
2831 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2832 "\tvoid *x_p,\n"
2833 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2834 "\tATTRIBUTE_UNUSED void *cookie)\n");
17211ab5
GK
2835 oprintf (d.of, "{\n");
2836 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2837 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2838 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2839 d.indent = 2;
2840 walk_type (s, &d);
2841 oprintf (d.of, "}\n");
2842}
2843
2844/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2845
2846static void
3d7aafde 2847write_local (type_p structures, type_p param_structs)
17211ab5
GK
2848{
2849 type_p s;
3d7aafde 2850
17211ab5
GK
2851 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2852 for (s = structures; s; s = s->next)
2853 if (s->gc_used == GC_POINTED_TO
2854 || s->gc_used == GC_MAYBE_POINTED_TO)
2855 {
2856 options_p opt;
3d7aafde 2857
17211ab5
GK
2858 if (s->u.s.line.file == NULL)
2859 continue;
2860
2861 for (opt = s->u.s.opt; opt; opt = opt->next)
2862 if (strcmp (opt->name, "ptr_alias") == 0)
2863 {
e5cfc29f 2864 const_type_p const t = (const_type_p) opt->info;
3d7aafde 2865 if (t->kind == TYPE_STRUCT
17211ab5
GK
2866 || t->kind == TYPE_UNION
2867 || t->kind == TYPE_LANG_STRUCT)
2868 {
2869 oprintf (header_file, "#define gt_pch_p_");
2870 output_mangled_typename (header_file, s);
2871 oprintf (header_file, " gt_pch_p_");
2872 output_mangled_typename (header_file, t);
2873 oprintf (header_file, "\n");
2874 }
2875 else
3d7aafde 2876 error_at_line (&s->u.s.line,
17211ab5
GK
2877 "structure alias is not a structure");
2878 break;
2879 }
2880 if (opt)
2881 continue;
2882
2883 /* Declare the marker procedure only once. */
2884 oprintf (header_file, "extern void gt_pch_p_");
2885 output_mangled_typename (header_file, s);
3d7aafde
AJ
2886 oprintf (header_file,
2887 "\n (void *, void *, gt_pointer_operator, void *);\n");
2888
17211ab5
GK
2889 if (s->kind == TYPE_LANG_STRUCT)
2890 {
2891 type_p ss;
2892 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2893 write_local_func_for_structure (s, ss, NULL);
2894 }
2895 else
2896 write_local_func_for_structure (s, s, NULL);
2897 }
2898
2899 for (s = param_structs; s; s = s->next)
2900 if (s->gc_used == GC_POINTED_TO)
2901 {
2902 type_p * param = s->u.param_struct.param;
2903 type_p stru = s->u.param_struct.stru;
2904
2905 /* Declare the marker procedure. */
2906 oprintf (header_file, "extern void gt_pch_p_");
2907 output_mangled_typename (header_file, s);
3d7aafde
AJ
2908 oprintf (header_file,
2909 "\n (void *, void *, gt_pointer_operator, void *);\n");
2910
17211ab5
GK
2911 if (stru->u.s.line.file == NULL)
2912 {
3d7aafde 2913 fprintf (stderr, "warning: structure `%s' used but not defined\n",
17211ab5
GK
2914 s->u.s.tag);
2915 continue;
2916 }
3d7aafde 2917
17211ab5
GK
2918 if (stru->kind == TYPE_LANG_STRUCT)
2919 {
2920 type_p ss;
2921 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2922 write_local_func_for_structure (s, ss, param);
e2500fed
GK
2923 }
2924 else
17211ab5 2925 write_local_func_for_structure (s, stru, param);
36a5eadd
GK
2926 }
2927}
2928
2929/* Write out the 'enum' definition for gt_types_enum. */
2930
2931static void
8c80adb7 2932write_enum_defn (type_p structures, type_p param_structs)
36a5eadd
GK
2933{
2934 type_p s;
3d7aafde 2935
36a5eadd
GK
2936 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2937 oprintf (header_file, "enum gt_types_enum {\n");
2938 for (s = structures; s; s = s->next)
2939 if (s->gc_used == GC_POINTED_TO
2940 || s->gc_used == GC_MAYBE_POINTED_TO)
2941 {
2942 if (s->gc_used == GC_MAYBE_POINTED_TO
2943 && s->u.s.line.file == NULL)
2944 continue;
2945
2946 oprintf (header_file, " gt_ggc_e_");
2947 output_mangled_typename (header_file, s);
2948 oprintf (header_file, ", \n");
e2500fed 2949 }
36a5eadd
GK
2950 for (s = param_structs; s; s = s->next)
2951 if (s->gc_used == GC_POINTED_TO)
2952 {
2953 oprintf (header_file, " gt_e_");
2954 output_mangled_typename (header_file, s);
2955 oprintf (header_file, ", \n");
2956 }
2957 oprintf (header_file, " gt_types_enum_last\n");
2958 oprintf (header_file, "};\n");
e2500fed
GK
2959}
2960
17211ab5
GK
2961/* Might T contain any non-pointer elements? */
2962
2963static int
3d7aafde 2964contains_scalar_p (type_p t)
17211ab5
GK
2965{
2966 switch (t->kind)
2967 {
2968 case TYPE_STRING:
2969 case TYPE_POINTER:
2970 return 0;
2971 case TYPE_ARRAY:
2972 return contains_scalar_p (t->u.a.p);
2973 default:
2974 /* Could also check for structures that have no non-pointer
2975 fields, but there aren't enough of those to worry about. */
2976 return 1;
2977 }
2978}
36a5eadd 2979
9f313342
GK
2980/* Mangle FN and print it to F. */
2981
e2500fed 2982static void
3d7aafde 2983put_mangled_filename (outf_p f, const char *fn)
e2500fed
GK
2984{
2985 const char *name = get_output_file_name (fn);
2986 for (; *name != 0; name++)
1f8e4682 2987 if (ISALNUM (*name))
e03856fe 2988 oprintf (f, "%c", *name);
e2500fed 2989 else
e03856fe 2990 oprintf (f, "%c", '_');
e2500fed
GK
2991}
2992
9f313342
GK
2993/* Finish off the currently-created root tables in FLP. PFX, TNAME,
2994 LASTNAME, and NAME are all strings to insert in various places in
2995 the resulting code. */
2996
e2500fed 2997static void
3d7aafde
AJ
2998finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2999 const char *tname, const char *name)
e2500fed
GK
3000{
3001 struct flist *fli2;
3d7aafde 3002
e2500fed
GK
3003 for (fli2 = flp; fli2; fli2 = fli2->next)
3004 if (fli2->started_p)
3005 {
e03856fe
GK
3006 oprintf (fli2->f, " %s\n", lastname);
3007 oprintf (fli2->f, "};\n\n");
e2500fed
GK
3008 }
3009
3010 for (fli2 = flp; fli2; fli2 = fli2->next)
3011 if (fli2->started_p)
3012 {
11a67599 3013 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3014 int fnum;
3015
3016 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3017 if (bitmap & 1)
3018 {
e03856fe 3019 oprintf (base_files[fnum],
17211ab5 3020 "extern const struct %s gt_%s_",
e2500fed
GK
3021 tname, pfx);
3022 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3023 oprintf (base_files[fnum], "[];\n");
e2500fed
GK
3024 }
3025 }
3d7aafde 3026
17211ab5
GK
3027 {
3028 size_t fnum;
11a67599 3029 for (fnum = 0; fnum < num_lang_dirs; fnum++)
17211ab5 3030 oprintf (base_files [fnum],
6bc7bc14 3031 "EXPORTED_CONST struct %s * const %s[] = {\n",
17211ab5
GK
3032 tname, name);
3033 }
3d7aafde 3034
e2500fed
GK
3035
3036 for (fli2 = flp; fli2; fli2 = fli2->next)
3037 if (fli2->started_p)
3038 {
11a67599 3039 lang_bitmap bitmap = get_lang_bitmap (fli2->name);
e2500fed
GK
3040 int fnum;
3041
3042 fli2->started_p = 0;
3043
3044 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3045 if (bitmap & 1)
3046 {
17211ab5 3047 oprintf (base_files[fnum], " gt_%s_", pfx);
e2500fed 3048 put_mangled_filename (base_files[fnum], fli2->name);
e03856fe 3049 oprintf (base_files[fnum], ",\n");
e2500fed
GK
3050 }
3051 }
3052
3053 {
17211ab5 3054 size_t fnum;
11a67599 3055 for (fnum = 0; fnum < num_lang_dirs; fnum++)
17211ab5
GK
3056 {
3057 oprintf (base_files[fnum], " NULL\n");
3058 oprintf (base_files[fnum], "};\n");
3059 }
e2500fed
GK
3060 }
3061}
3062
9f313342
GK
3063/* Write out to F the table entry and any marker routines needed to
3064 mark NAME as TYPE. The original variable is V, at LINE.
3065 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
3066 is nonzero iff we are building the root table for hash table caches. */
3067
e2500fed 3068static void
3d7aafde
AJ
3069write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3070 struct fileloc *line, const char *if_marked)
e2500fed
GK
3071{
3072 switch (type->kind)
3073 {
3074 case TYPE_STRUCT:
3075 {
3076 pair_p fld;
3077 for (fld = type->u.s.fields; fld; fld = fld->next)
3078 {
3079 int skip_p = 0;
3080 const char *desc = NULL;
3081 options_p o;
3d7aafde 3082
e2500fed
GK
3083 for (o = fld->opt; o; o = o->next)
3084 if (strcmp (o->name, "skip") == 0)
3085 skip_p = 1;
3086 else if (strcmp (o->name, "desc") == 0)
9e2878cf 3087 desc = o->info;
69c32ec8
JH
3088 else if (strcmp (o->name, "param_is") == 0)
3089 ;
e2500fed
GK
3090 else
3091 error_at_line (line,
3092 "field `%s' of global `%s' has unknown option `%s'",
3093 fld->name, name, o->name);
3d7aafde 3094
e2500fed
GK
3095 if (skip_p)
3096 continue;
3097 else if (desc && fld->type->kind == TYPE_UNION)
3098 {
3099 pair_p validf = NULL;
3100 pair_p ufld;
3d7aafde 3101
e2500fed
GK
3102 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3103 {
3104 const char *tag = NULL;
3105 options_p oo;
3d7aafde 3106
e2500fed
GK
3107 for (oo = ufld->opt; oo; oo = oo->next)
3108 if (strcmp (oo->name, "tag") == 0)
9e2878cf 3109 tag = oo->info;
e2500fed
GK
3110 if (tag == NULL || strcmp (tag, desc) != 0)
3111 continue;
3112 if (validf != NULL)
3d7aafde 3113 error_at_line (line,
e2500fed
GK
3114 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3115 name, fld->name, validf->name,
3116 name, fld->name, ufld->name,
3117 tag);
3118 validf = ufld;
3119 }
3120 if (validf != NULL)
3121 {
3122 char *newname;
3d7aafde 3123 newname = xasprintf ("%s.%s.%s",
e03856fe 3124 name, fld->name, validf->name);
17211ab5
GK
3125 write_root (f, v, validf->type, newname, 0, line,
3126 if_marked);
e2500fed
GK
3127 free (newname);
3128 }
3129 }
3130 else if (desc)
3d7aafde 3131 error_at_line (line,
e2500fed
GK
3132 "global `%s.%s' has `desc' option but is not union",
3133 name, fld->name);
3134 else
3135 {
3136 char *newname;
e03856fe 3137 newname = xasprintf ("%s.%s", name, fld->name);
17211ab5 3138 write_root (f, v, fld->type, newname, 0, line, if_marked);
e2500fed
GK
3139 free (newname);
3140 }
3141 }
3142 }
3143 break;
3144
3145 case TYPE_ARRAY:
3146 {
3147 char *newname;
e03856fe 3148 newname = xasprintf ("%s[0]", name);
17211ab5 3149 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
e2500fed
GK
3150 free (newname);
3151 }
3152 break;
3d7aafde 3153
e2500fed
GK
3154 case TYPE_POINTER:
3155 {
3156 type_p ap, tp;
3d7aafde 3157
e03856fe
GK
3158 oprintf (f, " {\n");
3159 oprintf (f, " &%s,\n", name);
3160 oprintf (f, " 1");
3d7aafde 3161
e2500fed
GK
3162 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3163 if (ap->u.a.len[0])
e03856fe 3164 oprintf (f, " * (%s)", ap->u.a.len);
e2500fed 3165 else if (ap == v->type)
62c71f4b 3166 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
e03856fe
GK
3167 oprintf (f, ",\n");
3168 oprintf (f, " sizeof (%s", v->name);
e2500fed 3169 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
e03856fe
GK
3170 oprintf (f, "[0]");
3171 oprintf (f, "),\n");
3d7aafde 3172
e2500fed 3173 tp = type->u.p;
3d7aafde 3174
e2500fed
GK
3175 if (! has_length && UNION_OR_STRUCT_P (tp))
3176 {
17211ab5
GK
3177 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
3178 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
e2500fed
GK
3179 }
3180 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3181 {
36a5eadd
GK
3182 oprintf (f, " &gt_ggc_m_");
3183 output_mangled_typename (f, tp);
17211ab5
GK
3184 oprintf (f, ",\n &gt_pch_n_");
3185 output_mangled_typename (f, tp);
e2500fed
GK
3186 }
3187 else if (has_length
afb0f770 3188 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
e2500fed 3189 {
17211ab5
GK
3190 oprintf (f, " &gt_ggc_ma_%s,\n", name);
3191 oprintf (f, " &gt_pch_na_%s", name);
e2500fed
GK
3192 }
3193 else
3194 {
3d7aafde 3195 error_at_line (line,
e2500fed
GK
3196 "global `%s' is pointer to unimplemented type",
3197 name);
3198 }
3199 if (if_marked)
e03856fe
GK
3200 oprintf (f, ",\n &%s", if_marked);
3201 oprintf (f, "\n },\n");
e2500fed
GK
3202 }
3203 break;
3204
e2500fed 3205 case TYPE_STRING:
17211ab5
GK
3206 {
3207 oprintf (f, " {\n");
3208 oprintf (f, " &%s,\n", name);
3209 oprintf (f, " 1, \n");
3210 oprintf (f, " sizeof (%s),\n", v->name);
dae4174e 3211 oprintf (f, " (gt_pointer_walker) &gt_ggc_m_S,\n");
f099d360 3212 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
17211ab5
GK
3213 oprintf (f, " },\n");
3214 }
3215 break;
3d7aafde 3216
17211ab5 3217 case TYPE_SCALAR:
e2500fed 3218 break;
3d7aafde 3219
e2500fed 3220 default:
3d7aafde 3221 error_at_line (line,
e2500fed
GK
3222 "global `%s' is unimplemented type",
3223 name);
3224 }
3225}
3226
17211ab5
GK
3227/* This generates a routine to walk an array. */
3228
3229static void
3d7aafde 3230write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
17211ab5
GK
3231{
3232 struct walk_type_data d;
3233 char *prevval3;
3d7aafde 3234
17211ab5
GK
3235 memset (&d, 0, sizeof (d));
3236 d.of = f;
3237 d.cookie = wtd;
3238 d.indent = 2;
3239 d.line = &v->line;
3240 d.opt = v->opt;
11a67599 3241 d.bitmap = get_lang_bitmap (v->line.file);
17211ab5
GK
3242 d.param = NULL;
3243
3244 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3245
3246 if (wtd->param_prefix)
3247 {
3248 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3d7aafde
AJ
3249 oprintf (f,
3250 " (void *, void *, gt_pointer_operator, void *);\n");
e18476eb 3251 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
17211ab5 3252 wtd->param_prefix, v->name);
e18476eb
BI
3253 oprintf (d.of,
3254 " ATTRIBUTE_UNUSED void *x_p,\n"
3255 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3256 " ATTRIBUTE_UNUSED void * cookie)\n");
17211ab5
GK
3257 oprintf (d.of, "{\n");
3258 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3259 d.process_field = write_types_local_process_field;
3260 walk_type (v->type, &d);
3261 oprintf (f, "}\n\n");
3262 }
3263
3264 d.opt = v->opt;
3d7aafde 3265 oprintf (f, "static void gt_%sa_%s (void *);\n",
17211ab5 3266 wtd->prefix, v->name);
e18476eb 3267 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
17211ab5 3268 wtd->prefix, v->name);
17211ab5
GK
3269 oprintf (f, "{\n");
3270 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3271 d.process_field = write_types_process_field;
3272 walk_type (v->type, &d);
3273 free (prevval3);
3274 oprintf (f, "}\n\n");
3275}
3276
9f313342
GK
3277/* Output a table describing the locations and types of VARIABLES. */
3278
e2500fed 3279static void
3d7aafde 3280write_roots (pair_p variables)
e2500fed
GK
3281{
3282 pair_p v;
3283 struct flist *flp = NULL;
3284
3285 for (v = variables; v; v = v->next)
3286 {
e03856fe 3287 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3288 struct flist *fli;
3289 const char *length = NULL;
3290 int deletable_p = 0;
3291 options_p o;
3292
3293 for (o = v->opt; o; o = o->next)
3294 if (strcmp (o->name, "length") == 0)
9e2878cf 3295 length = o->info;
e2500fed
GK
3296 else if (strcmp (o->name, "deletable") == 0)
3297 deletable_p = 1;
3298 else if (strcmp (o->name, "param_is") == 0)
3299 ;
3d7aafde 3300 else if (strncmp (o->name, "param", 5) == 0
36a5eadd
GK
3301 && ISDIGIT (o->name[5])
3302 && strcmp (o->name + 6, "_is") == 0)
3303 ;
e2500fed
GK
3304 else if (strcmp (o->name, "if_marked") == 0)
3305 ;
3306 else
3d7aafde 3307 error_at_line (&v->line,
e2500fed
GK
3308 "global `%s' has unknown option `%s'",
3309 v->name, o->name);
3310
3311 for (fli = flp; fli; fli = fli->next)
3312 if (fli->f == f)
3313 break;
3314 if (fli == NULL)
3315 {
5d038c4c 3316 fli = XNEW (struct flist);
e2500fed
GK
3317 fli->f = f;
3318 fli->next = flp;
3319 fli->started_p = 0;
3320 fli->name = v->line.file;
3321 flp = fli;
3322
e03856fe 3323 oprintf (f, "\n/* GC roots. */\n\n");
e2500fed
GK
3324 }
3325
3326 if (! deletable_p
3327 && length
3328 && v->type->kind == TYPE_POINTER
3329 && (v->type->u.p->kind == TYPE_POINTER
3330 || v->type->u.p->kind == TYPE_STRUCT))
3331 {
17211ab5
GK
3332 write_array (f, v, &ggc_wtd);
3333 write_array (f, v, &pch_wtd);
e2500fed
GK
3334 }
3335 }
3336
3337 for (v = variables; v; v = v->next)
3338 {
e03856fe 3339 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3340 struct flist *fli;
3341 int skip_p = 0;
3342 int length_p = 0;
3343 options_p o;
3d7aafde 3344
e2500fed
GK
3345 for (o = v->opt; o; o = o->next)
3346 if (strcmp (o->name, "length") == 0)
3347 length_p = 1;
3348 else if (strcmp (o->name, "deletable") == 0
3349 || strcmp (o->name, "if_marked") == 0)
3350 skip_p = 1;
3351
3352 if (skip_p)
3353 continue;
3354
3355 for (fli = flp; fli; fli = fli->next)
3356 if (fli->f == f)
3357 break;
3358 if (! fli->started_p)
3359 {
3360 fli->started_p = 1;
3361
6bc7bc14 3362 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
e2500fed 3363 put_mangled_filename (f, v->line.file);
e03856fe 3364 oprintf (f, "[] = {\n");
e2500fed
GK
3365 }
3366
17211ab5 3367 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
e2500fed
GK
3368 }
3369
3d7aafde 3370 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3371 "gt_ggc_rtab");
3372
3373 for (v = variables; v; v = v->next)
3374 {
e03856fe 3375 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3376 struct flist *fli;
3377 int skip_p = 1;
3378 options_p o;
3379
3380 for (o = v->opt; o; o = o->next)
3381 if (strcmp (o->name, "deletable") == 0)
3382 skip_p = 0;
3383 else if (strcmp (o->name, "if_marked") == 0)
3384 skip_p = 1;
3385
3386 if (skip_p)
3387 continue;
3388
3389 for (fli = flp; fli; fli = fli->next)
3390 if (fli->f == f)
3391 break;
3392 if (! fli->started_p)
3393 {
3394 fli->started_p = 1;
3395
6bc7bc14 3396 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
e2500fed 3397 put_mangled_filename (f, v->line.file);
e03856fe 3398 oprintf (f, "[] = {\n");
e2500fed 3399 }
3d7aafde 3400
17211ab5 3401 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
e2500fed
GK
3402 v->name, v->name);
3403 }
3d7aafde 3404
17211ab5 3405 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
e2500fed
GK
3406 "gt_ggc_deletable_rtab");
3407
3408 for (v = variables; v; v = v->next)
3409 {
e03856fe 3410 outf_p f = get_output_file_with_visibility (v->line.file);
e2500fed
GK
3411 struct flist *fli;
3412 const char *if_marked = NULL;
3413 int length_p = 0;
3414 options_p o;
3d7aafde 3415
e2500fed
GK
3416 for (o = v->opt; o; o = o->next)
3417 if (strcmp (o->name, "length") == 0)
3418 length_p = 1;
3419 else if (strcmp (o->name, "if_marked") == 0)
9e2878cf 3420 if_marked = o->info;
e2500fed
GK
3421
3422 if (if_marked == NULL)
3423 continue;
3424
3425 if (v->type->kind != TYPE_POINTER
3426 || v->type->u.p->kind != TYPE_PARAM_STRUCT
3427 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3428 {
3429 error_at_line (&v->line, "if_marked option used but not hash table");
3430 continue;
3431 }
3432
3433 for (fli = flp; fli; fli = fli->next)
3434 if (fli->f == f)
3435 break;
3436 if (! fli->started_p)
3437 {
3438 fli->started_p = 1;
3439
6bc7bc14 3440 oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
e2500fed 3441 put_mangled_filename (f, v->line.file);
e03856fe 3442 oprintf (f, "[] = {\n");
e2500fed 3443 }
3d7aafde 3444
17211ab5 3445 write_root (f, v, v->type->u.p->u.param_struct.param[0],
e2500fed
GK
3446 v->name, length_p, &v->line, if_marked);
3447 }
3d7aafde 3448
17211ab5 3449 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
e2500fed 3450 "gt_ggc_cache_rtab");
17211ab5
GK
3451
3452 for (v = variables; v; v = v->next)
3453 {
3454 outf_p f = get_output_file_with_visibility (v->line.file);
3455 struct flist *fli;
3456 int length_p = 0;
3457 int if_marked_p = 0;
3458 options_p o;
3d7aafde 3459
17211ab5
GK
3460 for (o = v->opt; o; o = o->next)
3461 if (strcmp (o->name, "length") == 0)
3462 length_p = 1;
3463 else if (strcmp (o->name, "if_marked") == 0)
3464 if_marked_p = 1;
3465
3466 if (! if_marked_p)
3467 continue;
3468
3469 for (fli = flp; fli; fli = fli->next)
3470 if (fli->f == f)
3471 break;
3472 if (! fli->started_p)
3473 {
3474 fli->started_p = 1;
3475
6bc7bc14 3476 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
17211ab5
GK
3477 put_mangled_filename (f, v->line.file);
3478 oprintf (f, "[] = {\n");
3479 }
3480
3481 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3482 }
3d7aafde 3483
17211ab5
GK
3484 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3485 "gt_pch_cache_rtab");
3486
3487 for (v = variables; v; v = v->next)
3488 {
3489 outf_p f = get_output_file_with_visibility (v->line.file);
3490 struct flist *fli;
3491 int skip_p = 0;
3492 options_p o;
3493
3494 for (o = v->opt; o; o = o->next)
3495 if (strcmp (o->name, "deletable") == 0
3496 || strcmp (o->name, "if_marked") == 0)
3497 skip_p = 1;
3498
3499 if (skip_p)
3500 continue;
3501
3502 if (! contains_scalar_p (v->type))
3503 continue;
3504
3505 for (fli = flp; fli; fli = fli->next)
3506 if (fli->f == f)
3507 break;
3508 if (! fli->started_p)
3509 {
3510 fli->started_p = 1;
3511
6bc7bc14 3512 oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
17211ab5
GK
3513 put_mangled_filename (f, v->line.file);
3514 oprintf (f, "[] = {\n");
3515 }
3d7aafde 3516
17211ab5
GK
3517 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
3518 v->name, v->name);
3519 }
3d7aafde 3520
17211ab5
GK
3521 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3522 "gt_pch_scalar_rtab");
e2500fed
GK
3523}
3524
4a399aef
ZW
3525/* Record the definition of a generic VEC structure, as if we had expanded
3526 the macros in vec.h:
3527
3528 typedef struct VEC_<type>_base GTY(()) {
3529 unsigned num;
3530 unsigned alloc;
3531 <type> GTY((length ("%h.num"))) vec[1];
3532 } VEC_<type>_base
3533
3534 where the GTY(()) tags are only present if is_scalar is _false_. */
3535
3536void
8ad97cfc 3537note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
4a399aef 3538{
065ae611 3539 pair_p fields;
4a399aef
ZW
3540 type_p t;
3541 options_p o;
065ae611 3542 type_p len_ty = create_scalar_type ("unsigned");
8ad97cfc 3543 const char *name = concat ("VEC_", type_name, "_base", (char *)0);
4a399aef
ZW
3544
3545 if (is_scalar)
3546 {
8ad97cfc 3547 t = create_scalar_type (type_name);
4a399aef
ZW
3548 o = 0;
3549 }
3550 else
3551 {
8ad97cfc 3552 t = resolve_typedef (type_name, pos);
4a399aef
ZW
3553 o = create_option (0, "length", "%h.num");
3554 }
3555
3556 /* We assemble the field list in reverse order. */
065ae611
ZW
3557 fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3558 fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3559 fields = create_field_at (fields, len_ty, "num", 0, pos);
4a399aef
ZW
3560
3561 do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3562}
3563
3564/* Record the definition of an allocation-specific VEC structure, as if
3565 we had expanded the macros in vec.h:
3566
3567 typedef struct VEC_<type>_<astrat> {
3568 VEC_<type>_base base;
3569 } VEC_<type>_<astrat>;
3570*/
3571void
3572note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3573{
3574 const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3575 const char *basename = concat ("VEC_", type, "_base", (char *)0);
3576
065ae611
ZW
3577 pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3578 "base", 0, pos);
4a399aef
ZW
3579
3580 do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3581}
3582
e2500fed 3583\f
3d7aafde 3584int
11a67599 3585main (int argc, char **argv)
e2500fed 3586{
11a67599 3587 size_t i;
01d419ae 3588 static struct fileloc pos = { this_file, 0 };
3d7aafde 3589
11a67599
ZW
3590 /* fatal uses this */
3591 progname = "gengtype";
3592
3593 if (argc != 3)
3594 fatal ("usage: gengtype srcdir input-list");
3595
3596 srcdir = argv[1];
8ac9d31f 3597 srcdir_len = strlen (srcdir);
e2500fed 3598
11a67599
ZW
3599 read_input_list (argv[2]);
3600 if (hit_error)
3601 return 1;
3602
95161faf
ZW
3603 scalar_char.u.scalar_is_char = true;
3604 scalar_nonchar.u.scalar_is_char = false;
95161faf
ZW
3605 gen_rtx_next ();
3606
01d419ae
ZW
3607 /* These types are set up with #define or else outside of where
3608 we can see them. */
3609 pos.line = __LINE__ + 1;
3610 do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3611 do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
1e1ba002 3612 do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
01d419ae
ZW
3613 do_scalar_typedef ("double_int", &pos); pos.line++;
3614 do_scalar_typedef ("uint8", &pos); pos.line++;
3615 do_scalar_typedef ("jword", &pos); pos.line++;
3616 do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3617 do_scalar_typedef ("void", &pos); pos.line++;
a813c111 3618 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
ed8d2920 3619
11a67599 3620 for (i = 0; i < num_gt_files; i++)
01d419ae 3621 parse_file (gt_files[i]);
e2500fed 3622
01d419ae 3623 if (hit_error)
065ae611 3624 return 1;
e2500fed
GK
3625
3626 set_gc_used (variables);
3627
3628 open_base_files ();
36a5eadd 3629 write_enum_defn (structures, param_structs);
17211ab5
GK
3630 write_types (structures, param_structs, &ggc_wtd);
3631 write_types (structures, param_structs, &pch_wtd);
3632 write_local (structures, param_structs);
3633 write_roots (variables);
36a5eadd 3634 write_rtx_next ();
e2500fed
GK
3635 close_output_files ();
3636
01d419ae
ZW
3637 if (hit_error)
3638 return 1;
3639 return 0;
e2500fed 3640}