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