OSDN Git Service

* gengtype.c: Don't include gtyp-gen.h.
[pf3gnuchains/gcc-fork.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21
22 #include "bconfig.h"
23 #include "system.h"
24 #include "gengtype.h"
25 #include "errors.h"     /* for fatal */
26
27 /* Data types, macros, etc. used only in this file.  */
28
29 /* Kinds of types we can understand.  */
30 enum 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
41 typedef unsigned lang_bitmap;
42
43 /* A way to pass data through to the output end.  */
44 struct options
45 {
46   struct options *next;
47   const char *name;
48   const char *info;
49 };
50
51 /* Option data for the 'nested_ptr' option.  */
52 struct 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.  */
60 struct 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.  */
72 enum gc_used_enum
73   {
74     GC_UNUSED = 0,
75     GC_USED,
76     GC_MAYBE_POINTED_TO,
77     GC_POINTED_TO
78   };
79
80 struct 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.  */
119 struct outf
120 {
121   struct outf *next;
122   const char *name;
123   size_t buflength;
124   size_t bufused;
125   char *buf;
126 };
127 typedef 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.  */
132 extern outf_p get_output_file_with_visibility
133    (const char *input_file);
134 const char *get_output_file_name (const char *);
135
136 /* Print, like fprintf, to O.  */
137 static void oprintf (outf_p o, const char *S, ...)
138      ATTRIBUTE_PRINTF_2;
139
140 /* The list of output files.  */
141 static outf_p output_files;
142
143 /* The output header file that is included into pretty much every
144    source file.  */
145 static outf_p header_file;
146
147 /* Source directory.  */
148 static const char *srcdir;
149
150 /* Length of srcdir name.  */
151 static int srcdir_len = 0;
152
153 static outf_p create_file (const char *, const char *);
154 static const char * get_file_basename (const char *);
155
156 \f
157 /* Nonzero iff an error has occurred.  */
158 static int hit_error = 0;
159
160 static void gen_rtx_next (void);
161 static void write_rtx_next (void);
162 static void open_base_files (void);
163 static void close_output_files (void);
164
165 /* Report an error at POS, printing MSG.  */
166
167 void
168 error_at_line (struct fileloc *pos, const char *msg, ...)
169 {
170   va_list ap;
171
172   va_start (ap, msg);
173
174   fprintf (stderr, "%s:%d: ", pos->file, pos->line);
175   vfprintf (stderr, msg, ap);
176   fputc ('\n', stderr);
177   hit_error = 1;
178
179   va_end (ap);
180 }
181
182 /* asprintf, but produces fatal message on out-of-memory.  */
183 static char * ATTRIBUTE_PRINTF_1
184 xasprintf (const char *format, ...)
185 {
186   int n;
187   char *result;
188   va_list ap;
189
190   va_start (ap, format);
191   n = vasprintf (&result, format, ap);
192   if (result == NULL || n < 0)
193     fatal ("out of memory");
194   va_end (ap);
195
196   return result;
197 }
198 \f
199 /* Input file handling. */
200
201 /* Table of all input files.  */
202 static const char **gt_files;
203 static size_t num_gt_files;
204
205 /* Vector of per-language directories.  */
206 static const char **lang_dir_names;
207 static 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.  */
211 static 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.  */
224
225 static lang_bitmap
226 get_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.  */
237 static void
238 set_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.  */
252 static size_t
253 measure_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.  */
291 static bool
292 read_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.  */
356 static void
357 read_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
477 /* The one and only TYPE_STRING.  */
478
479 static 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
486 static struct type scalar_nonchar = {
487   TYPE_SCALAR, 0, 0, GC_USED, {0}
488 };
489 static struct type scalar_char = {
490   TYPE_SCALAR, 0, 0, GC_USED, {0}
491 };
492
493 /* Lists of various things.  */
494
495 static pair_p typedefs;
496 static type_p structures;
497 static type_p param_structs;
498 static pair_p variables;
499
500 static type_p find_param_structure
501   (type_p t, type_p param[NUM_PARAM]);
502 static type_p adjust_field_tree_exp (type_p t, options_p opt);
503 static type_p adjust_field_rtx_def (type_p t, options_p opt);
504
505 /* Define S as a typedef to T at POS.  */
506
507 void
508 do_typedef (const char *s, type_p t, struct fileloc *pos)
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
523   p = XNEW (struct pair);
524   p->next = typedefs;
525   p->name = s;
526   p->type = t;
527   p->line = *pos;
528   typedefs = p;
529 }
530
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).  */
534
535 void
536 do_scalar_typedef (const char *s, struct fileloc *pos)
537 {
538   do_typedef (s, &scalar_nonchar, pos);
539 }
540
541 /* Return the type previously defined for S.  Use POS to report errors.  */
542
543 type_p
544 resolve_typedef (const char *s, struct fileloc *pos)
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);
551   return &scalar_nonchar;  /* treat as "int" */
552 }
553
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.  */
556
557 type_p
558 new_structure (const char *name, int isunion, struct fileloc *pos,
559                pair_p fields, options_p o)
560 {
561   type_p si;
562   type_p s = NULL;
563   lang_bitmap bitmap = get_lang_bitmap (pos->file);
564
565   for (si = structures; si != NULL; si = si->next)
566     if (strcmp (name, si->u.s.tag) == 0
567         && UNION_P (si) == isunion)
568       {
569         type_p ls = NULL;
570         if (si->kind == TYPE_LANG_STRUCT)
571           {
572             ls = si;
573
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;
581             si = XCNEW (struct type);
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           {
595             s = XCNEW (struct type);
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       }
602
603   if (s == NULL)
604     {
605       s = XCNEW (struct type);
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;
625
626   return s;
627 }
628
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
633 type_p
634 find_structure (const char *name, int isunion)
635 {
636   type_p s;
637
638   for (s = structures; s != NULL; s = s->next)
639     if (strcmp (name, s->u.s.tag) == 0
640         && UNION_P (s) == isunion)
641       return s;
642
643   s = XCNEW (struct type);
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
652 /* Return the previously-defined parameterized structure for structure
653    T and parameters PARAM, or a new parameterized empty structure or
654    union if none was defined previously.  */
655
656 static type_p
657 find_param_structure (type_p t, type_p param[NUM_PARAM])
658 {
659   type_p res;
660
661   for (res = param_structs; res; res = res->next)
662     if (res->u.param_struct.stru == t
663         && memcmp (res->u.param_struct.param, param,
664                    sizeof (type_p) * NUM_PARAM) == 0)
665       break;
666   if (res == NULL)
667     {
668       res = XCNEW (struct type);
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
678 /* Return a scalar type with name NAME.  */
679
680 type_p
681 create_scalar_type (const char *name)
682 {
683   if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
684     return &scalar_char;
685   else
686     return &scalar_nonchar;
687 }
688
689 /* Return a pointer to T.  */
690
691 type_p
692 create_pointer (type_p t)
693 {
694   if (! t->pointer_to)
695     {
696       type_p r = XCNEW (struct type);
697       r->kind = TYPE_POINTER;
698       r->u.p = t;
699       t->pointer_to = r;
700     }
701   return t->pointer_to;
702 }
703
704 /* Return an array of length LEN.  */
705
706 type_p
707 create_array (type_p t, const char *len)
708 {
709   type_p v;
710
711   v = XCNEW (struct type);
712   v->kind = TYPE_ARRAY;
713   v->u.a.p = t;
714   v->u.a.len = len;
715   return v;
716 }
717
718 /* Return an options structure with name NAME and info INFO.  NEXT is the
719    next option in the chain.  */
720
721 options_p
722 create_option (options_p next, const char *name, const void *info)
723 {
724   options_p o = XNEW (struct options);
725   o->next = next;
726   o->name = name;
727   o->info = (const char*) info;
728   return o;
729 }
730
731 /* Return an options structure for a "nested_ptr" option.  */
732 options_p
733 create_nested_ptr_option (options_p next, type_p t,
734                           const char *to, const char *from)
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;
741   return create_option (next, "nested_ptr", d);
742 }
743
744 /* Add a variable named S of type T with options O defined at POS,
745    to `variables'.  */
746
747 void
748 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
749 {
750   pair_p n;
751   n = XNEW (struct pair);
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
760 /* Most-general structure field creator.  */
761 static pair_p
762 create_field_all (pair_p next, type_p type, const char *name, options_p opt,
763                   const char *file, int line)
764 {
765   pair_p field;
766
767   field = XNEW (struct pair);
768   field->next = next;
769   field->type = type;
770   field->name = name;
771   field->opt = opt;
772   field->line.file = file;
773   field->line.line = line;
774   return field;
775 }
776
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.  */
780 pair_p
781 create_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
793 /* Like create_field, but the field is only valid when condition COND
794    is true.  */
795
796 static pair_p
797 create_optional_field_ (pair_p next, type_p type, const char *name,
798                         const char *cond, int line)
799 {
800   static int id = 1;
801   pair_p union_fields;
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.  */
815   return create_field_all (next, union_type, name,
816                            create_option (0, "desc", cond),
817                            __FILE__, line);
818 }
819 #define create_optional_field(next,type,name,cond)      \
820        create_optional_field_(next,type,name,cond,__LINE__)
821
822 /* We don't care how long a CONST_DOUBLE is.  */
823 #define CONST_DOUBLE_FORMAT "ww"
824 /* We don't want to see codes that are only for generator files.  */
825 #undef GENERATOR_FILE
826
827 enum 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
834 static 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
840 static const char * const rtx_format[NUM_RTX_CODE] = {
841 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
842 #include "rtl.def"
843 #undef DEF_RTL_EXPR
844 };
845
846 static int rtx_next_new[NUM_RTX_CODE];
847
848 /* We also need codes and names for insn notes (not register notes).
849    Note that we do *not* bias the note values here.  */
850 enum 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
858 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
859    default field for line number notes.  */
860 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
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
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
872 static void
873 gen_rtx_next (void)
874 {
875   int i;
876   for (i = 0; i < NUM_RTX_CODE; i++)
877     {
878       int k;
879
880       rtx_next_new[i] = -1;
881       if (strncmp (rtx_format[i], "iuu", 3) == 0)
882         rtx_next_new[i] = 2;
883       else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
884         rtx_next_new[i] = 1;
885       else
886         for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
887           if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
888             rtx_next_new[i] = k;
889     }
890 }
891
892 /* Write out the contents of the rtx_next array.  */
893 static void
894 write_rtx_next (void)
895 {
896   outf_p f = get_output_file_with_visibility (NULL);
897   int i;
898
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++)
902     if (rtx_next_new[i] == -1)
903       oprintf (f, "  0,\n");
904     else
905       oprintf (f,
906                "  RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
907                rtx_next_new[i]);
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
915 static type_p
916 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
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;
922   type_p bitmap_tp, basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
923
924   if (t->kind != TYPE_UNION)
925     {
926       error_at_line (&lexer_line,
927                      "special `rtx_def' must be applied to a union");
928       return &string_type;
929     }
930
931   nodot = create_option (NULL, "dot", "");
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));
937   reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
938   bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
939   basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
940   constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
941   scalar_tp = &scalar_nonchar;  /* rtunion int */
942
943   {
944     pair_p note_flds = NULL;
945     int c;
946
947     for (c = 0; c <= NOTE_INSN_MAX; c++)
948       {
949         switch (c)
950           {
951           case NOTE_INSN_MAX:
952             note_flds = create_field (note_flds, &string_type, "rt_str");
953             break;
954
955           case NOTE_INSN_BLOCK_BEG:
956           case NOTE_INSN_BLOCK_END:
957             note_flds = create_field (note_flds, tree_tp, "rt_tree");
958             break;
959
960           case NOTE_INSN_VAR_LOCATION:
961             note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
962             break;
963
964           default:
965             note_flds = create_field (note_flds, scalar_tp, "rt_int");
966             break;
967           }
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]);
974       }
975     note_union_tp = new_structure ("rtx_def_note_subunion", 1,
976                                    &lexer_line, note_flds, NULL);
977   }
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   }
991   for (i = 0; i < NUM_RTX_CODE; i++)
992     {
993       pair_p subfields = NULL;
994       size_t aindex, nmindex;
995       const char *sname;
996       type_p substruct;
997       char *ftag;
998
999       for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1000         {
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;
1011               subname = "rt_int";
1012               break;
1013
1014             case '0':
1015               if (i == MEM && aindex == 1)
1016                 t = mem_attrs_tp, subname = "rt_mem";
1017               else if (i == JUMP_INSN && aindex == 9)
1018                 t = rtx_tp, subname = "rt_rtx";
1019               else if (i == CODE_LABEL && aindex == 4)
1020                 t = scalar_tp, subname = "rt_int";
1021               else if (i == CODE_LABEL && aindex == 5)
1022                 t = rtx_tp, subname = "rt_rtx";
1023               else if (i == LABEL_REF
1024                        && (aindex == 1 || aindex == 2))
1025                 t = rtx_tp, subname = "rt_rtx";
1026               else if (i == NOTE && aindex == 4)
1027                 t = note_union_tp, subname = "";
1028               else if (i == NOTE && aindex >= 7)
1029                 t = scalar_tp, subname = "rt_int";
1030               else if (i == ADDR_DIFF_VEC && aindex == 4)
1031                 t = scalar_tp, subname = "rt_int";
1032               else if (i == VALUE && aindex == 0)
1033                 t = scalar_tp, subname = "rt_int";
1034               else if (i == REG && aindex == 1)
1035                 t = scalar_tp, subname = "rt_int";
1036               else if (i == REG && aindex == 2)
1037                 t = reg_attrs_tp, subname = "rt_reg";
1038               else if (i == SCRATCH && aindex == 0)
1039                 t = scalar_tp, subname = "rt_int";
1040               else if (i == SYMBOL_REF && aindex == 1)
1041                 t = scalar_tp, subname = "rt_int";
1042               else if (i == SYMBOL_REF && aindex == 2)
1043                 t = symbol_union_tp, subname = "";
1044               else if (i == BARRIER && aindex >= 3)
1045                 t = scalar_tp, subname = "rt_int";
1046               else
1047                 {
1048                   error_at_line (&lexer_line,
1049                         "rtx type `%s' has `0' in position %lu, can't handle",
1050                                  rtx_name[i], (unsigned long) aindex);
1051                   t = &string_type;
1052                   subname = "rt_int";
1053                 }
1054               break;
1055
1056             case 's':
1057             case 'S':
1058             case 'T':
1059               t = &string_type;
1060               subname = "rt_str";
1061               break;
1062
1063             case 'e':
1064             case 'u':
1065               t = rtx_tp;
1066               subname = "rt_rtx";
1067               break;
1068
1069             case 'E':
1070             case 'V':
1071               t = rtvec_tp;
1072               subname = "rt_rtvec";
1073               break;
1074
1075             case 't':
1076               t = tree_tp;
1077               subname = "rt_tree";
1078               break;
1079
1080             case 'b':
1081               t = bitmap_tp;
1082               subname = "rt_bit";
1083               break;
1084
1085             case 'B':
1086               t = basic_block_tp;
1087               subname = "rt_bb";
1088               break;
1089
1090             default:
1091               error_at_line (&lexer_line,
1092                      "rtx type `%s' has `%c' in position %lu, can't handle",
1093                              rtx_name[i], rtx_format[i][aindex],
1094                              (unsigned long)aindex);
1095               t = &string_type;
1096               subname = "rt_int";
1097               break;
1098             }
1099
1100           subfields = create_field (subfields, t,
1101                                     xasprintf (".fld[%lu].%s",
1102                                                (unsigned long) aindex,
1103                                                subname));
1104           subfields->opt = nodot;
1105           if (t == note_union_tp)
1106             subfields->opt = create_option (subfields->opt, "desc",
1107                                             "NOTE_LINE_NUMBER (&%0)");
1108           if (t == symbol_union_tp)
1109             subfields->opt = create_option (subfields->opt, "desc",
1110                                             "CONSTANT_POOL_ADDRESS_P (&%0)");
1111         }
1112
1113       if (i == SYMBOL_REF)
1114         {
1115           /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds.  */
1116           type_p field_tp = find_structure ("block_symbol", 0);
1117           subfields
1118             = create_optional_field (subfields, field_tp, "block_sym",
1119                                      "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
1120         }
1121
1122       sname = xasprintf ("rtx_def_%s", rtx_name[i]);
1123       substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1124
1125       ftag = xstrdup (rtx_name[i]);
1126       for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1127         ftag[nmindex] = TOUPPER (ftag[nmindex]);
1128
1129       flds = create_field (flds, substruct, "");
1130       flds->opt = create_option (nodot, "tag", ftag);
1131     }
1132
1133   return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
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
1138    pointers to trees, actually sometimes contains pointers to RTL too.
1139    Passed T, the old type of the field, and OPT its options.  Returns
1140    a new type for the field.  */
1141
1142 static type_p
1143 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
1144 {
1145   pair_p flds;
1146   options_p nodot;
1147
1148   if (t->kind != TYPE_ARRAY)
1149     {
1150       error_at_line (&lexer_line,
1151                      "special `tree_exp' must be applied to an array");
1152       return &string_type;
1153     }
1154
1155   nodot = create_option (NULL, "dot", "");
1156
1157   flds = create_field (NULL, t, "");
1158   flds->opt = create_option (nodot, "length",
1159                              "TREE_OPERAND_LENGTH ((tree) &%0)");
1160   flds->opt = create_option (flds->opt, "default", "");
1161
1162   return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
1163 }
1164
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
1171      TYPE_PARAM_STRUCT;
1172    - Handles "special" options.
1173 */
1174
1175 type_p
1176 adjust_field_type (type_p t, options_p opt)
1177 {
1178   int length_p = 0;
1179   const int pointer_p = t->kind == TYPE_POINTER;
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;
1186
1187   for (; opt; opt = opt->next)
1188     if (strcmp (opt->name, "length") == 0)
1189       length_p = 1;
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))
1194       {
1195         int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
1196
1197         if (! UNION_OR_STRUCT_P (t)
1198             && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1199           {
1200             error_at_line (&lexer_line,
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;
1213       }
1214     else if (strcmp (opt->name, "special") == 0)
1215       {
1216         const char *special_name = opt->info;
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;
1228
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
1235   if (! length_p
1236       && pointer_p
1237       && t->u.p->kind == TYPE_SCALAR
1238       && t->u.p->u.scalar_is_char)
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
1242       && t->u.a.p->u.p->u.scalar_is_char)
1243     return create_array (&string_type, t->u.a.len);
1244
1245   return t;
1246 }
1247
1248 \f
1249 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1250 static void set_gc_used (pair_p);
1251
1252 /* Handle OPT for set_gc_used_type.  */
1253
1254 static void
1255 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
1256                     int *pass_param, int *length, int *skip, type_p *nested_ptr)
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)
1261       set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
1262     else if (strcmp (o->name, "maybe_undef") == 0)
1263       *maybe_undef = 1;
1264     else if (strcmp (o->name, "use_params") == 0)
1265       *pass_param = 1;
1266     else if (strcmp (o->name, "length") == 0)
1267       *length = 1;
1268     else if (strcmp (o->name, "skip") == 0)
1269       *skip = 1;
1270     else if (strcmp (o->name, "nested_ptr") == 0)
1271       *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
1272 }
1273
1274 /* Set the gc_used field of T to LEVEL, and handle the types it references.  */
1275
1276 static void
1277 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
1278 {
1279   if (t->gc_used >= level)
1280     return;
1281
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;
1291         type_p dummy2;
1292
1293         process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
1294                             &dummy2);
1295
1296         for (f = t->u.s.fields; f; f = f->next)
1297           {
1298             int maybe_undef = 0;
1299             int pass_param = 0;
1300             int length = 0;
1301             int skip = 0;
1302             type_p nested_ptr = NULL;
1303             process_gc_options (f->opt, level, &maybe_undef, &pass_param,
1304                                 &length, &skip, &nested_ptr);
1305
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)
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);
1316             else if (skip)
1317               ; /* target type is not used through this field */
1318             else
1319               set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
1320           }
1321         break;
1322       }
1323
1324     case TYPE_POINTER:
1325       set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
1326       break;
1327
1328     case TYPE_ARRAY:
1329       set_gc_used_type (t->u.a.p, GC_USED, param);
1330       break;
1331
1332     case TYPE_LANG_STRUCT:
1333       for (t = t->u.s.lang_struct; t; t = t->next)
1334         set_gc_used_type (t, level, param);
1335       break;
1336
1337     case TYPE_PARAM_STRUCT:
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;
1349       set_gc_used_type (t->u.param_struct.stru, level,
1350                         t->u.param_struct.param);
1351       break;
1352
1353     default:
1354       break;
1355     }
1356 }
1357
1358 /* Set the gc_used fields of all the types pointed to by VARIABLES.  */
1359
1360 static void
1361 set_gc_used (pair_p variables)
1362 {
1363   pair_p p;
1364   for (p = variables; p; p = p->next)
1365     set_gc_used_type (p->type, GC_USED, NULL);
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
1372 /* Output file handling.  */
1373
1374 /* Create and return an outf_p for a new file for NAME, to be called
1375    ONAME.  */
1376
1377 static outf_p
1378 create_file (const char *name, const char *oname)
1379 {
1380   static const char *const hdr[] = {
1381     "   Copyright (C) 2004 Free Software Foundation, Inc.\n",
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",
1397     "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1398     "02110-1301, USA.  */\n",
1399     "\n",
1400     "/* This file is machine generated.  Do not edit.  */\n"
1401   };
1402   outf_p f;
1403   size_t i;
1404
1405   f = XCNEW (struct outf);
1406   f->next = output_files;
1407   f->name = oname;
1408   output_files = f;
1409
1410   oprintf (f, "/* Type information for %s.\n", name);
1411   for (i = 0; i < ARRAY_SIZE (hdr); i++)
1412     oprintf (f, "%s", hdr[i]);
1413   return f;
1414 }
1415
1416 /* Print, like fprintf, to O.  */
1417 void
1418 oprintf (outf_p o, const char *format, ...)
1419 {
1420   size_t slength;
1421
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   }
1430
1431   if (o->bufused + slength >= o->buflength)
1432     {
1433       /* There wasn't enough space.  */
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);
1440       o->buf = XRESIZEVEC (char, o->buf, new_len);
1441       o->buflength = new_len;
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       }
1455     }
1456   o->bufused += slength;
1457 }
1458
1459 /* Open the global header file and the language-specific header files.  */
1460
1461 static void
1462 open_base_files (void)
1463 {
1464   size_t i;
1465
1466   header_file = create_file ("GCC", "gtype-desc.h");
1467
1468   base_files = XNEWVEC (outf_p, num_lang_dirs);
1469
1470   for (i = 0; i < num_lang_dirs; i++)
1471     base_files[i] = create_file (lang_dir_names[i],
1472                                  xasprintf ("gtype-%s.h", lang_dir_names[i]));
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 [] = {
1478       "config.h", "system.h", "coretypes.h", "tm.h", "varray.h", 
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",
1484       "cfglayout.h", "except.h", "output.h", NULL
1485     };
1486     const char *const *ifp;
1487     outf_p gtype_desc_c;
1488
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   }
1493 }
1494
1495 /* Determine the pathname to F relative to $(srcdir).  */
1496
1497 static const char *
1498 get_file_basename (const char *f)
1499 {
1500   const char *basename;
1501   unsigned i;
1502
1503   basename = strrchr (f, '/');
1504
1505   if (!basename)
1506     return f;
1507
1508   basename++;
1509
1510   for (i = 0; i < num_lang_dirs; i++)
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);
1520       if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1521         {
1522           basename -= l2 + 1;
1523           if ((basename - f - 1) != srcdir_len)
1524             fatal ("filename `%s' should be preceded by $srcdir", f);
1525           break;
1526         }
1527     }
1528
1529   return basename;
1530 }
1531
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
1536 outf_p
1537 get_output_file_with_visibility (const char *input_file)
1538 {
1539   outf_p r;
1540   size_t len;
1541   const char *basename;
1542   const char *for_name;
1543   const char *output_name;
1544
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";
1550
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;
1560
1561       output_name = s = xasprintf ("gt-%s", basename);
1562       for (; *s != '.'; s++)
1563         if (! ISALNUM (*s) && *s != '-')
1564           *s = '-';
1565       memcpy (s, ".h", sizeof (".h"));
1566       for_name = basename;
1567     }
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).  */
1573   else if (strcmp (basename, "c-common.h") == 0)
1574     output_name = "gt-c-common.h", for_name = "c-common.c";
1575   else if (strcmp (basename, "c-tree.h") == 0)
1576     output_name = "gt-c-decl.h", for_name = "c-decl.c";
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";
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 
1590     {
1591       size_t i;
1592
1593       for (i = 0; i < num_lang_dirs; i++)
1594         if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1595             && basename[strlen(lang_dir_names[i])] == '/')
1596           return base_files[i];
1597
1598       output_name = "gtype-desc.c";
1599       for_name = NULL;
1600     }
1601
1602   /* Look through to see if we've ever seen this output filename before.  */
1603   for (r = output_files; r; r = r->next)
1604     if (strcmp (r->name, output_name) == 0)
1605       return r;
1606
1607   /* If not, create it.  */
1608   r = create_file (for_name, output_name);
1609
1610   return r;
1611 }
1612
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
1617 const char *
1618 get_output_file_name (const char *input_file)
1619 {
1620   return get_output_file_with_visibility (input_file)->name;
1621 }
1622
1623 /* Copy the output to its final destination,
1624    but don't unnecessarily change modification times.  */
1625
1626 static void
1627 close_output_files (void)
1628 {
1629   outf_p of;
1630
1631   for (of = output_files; of; of = of->next)
1632     {
1633       FILE * newfile;
1634
1635       newfile = fopen (of->name, "r");
1636       if (newfile != NULL )
1637         {
1638           int no_write_p;
1639           size_t i;
1640
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;
1649           fclose (newfile);
1650
1651           if (no_write_p)
1652             continue;
1653         }
1654
1655       newfile = fopen (of->name, "w");
1656       if (newfile == NULL)
1657         fatal ("opening output file %s: %s", of->name, strerror (errno));
1658       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1659         fatal ("writing output file %s: %s", of->name, strerror (errno));
1660       if (fclose (newfile) != 0)
1661         fatal ("closing output file %s: %s", of->name, strerror (errno));
1662     }
1663 }
1664 \f
1665 struct flist {
1666   struct flist *next;
1667   int started_p;
1668   const char *name;
1669   outf_p f;
1670 };
1671
1672 struct 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 */
1678 typedef void (*process_field_fn)
1679      (type_p f, const struct walk_type_data *p);
1680 typedef void (*func_name_fn)
1681      (type_p s, const struct walk_type_data *p);
1682
1683 /* Parameters for write_types.  */
1684
1685 struct write_types_data
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;
1693   int skip_hooks;               /* skip hook generation if non zero */
1694 };
1695
1696 static void output_escaped_param (struct walk_type_data *d,
1697                                   const char *, const char *);
1698 static void output_mangled_typename (outf_p, type_p);
1699 static void walk_type (type_p t, struct walk_type_data *d);
1700 static void write_func_for_structure
1701      (type_p orig_s, type_p s, type_p * param,
1702       const struct write_types_data *wtd);
1703 static void write_types_process_field
1704      (type_p f, const struct walk_type_data *d);
1705 static void write_types (type_p structures,
1706                          type_p param_structs,
1707                          const struct write_types_data *wtd);
1708 static void write_types_local_process_field
1709      (type_p f, const struct walk_type_data *d);
1710 static void write_local_func_for_structure
1711      (type_p orig_s, type_p s, type_p * param);
1712 static void write_local (type_p structures,
1713                          type_p param_structs);
1714 static void write_enum_defn (type_p structures, type_p param_structs);
1715 static int contains_scalar_p (type_p t);
1716 static void put_mangled_filename (outf_p , const char *);
1717 static void finish_root_table (struct flist *flp, const char *pfx,
1718                                const char *tname, const char *lastname,
1719                                const char *name);
1720 static void write_root (outf_p , pair_p, type_p, const char *, int,
1721                         struct fileloc *, const char *);
1722 static void write_array (outf_p f, pair_p v,
1723                          const struct write_types_data *wtd);
1724 static void write_roots (pair_p);
1725
1726 /* Parameters for walk_type.  */
1727
1728 struct walk_type_data
1729 {
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;
1744   bool needs_cast_p;
1745   bool fn_wants_lvalue;
1746 };
1747
1748 /* Print a mangled name representing T to OF.  */
1749
1750 static void
1751 output_mangled_typename (outf_p of, type_p t)
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:
1770       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
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]);
1778         output_mangled_typename (of, t->u.param_struct.stru);
1779       }
1780       break;
1781     case TYPE_ARRAY:
1782       gcc_unreachable ();
1783     }
1784 }
1785
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.  */
1790
1791 static void
1792 output_escaped_param (struct walk_type_data *d, const char *param,
1793                       const char *oname)
1794 {
1795   const char *p;
1796
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':
1812         {
1813           const char *pp = d->val + strlen (d->val);
1814           while (pp[-1] == ']')
1815             while (*pp != '[')
1816               pp--;
1817           oprintf (d->of, "%s", pp);
1818         }
1819         break;
1820       default:
1821         error_at_line (d->line, "`%s' option contains bad escape %c%c",
1822                        oname, '%', *p);
1823       }
1824 }
1825
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
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).  */
1836
1837 static void
1838 walk_type (type_p t, struct walk_type_data *d)
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;
1845   options_p oo;
1846   const struct nested_ptr_data *nested_ptr_d = NULL;
1847
1848   d->needs_cast_p = false;
1849   for (oo = d->opt; oo; oo = oo->next)
1850     if (strcmp (oo->name, "length") == 0)
1851       length = oo->info;
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)
1860       desc = oo->info;
1861     else if (strcmp (oo->name, "mark_hook") == 0)
1862       ;
1863     else if (strcmp (oo->name, "nested_ptr") == 0)
1864       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
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       ;
1879     else if (strncmp (oo->name, "param", 5) == 0
1880              && ISDIGIT (oo->name[5])
1881              && strcmp (oo->name + 6, "_is") == 0)
1882       ;
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);
1891
1892   if (d->used_length)
1893     length = NULL;
1894
1895   if (use_params_p)
1896     {
1897       int pointer_p = t->kind == TYPE_POINTER;
1898
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");
1903       else
1904         t = find_param_structure (t, d->param);
1905       if (pointer_p)
1906         t = create_pointer (t);
1907     }
1908
1909   if (use_param_num != -1)
1910     {
1911       if (d->param != NULL && d->param[use_param_num] != NULL)
1912         {
1913           type_p nt = d->param[use_param_num];
1914
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);
1919           d->needs_cast_p = (t->kind != TYPE_POINTER
1920                              && (nt->kind == TYPE_POINTER
1921                                  || nt->kind == TYPE_STRING));
1922           t = nt;
1923         }
1924       else
1925         error_at_line (d->line, "no parameter defined for `%s'",
1926                        d->val);
1927     }
1928
1929   if (maybe_undef_p
1930       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1931     {
1932       error_at_line (d->line,
1933                      "field `%s' has invalid option `maybe_undef_p'\n",
1934                      d->val);
1935       return;
1936     }
1937
1938   switch (t->kind)
1939     {
1940     case TYPE_SCALAR:
1941     case TYPE_STRING:
1942       d->process_field (t, d);
1943       break;
1944
1945     case TYPE_POINTER:
1946       {
1947         if (maybe_undef_p
1948             && t->u.p->u.s.line.file == NULL)
1949           {
1950             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1951             break;
1952           }
1953
1954         if (! length)
1955           {
1956             if (! UNION_OR_STRUCT_P (t->u.p)
1957                 && t->u.p->kind != TYPE_PARAM_STRUCT)
1958               {
1959                 error_at_line (d->line,
1960                                "field `%s' is pointer to unimplemented type",
1961                                d->val);
1962                 break;
1963               }
1964
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++);
1982                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1983                          (nested_ptr_d->type->kind == TYPE_UNION 
1984                           ? "union" : "struct"), 
1985                          nested_ptr_d->type->u.s.tag, 
1986                          d->fn_wants_lvalue ? "" : "const ",
1987                          d->val);
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
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                   }
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);
2012           }
2013         else
2014           {
2015             int loopcounter = d->counter++;
2016             const char *oldval = d->val;
2017             const char *oldprevval3 = d->prev_val[3];
2018             char *newval;
2019
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);
2023             oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
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);
2032             free (newval);
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, "");
2038             d->process_field(t, d);
2039             d->indent -= 2;
2040             oprintf (d->of, "%*s}\n", d->indent, "");
2041           }
2042       }
2043       break;
2044
2045     case TYPE_ARRAY:
2046       {
2047         int loopcounter = d->counter++;
2048         const char *oldval = d->val;
2049         char *newval;
2050
2051         /* If it's an array of scalars, we optimize by not generating
2052            any code.  */
2053         if (t->u.a.p->kind == TYPE_SCALAR)
2054           break;
2055
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.  */
2063         oprintf (d->of, "%*s{\n", d->indent, "");
2064         d->indent += 2;
2065         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2066         oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2067                  d->indent, "", loopcounter);
2068         if (length)
2069           output_escaped_param (d, length, "length");
2070         else
2071           oprintf (d->of, "%s", t->u.a.len);
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);
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;
2090
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);
2104
2105         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2106           {
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           }
2112
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)
2116             desc = o->info;
2117
2118         d->prev_val[2] = oldval;
2119         d->prev_val[1] = oldprevval2;
2120         if (union_p)
2121           {
2122             if (desc == NULL)
2123               {
2124                 error_at_line (d->line, "missing `desc' option for union `%s'",
2125                                t->u.s.tag);
2126                 desc = "1";
2127               }
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)
2147                 dot = oo->info;
2148               else if (strcmp (oo->name, "tag") == 0)
2149                 tagid = oo->info;
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)
2155                 d->reorder_fn = oo->info;
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)
2164               {
2165                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2166                 d->indent += 2;
2167               }
2168             else if (union_p && default_p)
2169               {
2170                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2171                 d->indent += 2;
2172                 seen_default_p = 1;
2173               }
2174             else if (! union_p && (default_p || tagid))
2175               error_at_line (d->line,
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)
2180               {
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;
2185               }
2186             else if (union_p && ! (default_p || tagid))
2187               error_at_line (d->line,
2188                              "field `%s' is missing `tag' or `default' option",
2189                              f->name);
2190
2191             d->line = &f->line;
2192             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2193             d->opt = f->opt;
2194             d->used_length = false;
2195
2196             if (union_p && use_param_p && d->param == NULL)
2197               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2198             else
2199               walk_type (f->type, d);
2200
2201             free (newval);
2202
2203             if (union_p)
2204               {
2205                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2206                 d->indent -= 2;
2207               }
2208           }
2209         d->reorder_fn = NULL;
2210
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;
2224           }
2225       }
2226       break;
2227
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;
2245
2246         d->param = t->u.param_struct.param;
2247         walk_type (t->u.param_struct.stru, d);
2248         d->param = oldparam;
2249       }
2250       break;
2251
2252     default:
2253       gcc_unreachable ();
2254     }
2255 }
2256
2257 /* process_field routine for marking routines.  */
2258
2259 static void
2260 write_types_process_field (type_p f, const struct walk_type_data *d)
2261 {
2262   const struct write_types_data *wtd;
2263   const char *cast = d->needs_cast_p ? "(void *)" : "";
2264   wtd = (const struct write_types_data *) d->cookie;
2265
2266   switch (f->kind)
2267     {
2268     case TYPE_POINTER:
2269       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2270                wtd->subfield_marker_routine, cast, d->val);
2271       if (wtd->param_prefix)
2272         {
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]);
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");
2296         }
2297       oprintf (d->of, ");\n");
2298       if (d->reorder_fn && wtd->reorder_note_routine)
2299         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2300                  wtd->reorder_note_routine, cast, d->val,
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);
2314       oprintf (d->of, " (%s%s);\n", cast, d->val);
2315       if (d->reorder_fn && wtd->reorder_note_routine)
2316         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2317                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
2318                  d->reorder_fn);
2319       break;
2320
2321     case TYPE_SCALAR:
2322       break;
2323
2324     default:
2325       gcc_unreachable ();
2326     }
2327 }
2328
2329 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2330
2331 static void
2332 output_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
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 */
2355
2356 static void
2357 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2358                           const struct write_types_data *wtd)
2359 {
2360   const char *fn = s->u.s.line.file;
2361   int i;
2362   const char *chain_next = NULL;
2363   const char *chain_prev = NULL;
2364   const char *mark_hook_name = NULL;
2365   options_p opt;
2366   struct walk_type_data d;
2367
2368   /* This is a hack, and not the good kind either.  */
2369   for (i = NUM_PARAM - 1; i >= 0; i--)
2370     if (param && param[i] && param[i]->kind == TYPE_POINTER
2371         && UNION_OR_STRUCT_P (param[i]->u.p))
2372       fn = param[i]->u.p->u.s.line.file;
2373
2374   memset (&d, 0, sizeof (d));
2375   d.of = get_output_file_with_visibility (fn);
2376
2377   for (opt = s->u.s.opt; opt; opt = opt->next)
2378     if (strcmp (opt->name, "chain_next") == 0)
2379       chain_next = opt->info;
2380     else if (strcmp (opt->name, "chain_prev") == 0)
2381       chain_prev = opt->info;
2382     else if (strcmp (opt->name, "mark_hook") == 0)
2383       mark_hook_name = opt->info;
2384
2385   if (chain_prev != NULL && chain_next == NULL)
2386     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2387
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";
2396   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2397   d.prev_val[3] = "x";
2398   d.val = "(*x)";
2399
2400   oprintf (d.of, "\n");
2401   oprintf (d.of, "void\n");
2402   if (param == NULL)
2403     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2404   else
2405     {
2406       oprintf (d.of, "gt_%s_", wtd->prefix);
2407       output_mangled_typename (d.of, orig_s);
2408     }
2409   oprintf (d.of, " (void *x_p)\n");
2410   oprintf (d.of, "{\n");
2411   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2412            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2413            chain_next == NULL ? "const " : "",
2414            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2415   if (chain_next != NULL)
2416     oprintf (d.of, "  %s %s * xlimit = x;\n",
2417              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2418   if (chain_next == NULL)
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);
2425           output_type_enum (d.of, orig_s);
2426         }
2427       oprintf (d.of, "))\n");
2428     }
2429   else
2430     {
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);
2436           output_type_enum (d.of, orig_s);
2437         }
2438       oprintf (d.of, "))\n");
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         }
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");
2448       if (mark_hook_name && !wtd->skip_hooks)
2449         oprintf (d.of, "    }\n");
2450       if (chain_prev != NULL)
2451         {
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 = (",
2456                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2457
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");
2463           oprintf (d.of, "        (void) %s (xprev",
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);
2469               output_type_enum (d.of, orig_s);
2470             }
2471           oprintf (d.of, ");\n");
2472           oprintf (d.of, "      }\n");
2473         }
2474       oprintf (d.of, "  while (x != xlimit)\n");
2475     }
2476   oprintf (d.of, "    {\n");
2477   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2478     {
2479       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2480     }
2481   d.prev_val[2] = "*x";
2482   d.indent = 6;
2483   walk_type (s, &d);
2484
2485   if (chain_next != NULL)
2486     {
2487       oprintf (d.of, "      x = (");
2488       output_escaped_param (&d, chain_next, "chain_next");
2489       oprintf (d.of, ");\n");
2490     }
2491
2492   oprintf (d.of, "    }\n");
2493   oprintf (d.of, "}\n");
2494 }
2495
2496 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2497
2498 static void
2499 write_types (type_p structures, type_p param_structs,
2500              const struct write_types_data *wtd)
2501 {
2502   type_p s;
2503
2504   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
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;
2510
2511         if (s->gc_used == GC_MAYBE_POINTED_TO
2512             && s->u.s.line.file == NULL)
2513           continue;
2514
2515         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2516         output_mangled_typename (header_file, s);
2517         oprintf (header_file, "(X) do { \\\n");
2518         oprintf (header_file,
2519                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2520                  s->u.s.tag);
2521         oprintf (header_file,
2522                  "  } while (0)\n");
2523
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;
2528               if (t->kind == TYPE_STRUCT
2529                   || t->kind == TYPE_UNION
2530                   || t->kind == TYPE_LANG_STRUCT)
2531                 oprintf (header_file,
2532                          "#define gt_%sx_%s gt_%sx_%s\n",
2533                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2534               else
2535                 error_at_line (&s->u.s.line,
2536                                "structure alias is not a structure");
2537               break;
2538             }
2539         if (opt)
2540           continue;
2541
2542         /* Declare the marker procedure only once.  */
2543         oprintf (header_file,
2544                  "extern void gt_%sx_%s (void *);\n",
2545                  wtd->prefix, s->u.s.tag);
2546
2547         if (s->u.s.line.file == NULL)
2548           {
2549             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2550                      s->u.s.tag);
2551             continue;
2552           }
2553
2554         if (s->kind == TYPE_LANG_STRUCT)
2555           {
2556             type_p ss;
2557             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2558               write_func_for_structure (s, ss, NULL, wtd);
2559           }
2560         else
2561           write_func_for_structure (s, s, NULL, wtd);
2562       }
2563
2564   for (s = param_structs; s; s = s->next)
2565     if (s->gc_used == GC_POINTED_TO)
2566       {
2567         type_p * param = s->u.param_struct.param;
2568         type_p stru = s->u.param_struct.stru;
2569
2570         /* Declare the marker procedure.  */
2571         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2572         output_mangled_typename (header_file, s);
2573         oprintf (header_file, " (void *);\n");
2574
2575         if (stru->u.s.line.file == NULL)
2576           {
2577             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2578                      s->u.s.tag);
2579             continue;
2580           }
2581
2582         if (stru->kind == TYPE_LANG_STRUCT)
2583           {
2584             type_p ss;
2585             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2586               write_func_for_structure (s, ss, param, wtd);
2587           }
2588         else
2589           write_func_for_structure (s, stru, param, wtd);
2590       }
2591 }
2592
2593 static const struct write_types_data ggc_wtd =
2594 {
2595   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2596   "GC marker procedures.  ",
2597   FALSE
2598 };
2599
2600 static 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",
2604   "PCH type-walking procedures.  ",
2605   TRUE
2606 };
2607
2608 /* Write out the local pointer-walking routines.  */
2609
2610 /* process_field routine for local pointer-walking.  */
2611
2612 static void
2613 write_types_local_process_field (type_p f, const struct walk_type_data *d)
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;
2630
2631     default:
2632       gcc_unreachable ();
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
2639    - Calls PROCESS_FIELD on each field of S or its substructures.
2640 */
2641
2642 static void
2643 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2644 {
2645   const char *fn = s->u.s.line.file;
2646   int i;
2647   struct walk_type_data d;
2648
2649   /* This is a hack, and not the good kind either.  */
2650   for (i = NUM_PARAM - 1; i >= 0; i--)
2651     if (param && param[i] && param[i]->kind == TYPE_POINTER
2652         && UNION_OR_STRUCT_P (param[i]->u.p))
2653       fn = param[i]->u.p->u.s.line.file;
2654
2655   memset (&d, 0, sizeof (d));
2656   d.of = get_output_file_with_visibility (fn);
2657
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";
2664   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2665   d.prev_val[3] = "x";
2666   d.val = "(*x)";
2667   d.fn_wants_lvalue = true;
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);
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");
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
2688 static void
2689 write_local (type_p structures, type_p param_structs)
2690 {
2691   type_p s;
2692
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;
2699
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;
2707               if (t->kind == TYPE_STRUCT
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
2718                 error_at_line (&s->u.s.line,
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);
2728         oprintf (header_file,
2729          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2730
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);
2750         oprintf (header_file,
2751          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2752
2753         if (stru->u.s.line.file == NULL)
2754           {
2755             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2756                      s->u.s.tag);
2757             continue;
2758           }
2759
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);
2765           }
2766         else
2767           write_local_func_for_structure (s, stru, param);
2768       }
2769 }
2770
2771 /* Write out the 'enum' definition for gt_types_enum.  */
2772
2773 static void
2774 write_enum_defn (type_p structures, type_p param_structs)
2775 {
2776   type_p s;
2777
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");
2791       }
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");
2801 }
2802
2803 /* Might T contain any non-pointer elements?  */
2804
2805 static int
2806 contains_scalar_p (type_p t)
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 }
2821
2822 /* Mangle FN and print it to F.  */
2823
2824 static void
2825 put_mangled_filename (outf_p f, const char *fn)
2826 {
2827   const char *name = get_output_file_name (fn);
2828   for (; *name != 0; name++)
2829     if (ISALNUM (*name))
2830       oprintf (f, "%c", *name);
2831     else
2832       oprintf (f, "%c", '_');
2833 }
2834
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
2839 static void
2840 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2841                    const char *tname, const char *name)
2842 {
2843   struct flist *fli2;
2844
2845   for (fli2 = flp; fli2; fli2 = fli2->next)
2846     if (fli2->started_p)
2847       {
2848         oprintf (fli2->f, "  %s\n", lastname);
2849         oprintf (fli2->f, "};\n\n");
2850       }
2851
2852   for (fli2 = flp; fli2; fli2 = fli2->next)
2853     if (fli2->started_p)
2854       {
2855         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2856         int fnum;
2857
2858         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2859           if (bitmap & 1)
2860             {
2861               oprintf (base_files[fnum],
2862                        "extern const struct %s gt_%s_",
2863                        tname, pfx);
2864               put_mangled_filename (base_files[fnum], fli2->name);
2865               oprintf (base_files[fnum], "[];\n");
2866             }
2867       }
2868
2869   {
2870     size_t fnum;
2871     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2872       oprintf (base_files [fnum],
2873                "const struct %s * const %s[] = {\n",
2874                tname, name);
2875   }
2876
2877
2878   for (fli2 = flp; fli2; fli2 = fli2->next)
2879     if (fli2->started_p)
2880       {
2881         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2882         int fnum;
2883
2884         fli2->started_p = 0;
2885
2886         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2887           if (bitmap & 1)
2888             {
2889               oprintf (base_files[fnum], "  gt_%s_", pfx);
2890               put_mangled_filename (base_files[fnum], fli2->name);
2891               oprintf (base_files[fnum], ",\n");
2892             }
2893       }
2894
2895   {
2896     size_t fnum;
2897     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2898       {
2899         oprintf (base_files[fnum], "  NULL\n");
2900         oprintf (base_files[fnum], "};\n");
2901       }
2902   }
2903 }
2904
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
2910 static void
2911 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2912             struct fileloc *line, const char *if_marked)
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;
2924
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)
2929                 desc = o->info;
2930               else
2931                 error_at_line (line,
2932                        "field `%s' of global `%s' has unknown option `%s'",
2933                                fld->name, name, o->name);
2934
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;
2941
2942                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2943                   {
2944                     const char *tag = NULL;
2945                     options_p oo;
2946
2947                     for (oo = ufld->opt; oo; oo = oo->next)
2948                       if (strcmp (oo->name, "tag") == 0)
2949                         tag = oo->info;
2950                     if (tag == NULL || strcmp (tag, desc) != 0)
2951                       continue;
2952                     if (validf != NULL)
2953                       error_at_line (line,
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;
2963                     newname = xasprintf ("%s.%s.%s",
2964                                          name, fld->name, validf->name);
2965                     write_root (f, v, validf->type, newname, 0, line,
2966                                 if_marked);
2967                     free (newname);
2968                   }
2969               }
2970             else if (desc)
2971               error_at_line (line,
2972                      "global `%s.%s' has `desc' option but is not union",
2973                              name, fld->name);
2974             else
2975               {
2976                 char *newname;
2977                 newname = xasprintf ("%s.%s", name, fld->name);
2978                 write_root (f, v, fld->type, newname, 0, line, if_marked);
2979                 free (newname);
2980               }
2981           }
2982       }
2983       break;
2984
2985     case TYPE_ARRAY:
2986       {
2987         char *newname;
2988         newname = xasprintf ("%s[0]", name);
2989         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2990         free (newname);
2991       }
2992       break;
2993
2994     case TYPE_POINTER:
2995       {
2996         type_p ap, tp;
2997
2998         oprintf (f, "  {\n");
2999         oprintf (f, "    &%s,\n", name);
3000         oprintf (f, "    1");
3001
3002         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3003           if (ap->u.a.len[0])
3004             oprintf (f, " * (%s)", ap->u.a.len);
3005           else if (ap == v->type)
3006             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3007         oprintf (f, ",\n");
3008         oprintf (f, "    sizeof (%s", v->name);
3009         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3010           oprintf (f, "[0]");
3011         oprintf (f, "),\n");
3012
3013         tp = type->u.p;
3014
3015         if (! has_length && UNION_OR_STRUCT_P (tp))
3016           {
3017             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3018             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3019           }
3020         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3021           {
3022             oprintf (f, "    &gt_ggc_m_");
3023             output_mangled_typename (f, tp);
3024             oprintf (f, ",\n    &gt_pch_n_");
3025             output_mangled_typename (f, tp);
3026           }
3027         else if (has_length
3028                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3029           {
3030             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3031             oprintf (f, "    &gt_pch_na_%s", name);
3032           }
3033         else
3034           {
3035             error_at_line (line,
3036                            "global `%s' is pointer to unimplemented type",
3037                            name);
3038           }
3039         if (if_marked)
3040           oprintf (f, ",\n    &%s", if_marked);
3041         oprintf (f, "\n  },\n");
3042       }
3043       break;
3044
3045     case TYPE_STRING:
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");
3052         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3053         oprintf (f, "  },\n");
3054       }
3055       break;
3056
3057     case TYPE_SCALAR:
3058       break;
3059
3060     default:
3061       error_at_line (line,
3062                      "global `%s' is unimplemented type",
3063                      name);
3064     }
3065 }
3066
3067 /* This generates a routine to walk an array.  */
3068
3069 static void
3070 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3071 {
3072   struct walk_type_data d;
3073   char *prevval3;
3074
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;
3081   d.bitmap = get_lang_bitmap (v->line.file);
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);
3089       oprintf (f,
3090        "    (void *, void *, gt_pointer_operator, void *);\n");
3091       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3092                wtd->param_prefix, v->name);
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");
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;
3105   oprintf (f, "static void gt_%sa_%s (void *);\n",
3106            wtd->prefix, v->name);
3107   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3108            wtd->prefix, v->name);
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
3117 /* Output a table describing the locations and types of VARIABLES.  */
3118
3119 static void
3120 write_roots (pair_p variables)
3121 {
3122   pair_p v;
3123   struct flist *flp = NULL;
3124
3125   for (v = variables; v; v = v->next)
3126     {
3127       outf_p f = get_output_file_with_visibility (v->line.file);
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)
3135           length = o->info;
3136         else if (strcmp (o->name, "deletable") == 0)
3137           deletable_p = 1;
3138         else if (strcmp (o->name, "param_is") == 0)
3139           ;
3140         else if (strncmp (o->name, "param", 5) == 0
3141                  && ISDIGIT (o->name[5])
3142                  && strcmp (o->name + 6, "_is") == 0)
3143           ;
3144         else if (strcmp (o->name, "if_marked") == 0)
3145           ;
3146         else
3147           error_at_line (&v->line,
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         {
3156           fli = XNEW (struct flist);
3157           fli->f = f;
3158           fli->next = flp;
3159           fli->started_p = 0;
3160           fli->name = v->line.file;
3161           flp = fli;
3162
3163           oprintf (f, "\n/* GC roots.  */\n\n");
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         {
3172           write_array (f, v, &ggc_wtd);
3173           write_array (f, v, &pch_wtd);
3174         }
3175     }
3176
3177   for (v = variables; v; v = v->next)
3178     {
3179       outf_p f = get_output_file_with_visibility (v->line.file);
3180       struct flist *fli;
3181       int skip_p = 0;
3182       int length_p = 0;
3183       options_p o;
3184
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
3202           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
3203           put_mangled_filename (f, v->line.file);
3204           oprintf (f, "[] = {\n");
3205         }
3206
3207       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3208     }
3209
3210   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3211                      "gt_ggc_rtab");
3212
3213   for (v = variables; v; v = v->next)
3214     {
3215       outf_p f = get_output_file_with_visibility (v->line.file);
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
3236           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
3237           put_mangled_filename (f, v->line.file);
3238           oprintf (f, "[] = {\n");
3239         }
3240
3241       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3242                v->name, v->name);
3243     }
3244
3245   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3246                      "gt_ggc_deletable_rtab");
3247
3248   for (v = variables; v; v = v->next)
3249     {
3250       outf_p f = get_output_file_with_visibility (v->line.file);
3251       struct flist *fli;
3252       const char *if_marked = NULL;
3253       int length_p = 0;
3254       options_p o;
3255
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)
3260           if_marked = o->info;
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
3280           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
3281           put_mangled_filename (f, v->line.file);
3282           oprintf (f, "[] = {\n");
3283         }
3284
3285       write_root (f, v, v->type->u.p->u.param_struct.param[0],
3286                      v->name, length_p, &v->line, if_marked);
3287     }
3288
3289   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3290                      "gt_ggc_cache_rtab");
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;
3299
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     }
3323
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         }
3356
3357       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3358                v->name, v->name);
3359     }
3360
3361   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3362                      "gt_pch_scalar_rtab");
3363 }
3364
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
3376 void
3377 note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
3378 {
3379   pair_p fields;
3380   type_p t;
3381   options_p o;
3382   type_p len_ty = create_scalar_type ("unsigned");
3383   const char *name = concat ("VEC_", typename, "_base", (char *)0);
3384
3385   if (is_scalar)
3386     {
3387       t = create_scalar_type (typename);
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.  */
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);
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 */
3411 void
3412 note_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
3417   pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3418                                   "base", 0, pos);
3419
3420   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3421 }
3422
3423 \f
3424 int
3425 main (int argc, char **argv)
3426 {
3427   size_t i;
3428   static struct fileloc pos = { __FILE__, __LINE__ };
3429
3430   /* fatal uses this */
3431   progname = "gengtype";
3432
3433   if (argc != 3)
3434     fatal ("usage: gengtype srcdir input-list");
3435
3436   srcdir = argv[1];
3437   srcdir_len = strlen (srcdir);
3438
3439   read_input_list (argv[2]);
3440   if (hit_error)
3441     return 1;
3442
3443   scalar_char.u.scalar_is_char = true;
3444   scalar_nonchar.u.scalar_is_char = false;
3445   gen_rtx_next ();
3446
3447   do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3448   do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3449   do_scalar_typedef ("double_int", &pos);
3450   do_scalar_typedef ("uint8", &pos);
3451   do_scalar_typedef ("jword", &pos);
3452   do_scalar_typedef ("JCF_u2", &pos);
3453 #ifdef USE_MAPPED_LOCATION
3454   do_scalar_typedef ("location_t", &pos);
3455   do_scalar_typedef ("source_locus", &pos);
3456 #endif
3457   do_scalar_typedef ("void", &pos);
3458
3459   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3460
3461   do_typedef ("HARD_REG_SET", create_array (&scalar_nonchar, "2"), &pos);
3462
3463   for (i = 0; i < num_gt_files; i++)
3464     {
3465       parse_file (gt_files[i]);
3466 #ifndef USE_MAPPED_LOCATION
3467       /* temporary kludge - gengtype doesn't handle conditionals.
3468          Manually add source_locus *after* we've processed input.h.  */
3469       if (i == 0)
3470         do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3471 #endif
3472     }
3473
3474   if (hit_error != 0)
3475     return 1;
3476
3477   set_gc_used (variables);
3478
3479   open_base_files ();
3480   write_enum_defn (structures, param_structs);
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);
3485   write_rtx_next ();
3486   close_output_files ();
3487
3488   return (hit_error != 0);
3489 }