OSDN Git Service

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