OSDN Git Service

Change copyright header to refer to version 3 of the GNU General Public License and...
[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 }
1548
1549 /* Determine the pathname to F relative to $(srcdir).  */
1550
1551 static const char *
1552 get_file_basename (const char *f)
1553 {
1554   const char *basename;
1555   unsigned i;
1556
1557   basename = strrchr (f, '/');
1558
1559   if (!basename)
1560     return f;
1561
1562   basename++;
1563
1564   for (i = 0; i < num_lang_dirs; i++)
1565     {
1566       const char * s1;
1567       const char * s2;
1568       int l1;
1569       int l2;
1570       s1 = basename - strlen (lang_dir_names [i]) - 1;
1571       s2 = lang_dir_names [i];
1572       l1 = strlen (s1);
1573       l2 = strlen (s2);
1574       if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1575         {
1576           basename -= l2 + 1;
1577           if ((basename - f - 1) != srcdir_len)
1578             fatal ("filename `%s' should be preceded by $srcdir", f);
1579           break;
1580         }
1581     }
1582
1583   return basename;
1584 }
1585
1586 /* An output file, suitable for definitions, that can see declarations
1587    made in INPUT_FILE and is linked into every language that uses
1588    INPUT_FILE.  */
1589
1590 outf_p
1591 get_output_file_with_visibility (const char *input_file)
1592 {
1593   outf_p r;
1594   size_t len;
1595   const char *basename;
1596   const char *for_name;
1597   const char *output_name;
1598
1599   /* This can happen when we need a file with visibility on a
1600      structure that we've never seen.  We have to just hope that it's
1601      globally visible.  */
1602   if (input_file == NULL)
1603     input_file = "system.h";
1604
1605   /* Determine the output file name.  */
1606   basename = get_file_basename (input_file);
1607
1608   len = strlen (basename);
1609   if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1610       || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1611       || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1612     {
1613       char *s;
1614
1615       output_name = s = xasprintf ("gt-%s", basename);
1616       for (; *s != '.'; s++)
1617         if (! ISALNUM (*s) && *s != '-')
1618           *s = '-';
1619       memcpy (s, ".h", sizeof (".h"));
1620       for_name = basename;
1621     }
1622   /* Some headers get used by more than one front-end; hence, it
1623      would be inappropriate to spew them out to a single gtype-<lang>.h
1624      (and gengtype doesn't know how to direct spewage into multiple
1625      gtype-<lang>.h headers at this time).  Instead, we pair up these
1626      headers with source files (and their special purpose gt-*.h headers).  */
1627   else if (strcmp (basename, "c-common.h") == 0)
1628     output_name = "gt-c-common.h", for_name = "c-common.c";
1629   else if (strcmp (basename, "c-tree.h") == 0)
1630     output_name = "gt-c-decl.h", for_name = "c-decl.c";
1631   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1632            && strcmp (basename + 3, "cp-tree.h") == 0)
1633     output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1634   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1635            && strcmp (basename + 3, "decl.h") == 0)
1636     output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1637   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1638            && strcmp (basename + 3, "name-lookup.h") == 0)
1639     output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1640   else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1641            && strcmp (basename + 5, "objc-act.h") == 0)
1642     output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1643   else 
1644     {
1645       size_t i;
1646
1647       for (i = 0; i < num_lang_dirs; i++)
1648         if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1649             && basename[strlen(lang_dir_names[i])] == '/')
1650           return base_files[i];
1651
1652       output_name = "gtype-desc.c";
1653       for_name = NULL;
1654     }
1655
1656   /* Look through to see if we've ever seen this output filename before.  */
1657   for (r = output_files; r; r = r->next)
1658     if (strcmp (r->name, output_name) == 0)
1659       return r;
1660
1661   /* If not, create it.  */
1662   r = create_file (for_name, output_name);
1663
1664   return r;
1665 }
1666
1667 /* The name of an output file, suitable for definitions, that can see
1668    declarations made in INPUT_FILE and is linked into every language
1669    that uses INPUT_FILE.  */
1670
1671 const char *
1672 get_output_file_name (const char *input_file)
1673 {
1674   return get_output_file_with_visibility (input_file)->name;
1675 }
1676
1677 /* Copy the output to its final destination,
1678    but don't unnecessarily change modification times.  */
1679
1680 static void
1681 close_output_files (void)
1682 {
1683   outf_p of;
1684
1685   for (of = output_files; of; of = of->next)
1686     {
1687       FILE * newfile;
1688
1689       newfile = fopen (of->name, "r");
1690       if (newfile != NULL )
1691         {
1692           int no_write_p;
1693           size_t i;
1694
1695           for (i = 0; i < of->bufused; i++)
1696             {
1697               int ch;
1698               ch = fgetc (newfile);
1699               if (ch == EOF || ch != (unsigned char) of->buf[i])
1700                 break;
1701             }
1702           no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1703           fclose (newfile);
1704
1705           if (no_write_p)
1706             continue;
1707         }
1708
1709       newfile = fopen (of->name, "w");
1710       if (newfile == NULL)
1711         fatal ("opening output file %s: %s", of->name, strerror (errno));
1712       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1713         fatal ("writing output file %s: %s", of->name, strerror (errno));
1714       if (fclose (newfile) != 0)
1715         fatal ("closing output file %s: %s", of->name, strerror (errno));
1716     }
1717 }
1718 \f
1719 struct flist {
1720   struct flist *next;
1721   int started_p;
1722   const char *name;
1723   outf_p f;
1724 };
1725
1726 struct walk_type_data;
1727
1728 /* For scalars and strings, given the item in 'val'.
1729    For structures, given a pointer to the item in 'val'.
1730    For misc. pointers, given the item in 'val'.
1731 */
1732 typedef void (*process_field_fn)
1733      (type_p f, const struct walk_type_data *p);
1734 typedef void (*func_name_fn)
1735      (type_p s, const struct walk_type_data *p);
1736
1737 /* Parameters for write_types.  */
1738
1739 struct write_types_data
1740 {
1741   const char *prefix;
1742   const char *param_prefix;
1743   const char *subfield_marker_routine;
1744   const char *marker_routine;
1745   const char *reorder_note_routine;
1746   const char *comment;
1747   int skip_hooks;               /* skip hook generation if non zero */
1748 };
1749
1750 static void output_escaped_param (struct walk_type_data *d,
1751                                   const char *, const char *);
1752 static void output_mangled_typename (outf_p, const_type_p);
1753 static void walk_type (type_p t, struct walk_type_data *d);
1754 static void write_func_for_structure
1755      (type_p orig_s, type_p s, type_p * param,
1756       const struct write_types_data *wtd);
1757 static void write_types_process_field
1758      (type_p f, const struct walk_type_data *d);
1759 static void write_types (type_p structures,
1760                          type_p param_structs,
1761                          const struct write_types_data *wtd);
1762 static void write_types_local_process_field
1763      (type_p f, const struct walk_type_data *d);
1764 static void write_local_func_for_structure
1765      (type_p orig_s, type_p s, type_p * param);
1766 static void write_local (type_p structures,
1767                          type_p param_structs);
1768 static void write_enum_defn (type_p structures, type_p param_structs);
1769 static int contains_scalar_p (type_p t);
1770 static void put_mangled_filename (outf_p , const char *);
1771 static void finish_root_table (struct flist *flp, const char *pfx,
1772                                const char *tname, const char *lastname,
1773                                const char *name);
1774 static void write_root (outf_p , pair_p, type_p, const char *, int,
1775                         struct fileloc *, const char *);
1776 static void write_array (outf_p f, pair_p v,
1777                          const struct write_types_data *wtd);
1778 static void write_roots (pair_p);
1779
1780 /* Parameters for walk_type.  */
1781
1782 struct walk_type_data
1783 {
1784   process_field_fn process_field;
1785   const void *cookie;
1786   outf_p of;
1787   options_p opt;
1788   const char *val;
1789   const char *prev_val[4];
1790   int indent;
1791   int counter;
1792   struct fileloc *line;
1793   lang_bitmap bitmap;
1794   type_p *param;
1795   int used_length;
1796   type_p orig_s;
1797   const char *reorder_fn;
1798   bool needs_cast_p;
1799   bool fn_wants_lvalue;
1800 };
1801
1802 /* Print a mangled name representing T to OF.  */
1803
1804 static void
1805 output_mangled_typename (outf_p of, const_type_p t)
1806 {
1807   if (t == NULL)
1808     oprintf (of, "Z");
1809   else switch (t->kind)
1810     {
1811     case TYPE_POINTER:
1812       oprintf (of, "P");
1813       output_mangled_typename (of, t->u.p);
1814       break;
1815     case TYPE_SCALAR:
1816       oprintf (of, "I");
1817       break;
1818     case TYPE_STRING:
1819       oprintf (of, "S");
1820       break;
1821     case TYPE_STRUCT:
1822     case TYPE_UNION:
1823     case TYPE_LANG_STRUCT:
1824       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1825       break;
1826     case TYPE_PARAM_STRUCT:
1827       {
1828         int i;
1829         for (i = 0; i < NUM_PARAM; i++)
1830           if (t->u.param_struct.param[i] != NULL)
1831             output_mangled_typename (of, t->u.param_struct.param[i]);
1832         output_mangled_typename (of, t->u.param_struct.stru);
1833       }
1834       break;
1835     case TYPE_ARRAY:
1836       gcc_unreachable ();
1837     }
1838 }
1839
1840 /* Print PARAM to D->OF processing escapes.  D->VAL references the
1841    current object, D->PREV_VAL the object containing the current
1842    object, ONAME is the name of the option and D->LINE is used to
1843    print error messages.  */
1844
1845 static void
1846 output_escaped_param (struct walk_type_data *d, const char *param,
1847                       const char *oname)
1848 {
1849   const char *p;
1850
1851   for (p = param; *p; p++)
1852     if (*p != '%')
1853       oprintf (d->of, "%c", *p);
1854     else switch (*++p)
1855       {
1856       case 'h':
1857         oprintf (d->of, "(%s)", d->prev_val[2]);
1858         break;
1859       case '0':
1860         oprintf (d->of, "(%s)", d->prev_val[0]);
1861         break;
1862       case '1':
1863         oprintf (d->of, "(%s)", d->prev_val[1]);
1864         break;
1865       case 'a':
1866         {
1867           const char *pp = d->val + strlen (d->val);
1868           while (pp[-1] == ']')
1869             while (*pp != '[')
1870               pp--;
1871           oprintf (d->of, "%s", pp);
1872         }
1873         break;
1874       default:
1875         error_at_line (d->line, "`%s' option contains bad escape %c%c",
1876                        oname, '%', *p);
1877       }
1878 }
1879
1880 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1881    which is of type T.  Write code to D->OF to constrain execution (at
1882    the point that D->PROCESS_FIELD is called) to the appropriate
1883    cases.  Call D->PROCESS_FIELD on subobjects before calling it on
1884    pointers to those objects.  D->PREV_VAL lists the objects
1885    containing the current object, D->OPT is a list of options to
1886    apply, D->INDENT is the current indentation level, D->LINE is used
1887    to print error messages, D->BITMAP indicates which languages to
1888    print the structure for, and D->PARAM is the current parameter
1889    (from an enclosing param_is option).  */
1890
1891 static void
1892 walk_type (type_p t, struct walk_type_data *d)
1893 {
1894   const char *length = NULL;
1895   const char *desc = NULL;
1896   int maybe_undef_p = 0;
1897   int use_param_num = -1;
1898   int use_params_p = 0;
1899   options_p oo;
1900   const struct nested_ptr_data *nested_ptr_d = NULL;
1901
1902   d->needs_cast_p = false;
1903   for (oo = d->opt; oo; oo = oo->next)
1904     if (strcmp (oo->name, "length") == 0)
1905       length = oo->info;
1906     else if (strcmp (oo->name, "maybe_undef") == 0)
1907       maybe_undef_p = 1;
1908     else if (strncmp (oo->name, "use_param", 9) == 0
1909              && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1910       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1911     else if (strcmp (oo->name, "use_params") == 0)
1912       use_params_p = 1;
1913     else if (strcmp (oo->name, "desc") == 0)
1914       desc = oo->info;
1915     else if (strcmp (oo->name, "mark_hook") == 0)
1916       ;
1917     else if (strcmp (oo->name, "nested_ptr") == 0)
1918       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1919     else if (strcmp (oo->name, "dot") == 0)
1920       ;
1921     else if (strcmp (oo->name, "tag") == 0)
1922       ;
1923     else if (strcmp (oo->name, "special") == 0)
1924       ;
1925     else if (strcmp (oo->name, "skip") == 0)
1926       ;
1927     else if (strcmp (oo->name, "default") == 0)
1928       ;
1929     else if (strcmp (oo->name, "descbits") == 0)
1930       ;
1931     else if (strcmp (oo->name, "param_is") == 0)
1932       ;
1933     else if (strncmp (oo->name, "param", 5) == 0
1934              && ISDIGIT (oo->name[5])
1935              && strcmp (oo->name + 6, "_is") == 0)
1936       ;
1937     else if (strcmp (oo->name, "chain_next") == 0)
1938       ;
1939     else if (strcmp (oo->name, "chain_prev") == 0)
1940       ;
1941     else if (strcmp (oo->name, "reorder") == 0)
1942       ;
1943     else
1944       error_at_line (d->line, "unknown option `%s'\n", oo->name);
1945
1946   if (d->used_length)
1947     length = NULL;
1948
1949   if (use_params_p)
1950     {
1951       int pointer_p = t->kind == TYPE_POINTER;
1952
1953       if (pointer_p)
1954         t = t->u.p;
1955       if (! UNION_OR_STRUCT_P (t))
1956         error_at_line (d->line, "`use_params' option on unimplemented type");
1957       else
1958         t = find_param_structure (t, d->param);
1959       if (pointer_p)
1960         t = create_pointer (t);
1961     }
1962
1963   if (use_param_num != -1)
1964     {
1965       if (d->param != NULL && d->param[use_param_num] != NULL)
1966         {
1967           type_p nt = d->param[use_param_num];
1968
1969           if (t->kind == TYPE_ARRAY)
1970             nt = create_array (nt, t->u.a.len);
1971           else if (length != NULL && t->kind == TYPE_POINTER)
1972             nt = create_pointer (nt);
1973           d->needs_cast_p = (t->kind != TYPE_POINTER
1974                              && (nt->kind == TYPE_POINTER
1975                                  || nt->kind == TYPE_STRING));
1976           t = nt;
1977         }
1978       else
1979         error_at_line (d->line, "no parameter defined for `%s'",
1980                        d->val);
1981     }
1982
1983   if (maybe_undef_p
1984       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1985     {
1986       error_at_line (d->line,
1987                      "field `%s' has invalid option `maybe_undef_p'\n",
1988                      d->val);
1989       return;
1990     }
1991
1992   switch (t->kind)
1993     {
1994     case TYPE_SCALAR:
1995     case TYPE_STRING:
1996       d->process_field (t, d);
1997       break;
1998
1999     case TYPE_POINTER:
2000       {
2001         if (maybe_undef_p
2002             && t->u.p->u.s.line.file == NULL)
2003           {
2004             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2005             break;
2006           }
2007
2008         if (! length)
2009           {
2010             if (! UNION_OR_STRUCT_P (t->u.p)
2011                 && t->u.p->kind != TYPE_PARAM_STRUCT)
2012               {
2013                 error_at_line (d->line,
2014                                "field `%s' is pointer to unimplemented type",
2015                                d->val);
2016                 break;
2017               }
2018
2019             if (nested_ptr_d)
2020               {
2021                 const char *oldprevval2 = d->prev_val[2];
2022
2023                 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2024                   {
2025                     error_at_line (d->line,
2026                                    "field `%s' has invalid "
2027                                    "option `nested_ptr'\n",
2028                                    d->val);
2029                     return;
2030                   }
2031
2032                 d->prev_val[2] = d->val;
2033                 oprintf (d->of, "%*s{\n", d->indent, "");
2034                 d->indent += 2;
2035                 d->val = xasprintf ("x%d", d->counter++);
2036                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2037                          (nested_ptr_d->type->kind == TYPE_UNION 
2038                           ? "union" : "struct"), 
2039                          nested_ptr_d->type->u.s.tag, 
2040                          d->fn_wants_lvalue ? "" : "const ",
2041                          d->val);
2042                 oprintf (d->of, "%*s", d->indent + 2, "");
2043                 output_escaped_param (d, nested_ptr_d->convert_from,
2044                                       "nested_ptr");
2045                 oprintf (d->of, ";\n");
2046
2047                 d->process_field (nested_ptr_d->type, d);
2048
2049                 if (d->fn_wants_lvalue)
2050                   {
2051                     oprintf (d->of, "%*s%s = ", d->indent, "",
2052                              d->prev_val[2]);
2053                     d->prev_val[2] = d->val;
2054                     output_escaped_param (d, nested_ptr_d->convert_to,
2055                                           "nested_ptr");
2056                     oprintf (d->of, ";\n");
2057                   }
2058
2059                 d->indent -= 2;
2060                 oprintf (d->of, "%*s}\n", d->indent, "");
2061                 d->val = d->prev_val[2];
2062                 d->prev_val[2] = oldprevval2;
2063               }
2064             else
2065               d->process_field (t->u.p, d);
2066           }
2067         else
2068           {
2069             int loopcounter = d->counter++;
2070             const char *oldval = d->val;
2071             const char *oldprevval3 = d->prev_val[3];
2072             char *newval;
2073
2074             oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2075             d->indent += 2;
2076             oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2077             oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
2078                      loopcounter, loopcounter);
2079             output_escaped_param (d, length, "length");
2080             oprintf (d->of, "); i%d++) {\n", loopcounter);
2081             d->indent += 2;
2082             d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2083             d->used_length = 1;
2084             d->prev_val[3] = oldval;
2085             walk_type (t->u.p, d);
2086             free (newval);
2087             d->val = oldval;
2088             d->prev_val[3] = oldprevval3;
2089             d->used_length = 0;
2090             d->indent -= 2;
2091             oprintf (d->of, "%*s}\n", d->indent, "");
2092             d->process_field(t, d);
2093             d->indent -= 2;
2094             oprintf (d->of, "%*s}\n", d->indent, "");
2095           }
2096       }
2097       break;
2098
2099     case TYPE_ARRAY:
2100       {
2101         int loopcounter = d->counter++;
2102         const char *oldval = d->val;
2103         char *newval;
2104
2105         /* If it's an array of scalars, we optimize by not generating
2106            any code.  */
2107         if (t->u.a.p->kind == TYPE_SCALAR)
2108           break;
2109
2110         /* When walking an array, compute the length and store it in a
2111            local variable before walking the array elements, instead of
2112            recomputing the length expression each time through the loop.
2113            This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2114            where the length is stored in the first array element,
2115            because otherwise that operand can get overwritten on the
2116            first iteration.  */
2117         oprintf (d->of, "%*s{\n", d->indent, "");
2118         d->indent += 2;
2119         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2120         oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2121                  d->indent, "", loopcounter);
2122         if (length)
2123           output_escaped_param (d, length, "length");
2124         else
2125           oprintf (d->of, "%s", t->u.a.len);
2126         oprintf (d->of, ");\n");
2127         
2128         oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2129                  d->indent, "",
2130                  loopcounter, loopcounter, loopcounter, loopcounter);
2131         d->indent += 2;
2132         d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2133         d->used_length = 1;
2134         walk_type (t->u.a.p, d);
2135         free (newval);
2136         d->used_length = 0;
2137         d->val = oldval;
2138         d->indent -= 2;
2139         oprintf (d->of, "%*s}\n", d->indent, "");
2140         d->indent -= 2;
2141         oprintf (d->of, "%*s}\n", d->indent, "");
2142       }
2143       break;
2144
2145     case TYPE_STRUCT:
2146     case TYPE_UNION:
2147       {
2148         pair_p f;
2149         const char *oldval = d->val;
2150         const char *oldprevval1 = d->prev_val[1];
2151         const char *oldprevval2 = d->prev_val[2];
2152         const int union_p = t->kind == TYPE_UNION;
2153         int seen_default_p = 0;
2154         options_p o;
2155
2156         if (! t->u.s.line.file)
2157           error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2158
2159         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2160           {
2161             error_at_line (d->line,
2162                            "structure `%s' defined for mismatching languages",
2163                            t->u.s.tag);
2164             error_at_line (&t->u.s.line, "one structure defined here");
2165           }
2166
2167         /* Some things may also be defined in the structure's options.  */
2168         for (o = t->u.s.opt; o; o = o->next)
2169           if (! desc && strcmp (o->name, "desc") == 0)
2170             desc = o->info;
2171
2172         d->prev_val[2] = oldval;
2173         d->prev_val[1] = oldprevval2;
2174         if (union_p)
2175           {
2176             if (desc == NULL)
2177               {
2178                 error_at_line (d->line, "missing `desc' option for union `%s'",
2179                                t->u.s.tag);
2180                 desc = "1";
2181               }
2182             oprintf (d->of, "%*sswitch (", d->indent, "");
2183             output_escaped_param (d, desc, "desc");
2184             oprintf (d->of, ")\n");
2185             d->indent += 2;
2186             oprintf (d->of, "%*s{\n", d->indent, "");
2187           }
2188         for (f = t->u.s.fields; f; f = f->next)
2189           {
2190             options_p oo;
2191             const char *dot = ".";
2192             const char *tagid = NULL;
2193             int skip_p = 0;
2194             int default_p = 0;
2195             int use_param_p = 0;
2196             char *newval;
2197
2198             d->reorder_fn = NULL;
2199             for (oo = f->opt; oo; oo = oo->next)
2200               if (strcmp (oo->name, "dot") == 0)
2201                 dot = oo->info;
2202               else if (strcmp (oo->name, "tag") == 0)
2203                 tagid = oo->info;
2204               else if (strcmp (oo->name, "skip") == 0)
2205                 skip_p = 1;
2206               else if (strcmp (oo->name, "default") == 0)
2207                 default_p = 1;
2208               else if (strcmp (oo->name, "reorder") == 0)
2209                 d->reorder_fn = oo->info;
2210               else if (strncmp (oo->name, "use_param", 9) == 0
2211                        && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2212                 use_param_p = 1;
2213
2214             if (skip_p)
2215               continue;
2216
2217             if (union_p && tagid)
2218               {
2219                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2220                 d->indent += 2;
2221               }
2222             else if (union_p && default_p)
2223               {
2224                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2225                 d->indent += 2;
2226                 seen_default_p = 1;
2227               }
2228             else if (! union_p && (default_p || tagid))
2229               error_at_line (d->line,
2230                              "can't use `%s' outside a union on field `%s'",
2231                              default_p ? "default" : "tag", f->name);
2232             else if (union_p && ! (default_p || tagid)
2233                      && f->type->kind == TYPE_SCALAR)
2234               {
2235                 fprintf (stderr,
2236         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2237                          d->line->file, d->line->line, f->name);
2238                 continue;
2239               }
2240             else if (union_p && ! (default_p || tagid))
2241               error_at_line (d->line,
2242                              "field `%s' is missing `tag' or `default' option",
2243                              f->name);
2244
2245             d->line = &f->line;
2246             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2247             d->opt = f->opt;
2248             d->used_length = false;
2249
2250             if (union_p && use_param_p && d->param == NULL)
2251               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2252             else
2253               walk_type (f->type, d);
2254
2255             free (newval);
2256
2257             if (union_p)
2258               {
2259                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2260                 d->indent -= 2;
2261               }
2262           }
2263         d->reorder_fn = NULL;
2264
2265         d->val = oldval;
2266         d->prev_val[1] = oldprevval1;
2267         d->prev_val[2] = oldprevval2;
2268
2269         if (union_p && ! seen_default_p)
2270           {
2271             oprintf (d->of, "%*sdefault:\n", d->indent, "");
2272             oprintf (d->of, "%*s  break;\n", d->indent, "");
2273           }
2274         if (union_p)
2275           {
2276             oprintf (d->of, "%*s}\n", d->indent, "");
2277             d->indent -= 2;
2278           }
2279       }
2280       break;
2281
2282     case TYPE_LANG_STRUCT:
2283       {
2284         type_p nt;
2285         for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2286           if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2287             break;
2288         if (nt == NULL)
2289           error_at_line (d->line, "structure `%s' differs between languages",
2290                          t->u.s.tag);
2291         else
2292           walk_type (nt, d);
2293       }
2294       break;
2295
2296     case TYPE_PARAM_STRUCT:
2297       {
2298         type_p *oldparam = d->param;
2299
2300         d->param = t->u.param_struct.param;
2301         walk_type (t->u.param_struct.stru, d);
2302         d->param = oldparam;
2303       }
2304       break;
2305
2306     default:
2307       gcc_unreachable ();
2308     }
2309 }
2310
2311 /* process_field routine for marking routines.  */
2312
2313 static void
2314 write_types_process_field (type_p f, const struct walk_type_data *d)
2315 {
2316   const struct write_types_data *wtd;
2317   const char *cast = d->needs_cast_p ? "(void *)" : "";
2318   wtd = (const struct write_types_data *) d->cookie;
2319
2320   switch (f->kind)
2321     {
2322     case TYPE_POINTER:
2323       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2324                wtd->subfield_marker_routine, cast, d->val);
2325       if (wtd->param_prefix)
2326         {
2327           oprintf (d->of, ", %s", d->prev_val[3]);
2328           if (d->orig_s)
2329             {
2330               oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2331               output_mangled_typename (d->of, d->orig_s);
2332             }
2333           else
2334             oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2335
2336           if (f->u.p->kind == TYPE_PARAM_STRUCT
2337               && f->u.p->u.s.line.file != NULL)
2338             {
2339               oprintf (d->of, ", gt_e_");
2340               output_mangled_typename (d->of, f);
2341             }
2342           else if (UNION_OR_STRUCT_P (f)
2343                    && f->u.p->u.s.line.file != NULL)
2344             {
2345               oprintf (d->of, ", gt_ggc_e_");
2346               output_mangled_typename (d->of, f);
2347             }
2348           else
2349             oprintf (d->of, ", gt_types_enum_last");
2350         }
2351       oprintf (d->of, ");\n");
2352       if (d->reorder_fn && wtd->reorder_note_routine)
2353         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2354                  wtd->reorder_note_routine, cast, d->val,
2355                  d->prev_val[3], d->reorder_fn);
2356       break;
2357
2358     case TYPE_STRING:
2359       if (wtd->param_prefix == NULL)
2360         break;
2361
2362     case TYPE_STRUCT:
2363     case TYPE_UNION:
2364     case TYPE_LANG_STRUCT:
2365     case TYPE_PARAM_STRUCT:
2366       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2367       output_mangled_typename (d->of, f);
2368       oprintf (d->of, " (%s%s);\n", cast, d->val);
2369       if (d->reorder_fn && wtd->reorder_note_routine)
2370         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2371                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
2372                  d->reorder_fn);
2373       break;
2374
2375     case TYPE_SCALAR:
2376       break;
2377
2378     default:
2379       gcc_unreachable ();
2380     }
2381 }
2382
2383 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2384
2385 static void
2386 output_type_enum (outf_p of, type_p s)
2387 {
2388   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2389     {
2390       oprintf (of, ", gt_e_");
2391       output_mangled_typename (of, s);
2392     }
2393   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2394     {
2395       oprintf (of, ", gt_ggc_e_");
2396       output_mangled_typename (of, s);
2397     }
2398   else
2399     oprintf (of, ", gt_types_enum_last");
2400 }
2401
2402 /* For S, a structure that's part of ORIG_S, and using parameters
2403    PARAM, write out a routine that:
2404    - Takes a parameter, a void * but actually of type *S
2405    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2406      field of S or its substructures and (in some cases) things
2407      that are pointed to by S.
2408 */
2409
2410 static void
2411 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2412                           const struct write_types_data *wtd)
2413 {
2414   const char *fn = s->u.s.line.file;
2415   int i;
2416   const char *chain_next = NULL;
2417   const char *chain_prev = NULL;
2418   const char *mark_hook_name = NULL;
2419   options_p opt;
2420   struct walk_type_data d;
2421
2422   /* This is a hack, and not the good kind either.  */
2423   for (i = NUM_PARAM - 1; i >= 0; i--)
2424     if (param && param[i] && param[i]->kind == TYPE_POINTER
2425         && UNION_OR_STRUCT_P (param[i]->u.p))
2426       fn = param[i]->u.p->u.s.line.file;
2427
2428   memset (&d, 0, sizeof (d));
2429   d.of = get_output_file_with_visibility (fn);
2430
2431   for (opt = s->u.s.opt; opt; opt = opt->next)
2432     if (strcmp (opt->name, "chain_next") == 0)
2433       chain_next = opt->info;
2434     else if (strcmp (opt->name, "chain_prev") == 0)
2435       chain_prev = opt->info;
2436     else if (strcmp (opt->name, "mark_hook") == 0)
2437       mark_hook_name = opt->info;
2438
2439   if (chain_prev != NULL && chain_next == NULL)
2440     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2441
2442   d.process_field = write_types_process_field;
2443   d.cookie = wtd;
2444   d.orig_s = orig_s;
2445   d.opt = s->u.s.opt;
2446   d.line = &s->u.s.line;
2447   d.bitmap = s->u.s.bitmap;
2448   d.param = param;
2449   d.prev_val[0] = "*x";
2450   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2451   d.prev_val[3] = "x";
2452   d.val = "(*x)";
2453
2454   oprintf (d.of, "\n");
2455   oprintf (d.of, "void\n");
2456   if (param == NULL)
2457     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2458   else
2459     {
2460       oprintf (d.of, "gt_%s_", wtd->prefix);
2461       output_mangled_typename (d.of, orig_s);
2462     }
2463   oprintf (d.of, " (void *x_p)\n");
2464   oprintf (d.of, "{\n");
2465   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2466            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2467            chain_next == NULL ? "const " : "",
2468            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2469   if (chain_next != NULL)
2470     oprintf (d.of, "  %s %s * xlimit = x;\n",
2471              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2472   if (chain_next == NULL)
2473     {
2474       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2475       if (wtd->param_prefix)
2476         {
2477           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2478           output_mangled_typename (d.of, orig_s);
2479           output_type_enum (d.of, orig_s);
2480         }
2481       oprintf (d.of, "))\n");
2482     }
2483   else
2484     {
2485       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2486       if (wtd->param_prefix)
2487         {
2488           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2489           output_mangled_typename (d.of, orig_s);
2490           output_type_enum (d.of, orig_s);
2491         }
2492       oprintf (d.of, "))\n");
2493       if (mark_hook_name && !wtd->skip_hooks)
2494         {
2495           oprintf (d.of, "    {\n");
2496           oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
2497         }
2498       oprintf (d.of, "   xlimit = (");
2499       d.prev_val[2] = "*xlimit";
2500       output_escaped_param (&d, chain_next, "chain_next");
2501       oprintf (d.of, ");\n");
2502       if (mark_hook_name && !wtd->skip_hooks)
2503         oprintf (d.of, "    }\n");
2504       if (chain_prev != NULL)
2505         {
2506           oprintf (d.of, "  if (x != xlimit)\n");
2507           oprintf (d.of, "    for (;;)\n");
2508           oprintf (d.of, "      {\n");
2509           oprintf (d.of, "        %s %s * const xprev = (",
2510                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2511
2512           d.prev_val[2] = "*x";
2513           output_escaped_param (&d, chain_prev, "chain_prev");
2514           oprintf (d.of, ");\n");
2515           oprintf (d.of, "        if (xprev == NULL) break;\n");
2516           oprintf (d.of, "        x = xprev;\n");
2517           oprintf (d.of, "        (void) %s (xprev",
2518                    wtd->marker_routine);
2519           if (wtd->param_prefix)
2520             {
2521               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2522               output_mangled_typename (d.of, orig_s);
2523               output_type_enum (d.of, orig_s);
2524             }
2525           oprintf (d.of, ");\n");
2526           oprintf (d.of, "      }\n");
2527         }
2528       oprintf (d.of, "  while (x != xlimit)\n");
2529     }
2530   oprintf (d.of, "    {\n");
2531   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2532     {
2533       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2534     }
2535   d.prev_val[2] = "*x";
2536   d.indent = 6;
2537   walk_type (s, &d);
2538
2539   if (chain_next != NULL)
2540     {
2541       oprintf (d.of, "      x = (");
2542       output_escaped_param (&d, chain_next, "chain_next");
2543       oprintf (d.of, ");\n");
2544     }
2545
2546   oprintf (d.of, "    }\n");
2547   oprintf (d.of, "}\n");
2548 }
2549
2550 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2551
2552 static void
2553 write_types (type_p structures, type_p param_structs,
2554              const struct write_types_data *wtd)
2555 {
2556   type_p s;
2557
2558   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2559   for (s = structures; s; s = s->next)
2560     if (s->gc_used == GC_POINTED_TO
2561         || s->gc_used == GC_MAYBE_POINTED_TO)
2562       {
2563         options_p opt;
2564
2565         if (s->gc_used == GC_MAYBE_POINTED_TO
2566             && s->u.s.line.file == NULL)
2567           continue;
2568
2569         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2570         output_mangled_typename (header_file, s);
2571         oprintf (header_file, "(X) do { \\\n");
2572         oprintf (header_file,
2573                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2574                  s->u.s.tag);
2575         oprintf (header_file,
2576                  "  } while (0)\n");
2577
2578         for (opt = s->u.s.opt; opt; opt = opt->next)
2579           if (strcmp (opt->name, "ptr_alias") == 0)
2580             {
2581               const_type_p const t = (const_type_p) opt->info;
2582               if (t->kind == TYPE_STRUCT
2583                   || t->kind == TYPE_UNION
2584                   || t->kind == TYPE_LANG_STRUCT)
2585                 oprintf (header_file,
2586                          "#define gt_%sx_%s gt_%sx_%s\n",
2587                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2588               else
2589                 error_at_line (&s->u.s.line,
2590                                "structure alias is not a structure");
2591               break;
2592             }
2593         if (opt)
2594           continue;
2595
2596         /* Declare the marker procedure only once.  */
2597         oprintf (header_file,
2598                  "extern void gt_%sx_%s (void *);\n",
2599                  wtd->prefix, s->u.s.tag);
2600
2601         if (s->u.s.line.file == NULL)
2602           {
2603             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2604                      s->u.s.tag);
2605             continue;
2606           }
2607
2608         if (s->kind == TYPE_LANG_STRUCT)
2609           {
2610             type_p ss;
2611             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2612               write_func_for_structure (s, ss, NULL, wtd);
2613           }
2614         else
2615           write_func_for_structure (s, s, NULL, wtd);
2616       }
2617
2618   for (s = param_structs; s; s = s->next)
2619     if (s->gc_used == GC_POINTED_TO)
2620       {
2621         type_p * param = s->u.param_struct.param;
2622         type_p stru = s->u.param_struct.stru;
2623
2624         /* Declare the marker procedure.  */
2625         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2626         output_mangled_typename (header_file, s);
2627         oprintf (header_file, " (void *);\n");
2628
2629         if (stru->u.s.line.file == NULL)
2630           {
2631             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2632                      s->u.s.tag);
2633             continue;
2634           }
2635
2636         if (stru->kind == TYPE_LANG_STRUCT)
2637           {
2638             type_p ss;
2639             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2640               write_func_for_structure (s, ss, param, wtd);
2641           }
2642         else
2643           write_func_for_structure (s, stru, param, wtd);
2644       }
2645 }
2646
2647 static const struct write_types_data ggc_wtd =
2648 {
2649   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2650   "GC marker procedures.  ",
2651   FALSE
2652 };
2653
2654 static const struct write_types_data pch_wtd =
2655 {
2656   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2657   "gt_pch_note_reorder",
2658   "PCH type-walking procedures.  ",
2659   TRUE
2660 };
2661
2662 /* Write out the local pointer-walking routines.  */
2663
2664 /* process_field routine for local pointer-walking.  */
2665
2666 static void
2667 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2668 {
2669   switch (f->kind)
2670     {
2671     case TYPE_POINTER:
2672     case TYPE_STRUCT:
2673     case TYPE_UNION:
2674     case TYPE_LANG_STRUCT:
2675     case TYPE_PARAM_STRUCT:
2676     case TYPE_STRING:
2677       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2678                d->prev_val[3]);
2679       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2680       break;
2681
2682     case TYPE_SCALAR:
2683       break;
2684
2685     default:
2686       gcc_unreachable ();
2687     }
2688 }
2689
2690 /* For S, a structure that's part of ORIG_S, and using parameters
2691    PARAM, write out a routine that:
2692    - Is of type gt_note_pointers
2693    - Calls PROCESS_FIELD on each field of S or its substructures.
2694 */
2695
2696 static void
2697 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2698 {
2699   const char *fn = s->u.s.line.file;
2700   int i;
2701   struct walk_type_data d;
2702
2703   /* This is a hack, and not the good kind either.  */
2704   for (i = NUM_PARAM - 1; i >= 0; i--)
2705     if (param && param[i] && param[i]->kind == TYPE_POINTER
2706         && UNION_OR_STRUCT_P (param[i]->u.p))
2707       fn = param[i]->u.p->u.s.line.file;
2708
2709   memset (&d, 0, sizeof (d));
2710   d.of = get_output_file_with_visibility (fn);
2711
2712   d.process_field = write_types_local_process_field;
2713   d.opt = s->u.s.opt;
2714   d.line = &s->u.s.line;
2715   d.bitmap = s->u.s.bitmap;
2716   d.param = param;
2717   d.prev_val[0] = d.prev_val[2] = "*x";
2718   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2719   d.prev_val[3] = "x";
2720   d.val = "(*x)";
2721   d.fn_wants_lvalue = true;
2722
2723   oprintf (d.of, "\n");
2724   oprintf (d.of, "void\n");
2725   oprintf (d.of, "gt_pch_p_");
2726   output_mangled_typename (d.of, orig_s);
2727   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2728            "\tvoid *x_p,\n"
2729            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2730            "\tATTRIBUTE_UNUSED void *cookie)\n");
2731   oprintf (d.of, "{\n");
2732   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2733            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2734            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2735   d.indent = 2;
2736   walk_type (s, &d);
2737   oprintf (d.of, "}\n");
2738 }
2739
2740 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2741
2742 static void
2743 write_local (type_p structures, type_p param_structs)
2744 {
2745   type_p s;
2746
2747   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2748   for (s = structures; s; s = s->next)
2749     if (s->gc_used == GC_POINTED_TO
2750         || s->gc_used == GC_MAYBE_POINTED_TO)
2751       {
2752         options_p opt;
2753
2754         if (s->u.s.line.file == NULL)
2755           continue;
2756
2757         for (opt = s->u.s.opt; opt; opt = opt->next)
2758           if (strcmp (opt->name, "ptr_alias") == 0)
2759             {
2760               const_type_p const t = (const_type_p) opt->info;
2761               if (t->kind == TYPE_STRUCT
2762                   || t->kind == TYPE_UNION
2763                   || t->kind == TYPE_LANG_STRUCT)
2764                 {
2765                   oprintf (header_file, "#define gt_pch_p_");
2766                   output_mangled_typename (header_file, s);
2767                   oprintf (header_file, " gt_pch_p_");
2768                   output_mangled_typename (header_file, t);
2769                   oprintf (header_file, "\n");
2770                 }
2771               else
2772                 error_at_line (&s->u.s.line,
2773                                "structure alias is not a structure");
2774               break;
2775             }
2776         if (opt)
2777           continue;
2778
2779         /* Declare the marker procedure only once.  */
2780         oprintf (header_file, "extern void gt_pch_p_");
2781         output_mangled_typename (header_file, s);
2782         oprintf (header_file,
2783          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2784
2785         if (s->kind == TYPE_LANG_STRUCT)
2786           {
2787             type_p ss;
2788             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2789               write_local_func_for_structure (s, ss, NULL);
2790           }
2791         else
2792           write_local_func_for_structure (s, s, NULL);
2793       }
2794
2795   for (s = param_structs; s; s = s->next)
2796     if (s->gc_used == GC_POINTED_TO)
2797       {
2798         type_p * param = s->u.param_struct.param;
2799         type_p stru = s->u.param_struct.stru;
2800
2801         /* Declare the marker procedure.  */
2802         oprintf (header_file, "extern void gt_pch_p_");
2803         output_mangled_typename (header_file, s);
2804         oprintf (header_file,
2805          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2806
2807         if (stru->u.s.line.file == NULL)
2808           {
2809             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2810                      s->u.s.tag);
2811             continue;
2812           }
2813
2814         if (stru->kind == TYPE_LANG_STRUCT)
2815           {
2816             type_p ss;
2817             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2818               write_local_func_for_structure (s, ss, param);
2819           }
2820         else
2821           write_local_func_for_structure (s, stru, param);
2822       }
2823 }
2824
2825 /* Write out the 'enum' definition for gt_types_enum.  */
2826
2827 static void
2828 write_enum_defn (type_p structures, type_p param_structs)
2829 {
2830   type_p s;
2831
2832   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2833   oprintf (header_file, "enum gt_types_enum {\n");
2834   for (s = structures; s; s = s->next)
2835     if (s->gc_used == GC_POINTED_TO
2836         || s->gc_used == GC_MAYBE_POINTED_TO)
2837       {
2838         if (s->gc_used == GC_MAYBE_POINTED_TO
2839             && s->u.s.line.file == NULL)
2840           continue;
2841
2842         oprintf (header_file, " gt_ggc_e_");
2843         output_mangled_typename (header_file, s);
2844         oprintf (header_file, ", \n");
2845       }
2846   for (s = param_structs; s; s = s->next)
2847     if (s->gc_used == GC_POINTED_TO)
2848       {
2849         oprintf (header_file, " gt_e_");
2850         output_mangled_typename (header_file, s);
2851         oprintf (header_file, ", \n");
2852       }
2853   oprintf (header_file, " gt_types_enum_last\n");
2854   oprintf (header_file, "};\n");
2855 }
2856
2857 /* Might T contain any non-pointer elements?  */
2858
2859 static int
2860 contains_scalar_p (type_p t)
2861 {
2862   switch (t->kind)
2863     {
2864     case TYPE_STRING:
2865     case TYPE_POINTER:
2866       return 0;
2867     case TYPE_ARRAY:
2868       return contains_scalar_p (t->u.a.p);
2869     default:
2870       /* Could also check for structures that have no non-pointer
2871          fields, but there aren't enough of those to worry about.  */
2872       return 1;
2873     }
2874 }
2875
2876 /* Mangle FN and print it to F.  */
2877
2878 static void
2879 put_mangled_filename (outf_p f, const char *fn)
2880 {
2881   const char *name = get_output_file_name (fn);
2882   for (; *name != 0; name++)
2883     if (ISALNUM (*name))
2884       oprintf (f, "%c", *name);
2885     else
2886       oprintf (f, "%c", '_');
2887 }
2888
2889 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2890    LASTNAME, and NAME are all strings to insert in various places in
2891    the resulting code.  */
2892
2893 static void
2894 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2895                    const char *tname, const char *name)
2896 {
2897   struct flist *fli2;
2898
2899   for (fli2 = flp; fli2; fli2 = fli2->next)
2900     if (fli2->started_p)
2901       {
2902         oprintf (fli2->f, "  %s\n", lastname);
2903         oprintf (fli2->f, "};\n\n");
2904       }
2905
2906   for (fli2 = flp; fli2; fli2 = fli2->next)
2907     if (fli2->started_p)
2908       {
2909         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2910         int fnum;
2911
2912         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2913           if (bitmap & 1)
2914             {
2915               oprintf (base_files[fnum],
2916                        "extern const struct %s gt_%s_",
2917                        tname, pfx);
2918               put_mangled_filename (base_files[fnum], fli2->name);
2919               oprintf (base_files[fnum], "[];\n");
2920             }
2921       }
2922
2923   {
2924     size_t fnum;
2925     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2926       oprintf (base_files [fnum],
2927                "const struct %s * const %s[] = {\n",
2928                tname, name);
2929   }
2930
2931
2932   for (fli2 = flp; fli2; fli2 = fli2->next)
2933     if (fli2->started_p)
2934       {
2935         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2936         int fnum;
2937
2938         fli2->started_p = 0;
2939
2940         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2941           if (bitmap & 1)
2942             {
2943               oprintf (base_files[fnum], "  gt_%s_", pfx);
2944               put_mangled_filename (base_files[fnum], fli2->name);
2945               oprintf (base_files[fnum], ",\n");
2946             }
2947       }
2948
2949   {
2950     size_t fnum;
2951     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2952       {
2953         oprintf (base_files[fnum], "  NULL\n");
2954         oprintf (base_files[fnum], "};\n");
2955       }
2956   }
2957 }
2958
2959 /* Write out to F the table entry and any marker routines needed to
2960    mark NAME as TYPE.  The original variable is V, at LINE.
2961    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2962    is nonzero iff we are building the root table for hash table caches.  */
2963
2964 static void
2965 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2966             struct fileloc *line, const char *if_marked)
2967 {
2968   switch (type->kind)
2969     {
2970     case TYPE_STRUCT:
2971       {
2972         pair_p fld;
2973         for (fld = type->u.s.fields; fld; fld = fld->next)
2974           {
2975             int skip_p = 0;
2976             const char *desc = NULL;
2977             options_p o;
2978
2979             for (o = fld->opt; o; o = o->next)
2980               if (strcmp (o->name, "skip") == 0)
2981                 skip_p = 1;
2982               else if (strcmp (o->name, "desc") == 0)
2983                 desc = o->info;
2984               else
2985                 error_at_line (line,
2986                        "field `%s' of global `%s' has unknown option `%s'",
2987                                fld->name, name, o->name);
2988
2989             if (skip_p)
2990               continue;
2991             else if (desc && fld->type->kind == TYPE_UNION)
2992               {
2993                 pair_p validf = NULL;
2994                 pair_p ufld;
2995
2996                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2997                   {
2998                     const char *tag = NULL;
2999                     options_p oo;
3000
3001                     for (oo = ufld->opt; oo; oo = oo->next)
3002                       if (strcmp (oo->name, "tag") == 0)
3003                         tag = oo->info;
3004                     if (tag == NULL || strcmp (tag, desc) != 0)
3005                       continue;
3006                     if (validf != NULL)
3007                       error_at_line (line,
3008                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3009                                      name, fld->name, validf->name,
3010                                      name, fld->name, ufld->name,
3011                                      tag);
3012                     validf = ufld;
3013                   }
3014                 if (validf != NULL)
3015                   {
3016                     char *newname;
3017                     newname = xasprintf ("%s.%s.%s",
3018                                          name, fld->name, validf->name);
3019                     write_root (f, v, validf->type, newname, 0, line,
3020                                 if_marked);
3021                     free (newname);
3022                   }
3023               }
3024             else if (desc)
3025               error_at_line (line,
3026                      "global `%s.%s' has `desc' option but is not union",
3027                              name, fld->name);
3028             else
3029               {
3030                 char *newname;
3031                 newname = xasprintf ("%s.%s", name, fld->name);
3032                 write_root (f, v, fld->type, newname, 0, line, if_marked);
3033                 free (newname);
3034               }
3035           }
3036       }
3037       break;
3038
3039     case TYPE_ARRAY:
3040       {
3041         char *newname;
3042         newname = xasprintf ("%s[0]", name);
3043         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
3044         free (newname);
3045       }
3046       break;
3047
3048     case TYPE_POINTER:
3049       {
3050         type_p ap, tp;
3051
3052         oprintf (f, "  {\n");
3053         oprintf (f, "    &%s,\n", name);
3054         oprintf (f, "    1");
3055
3056         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3057           if (ap->u.a.len[0])
3058             oprintf (f, " * (%s)", ap->u.a.len);
3059           else if (ap == v->type)
3060             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3061         oprintf (f, ",\n");
3062         oprintf (f, "    sizeof (%s", v->name);
3063         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3064           oprintf (f, "[0]");
3065         oprintf (f, "),\n");
3066
3067         tp = type->u.p;
3068
3069         if (! has_length && UNION_OR_STRUCT_P (tp))
3070           {
3071             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3072             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3073           }
3074         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3075           {
3076             oprintf (f, "    &gt_ggc_m_");
3077             output_mangled_typename (f, tp);
3078             oprintf (f, ",\n    &gt_pch_n_");
3079             output_mangled_typename (f, tp);
3080           }
3081         else if (has_length
3082                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3083           {
3084             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3085             oprintf (f, "    &gt_pch_na_%s", name);
3086           }
3087         else
3088           {
3089             error_at_line (line,
3090                            "global `%s' is pointer to unimplemented type",
3091                            name);
3092           }
3093         if (if_marked)
3094           oprintf (f, ",\n    &%s", if_marked);
3095         oprintf (f, "\n  },\n");
3096       }
3097       break;
3098
3099     case TYPE_STRING:
3100       {
3101         oprintf (f, "  {\n");
3102         oprintf (f, "    &%s,\n", name);
3103         oprintf (f, "    1, \n");
3104         oprintf (f, "    sizeof (%s),\n", v->name);
3105         oprintf (f, "    &gt_ggc_m_S,\n");
3106         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3107         oprintf (f, "  },\n");
3108       }
3109       break;
3110
3111     case TYPE_SCALAR:
3112       break;
3113
3114     default:
3115       error_at_line (line,
3116                      "global `%s' is unimplemented type",
3117                      name);
3118     }
3119 }
3120
3121 /* This generates a routine to walk an array.  */
3122
3123 static void
3124 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3125 {
3126   struct walk_type_data d;
3127   char *prevval3;
3128
3129   memset (&d, 0, sizeof (d));
3130   d.of = f;
3131   d.cookie = wtd;
3132   d.indent = 2;
3133   d.line = &v->line;
3134   d.opt = v->opt;
3135   d.bitmap = get_lang_bitmap (v->line.file);
3136   d.param = NULL;
3137
3138   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3139
3140   if (wtd->param_prefix)
3141     {
3142       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3143       oprintf (f,
3144        "    (void *, void *, gt_pointer_operator, void *);\n");
3145       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3146                wtd->param_prefix, v->name);
3147       oprintf (d.of,
3148                "      ATTRIBUTE_UNUSED void *x_p,\n"
3149                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3150                "      ATTRIBUTE_UNUSED void * cookie)\n");
3151       oprintf (d.of, "{\n");
3152       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3153       d.process_field = write_types_local_process_field;
3154       walk_type (v->type, &d);
3155       oprintf (f, "}\n\n");
3156     }
3157
3158   d.opt = v->opt;
3159   oprintf (f, "static void gt_%sa_%s (void *);\n",
3160            wtd->prefix, v->name);
3161   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3162            wtd->prefix, v->name);
3163   oprintf (f, "{\n");
3164   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3165   d.process_field = write_types_process_field;
3166   walk_type (v->type, &d);
3167   free (prevval3);
3168   oprintf (f, "}\n\n");
3169 }
3170
3171 /* Output a table describing the locations and types of VARIABLES.  */
3172
3173 static void
3174 write_roots (pair_p variables)
3175 {
3176   pair_p v;
3177   struct flist *flp = NULL;
3178
3179   for (v = variables; v; v = v->next)
3180     {
3181       outf_p f = get_output_file_with_visibility (v->line.file);
3182       struct flist *fli;
3183       const char *length = NULL;
3184       int deletable_p = 0;
3185       options_p o;
3186
3187       for (o = v->opt; o; o = o->next)
3188         if (strcmp (o->name, "length") == 0)
3189           length = o->info;
3190         else if (strcmp (o->name, "deletable") == 0)
3191           deletable_p = 1;
3192         else if (strcmp (o->name, "param_is") == 0)
3193           ;
3194         else if (strncmp (o->name, "param", 5) == 0
3195                  && ISDIGIT (o->name[5])
3196                  && strcmp (o->name + 6, "_is") == 0)
3197           ;
3198         else if (strcmp (o->name, "if_marked") == 0)
3199           ;
3200         else
3201           error_at_line (&v->line,
3202                          "global `%s' has unknown option `%s'",
3203                          v->name, o->name);
3204
3205       for (fli = flp; fli; fli = fli->next)
3206         if (fli->f == f)
3207           break;
3208       if (fli == NULL)
3209         {
3210           fli = XNEW (struct flist);
3211           fli->f = f;
3212           fli->next = flp;
3213           fli->started_p = 0;
3214           fli->name = v->line.file;
3215           flp = fli;
3216
3217           oprintf (f, "\n/* GC roots.  */\n\n");
3218         }
3219
3220       if (! deletable_p
3221           && length
3222           && v->type->kind == TYPE_POINTER
3223           && (v->type->u.p->kind == TYPE_POINTER
3224               || v->type->u.p->kind == TYPE_STRUCT))
3225         {
3226           write_array (f, v, &ggc_wtd);
3227           write_array (f, v, &pch_wtd);
3228         }
3229     }
3230
3231   for (v = variables; v; v = v->next)
3232     {
3233       outf_p f = get_output_file_with_visibility (v->line.file);
3234       struct flist *fli;
3235       int skip_p = 0;
3236       int length_p = 0;
3237       options_p o;
3238
3239       for (o = v->opt; o; o = o->next)
3240         if (strcmp (o->name, "length") == 0)
3241           length_p = 1;
3242         else if (strcmp (o->name, "deletable") == 0
3243                  || strcmp (o->name, "if_marked") == 0)
3244           skip_p = 1;
3245
3246       if (skip_p)
3247         continue;
3248
3249       for (fli = flp; fli; fli = fli->next)
3250         if (fli->f == f)
3251           break;
3252       if (! fli->started_p)
3253         {
3254           fli->started_p = 1;
3255
3256           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
3257           put_mangled_filename (f, v->line.file);
3258           oprintf (f, "[] = {\n");
3259         }
3260
3261       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3262     }
3263
3264   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3265                      "gt_ggc_rtab");
3266
3267   for (v = variables; v; v = v->next)
3268     {
3269       outf_p f = get_output_file_with_visibility (v->line.file);
3270       struct flist *fli;
3271       int skip_p = 1;
3272       options_p o;
3273
3274       for (o = v->opt; o; o = o->next)
3275         if (strcmp (o->name, "deletable") == 0)
3276           skip_p = 0;
3277         else if (strcmp (o->name, "if_marked") == 0)
3278           skip_p = 1;
3279
3280       if (skip_p)
3281         continue;
3282
3283       for (fli = flp; fli; fli = fli->next)
3284         if (fli->f == f)
3285           break;
3286       if (! fli->started_p)
3287         {
3288           fli->started_p = 1;
3289
3290           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
3291           put_mangled_filename (f, v->line.file);
3292           oprintf (f, "[] = {\n");
3293         }
3294
3295       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3296                v->name, v->name);
3297     }
3298
3299   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3300                      "gt_ggc_deletable_rtab");
3301
3302   for (v = variables; v; v = v->next)
3303     {
3304       outf_p f = get_output_file_with_visibility (v->line.file);
3305       struct flist *fli;
3306       const char *if_marked = NULL;
3307       int length_p = 0;
3308       options_p o;
3309
3310       for (o = v->opt; o; o = o->next)
3311         if (strcmp (o->name, "length") == 0)
3312           length_p = 1;
3313         else if (strcmp (o->name, "if_marked") == 0)
3314           if_marked = o->info;
3315
3316       if (if_marked == NULL)
3317         continue;
3318
3319       if (v->type->kind != TYPE_POINTER
3320           || v->type->u.p->kind != TYPE_PARAM_STRUCT
3321           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3322         {
3323           error_at_line (&v->line, "if_marked option used but not hash table");
3324           continue;
3325         }
3326
3327       for (fli = flp; fli; fli = fli->next)
3328         if (fli->f == f)
3329           break;
3330       if (! fli->started_p)
3331         {
3332           fli->started_p = 1;
3333
3334           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
3335           put_mangled_filename (f, v->line.file);
3336           oprintf (f, "[] = {\n");
3337         }
3338
3339       write_root (f, v, v->type->u.p->u.param_struct.param[0],
3340                      v->name, length_p, &v->line, if_marked);
3341     }
3342
3343   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3344                      "gt_ggc_cache_rtab");
3345
3346   for (v = variables; v; v = v->next)
3347     {
3348       outf_p f = get_output_file_with_visibility (v->line.file);
3349       struct flist *fli;
3350       int length_p = 0;
3351       int if_marked_p = 0;
3352       options_p o;
3353
3354       for (o = v->opt; o; o = o->next)
3355         if (strcmp (o->name, "length") == 0)
3356           length_p = 1;
3357         else if (strcmp (o->name, "if_marked") == 0)
3358           if_marked_p = 1;
3359
3360       if (! if_marked_p)
3361         continue;
3362
3363       for (fli = flp; fli; fli = fli->next)
3364         if (fli->f == f)
3365           break;
3366       if (! fli->started_p)
3367         {
3368           fli->started_p = 1;
3369
3370           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
3371           put_mangled_filename (f, v->line.file);
3372           oprintf (f, "[] = {\n");
3373         }
3374
3375       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3376     }
3377
3378   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3379                      "gt_pch_cache_rtab");
3380
3381   for (v = variables; v; v = v->next)
3382     {
3383       outf_p f = get_output_file_with_visibility (v->line.file);
3384       struct flist *fli;
3385       int skip_p = 0;
3386       options_p o;
3387
3388       for (o = v->opt; o; o = o->next)
3389         if (strcmp (o->name, "deletable") == 0
3390             || strcmp (o->name, "if_marked") == 0)
3391           skip_p = 1;
3392
3393       if (skip_p)
3394         continue;
3395
3396       if (! contains_scalar_p (v->type))
3397         continue;
3398
3399       for (fli = flp; fli; fli = fli->next)
3400         if (fli->f == f)
3401           break;
3402       if (! fli->started_p)
3403         {
3404           fli->started_p = 1;
3405
3406           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3407           put_mangled_filename (f, v->line.file);
3408           oprintf (f, "[] = {\n");
3409         }
3410
3411       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3412                v->name, v->name);
3413     }
3414
3415   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3416                      "gt_pch_scalar_rtab");
3417 }
3418
3419 /* Record the definition of a generic VEC structure, as if we had expanded
3420    the macros in vec.h:
3421
3422    typedef struct VEC_<type>_base GTY(()) {
3423    unsigned num;
3424    unsigned alloc;
3425    <type> GTY((length ("%h.num"))) vec[1];
3426    } VEC_<type>_base
3427
3428    where the GTY(()) tags are only present if is_scalar is _false_.  */
3429
3430 void
3431 note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
3432 {
3433   pair_p fields;
3434   type_p t;
3435   options_p o;
3436   type_p len_ty = create_scalar_type ("unsigned");
3437   const char *name = concat ("VEC_", typename, "_base", (char *)0);
3438
3439   if (is_scalar)
3440     {
3441       t = create_scalar_type (typename);
3442       o = 0;
3443     }
3444   else
3445     {
3446       t = resolve_typedef (typename, pos);
3447       o = create_option (0, "length", "%h.num");
3448     }
3449
3450   /* We assemble the field list in reverse order.  */
3451   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3452   fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3453   fields = create_field_at (fields, len_ty, "num", 0, pos);
3454
3455   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3456 }
3457
3458 /* Record the definition of an allocation-specific VEC structure, as if
3459    we had expanded the macros in vec.h:
3460
3461    typedef struct VEC_<type>_<astrat> {
3462      VEC_<type>_base base;
3463    } VEC_<type>_<astrat>;
3464 */
3465 void
3466 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3467 {
3468   const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3469   const char *basename = concat ("VEC_", type, "_base", (char *)0);
3470
3471   pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3472                                   "base", 0, pos);
3473
3474   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3475 }
3476
3477 /* Yet more temporary kludge since gengtype doesn't understand conditionals.
3478    This must be kept in sync with input.h.  */
3479 static void
3480 define_location_structures (void)
3481 {
3482   pair_p fields;
3483   type_p locs;
3484   static struct fileloc pos = { this_file, __LINE__ };
3485   do_scalar_typedef ("source_location", &pos);
3486
3487 #ifdef USE_MAPPED_LOCATION
3488     fields = create_field (0, &scalar_nonchar, "column");
3489     fields = create_field (fields, &scalar_nonchar, "line");
3490     fields = create_field (fields, &string_type, "file");
3491     locs = new_structure ("anon:expanded_location", 0, &pos, fields, 0);
3492
3493     do_typedef ("expanded_location", locs, &pos);
3494     do_scalar_typedef ("location_t", &pos);
3495     do_scalar_typedef ("source_locus", &pos);
3496 #else
3497     fields = create_field (0, &scalar_nonchar, "line");
3498     fields = create_field (fields, &string_type, "file");
3499     locs = new_structure ("location_s", 0, &pos, fields, 0);
3500
3501     do_typedef ("expanded_location", locs, &pos);
3502     do_typedef ("location_t", locs, &pos);
3503     do_typedef ("source_locus", create_pointer (locs), &pos);
3504 #endif
3505 }
3506
3507 \f
3508 int
3509 main (int argc, char **argv)
3510 {
3511   size_t i;
3512   static struct fileloc pos = { this_file, 0 };
3513
3514   /* fatal uses this */
3515   progname = "gengtype";
3516
3517   if (argc != 3)
3518     fatal ("usage: gengtype srcdir input-list");
3519
3520   srcdir = argv[1];
3521   srcdir_len = strlen (srcdir);
3522
3523   read_input_list (argv[2]);
3524   if (hit_error)
3525     return 1;
3526
3527   scalar_char.u.scalar_is_char = true;
3528   scalar_nonchar.u.scalar_is_char = false;
3529   gen_rtx_next ();
3530
3531   /* These types are set up with #define or else outside of where
3532      we can see them.  */
3533   pos.line = __LINE__ + 1;
3534   do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3535   do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
3536   do_scalar_typedef ("double_int", &pos); pos.line++;
3537   do_scalar_typedef ("uint8", &pos); pos.line++;
3538   do_scalar_typedef ("jword", &pos); pos.line++;
3539   do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3540   do_scalar_typedef ("void", &pos); pos.line++;
3541   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3542   define_location_structures ();
3543
3544   for (i = 0; i < num_gt_files; i++)
3545     parse_file (gt_files[i]);
3546
3547   if (hit_error)
3548     return 1;
3549
3550   set_gc_used (variables);
3551
3552   open_base_files ();
3553   write_enum_defn (structures, param_structs);
3554   write_types (structures, param_structs, &ggc_wtd);
3555   write_types (structures, param_structs, &pch_wtd);
3556   write_local (structures, param_structs);
3557   write_roots (variables);
3558   write_rtx_next ();
3559   close_output_files ();
3560
3561   if (hit_error)
3562     return 1;
3563   return 0;
3564 }