OSDN Git Service

* g-expect.adb (Get_Command_Output): When expanding the output buffer
[pf3gnuchains/gcc-fork.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21
22 #include "bconfig.h"
23 #include "system.h"
24 #include "gengtype.h"
25 #include "errors.h"     /* for fatal */
26
27 /* Data types, macros, etc. used only in this file.  */
28
29 /* Kinds of types we can understand.  */
30 enum typekind {
31   TYPE_SCALAR,
32   TYPE_STRING,
33   TYPE_STRUCT,
34   TYPE_UNION,
35   TYPE_POINTER,
36   TYPE_ARRAY,
37   TYPE_LANG_STRUCT,
38   TYPE_PARAM_STRUCT
39 };
40
41 typedef unsigned lang_bitmap;
42
43 /* A way to pass data through to the output end.  */
44 struct options
45 {
46   struct options *next;
47   const char *name;
48   const char *info;
49 };
50
51 /* Option data for the 'nested_ptr' option.  */
52 struct nested_ptr_data
53 {
54   type_p type;
55   const char *convert_to;
56   const char *convert_from;
57 };
58
59 /* A name and a type.  */
60 struct pair
61 {
62   pair_p next;
63   const char *name;
64   type_p type;
65   struct fileloc line;
66   options_p opt;
67 };
68
69 #define NUM_PARAM 10
70
71 /* A description of a type.  */
72 enum gc_used_enum
73   {
74     GC_UNUSED = 0,
75     GC_USED,
76     GC_MAYBE_POINTED_TO,
77     GC_POINTED_TO
78   };
79
80 struct type
81 {
82   enum typekind kind;
83   type_p next;
84   type_p pointer_to;
85   enum gc_used_enum gc_used;
86   union {
87     type_p p;
88     struct {
89       const char *tag;
90       struct fileloc line;
91       pair_p fields;
92       options_p opt;
93       lang_bitmap bitmap;
94       type_p lang_struct;
95     } s;
96     bool scalar_is_char;
97     struct {
98       type_p p;
99       const char *len;
100     } a;
101     struct {
102       type_p stru;
103       type_p param[NUM_PARAM];
104       struct fileloc line;
105     } param_struct;
106   } u;
107 };
108
109 #define UNION_P(x)                                      \
110  ((x)->kind == TYPE_UNION ||                            \
111   ((x)->kind == TYPE_LANG_STRUCT                        \
112    && (x)->u.s.lang_struct->kind == TYPE_UNION))
113 #define UNION_OR_STRUCT_P(x)                    \
114  ((x)->kind == TYPE_UNION                       \
115   || (x)->kind == TYPE_STRUCT                   \
116   || (x)->kind == TYPE_LANG_STRUCT)
117
118 /* Structure representing an output file.  */
119 struct outf
120 {
121   struct outf *next;
122   const char *name;
123   size_t buflength;
124   size_t bufused;
125   char *buf;
126 };
127 typedef struct outf * outf_p;
128
129 /* An output file, suitable for definitions, that can see declarations
130    made in INPUT_FILE and is linked into every language that uses
131    INPUT_FILE.  */
132 extern outf_p get_output_file_with_visibility
133    (const char *input_file);
134 const char *get_output_file_name (const char *);
135
136 /* Print, like fprintf, to O.  */
137 static void oprintf (outf_p o, const char *S, ...)
138      ATTRIBUTE_PRINTF_2;
139
140 /* The list of output files.  */
141 static outf_p output_files;
142
143 /* The output header file that is included into pretty much every
144    source file.  */
145 static outf_p header_file;
146
147 /* Source directory.  */
148 static const char *srcdir;
149
150 /* Length of srcdir name.  */
151 static int srcdir_len = 0;
152
153 static outf_p create_file (const char *, const char *);
154 static const char * get_file_basename (const char *);
155
156 \f
157 /* Nonzero iff an error has occurred.  */
158 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 == 9)
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 >= 7)
1091                 t = scalar_tp, subname = "rt_int";
1092               else if (i == ADDR_DIFF_VEC && aindex == 4)
1093                 t = scalar_tp, subname = "rt_int";
1094               else if (i == VALUE && aindex == 0)
1095                 t = scalar_tp, subname = "rt_int";
1096               else if (i == REG && aindex == 1)
1097                 t = scalar_tp, subname = "rt_int";
1098               else if (i == REG && aindex == 2)
1099                 t = reg_attrs_tp, subname = "rt_reg";
1100               else if (i == SCRATCH && aindex == 0)
1101                 t = scalar_tp, subname = "rt_int";
1102               else if (i == SYMBOL_REF && aindex == 1)
1103                 t = scalar_tp, subname = "rt_int";
1104               else if (i == SYMBOL_REF && aindex == 2)
1105                 t = symbol_union_tp, subname = "";
1106               else if (i == BARRIER && aindex >= 3)
1107                 t = scalar_tp, subname = "rt_int";
1108               else
1109                 {
1110                   error_at_line (&lexer_line,
1111                         "rtx type `%s' has `0' in position %lu, can't handle",
1112                                  rtx_name[i], (unsigned long) aindex);
1113                   t = &string_type;
1114                   subname = "rt_int";
1115                 }
1116               break;
1117
1118             case 's':
1119             case 'S':
1120             case 'T':
1121               t = &string_type;
1122               subname = "rt_str";
1123               break;
1124
1125             case 'e':
1126             case 'u':
1127               t = rtx_tp;
1128               subname = "rt_rtx";
1129               break;
1130
1131             case 'E':
1132             case 'V':
1133               t = rtvec_tp;
1134               subname = "rt_rtvec";
1135               break;
1136
1137             case 't':
1138               t = tree_tp;
1139               subname = "rt_tree";
1140               break;
1141
1142             case 'b':
1143               t = bitmap_tp;
1144               subname = "rt_bit";
1145               break;
1146
1147             case 'B':
1148               t = basic_block_tp;
1149               subname = "rt_bb";
1150               break;
1151
1152             default:
1153               error_at_line (&lexer_line,
1154                      "rtx type `%s' has `%c' in position %lu, can't handle",
1155                              rtx_name[i], rtx_format[i][aindex],
1156                              (unsigned long)aindex);
1157               t = &string_type;
1158               subname = "rt_int";
1159               break;
1160             }
1161
1162           subfields = create_field (subfields, t,
1163                                     xasprintf (".fld[%lu].%s",
1164                                                (unsigned long) aindex,
1165                                                subname));
1166           subfields->opt = nodot;
1167           if (t == note_union_tp)
1168             subfields->opt = create_option (subfields->opt, "desc",
1169                                             "NOTE_LINE_NUMBER (&%0)");
1170           if (t == symbol_union_tp)
1171             subfields->opt = create_option (subfields->opt, "desc",
1172                                             "CONSTANT_POOL_ADDRESS_P (&%0)");
1173         }
1174
1175       if (i == SYMBOL_REF)
1176         {
1177           /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds.  */
1178           type_p field_tp = find_structure ("block_symbol", 0);
1179           subfields
1180             = create_optional_field (subfields, field_tp, "block_sym",
1181                                      "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
1182         }
1183
1184       sname = xasprintf ("rtx_def_%s", rtx_name[i]);
1185       substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
1186
1187       ftag = xstrdup (rtx_name[i]);
1188       for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
1189         ftag[nmindex] = TOUPPER (ftag[nmindex]);
1190
1191       flds = create_field (flds, substruct, "");
1192       flds->opt = create_option (nodot, "tag", ftag);
1193     }
1194
1195   return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
1196 }
1197
1198 /* Handle `special("tree_exp")'.  This is a special case for
1199    field `operands' of struct tree_exp, which although it claims to contain
1200    pointers to trees, actually sometimes contains pointers to RTL too.
1201    Passed T, the old type of the field, and OPT its options.  Returns
1202    a new type for the field.  */
1203
1204 static type_p
1205 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
1206 {
1207   pair_p flds;
1208   options_p nodot;
1209
1210   if (t->kind != TYPE_ARRAY)
1211     {
1212       error_at_line (&lexer_line,
1213                      "special `tree_exp' must be applied to an array");
1214       return &string_type;
1215     }
1216
1217   nodot = create_option (NULL, "dot", "");
1218
1219   flds = create_field (NULL, t, "");
1220   flds->opt = create_option (nodot, "length",
1221                              "TREE_OPERAND_LENGTH ((tree) &%0)");
1222   flds->opt = create_option (flds->opt, "default", "");
1223
1224   return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
1225 }
1226
1227 /* Perform any special processing on a type T, about to become the type
1228    of a field.  Return the appropriate type for the field.
1229    At present:
1230    - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
1231    - Similarly for arrays of pointer-to-char;
1232    - Converts structures for which a parameter is provided to
1233      TYPE_PARAM_STRUCT;
1234    - Handles "special" options.
1235 */
1236
1237 type_p
1238 adjust_field_type (type_p t, options_p opt)
1239 {
1240   int length_p = 0;
1241   const int pointer_p = t->kind == TYPE_POINTER;
1242   type_p params[NUM_PARAM];
1243   int params_p = 0;
1244   int i;
1245
1246   for (i = 0; i < NUM_PARAM; i++)
1247     params[i] = NULL;
1248
1249   for (; opt; opt = opt->next)
1250     if (strcmp (opt->name, "length") == 0)
1251       length_p = 1;
1252     else if (strcmp (opt->name, "param_is") == 0
1253              || (strncmp (opt->name, "param", 5) == 0
1254                  && ISDIGIT (opt->name[5])
1255                  && strcmp (opt->name + 6, "_is") == 0))
1256       {
1257         int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
1258
1259         if (! UNION_OR_STRUCT_P (t)
1260             && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1261           {
1262             error_at_line (&lexer_line,
1263    "option `%s' may only be applied to structures or structure pointers",
1264                            opt->name);
1265             return t;
1266           }
1267
1268         params_p = 1;
1269         if (params[num] != NULL)
1270           error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
1271         if (! ISDIGIT (opt->name[5]))
1272           params[num] = create_pointer ((type_p) opt->info);
1273         else
1274           params[num] = (type_p) opt->info;
1275       }
1276     else if (strcmp (opt->name, "special") == 0)
1277       {
1278         const char *special_name = opt->info;
1279         if (strcmp (special_name, "tree_exp") == 0)
1280           t = adjust_field_tree_exp (t, opt);
1281         else if (strcmp (special_name, "rtx_def") == 0)
1282           t = adjust_field_rtx_def (t, opt);
1283         else
1284           error_at_line (&lexer_line, "unknown special `%s'", special_name);
1285       }
1286
1287   if (params_p)
1288     {
1289       type_p realt;
1290
1291       if (pointer_p)
1292         t = t->u.p;
1293       realt = find_param_structure (t, params);
1294       t = pointer_p ? create_pointer (realt) : realt;
1295     }
1296
1297   if (! length_p
1298       && pointer_p
1299       && t->u.p->kind == TYPE_SCALAR
1300       && t->u.p->u.scalar_is_char)
1301     return &string_type;
1302   if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
1303       && t->u.a.p->u.p->kind == TYPE_SCALAR
1304       && t->u.a.p->u.p->u.scalar_is_char)
1305     return create_array (&string_type, t->u.a.len);
1306
1307   return t;
1308 }
1309
1310 \f
1311 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
1312 static void set_gc_used (pair_p);
1313
1314 /* Handle OPT for set_gc_used_type.  */
1315
1316 static void
1317 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
1318                     int *pass_param, int *length, int *skip, type_p *nested_ptr)
1319 {
1320   options_p o;
1321   for (o = opt; o; o = o->next)
1322     if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
1323       set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
1324     else if (strcmp (o->name, "maybe_undef") == 0)
1325       *maybe_undef = 1;
1326     else if (strcmp (o->name, "use_params") == 0)
1327       *pass_param = 1;
1328     else if (strcmp (o->name, "length") == 0)
1329       *length = 1;
1330     else if (strcmp (o->name, "skip") == 0)
1331       *skip = 1;
1332     else if (strcmp (o->name, "nested_ptr") == 0)
1333       *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
1334 }
1335
1336 /* Set the gc_used field of T to LEVEL, and handle the types it references.  */
1337
1338 static void
1339 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
1340 {
1341   if (t->gc_used >= level)
1342     return;
1343
1344   t->gc_used = level;
1345
1346   switch (t->kind)
1347     {
1348     case TYPE_STRUCT:
1349     case TYPE_UNION:
1350       {
1351         pair_p f;
1352         int dummy;
1353         type_p dummy2;
1354
1355         process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
1356                             &dummy2);
1357
1358         for (f = t->u.s.fields; f; f = f->next)
1359           {
1360             int maybe_undef = 0;
1361             int pass_param = 0;
1362             int length = 0;
1363             int skip = 0;
1364             type_p nested_ptr = NULL;
1365             process_gc_options (f->opt, level, &maybe_undef, &pass_param,
1366                                 &length, &skip, &nested_ptr);
1367
1368             if (nested_ptr && f->type->kind == TYPE_POINTER)
1369               set_gc_used_type (nested_ptr, GC_POINTED_TO, 
1370                                 pass_param ? param : NULL);
1371             else if (length && f->type->kind == TYPE_POINTER)
1372               set_gc_used_type (f->type->u.p, GC_USED, NULL);
1373             else if (maybe_undef && f->type->kind == TYPE_POINTER)
1374               set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
1375             else if (pass_param && f->type->kind == TYPE_POINTER && param)
1376               set_gc_used_type (find_param_structure (f->type->u.p, param),
1377                                 GC_POINTED_TO, NULL);
1378             else if (skip)
1379               ; /* target type is not used through this field */
1380             else
1381               set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
1382           }
1383         break;
1384       }
1385
1386     case TYPE_POINTER:
1387       set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
1388       break;
1389
1390     case TYPE_ARRAY:
1391       set_gc_used_type (t->u.a.p, GC_USED, param);
1392       break;
1393
1394     case TYPE_LANG_STRUCT:
1395       for (t = t->u.s.lang_struct; t; t = t->next)
1396         set_gc_used_type (t, level, param);
1397       break;
1398
1399     case TYPE_PARAM_STRUCT:
1400       {
1401         int i;
1402         for (i = 0; i < NUM_PARAM; i++)
1403           if (t->u.param_struct.param[i] != 0)
1404             set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
1405       }
1406       if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
1407         level = GC_POINTED_TO;
1408       else
1409         level = GC_USED;
1410       t->u.param_struct.stru->gc_used = GC_UNUSED;
1411       set_gc_used_type (t->u.param_struct.stru, level,
1412                         t->u.param_struct.param);
1413       break;
1414
1415     default:
1416       break;
1417     }
1418 }
1419
1420 /* Set the gc_used fields of all the types pointed to by VARIABLES.  */
1421
1422 static void
1423 set_gc_used (pair_p variables)
1424 {
1425   pair_p p;
1426   for (p = variables; p; p = p->next)
1427     set_gc_used_type (p->type, GC_USED, NULL);
1428 }
1429 \f
1430 /* File mapping routines.  For each input file, there is one output .c file
1431    (but some output files have many input files), and there is one .h file
1432    for the whole build.  */
1433
1434 /* Output file handling.  */
1435
1436 /* Create and return an outf_p for a new file for NAME, to be called
1437    ONAME.  */
1438
1439 static outf_p
1440 create_file (const char *name, const char *oname)
1441 {
1442   static const char *const hdr[] = {
1443     "   Copyright (C) 2004 Free Software Foundation, Inc.\n",
1444     "\n",
1445     "This file is part of GCC.\n",
1446     "\n",
1447     "GCC is free software; you can redistribute it and/or modify it under\n",
1448     "the terms of the GNU General Public License as published by the Free\n",
1449     "Software Foundation; either version 2, or (at your option) any later\n",
1450     "version.\n",
1451     "\n",
1452     "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
1453     "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
1454     "FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n",
1455     "for more details.\n",
1456     "\n",
1457     "You should have received a copy of the GNU General Public License\n",
1458     "along with GCC; see the file COPYING.  If not, write to the Free\n",
1459     "Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA\n",
1460     "02110-1301, USA.  */\n",
1461     "\n",
1462     "/* This file is machine generated.  Do not edit.  */\n"
1463   };
1464   outf_p f;
1465   size_t i;
1466
1467   f = XCNEW (struct outf);
1468   f->next = output_files;
1469   f->name = oname;
1470   output_files = f;
1471
1472   oprintf (f, "/* Type information for %s.\n", name);
1473   for (i = 0; i < ARRAY_SIZE (hdr); i++)
1474     oprintf (f, "%s", hdr[i]);
1475   return f;
1476 }
1477
1478 /* Print, like fprintf, to O.  
1479    N.B. You might think this could be implemented more efficiently
1480    with vsnprintf().  Unfortunately, there are C libraries that
1481    provide that function but without the C99 semantics for its return
1482    value, making it impossible to know how much space is required.  */
1483 void
1484 oprintf (outf_p o, const char *format, ...)
1485 {
1486   char *s;
1487   size_t slength;
1488   va_list ap;
1489
1490   va_start (ap, format);
1491   slength = vasprintf (&s, format, ap);
1492   if (s == NULL || (int)slength < 0)
1493     fatal ("out of memory");
1494   va_end (ap);
1495
1496   if (o->bufused + slength > o->buflength)
1497     {
1498       size_t new_len = o->buflength;
1499       if (new_len == 0)
1500         new_len = 1024;
1501       do {
1502         new_len *= 2;
1503       } while (o->bufused + slength >= new_len);
1504       o->buf = XRESIZEVEC (char, o->buf, new_len);
1505       o->buflength = new_len;
1506     }
1507   memcpy (o->buf + o->bufused, s, slength);
1508   o->bufused += slength;
1509   free (s);
1510 }
1511
1512 /* Open the global header file and the language-specific header files.  */
1513
1514 static void
1515 open_base_files (void)
1516 {
1517   size_t i;
1518
1519   header_file = create_file ("GCC", "gtype-desc.h");
1520
1521   base_files = XNEWVEC (outf_p, num_lang_dirs);
1522
1523   for (i = 0; i < num_lang_dirs; i++)
1524     base_files[i] = create_file (lang_dir_names[i],
1525                                  xasprintf ("gtype-%s.h", lang_dir_names[i]));
1526
1527   /* gtype-desc.c is a little special, so we create it here.  */
1528   {
1529     /* The order of files here matters very much.  */
1530     static const char *const ifiles [] = {
1531       "config.h", "system.h", "coretypes.h", "tm.h", "varray.h", 
1532       "hashtab.h", "splay-tree.h",  "obstack.h", "bitmap.h", "input.h",
1533       "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1534       "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1535       "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1536       "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1537       "cfglayout.h", "except.h", "output.h", NULL
1538     };
1539     const char *const *ifp;
1540     outf_p gtype_desc_c;
1541
1542     gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1543     for (ifp = ifiles; *ifp; ifp++)
1544       oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1545   }
1546 }
1547
1548 /* Determine the pathname to F relative to $(srcdir).  */
1549
1550 static const char *
1551 get_file_basename (const char *f)
1552 {
1553   const char *basename;
1554   unsigned i;
1555
1556   basename = strrchr (f, '/');
1557
1558   if (!basename)
1559     return f;
1560
1561   basename++;
1562
1563   for (i = 0; i < num_lang_dirs; i++)
1564     {
1565       const char * s1;
1566       const char * s2;
1567       int l1;
1568       int l2;
1569       s1 = basename - strlen (lang_dir_names [i]) - 1;
1570       s2 = lang_dir_names [i];
1571       l1 = strlen (s1);
1572       l2 = strlen (s2);
1573       if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1574         {
1575           basename -= l2 + 1;
1576           if ((basename - f - 1) != srcdir_len)
1577             fatal ("filename `%s' should be preceded by $srcdir", f);
1578           break;
1579         }
1580     }
1581
1582   return basename;
1583 }
1584
1585 /* An output file, suitable for definitions, that can see declarations
1586    made in INPUT_FILE and is linked into every language that uses
1587    INPUT_FILE.  */
1588
1589 outf_p
1590 get_output_file_with_visibility (const char *input_file)
1591 {
1592   outf_p r;
1593   size_t len;
1594   const char *basename;
1595   const char *for_name;
1596   const char *output_name;
1597
1598   /* This can happen when we need a file with visibility on a
1599      structure that we've never seen.  We have to just hope that it's
1600      globally visible.  */
1601   if (input_file == NULL)
1602     input_file = "system.h";
1603
1604   /* Determine the output file name.  */
1605   basename = get_file_basename (input_file);
1606
1607   len = strlen (basename);
1608   if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1609       || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1610       || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1611     {
1612       char *s;
1613
1614       output_name = s = xasprintf ("gt-%s", basename);
1615       for (; *s != '.'; s++)
1616         if (! ISALNUM (*s) && *s != '-')
1617           *s = '-';
1618       memcpy (s, ".h", sizeof (".h"));
1619       for_name = basename;
1620     }
1621   /* Some headers get used by more than one front-end; hence, it
1622      would be inappropriate to spew them out to a single gtype-<lang>.h
1623      (and gengtype doesn't know how to direct spewage into multiple
1624      gtype-<lang>.h headers at this time).  Instead, we pair up these
1625      headers with source files (and their special purpose gt-*.h headers).  */
1626   else if (strcmp (basename, "c-common.h") == 0)
1627     output_name = "gt-c-common.h", for_name = "c-common.c";
1628   else if (strcmp (basename, "c-tree.h") == 0)
1629     output_name = "gt-c-decl.h", for_name = "c-decl.c";
1630   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1631            && strcmp (basename + 3, "cp-tree.h") == 0)
1632     output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1633   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1634            && strcmp (basename + 3, "decl.h") == 0)
1635     output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1636   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1637            && strcmp (basename + 3, "name-lookup.h") == 0)
1638     output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1639   else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1640            && strcmp (basename + 5, "objc-act.h") == 0)
1641     output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1642   else 
1643     {
1644       size_t i;
1645
1646       for (i = 0; i < num_lang_dirs; i++)
1647         if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1648             && basename[strlen(lang_dir_names[i])] == '/')
1649           return base_files[i];
1650
1651       output_name = "gtype-desc.c";
1652       for_name = NULL;
1653     }
1654
1655   /* Look through to see if we've ever seen this output filename before.  */
1656   for (r = output_files; r; r = r->next)
1657     if (strcmp (r->name, output_name) == 0)
1658       return r;
1659
1660   /* If not, create it.  */
1661   r = create_file (for_name, output_name);
1662
1663   return r;
1664 }
1665
1666 /* The name of an output file, suitable for definitions, that can see
1667    declarations made in INPUT_FILE and is linked into every language
1668    that uses INPUT_FILE.  */
1669
1670 const char *
1671 get_output_file_name (const char *input_file)
1672 {
1673   return get_output_file_with_visibility (input_file)->name;
1674 }
1675
1676 /* Copy the output to its final destination,
1677    but don't unnecessarily change modification times.  */
1678
1679 static void
1680 close_output_files (void)
1681 {
1682   outf_p of;
1683
1684   for (of = output_files; of; of = of->next)
1685     {
1686       FILE * newfile;
1687
1688       newfile = fopen (of->name, "r");
1689       if (newfile != NULL )
1690         {
1691           int no_write_p;
1692           size_t i;
1693
1694           for (i = 0; i < of->bufused; i++)
1695             {
1696               int ch;
1697               ch = fgetc (newfile);
1698               if (ch == EOF || ch != (unsigned char) of->buf[i])
1699                 break;
1700             }
1701           no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1702           fclose (newfile);
1703
1704           if (no_write_p)
1705             continue;
1706         }
1707
1708       newfile = fopen (of->name, "w");
1709       if (newfile == NULL)
1710         fatal ("opening output file %s: %s", of->name, strerror (errno));
1711       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1712         fatal ("writing output file %s: %s", of->name, strerror (errno));
1713       if (fclose (newfile) != 0)
1714         fatal ("closing output file %s: %s", of->name, strerror (errno));
1715     }
1716 }
1717 \f
1718 struct flist {
1719   struct flist *next;
1720   int started_p;
1721   const char *name;
1722   outf_p f;
1723 };
1724
1725 struct walk_type_data;
1726
1727 /* For scalars and strings, given the item in 'val'.
1728    For structures, given a pointer to the item in 'val'.
1729    For misc. pointers, given the item in 'val'.
1730 */
1731 typedef void (*process_field_fn)
1732      (type_p f, const struct walk_type_data *p);
1733 typedef void (*func_name_fn)
1734      (type_p s, const struct walk_type_data *p);
1735
1736 /* Parameters for write_types.  */
1737
1738 struct write_types_data
1739 {
1740   const char *prefix;
1741   const char *param_prefix;
1742   const char *subfield_marker_routine;
1743   const char *marker_routine;
1744   const char *reorder_note_routine;
1745   const char *comment;
1746   int skip_hooks;               /* skip hook generation if non zero */
1747 };
1748
1749 static void output_escaped_param (struct walk_type_data *d,
1750                                   const char *, const char *);
1751 static void output_mangled_typename (outf_p, type_p);
1752 static void walk_type (type_p t, struct walk_type_data *d);
1753 static void write_func_for_structure
1754      (type_p orig_s, type_p s, type_p * param,
1755       const struct write_types_data *wtd);
1756 static void write_types_process_field
1757      (type_p f, const struct walk_type_data *d);
1758 static void write_types (type_p structures,
1759                          type_p param_structs,
1760                          const struct write_types_data *wtd);
1761 static void write_types_local_process_field
1762      (type_p f, const struct walk_type_data *d);
1763 static void write_local_func_for_structure
1764      (type_p orig_s, type_p s, type_p * param);
1765 static void write_local (type_p structures,
1766                          type_p param_structs);
1767 static void write_enum_defn (type_p structures, type_p param_structs);
1768 static int contains_scalar_p (type_p t);
1769 static void put_mangled_filename (outf_p , const char *);
1770 static void finish_root_table (struct flist *flp, const char *pfx,
1771                                const char *tname, const char *lastname,
1772                                const char *name);
1773 static void write_root (outf_p , pair_p, type_p, const char *, int,
1774                         struct fileloc *, const char *);
1775 static void write_array (outf_p f, pair_p v,
1776                          const struct write_types_data *wtd);
1777 static void write_roots (pair_p);
1778
1779 /* Parameters for walk_type.  */
1780
1781 struct walk_type_data
1782 {
1783   process_field_fn process_field;
1784   const void *cookie;
1785   outf_p of;
1786   options_p opt;
1787   const char *val;
1788   const char *prev_val[4];
1789   int indent;
1790   int counter;
1791   struct fileloc *line;
1792   lang_bitmap bitmap;
1793   type_p *param;
1794   int used_length;
1795   type_p orig_s;
1796   const char *reorder_fn;
1797   bool needs_cast_p;
1798   bool fn_wants_lvalue;
1799 };
1800
1801 /* Print a mangled name representing T to OF.  */
1802
1803 static void
1804 output_mangled_typename (outf_p of, type_p t)
1805 {
1806   if (t == NULL)
1807     oprintf (of, "Z");
1808   else switch (t->kind)
1809     {
1810     case TYPE_POINTER:
1811       oprintf (of, "P");
1812       output_mangled_typename (of, t->u.p);
1813       break;
1814     case TYPE_SCALAR:
1815       oprintf (of, "I");
1816       break;
1817     case TYPE_STRING:
1818       oprintf (of, "S");
1819       break;
1820     case TYPE_STRUCT:
1821     case TYPE_UNION:
1822     case TYPE_LANG_STRUCT:
1823       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1824       break;
1825     case TYPE_PARAM_STRUCT:
1826       {
1827         int i;
1828         for (i = 0; i < NUM_PARAM; i++)
1829           if (t->u.param_struct.param[i] != NULL)
1830             output_mangled_typename (of, t->u.param_struct.param[i]);
1831         output_mangled_typename (of, t->u.param_struct.stru);
1832       }
1833       break;
1834     case TYPE_ARRAY:
1835       gcc_unreachable ();
1836     }
1837 }
1838
1839 /* Print PARAM to D->OF processing escapes.  D->VAL references the
1840    current object, D->PREV_VAL the object containing the current
1841    object, ONAME is the name of the option and D->LINE is used to
1842    print error messages.  */
1843
1844 static void
1845 output_escaped_param (struct walk_type_data *d, const char *param,
1846                       const char *oname)
1847 {
1848   const char *p;
1849
1850   for (p = param; *p; p++)
1851     if (*p != '%')
1852       oprintf (d->of, "%c", *p);
1853     else switch (*++p)
1854       {
1855       case 'h':
1856         oprintf (d->of, "(%s)", d->prev_val[2]);
1857         break;
1858       case '0':
1859         oprintf (d->of, "(%s)", d->prev_val[0]);
1860         break;
1861       case '1':
1862         oprintf (d->of, "(%s)", d->prev_val[1]);
1863         break;
1864       case 'a':
1865         {
1866           const char *pp = d->val + strlen (d->val);
1867           while (pp[-1] == ']')
1868             while (*pp != '[')
1869               pp--;
1870           oprintf (d->of, "%s", pp);
1871         }
1872         break;
1873       default:
1874         error_at_line (d->line, "`%s' option contains bad escape %c%c",
1875                        oname, '%', *p);
1876       }
1877 }
1878
1879 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1880    which is of type T.  Write code to D->OF to constrain execution (at
1881    the point that D->PROCESS_FIELD is called) to the appropriate
1882    cases.  Call D->PROCESS_FIELD on subobjects before calling it on
1883    pointers to those objects.  D->PREV_VAL lists the objects
1884    containing the current object, D->OPT is a list of options to
1885    apply, D->INDENT is the current indentation level, D->LINE is used
1886    to print error messages, D->BITMAP indicates which languages to
1887    print the structure for, and D->PARAM is the current parameter
1888    (from an enclosing param_is option).  */
1889
1890 static void
1891 walk_type (type_p t, struct walk_type_data *d)
1892 {
1893   const char *length = NULL;
1894   const char *desc = NULL;
1895   int maybe_undef_p = 0;
1896   int use_param_num = -1;
1897   int use_params_p = 0;
1898   options_p oo;
1899   const struct nested_ptr_data *nested_ptr_d = NULL;
1900
1901   d->needs_cast_p = false;
1902   for (oo = d->opt; oo; oo = oo->next)
1903     if (strcmp (oo->name, "length") == 0)
1904       length = oo->info;
1905     else if (strcmp (oo->name, "maybe_undef") == 0)
1906       maybe_undef_p = 1;
1907     else if (strncmp (oo->name, "use_param", 9) == 0
1908              && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1909       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1910     else if (strcmp (oo->name, "use_params") == 0)
1911       use_params_p = 1;
1912     else if (strcmp (oo->name, "desc") == 0)
1913       desc = oo->info;
1914     else if (strcmp (oo->name, "mark_hook") == 0)
1915       ;
1916     else if (strcmp (oo->name, "nested_ptr") == 0)
1917       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1918     else if (strcmp (oo->name, "dot") == 0)
1919       ;
1920     else if (strcmp (oo->name, "tag") == 0)
1921       ;
1922     else if (strcmp (oo->name, "special") == 0)
1923       ;
1924     else if (strcmp (oo->name, "skip") == 0)
1925       ;
1926     else if (strcmp (oo->name, "default") == 0)
1927       ;
1928     else if (strcmp (oo->name, "descbits") == 0)
1929       ;
1930     else if (strcmp (oo->name, "param_is") == 0)
1931       ;
1932     else if (strncmp (oo->name, "param", 5) == 0
1933              && ISDIGIT (oo->name[5])
1934              && strcmp (oo->name + 6, "_is") == 0)
1935       ;
1936     else if (strcmp (oo->name, "chain_next") == 0)
1937       ;
1938     else if (strcmp (oo->name, "chain_prev") == 0)
1939       ;
1940     else if (strcmp (oo->name, "reorder") == 0)
1941       ;
1942     else
1943       error_at_line (d->line, "unknown option `%s'\n", oo->name);
1944
1945   if (d->used_length)
1946     length = NULL;
1947
1948   if (use_params_p)
1949     {
1950       int pointer_p = t->kind == TYPE_POINTER;
1951
1952       if (pointer_p)
1953         t = t->u.p;
1954       if (! UNION_OR_STRUCT_P (t))
1955         error_at_line (d->line, "`use_params' option on unimplemented type");
1956       else
1957         t = find_param_structure (t, d->param);
1958       if (pointer_p)
1959         t = create_pointer (t);
1960     }
1961
1962   if (use_param_num != -1)
1963     {
1964       if (d->param != NULL && d->param[use_param_num] != NULL)
1965         {
1966           type_p nt = d->param[use_param_num];
1967
1968           if (t->kind == TYPE_ARRAY)
1969             nt = create_array (nt, t->u.a.len);
1970           else if (length != NULL && t->kind == TYPE_POINTER)
1971             nt = create_pointer (nt);
1972           d->needs_cast_p = (t->kind != TYPE_POINTER
1973                              && (nt->kind == TYPE_POINTER
1974                                  || nt->kind == TYPE_STRING));
1975           t = nt;
1976         }
1977       else
1978         error_at_line (d->line, "no parameter defined for `%s'",
1979                        d->val);
1980     }
1981
1982   if (maybe_undef_p
1983       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1984     {
1985       error_at_line (d->line,
1986                      "field `%s' has invalid option `maybe_undef_p'\n",
1987                      d->val);
1988       return;
1989     }
1990
1991   switch (t->kind)
1992     {
1993     case TYPE_SCALAR:
1994     case TYPE_STRING:
1995       d->process_field (t, d);
1996       break;
1997
1998     case TYPE_POINTER:
1999       {
2000         if (maybe_undef_p
2001             && t->u.p->u.s.line.file == NULL)
2002           {
2003             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2004             break;
2005           }
2006
2007         if (! length)
2008           {
2009             if (! UNION_OR_STRUCT_P (t->u.p)
2010                 && t->u.p->kind != TYPE_PARAM_STRUCT)
2011               {
2012                 error_at_line (d->line,
2013                                "field `%s' is pointer to unimplemented type",
2014                                d->val);
2015                 break;
2016               }
2017
2018             if (nested_ptr_d)
2019               {
2020                 const char *oldprevval2 = d->prev_val[2];
2021
2022                 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2023                   {
2024                     error_at_line (d->line,
2025                                    "field `%s' has invalid "
2026                                    "option `nested_ptr'\n",
2027                                    d->val);
2028                     return;
2029                   }
2030
2031                 d->prev_val[2] = d->val;
2032                 oprintf (d->of, "%*s{\n", d->indent, "");
2033                 d->indent += 2;
2034                 d->val = xasprintf ("x%d", d->counter++);
2035                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2036                          (nested_ptr_d->type->kind == TYPE_UNION 
2037                           ? "union" : "struct"), 
2038                          nested_ptr_d->type->u.s.tag, 
2039                          d->fn_wants_lvalue ? "" : "const ",
2040                          d->val);
2041                 oprintf (d->of, "%*s", d->indent + 2, "");
2042                 output_escaped_param (d, nested_ptr_d->convert_from,
2043                                       "nested_ptr");
2044                 oprintf (d->of, ";\n");
2045
2046                 d->process_field (nested_ptr_d->type, d);
2047
2048                 if (d->fn_wants_lvalue)
2049                   {
2050                     oprintf (d->of, "%*s%s = ", d->indent, "",
2051                              d->prev_val[2]);
2052                     d->prev_val[2] = d->val;
2053                     output_escaped_param (d, nested_ptr_d->convert_to,
2054                                           "nested_ptr");
2055                     oprintf (d->of, ";\n");
2056                   }
2057
2058                 d->indent -= 2;
2059                 oprintf (d->of, "%*s}\n", d->indent, "");
2060                 d->val = d->prev_val[2];
2061                 d->prev_val[2] = oldprevval2;
2062               }
2063             else
2064               d->process_field (t->u.p, d);
2065           }
2066         else
2067           {
2068             int loopcounter = d->counter++;
2069             const char *oldval = d->val;
2070             const char *oldprevval3 = d->prev_val[3];
2071             char *newval;
2072
2073             oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2074             d->indent += 2;
2075             oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2076             oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
2077                      loopcounter, loopcounter);
2078             output_escaped_param (d, length, "length");
2079             oprintf (d->of, "); i%d++) {\n", loopcounter);
2080             d->indent += 2;
2081             d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2082             d->used_length = 1;
2083             d->prev_val[3] = oldval;
2084             walk_type (t->u.p, d);
2085             free (newval);
2086             d->val = oldval;
2087             d->prev_val[3] = oldprevval3;
2088             d->used_length = 0;
2089             d->indent -= 2;
2090             oprintf (d->of, "%*s}\n", d->indent, "");
2091             d->process_field(t, d);
2092             d->indent -= 2;
2093             oprintf (d->of, "%*s}\n", d->indent, "");
2094           }
2095       }
2096       break;
2097
2098     case TYPE_ARRAY:
2099       {
2100         int loopcounter = d->counter++;
2101         const char *oldval = d->val;
2102         char *newval;
2103
2104         /* If it's an array of scalars, we optimize by not generating
2105            any code.  */
2106         if (t->u.a.p->kind == TYPE_SCALAR)
2107           break;
2108
2109         /* When walking an array, compute the length and store it in a
2110            local variable before walking the array elements, instead of
2111            recomputing the length expression each time through the loop.
2112            This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2113            where the length is stored in the first array element,
2114            because otherwise that operand can get overwritten on the
2115            first iteration.  */
2116         oprintf (d->of, "%*s{\n", d->indent, "");
2117         d->indent += 2;
2118         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2119         oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2120                  d->indent, "", loopcounter);
2121         if (length)
2122           output_escaped_param (d, length, "length");
2123         else
2124           oprintf (d->of, "%s", t->u.a.len);
2125         oprintf (d->of, ");\n");
2126         
2127         oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2128                  d->indent, "",
2129                  loopcounter, loopcounter, loopcounter, loopcounter);
2130         d->indent += 2;
2131         d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2132         d->used_length = 1;
2133         walk_type (t->u.a.p, d);
2134         free (newval);
2135         d->used_length = 0;
2136         d->val = oldval;
2137         d->indent -= 2;
2138         oprintf (d->of, "%*s}\n", d->indent, "");
2139         d->indent -= 2;
2140         oprintf (d->of, "%*s}\n", d->indent, "");
2141       }
2142       break;
2143
2144     case TYPE_STRUCT:
2145     case TYPE_UNION:
2146       {
2147         pair_p f;
2148         const char *oldval = d->val;
2149         const char *oldprevval1 = d->prev_val[1];
2150         const char *oldprevval2 = d->prev_val[2];
2151         const int union_p = t->kind == TYPE_UNION;
2152         int seen_default_p = 0;
2153         options_p o;
2154
2155         if (! t->u.s.line.file)
2156           error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2157
2158         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2159           {
2160             error_at_line (d->line,
2161                            "structure `%s' defined for mismatching languages",
2162                            t->u.s.tag);
2163             error_at_line (&t->u.s.line, "one structure defined here");
2164           }
2165
2166         /* Some things may also be defined in the structure's options.  */
2167         for (o = t->u.s.opt; o; o = o->next)
2168           if (! desc && strcmp (o->name, "desc") == 0)
2169             desc = o->info;
2170
2171         d->prev_val[2] = oldval;
2172         d->prev_val[1] = oldprevval2;
2173         if (union_p)
2174           {
2175             if (desc == NULL)
2176               {
2177                 error_at_line (d->line, "missing `desc' option for union `%s'",
2178                                t->u.s.tag);
2179                 desc = "1";
2180               }
2181             oprintf (d->of, "%*sswitch (", d->indent, "");
2182             output_escaped_param (d, desc, "desc");
2183             oprintf (d->of, ")\n");
2184             d->indent += 2;
2185             oprintf (d->of, "%*s{\n", d->indent, "");
2186           }
2187         for (f = t->u.s.fields; f; f = f->next)
2188           {
2189             options_p oo;
2190             const char *dot = ".";
2191             const char *tagid = NULL;
2192             int skip_p = 0;
2193             int default_p = 0;
2194             int use_param_p = 0;
2195             char *newval;
2196
2197             d->reorder_fn = NULL;
2198             for (oo = f->opt; oo; oo = oo->next)
2199               if (strcmp (oo->name, "dot") == 0)
2200                 dot = oo->info;
2201               else if (strcmp (oo->name, "tag") == 0)
2202                 tagid = oo->info;
2203               else if (strcmp (oo->name, "skip") == 0)
2204                 skip_p = 1;
2205               else if (strcmp (oo->name, "default") == 0)
2206                 default_p = 1;
2207               else if (strcmp (oo->name, "reorder") == 0)
2208                 d->reorder_fn = oo->info;
2209               else if (strncmp (oo->name, "use_param", 9) == 0
2210                        && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2211                 use_param_p = 1;
2212
2213             if (skip_p)
2214               continue;
2215
2216             if (union_p && tagid)
2217               {
2218                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2219                 d->indent += 2;
2220               }
2221             else if (union_p && default_p)
2222               {
2223                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2224                 d->indent += 2;
2225                 seen_default_p = 1;
2226               }
2227             else if (! union_p && (default_p || tagid))
2228               error_at_line (d->line,
2229                              "can't use `%s' outside a union on field `%s'",
2230                              default_p ? "default" : "tag", f->name);
2231             else if (union_p && ! (default_p || tagid)
2232                      && f->type->kind == TYPE_SCALAR)
2233               {
2234                 fprintf (stderr,
2235         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2236                          d->line->file, d->line->line, f->name);
2237                 continue;
2238               }
2239             else if (union_p && ! (default_p || tagid))
2240               error_at_line (d->line,
2241                              "field `%s' is missing `tag' or `default' option",
2242                              f->name);
2243
2244             d->line = &f->line;
2245             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2246             d->opt = f->opt;
2247             d->used_length = false;
2248
2249             if (union_p && use_param_p && d->param == NULL)
2250               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2251             else
2252               walk_type (f->type, d);
2253
2254             free (newval);
2255
2256             if (union_p)
2257               {
2258                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2259                 d->indent -= 2;
2260               }
2261           }
2262         d->reorder_fn = NULL;
2263
2264         d->val = oldval;
2265         d->prev_val[1] = oldprevval1;
2266         d->prev_val[2] = oldprevval2;
2267
2268         if (union_p && ! seen_default_p)
2269           {
2270             oprintf (d->of, "%*sdefault:\n", d->indent, "");
2271             oprintf (d->of, "%*s  break;\n", d->indent, "");
2272           }
2273         if (union_p)
2274           {
2275             oprintf (d->of, "%*s}\n", d->indent, "");
2276             d->indent -= 2;
2277           }
2278       }
2279       break;
2280
2281     case TYPE_LANG_STRUCT:
2282       {
2283         type_p nt;
2284         for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2285           if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2286             break;
2287         if (nt == NULL)
2288           error_at_line (d->line, "structure `%s' differs between languages",
2289                          t->u.s.tag);
2290         else
2291           walk_type (nt, d);
2292       }
2293       break;
2294
2295     case TYPE_PARAM_STRUCT:
2296       {
2297         type_p *oldparam = d->param;
2298
2299         d->param = t->u.param_struct.param;
2300         walk_type (t->u.param_struct.stru, d);
2301         d->param = oldparam;
2302       }
2303       break;
2304
2305     default:
2306       gcc_unreachable ();
2307     }
2308 }
2309
2310 /* process_field routine for marking routines.  */
2311
2312 static void
2313 write_types_process_field (type_p f, const struct walk_type_data *d)
2314 {
2315   const struct write_types_data *wtd;
2316   const char *cast = d->needs_cast_p ? "(void *)" : "";
2317   wtd = (const struct write_types_data *) d->cookie;
2318
2319   switch (f->kind)
2320     {
2321     case TYPE_POINTER:
2322       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2323                wtd->subfield_marker_routine, cast, d->val);
2324       if (wtd->param_prefix)
2325         {
2326           oprintf (d->of, ", %s", d->prev_val[3]);
2327           if (d->orig_s)
2328             {
2329               oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2330               output_mangled_typename (d->of, d->orig_s);
2331             }
2332           else
2333             oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2334
2335           if (f->u.p->kind == TYPE_PARAM_STRUCT
2336               && f->u.p->u.s.line.file != NULL)
2337             {
2338               oprintf (d->of, ", gt_e_");
2339               output_mangled_typename (d->of, f);
2340             }
2341           else if (UNION_OR_STRUCT_P (f)
2342                    && f->u.p->u.s.line.file != NULL)
2343             {
2344               oprintf (d->of, ", gt_ggc_e_");
2345               output_mangled_typename (d->of, f);
2346             }
2347           else
2348             oprintf (d->of, ", gt_types_enum_last");
2349         }
2350       oprintf (d->of, ");\n");
2351       if (d->reorder_fn && wtd->reorder_note_routine)
2352         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2353                  wtd->reorder_note_routine, cast, d->val,
2354                  d->prev_val[3], d->reorder_fn);
2355       break;
2356
2357     case TYPE_STRING:
2358       if (wtd->param_prefix == NULL)
2359         break;
2360
2361     case TYPE_STRUCT:
2362     case TYPE_UNION:
2363     case TYPE_LANG_STRUCT:
2364     case TYPE_PARAM_STRUCT:
2365       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2366       output_mangled_typename (d->of, f);
2367       oprintf (d->of, " (%s%s);\n", cast, d->val);
2368       if (d->reorder_fn && wtd->reorder_note_routine)
2369         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2370                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
2371                  d->reorder_fn);
2372       break;
2373
2374     case TYPE_SCALAR:
2375       break;
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381
2382 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2383
2384 static void
2385 output_type_enum (outf_p of, type_p s)
2386 {
2387   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2388     {
2389       oprintf (of, ", gt_e_");
2390       output_mangled_typename (of, s);
2391     }
2392   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2393     {
2394       oprintf (of, ", gt_ggc_e_");
2395       output_mangled_typename (of, s);
2396     }
2397   else
2398     oprintf (of, ", gt_types_enum_last");
2399 }
2400
2401 /* For S, a structure that's part of ORIG_S, and using parameters
2402    PARAM, write out a routine that:
2403    - Takes a parameter, a void * but actually of type *S
2404    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2405      field of S or its substructures and (in some cases) things
2406      that are pointed to by S.
2407 */
2408
2409 static void
2410 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2411                           const struct write_types_data *wtd)
2412 {
2413   const char *fn = s->u.s.line.file;
2414   int i;
2415   const char *chain_next = NULL;
2416   const char *chain_prev = NULL;
2417   const char *mark_hook_name = NULL;
2418   options_p opt;
2419   struct walk_type_data d;
2420
2421   /* This is a hack, and not the good kind either.  */
2422   for (i = NUM_PARAM - 1; i >= 0; i--)
2423     if (param && param[i] && param[i]->kind == TYPE_POINTER
2424         && UNION_OR_STRUCT_P (param[i]->u.p))
2425       fn = param[i]->u.p->u.s.line.file;
2426
2427   memset (&d, 0, sizeof (d));
2428   d.of = get_output_file_with_visibility (fn);
2429
2430   for (opt = s->u.s.opt; opt; opt = opt->next)
2431     if (strcmp (opt->name, "chain_next") == 0)
2432       chain_next = opt->info;
2433     else if (strcmp (opt->name, "chain_prev") == 0)
2434       chain_prev = opt->info;
2435     else if (strcmp (opt->name, "mark_hook") == 0)
2436       mark_hook_name = opt->info;
2437
2438   if (chain_prev != NULL && chain_next == NULL)
2439     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2440
2441   d.process_field = write_types_process_field;
2442   d.cookie = wtd;
2443   d.orig_s = orig_s;
2444   d.opt = s->u.s.opt;
2445   d.line = &s->u.s.line;
2446   d.bitmap = s->u.s.bitmap;
2447   d.param = param;
2448   d.prev_val[0] = "*x";
2449   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2450   d.prev_val[3] = "x";
2451   d.val = "(*x)";
2452
2453   oprintf (d.of, "\n");
2454   oprintf (d.of, "void\n");
2455   if (param == NULL)
2456     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2457   else
2458     {
2459       oprintf (d.of, "gt_%s_", wtd->prefix);
2460       output_mangled_typename (d.of, orig_s);
2461     }
2462   oprintf (d.of, " (void *x_p)\n");
2463   oprintf (d.of, "{\n");
2464   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2465            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2466            chain_next == NULL ? "const " : "",
2467            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2468   if (chain_next != NULL)
2469     oprintf (d.of, "  %s %s * xlimit = x;\n",
2470              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2471   if (chain_next == NULL)
2472     {
2473       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2474       if (wtd->param_prefix)
2475         {
2476           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2477           output_mangled_typename (d.of, orig_s);
2478           output_type_enum (d.of, orig_s);
2479         }
2480       oprintf (d.of, "))\n");
2481     }
2482   else
2483     {
2484       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2485       if (wtd->param_prefix)
2486         {
2487           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2488           output_mangled_typename (d.of, orig_s);
2489           output_type_enum (d.of, orig_s);
2490         }
2491       oprintf (d.of, "))\n");
2492       if (mark_hook_name && !wtd->skip_hooks)
2493         {
2494           oprintf (d.of, "    {\n");
2495           oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
2496         }
2497       oprintf (d.of, "   xlimit = (");
2498       d.prev_val[2] = "*xlimit";
2499       output_escaped_param (&d, chain_next, "chain_next");
2500       oprintf (d.of, ");\n");
2501       if (mark_hook_name && !wtd->skip_hooks)
2502         oprintf (d.of, "    }\n");
2503       if (chain_prev != NULL)
2504         {
2505           oprintf (d.of, "  if (x != xlimit)\n");
2506           oprintf (d.of, "    for (;;)\n");
2507           oprintf (d.of, "      {\n");
2508           oprintf (d.of, "        %s %s * const xprev = (",
2509                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2510
2511           d.prev_val[2] = "*x";
2512           output_escaped_param (&d, chain_prev, "chain_prev");
2513           oprintf (d.of, ");\n");
2514           oprintf (d.of, "        if (xprev == NULL) break;\n");
2515           oprintf (d.of, "        x = xprev;\n");
2516           oprintf (d.of, "        (void) %s (xprev",
2517                    wtd->marker_routine);
2518           if (wtd->param_prefix)
2519             {
2520               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2521               output_mangled_typename (d.of, orig_s);
2522               output_type_enum (d.of, orig_s);
2523             }
2524           oprintf (d.of, ");\n");
2525           oprintf (d.of, "      }\n");
2526         }
2527       oprintf (d.of, "  while (x != xlimit)\n");
2528     }
2529   oprintf (d.of, "    {\n");
2530   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2531     {
2532       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2533     }
2534   d.prev_val[2] = "*x";
2535   d.indent = 6;
2536   walk_type (s, &d);
2537
2538   if (chain_next != NULL)
2539     {
2540       oprintf (d.of, "      x = (");
2541       output_escaped_param (&d, chain_next, "chain_next");
2542       oprintf (d.of, ");\n");
2543     }
2544
2545   oprintf (d.of, "    }\n");
2546   oprintf (d.of, "}\n");
2547 }
2548
2549 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2550
2551 static void
2552 write_types (type_p structures, type_p param_structs,
2553              const struct write_types_data *wtd)
2554 {
2555   type_p s;
2556
2557   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2558   for (s = structures; s; s = s->next)
2559     if (s->gc_used == GC_POINTED_TO
2560         || s->gc_used == GC_MAYBE_POINTED_TO)
2561       {
2562         options_p opt;
2563
2564         if (s->gc_used == GC_MAYBE_POINTED_TO
2565             && s->u.s.line.file == NULL)
2566           continue;
2567
2568         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2569         output_mangled_typename (header_file, s);
2570         oprintf (header_file, "(X) do { \\\n");
2571         oprintf (header_file,
2572                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2573                  s->u.s.tag);
2574         oprintf (header_file,
2575                  "  } while (0)\n");
2576
2577         for (opt = s->u.s.opt; opt; opt = opt->next)
2578           if (strcmp (opt->name, "ptr_alias") == 0)
2579             {
2580               type_p t = (type_p) opt->info;
2581               if (t->kind == TYPE_STRUCT
2582                   || t->kind == TYPE_UNION
2583                   || t->kind == TYPE_LANG_STRUCT)
2584                 oprintf (header_file,
2585                          "#define gt_%sx_%s gt_%sx_%s\n",
2586                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2587               else
2588                 error_at_line (&s->u.s.line,
2589                                "structure alias is not a structure");
2590               break;
2591             }
2592         if (opt)
2593           continue;
2594
2595         /* Declare the marker procedure only once.  */
2596         oprintf (header_file,
2597                  "extern void gt_%sx_%s (void *);\n",
2598                  wtd->prefix, s->u.s.tag);
2599
2600         if (s->u.s.line.file == NULL)
2601           {
2602             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2603                      s->u.s.tag);
2604             continue;
2605           }
2606
2607         if (s->kind == TYPE_LANG_STRUCT)
2608           {
2609             type_p ss;
2610             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2611               write_func_for_structure (s, ss, NULL, wtd);
2612           }
2613         else
2614           write_func_for_structure (s, s, NULL, wtd);
2615       }
2616
2617   for (s = param_structs; s; s = s->next)
2618     if (s->gc_used == GC_POINTED_TO)
2619       {
2620         type_p * param = s->u.param_struct.param;
2621         type_p stru = s->u.param_struct.stru;
2622
2623         /* Declare the marker procedure.  */
2624         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2625         output_mangled_typename (header_file, s);
2626         oprintf (header_file, " (void *);\n");
2627
2628         if (stru->u.s.line.file == NULL)
2629           {
2630             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2631                      s->u.s.tag);
2632             continue;
2633           }
2634
2635         if (stru->kind == TYPE_LANG_STRUCT)
2636           {
2637             type_p ss;
2638             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2639               write_func_for_structure (s, ss, param, wtd);
2640           }
2641         else
2642           write_func_for_structure (s, stru, param, wtd);
2643       }
2644 }
2645
2646 static const struct write_types_data ggc_wtd =
2647 {
2648   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2649   "GC marker procedures.  ",
2650   FALSE
2651 };
2652
2653 static const struct write_types_data pch_wtd =
2654 {
2655   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2656   "gt_pch_note_reorder",
2657   "PCH type-walking procedures.  ",
2658   TRUE
2659 };
2660
2661 /* Write out the local pointer-walking routines.  */
2662
2663 /* process_field routine for local pointer-walking.  */
2664
2665 static void
2666 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2667 {
2668   switch (f->kind)
2669     {
2670     case TYPE_POINTER:
2671     case TYPE_STRUCT:
2672     case TYPE_UNION:
2673     case TYPE_LANG_STRUCT:
2674     case TYPE_PARAM_STRUCT:
2675     case TYPE_STRING:
2676       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2677                d->prev_val[3]);
2678       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2679       break;
2680
2681     case TYPE_SCALAR:
2682       break;
2683
2684     default:
2685       gcc_unreachable ();
2686     }
2687 }
2688
2689 /* For S, a structure that's part of ORIG_S, and using parameters
2690    PARAM, write out a routine that:
2691    - Is of type gt_note_pointers
2692    - Calls PROCESS_FIELD on each field of S or its substructures.
2693 */
2694
2695 static void
2696 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2697 {
2698   const char *fn = s->u.s.line.file;
2699   int i;
2700   struct walk_type_data d;
2701
2702   /* This is a hack, and not the good kind either.  */
2703   for (i = NUM_PARAM - 1; i >= 0; i--)
2704     if (param && param[i] && param[i]->kind == TYPE_POINTER
2705         && UNION_OR_STRUCT_P (param[i]->u.p))
2706       fn = param[i]->u.p->u.s.line.file;
2707
2708   memset (&d, 0, sizeof (d));
2709   d.of = get_output_file_with_visibility (fn);
2710
2711   d.process_field = write_types_local_process_field;
2712   d.opt = s->u.s.opt;
2713   d.line = &s->u.s.line;
2714   d.bitmap = s->u.s.bitmap;
2715   d.param = param;
2716   d.prev_val[0] = d.prev_val[2] = "*x";
2717   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2718   d.prev_val[3] = "x";
2719   d.val = "(*x)";
2720   d.fn_wants_lvalue = true;
2721
2722   oprintf (d.of, "\n");
2723   oprintf (d.of, "void\n");
2724   oprintf (d.of, "gt_pch_p_");
2725   output_mangled_typename (d.of, orig_s);
2726   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2727            "\tvoid *x_p,\n"
2728            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2729            "\tATTRIBUTE_UNUSED void *cookie)\n");
2730   oprintf (d.of, "{\n");
2731   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2732            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2733            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2734   d.indent = 2;
2735   walk_type (s, &d);
2736   oprintf (d.of, "}\n");
2737 }
2738
2739 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2740
2741 static void
2742 write_local (type_p structures, type_p param_structs)
2743 {
2744   type_p s;
2745
2746   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2747   for (s = structures; s; s = s->next)
2748     if (s->gc_used == GC_POINTED_TO
2749         || s->gc_used == GC_MAYBE_POINTED_TO)
2750       {
2751         options_p opt;
2752
2753         if (s->u.s.line.file == NULL)
2754           continue;
2755
2756         for (opt = s->u.s.opt; opt; opt = opt->next)
2757           if (strcmp (opt->name, "ptr_alias") == 0)
2758             {
2759               type_p t = (type_p) opt->info;
2760               if (t->kind == TYPE_STRUCT
2761                   || t->kind == TYPE_UNION
2762                   || t->kind == TYPE_LANG_STRUCT)
2763                 {
2764                   oprintf (header_file, "#define gt_pch_p_");
2765                   output_mangled_typename (header_file, s);
2766                   oprintf (header_file, " gt_pch_p_");
2767                   output_mangled_typename (header_file, t);
2768                   oprintf (header_file, "\n");
2769                 }
2770               else
2771                 error_at_line (&s->u.s.line,
2772                                "structure alias is not a structure");
2773               break;
2774             }
2775         if (opt)
2776           continue;
2777
2778         /* Declare the marker procedure only once.  */
2779         oprintf (header_file, "extern void gt_pch_p_");
2780         output_mangled_typename (header_file, s);
2781         oprintf (header_file,
2782          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2783
2784         if (s->kind == TYPE_LANG_STRUCT)
2785           {
2786             type_p ss;
2787             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2788               write_local_func_for_structure (s, ss, NULL);
2789           }
2790         else
2791           write_local_func_for_structure (s, s, NULL);
2792       }
2793
2794   for (s = param_structs; s; s = s->next)
2795     if (s->gc_used == GC_POINTED_TO)
2796       {
2797         type_p * param = s->u.param_struct.param;
2798         type_p stru = s->u.param_struct.stru;
2799
2800         /* Declare the marker procedure.  */
2801         oprintf (header_file, "extern void gt_pch_p_");
2802         output_mangled_typename (header_file, s);
2803         oprintf (header_file,
2804          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2805
2806         if (stru->u.s.line.file == NULL)
2807           {
2808             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2809                      s->u.s.tag);
2810             continue;
2811           }
2812
2813         if (stru->kind == TYPE_LANG_STRUCT)
2814           {
2815             type_p ss;
2816             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2817               write_local_func_for_structure (s, ss, param);
2818           }
2819         else
2820           write_local_func_for_structure (s, stru, param);
2821       }
2822 }
2823
2824 /* Write out the 'enum' definition for gt_types_enum.  */
2825
2826 static void
2827 write_enum_defn (type_p structures, type_p param_structs)
2828 {
2829   type_p s;
2830
2831   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2832   oprintf (header_file, "enum gt_types_enum {\n");
2833   for (s = structures; s; s = s->next)
2834     if (s->gc_used == GC_POINTED_TO
2835         || s->gc_used == GC_MAYBE_POINTED_TO)
2836       {
2837         if (s->gc_used == GC_MAYBE_POINTED_TO
2838             && s->u.s.line.file == NULL)
2839           continue;
2840
2841         oprintf (header_file, " gt_ggc_e_");
2842         output_mangled_typename (header_file, s);
2843         oprintf (header_file, ", \n");
2844       }
2845   for (s = param_structs; s; s = s->next)
2846     if (s->gc_used == GC_POINTED_TO)
2847       {
2848         oprintf (header_file, " gt_e_");
2849         output_mangled_typename (header_file, s);
2850         oprintf (header_file, ", \n");
2851       }
2852   oprintf (header_file, " gt_types_enum_last\n");
2853   oprintf (header_file, "};\n");
2854 }
2855
2856 /* Might T contain any non-pointer elements?  */
2857
2858 static int
2859 contains_scalar_p (type_p t)
2860 {
2861   switch (t->kind)
2862     {
2863     case TYPE_STRING:
2864     case TYPE_POINTER:
2865       return 0;
2866     case TYPE_ARRAY:
2867       return contains_scalar_p (t->u.a.p);
2868     default:
2869       /* Could also check for structures that have no non-pointer
2870          fields, but there aren't enough of those to worry about.  */
2871       return 1;
2872     }
2873 }
2874
2875 /* Mangle FN and print it to F.  */
2876
2877 static void
2878 put_mangled_filename (outf_p f, const char *fn)
2879 {
2880   const char *name = get_output_file_name (fn);
2881   for (; *name != 0; name++)
2882     if (ISALNUM (*name))
2883       oprintf (f, "%c", *name);
2884     else
2885       oprintf (f, "%c", '_');
2886 }
2887
2888 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2889    LASTNAME, and NAME are all strings to insert in various places in
2890    the resulting code.  */
2891
2892 static void
2893 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2894                    const char *tname, const char *name)
2895 {
2896   struct flist *fli2;
2897
2898   for (fli2 = flp; fli2; fli2 = fli2->next)
2899     if (fli2->started_p)
2900       {
2901         oprintf (fli2->f, "  %s\n", lastname);
2902         oprintf (fli2->f, "};\n\n");
2903       }
2904
2905   for (fli2 = flp; fli2; fli2 = fli2->next)
2906     if (fli2->started_p)
2907       {
2908         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2909         int fnum;
2910
2911         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2912           if (bitmap & 1)
2913             {
2914               oprintf (base_files[fnum],
2915                        "extern const struct %s gt_%s_",
2916                        tname, pfx);
2917               put_mangled_filename (base_files[fnum], fli2->name);
2918               oprintf (base_files[fnum], "[];\n");
2919             }
2920       }
2921
2922   {
2923     size_t fnum;
2924     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2925       oprintf (base_files [fnum],
2926                "const struct %s * const %s[] = {\n",
2927                tname, name);
2928   }
2929
2930
2931   for (fli2 = flp; fli2; fli2 = fli2->next)
2932     if (fli2->started_p)
2933       {
2934         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2935         int fnum;
2936
2937         fli2->started_p = 0;
2938
2939         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2940           if (bitmap & 1)
2941             {
2942               oprintf (base_files[fnum], "  gt_%s_", pfx);
2943               put_mangled_filename (base_files[fnum], fli2->name);
2944               oprintf (base_files[fnum], ",\n");
2945             }
2946       }
2947
2948   {
2949     size_t fnum;
2950     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2951       {
2952         oprintf (base_files[fnum], "  NULL\n");
2953         oprintf (base_files[fnum], "};\n");
2954       }
2955   }
2956 }
2957
2958 /* Write out to F the table entry and any marker routines needed to
2959    mark NAME as TYPE.  The original variable is V, at LINE.
2960    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2961    is nonzero iff we are building the root table for hash table caches.  */
2962
2963 static void
2964 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2965             struct fileloc *line, const char *if_marked)
2966 {
2967   switch (type->kind)
2968     {
2969     case TYPE_STRUCT:
2970       {
2971         pair_p fld;
2972         for (fld = type->u.s.fields; fld; fld = fld->next)
2973           {
2974             int skip_p = 0;
2975             const char *desc = NULL;
2976             options_p o;
2977
2978             for (o = fld->opt; o; o = o->next)
2979               if (strcmp (o->name, "skip") == 0)
2980                 skip_p = 1;
2981               else if (strcmp (o->name, "desc") == 0)
2982                 desc = o->info;
2983               else
2984                 error_at_line (line,
2985                        "field `%s' of global `%s' has unknown option `%s'",
2986                                fld->name, name, o->name);
2987
2988             if (skip_p)
2989               continue;
2990             else if (desc && fld->type->kind == TYPE_UNION)
2991               {
2992                 pair_p validf = NULL;
2993                 pair_p ufld;
2994
2995                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2996                   {
2997                     const char *tag = NULL;
2998                     options_p oo;
2999
3000                     for (oo = ufld->opt; oo; oo = oo->next)
3001                       if (strcmp (oo->name, "tag") == 0)
3002                         tag = oo->info;
3003                     if (tag == NULL || strcmp (tag, desc) != 0)
3004                       continue;
3005                     if (validf != NULL)
3006                       error_at_line (line,
3007                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3008                                      name, fld->name, validf->name,
3009                                      name, fld->name, ufld->name,
3010                                      tag);
3011                     validf = ufld;
3012                   }
3013                 if (validf != NULL)
3014                   {
3015                     char *newname;
3016                     newname = xasprintf ("%s.%s.%s",
3017                                          name, fld->name, validf->name);
3018                     write_root (f, v, validf->type, newname, 0, line,
3019                                 if_marked);
3020                     free (newname);
3021                   }
3022               }
3023             else if (desc)
3024               error_at_line (line,
3025                      "global `%s.%s' has `desc' option but is not union",
3026                              name, fld->name);
3027             else
3028               {
3029                 char *newname;
3030                 newname = xasprintf ("%s.%s", name, fld->name);
3031                 write_root (f, v, fld->type, newname, 0, line, if_marked);
3032                 free (newname);
3033               }
3034           }
3035       }
3036       break;
3037
3038     case TYPE_ARRAY:
3039       {
3040         char *newname;
3041         newname = xasprintf ("%s[0]", name);
3042         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
3043         free (newname);
3044       }
3045       break;
3046
3047     case TYPE_POINTER:
3048       {
3049         type_p ap, tp;
3050
3051         oprintf (f, "  {\n");
3052         oprintf (f, "    &%s,\n", name);
3053         oprintf (f, "    1");
3054
3055         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3056           if (ap->u.a.len[0])
3057             oprintf (f, " * (%s)", ap->u.a.len);
3058           else if (ap == v->type)
3059             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3060         oprintf (f, ",\n");
3061         oprintf (f, "    sizeof (%s", v->name);
3062         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3063           oprintf (f, "[0]");
3064         oprintf (f, "),\n");
3065
3066         tp = type->u.p;
3067
3068         if (! has_length && UNION_OR_STRUCT_P (tp))
3069           {
3070             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3071             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3072           }
3073         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3074           {
3075             oprintf (f, "    &gt_ggc_m_");
3076             output_mangled_typename (f, tp);
3077             oprintf (f, ",\n    &gt_pch_n_");
3078             output_mangled_typename (f, tp);
3079           }
3080         else if (has_length
3081                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3082           {
3083             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3084             oprintf (f, "    &gt_pch_na_%s", name);
3085           }
3086         else
3087           {
3088             error_at_line (line,
3089                            "global `%s' is pointer to unimplemented type",
3090                            name);
3091           }
3092         if (if_marked)
3093           oprintf (f, ",\n    &%s", if_marked);
3094         oprintf (f, "\n  },\n");
3095       }
3096       break;
3097
3098     case TYPE_STRING:
3099       {
3100         oprintf (f, "  {\n");
3101         oprintf (f, "    &%s,\n", name);
3102         oprintf (f, "    1, \n");
3103         oprintf (f, "    sizeof (%s),\n", v->name);
3104         oprintf (f, "    &gt_ggc_m_S,\n");
3105         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3106         oprintf (f, "  },\n");
3107       }
3108       break;
3109
3110     case TYPE_SCALAR:
3111       break;
3112
3113     default:
3114       error_at_line (line,
3115                      "global `%s' is unimplemented type",
3116                      name);
3117     }
3118 }
3119
3120 /* This generates a routine to walk an array.  */
3121
3122 static void
3123 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3124 {
3125   struct walk_type_data d;
3126   char *prevval3;
3127
3128   memset (&d, 0, sizeof (d));
3129   d.of = f;
3130   d.cookie = wtd;
3131   d.indent = 2;
3132   d.line = &v->line;
3133   d.opt = v->opt;
3134   d.bitmap = get_lang_bitmap (v->line.file);
3135   d.param = NULL;
3136
3137   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3138
3139   if (wtd->param_prefix)
3140     {
3141       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3142       oprintf (f,
3143        "    (void *, void *, gt_pointer_operator, void *);\n");
3144       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3145                wtd->param_prefix, v->name);
3146       oprintf (d.of,
3147                "      ATTRIBUTE_UNUSED void *x_p,\n"
3148                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3149                "      ATTRIBUTE_UNUSED void * cookie)\n");
3150       oprintf (d.of, "{\n");
3151       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3152       d.process_field = write_types_local_process_field;
3153       walk_type (v->type, &d);
3154       oprintf (f, "}\n\n");
3155     }
3156
3157   d.opt = v->opt;
3158   oprintf (f, "static void gt_%sa_%s (void *);\n",
3159            wtd->prefix, v->name);
3160   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3161            wtd->prefix, v->name);
3162   oprintf (f, "{\n");
3163   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3164   d.process_field = write_types_process_field;
3165   walk_type (v->type, &d);
3166   free (prevval3);
3167   oprintf (f, "}\n\n");
3168 }
3169
3170 /* Output a table describing the locations and types of VARIABLES.  */
3171
3172 static void
3173 write_roots (pair_p variables)
3174 {
3175   pair_p v;
3176   struct flist *flp = NULL;
3177
3178   for (v = variables; v; v = v->next)
3179     {
3180       outf_p f = get_output_file_with_visibility (v->line.file);
3181       struct flist *fli;
3182       const char *length = NULL;
3183       int deletable_p = 0;
3184       options_p o;
3185
3186       for (o = v->opt; o; o = o->next)
3187         if (strcmp (o->name, "length") == 0)
3188           length = o->info;
3189         else if (strcmp (o->name, "deletable") == 0)
3190           deletable_p = 1;
3191         else if (strcmp (o->name, "param_is") == 0)
3192           ;
3193         else if (strncmp (o->name, "param", 5) == 0
3194                  && ISDIGIT (o->name[5])
3195                  && strcmp (o->name + 6, "_is") == 0)
3196           ;
3197         else if (strcmp (o->name, "if_marked") == 0)
3198           ;
3199         else
3200           error_at_line (&v->line,
3201                          "global `%s' has unknown option `%s'",
3202                          v->name, o->name);
3203
3204       for (fli = flp; fli; fli = fli->next)
3205         if (fli->f == f)
3206           break;
3207       if (fli == NULL)
3208         {
3209           fli = XNEW (struct flist);
3210           fli->f = f;
3211           fli->next = flp;
3212           fli->started_p = 0;
3213           fli->name = v->line.file;
3214           flp = fli;
3215
3216           oprintf (f, "\n/* GC roots.  */\n\n");
3217         }
3218
3219       if (! deletable_p
3220           && length
3221           && v->type->kind == TYPE_POINTER
3222           && (v->type->u.p->kind == TYPE_POINTER
3223               || v->type->u.p->kind == TYPE_STRUCT))
3224         {
3225           write_array (f, v, &ggc_wtd);
3226           write_array (f, v, &pch_wtd);
3227         }
3228     }
3229
3230   for (v = variables; v; v = v->next)
3231     {
3232       outf_p f = get_output_file_with_visibility (v->line.file);
3233       struct flist *fli;
3234       int skip_p = 0;
3235       int length_p = 0;
3236       options_p o;
3237
3238       for (o = v->opt; o; o = o->next)
3239         if (strcmp (o->name, "length") == 0)
3240           length_p = 1;
3241         else if (strcmp (o->name, "deletable") == 0
3242                  || strcmp (o->name, "if_marked") == 0)
3243           skip_p = 1;
3244
3245       if (skip_p)
3246         continue;
3247
3248       for (fli = flp; fli; fli = fli->next)
3249         if (fli->f == f)
3250           break;
3251       if (! fli->started_p)
3252         {
3253           fli->started_p = 1;
3254
3255           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
3256           put_mangled_filename (f, v->line.file);
3257           oprintf (f, "[] = {\n");
3258         }
3259
3260       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3261     }
3262
3263   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3264                      "gt_ggc_rtab");
3265
3266   for (v = variables; v; v = v->next)
3267     {
3268       outf_p f = get_output_file_with_visibility (v->line.file);
3269       struct flist *fli;
3270       int skip_p = 1;
3271       options_p o;
3272
3273       for (o = v->opt; o; o = o->next)
3274         if (strcmp (o->name, "deletable") == 0)
3275           skip_p = 0;
3276         else if (strcmp (o->name, "if_marked") == 0)
3277           skip_p = 1;
3278
3279       if (skip_p)
3280         continue;
3281
3282       for (fli = flp; fli; fli = fli->next)
3283         if (fli->f == f)
3284           break;
3285       if (! fli->started_p)
3286         {
3287           fli->started_p = 1;
3288
3289           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
3290           put_mangled_filename (f, v->line.file);
3291           oprintf (f, "[] = {\n");
3292         }
3293
3294       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3295                v->name, v->name);
3296     }
3297
3298   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3299                      "gt_ggc_deletable_rtab");
3300
3301   for (v = variables; v; v = v->next)
3302     {
3303       outf_p f = get_output_file_with_visibility (v->line.file);
3304       struct flist *fli;
3305       const char *if_marked = NULL;
3306       int length_p = 0;
3307       options_p o;
3308
3309       for (o = v->opt; o; o = o->next)
3310         if (strcmp (o->name, "length") == 0)
3311           length_p = 1;
3312         else if (strcmp (o->name, "if_marked") == 0)
3313           if_marked = o->info;
3314
3315       if (if_marked == NULL)
3316         continue;
3317
3318       if (v->type->kind != TYPE_POINTER
3319           || v->type->u.p->kind != TYPE_PARAM_STRUCT
3320           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3321         {
3322           error_at_line (&v->line, "if_marked option used but not hash table");
3323           continue;
3324         }
3325
3326       for (fli = flp; fli; fli = fli->next)
3327         if (fli->f == f)
3328           break;
3329       if (! fli->started_p)
3330         {
3331           fli->started_p = 1;
3332
3333           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
3334           put_mangled_filename (f, v->line.file);
3335           oprintf (f, "[] = {\n");
3336         }
3337
3338       write_root (f, v, v->type->u.p->u.param_struct.param[0],
3339                      v->name, length_p, &v->line, if_marked);
3340     }
3341
3342   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3343                      "gt_ggc_cache_rtab");
3344
3345   for (v = variables; v; v = v->next)
3346     {
3347       outf_p f = get_output_file_with_visibility (v->line.file);
3348       struct flist *fli;
3349       int length_p = 0;
3350       int if_marked_p = 0;
3351       options_p o;
3352
3353       for (o = v->opt; o; o = o->next)
3354         if (strcmp (o->name, "length") == 0)
3355           length_p = 1;
3356         else if (strcmp (o->name, "if_marked") == 0)
3357           if_marked_p = 1;
3358
3359       if (! if_marked_p)
3360         continue;
3361
3362       for (fli = flp; fli; fli = fli->next)
3363         if (fli->f == f)
3364           break;
3365       if (! fli->started_p)
3366         {
3367           fli->started_p = 1;
3368
3369           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
3370           put_mangled_filename (f, v->line.file);
3371           oprintf (f, "[] = {\n");
3372         }
3373
3374       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3375     }
3376
3377   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3378                      "gt_pch_cache_rtab");
3379
3380   for (v = variables; v; v = v->next)
3381     {
3382       outf_p f = get_output_file_with_visibility (v->line.file);
3383       struct flist *fli;
3384       int skip_p = 0;
3385       options_p o;
3386
3387       for (o = v->opt; o; o = o->next)
3388         if (strcmp (o->name, "deletable") == 0
3389             || strcmp (o->name, "if_marked") == 0)
3390           skip_p = 1;
3391
3392       if (skip_p)
3393         continue;
3394
3395       if (! contains_scalar_p (v->type))
3396         continue;
3397
3398       for (fli = flp; fli; fli = fli->next)
3399         if (fli->f == f)
3400           break;
3401       if (! fli->started_p)
3402         {
3403           fli->started_p = 1;
3404
3405           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3406           put_mangled_filename (f, v->line.file);
3407           oprintf (f, "[] = {\n");
3408         }
3409
3410       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3411                v->name, v->name);
3412     }
3413
3414   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3415                      "gt_pch_scalar_rtab");
3416 }
3417
3418 /* Record the definition of a generic VEC structure, as if we had expanded
3419    the macros in vec.h:
3420
3421    typedef struct VEC_<type>_base GTY(()) {
3422    unsigned num;
3423    unsigned alloc;
3424    <type> GTY((length ("%h.num"))) vec[1];
3425    } VEC_<type>_base
3426
3427    where the GTY(()) tags are only present if is_scalar is _false_.  */
3428
3429 void
3430 note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
3431 {
3432   pair_p fields;
3433   type_p t;
3434   options_p o;
3435   type_p len_ty = create_scalar_type ("unsigned");
3436   const char *name = concat ("VEC_", typename, "_base", (char *)0);
3437
3438   if (is_scalar)
3439     {
3440       t = create_scalar_type (typename);
3441       o = 0;
3442     }
3443   else
3444     {
3445       t = resolve_typedef (typename, pos);
3446       o = create_option (0, "length", "%h.num");
3447     }
3448
3449   /* We assemble the field list in reverse order.  */
3450   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3451   fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3452   fields = create_field_at (fields, len_ty, "num", 0, pos);
3453
3454   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3455 }
3456
3457 /* Record the definition of an allocation-specific VEC structure, as if
3458    we had expanded the macros in vec.h:
3459
3460    typedef struct VEC_<type>_<astrat> {
3461      VEC_<type>_base base;
3462    } VEC_<type>_<astrat>;
3463 */
3464 void
3465 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3466 {
3467   const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3468   const char *basename = concat ("VEC_", type, "_base", (char *)0);
3469
3470   pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3471                                   "base", 0, pos);
3472
3473   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3474 }
3475
3476 /* Yet more temporary kludge since gengtype doesn't understand conditionals.
3477    This must be kept in sync with input.h.  */
3478 static void
3479 define_location_structures (void)
3480 {
3481   pair_p fields;
3482   type_p locs;
3483   static struct fileloc pos = { this_file, __LINE__ };
3484   do_scalar_typedef ("source_location", &pos);
3485
3486 #ifdef USE_MAPPED_LOCATION
3487     fields = create_field (0, &scalar_nonchar, "column");
3488     fields = create_field (fields, &scalar_nonchar, "line");
3489     fields = create_field (fields, &string_type, "file");
3490     locs = new_structure ("anon:expanded_location", 0, &pos, fields, 0);
3491
3492     do_typedef ("expanded_location", locs, &pos);
3493     do_scalar_typedef ("location_t", &pos);
3494     do_scalar_typedef ("source_locus", &pos);
3495 #else
3496     fields = create_field (0, &scalar_nonchar, "line");
3497     fields = create_field (fields, &string_type, "file");
3498     locs = new_structure ("location_s", 0, &pos, fields, 0);
3499
3500     do_typedef ("expanded_location", locs, &pos);
3501     do_typedef ("location_t", locs, &pos);
3502     do_typedef ("source_locus", create_pointer (locs), &pos);
3503 #endif
3504 }
3505
3506 \f
3507 int
3508 main (int argc, char **argv)
3509 {
3510   size_t i;
3511   static struct fileloc pos = { this_file, 0 };
3512
3513   /* fatal uses this */
3514   progname = "gengtype";
3515
3516   if (argc != 3)
3517     fatal ("usage: gengtype srcdir input-list");
3518
3519   srcdir = argv[1];
3520   srcdir_len = strlen (srcdir);
3521
3522   read_input_list (argv[2]);
3523   if (hit_error)
3524     return 1;
3525
3526   scalar_char.u.scalar_is_char = true;
3527   scalar_nonchar.u.scalar_is_char = false;
3528   gen_rtx_next ();
3529
3530   /* These types are set up with #define or else outside of where
3531      we can see them.  */
3532   pos.line = __LINE__ + 1;
3533   do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3534   do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
3535   do_scalar_typedef ("double_int", &pos); pos.line++;
3536   do_scalar_typedef ("uint8", &pos); pos.line++;
3537   do_scalar_typedef ("jword", &pos); pos.line++;
3538   do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3539   do_scalar_typedef ("void", &pos); pos.line++;
3540   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3541   define_location_structures ();
3542
3543   for (i = 0; i < num_gt_files; i++)
3544     parse_file (gt_files[i]);
3545
3546   if (hit_error)
3547     return 1;
3548
3549   set_gc_used (variables);
3550
3551   open_base_files ();
3552   write_enum_defn (structures, param_structs);
3553   write_types (structures, param_structs, &ggc_wtd);
3554   write_types (structures, param_structs, &pch_wtd);
3555   write_local (structures, param_structs);
3556   write_roots (variables);
3557   write_rtx_next ();
3558   close_output_files ();
3559
3560   if (hit_error)
3561     return 1;
3562   return 0;
3563 }