OSDN Git Service

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