OSDN Git Service

PR debug/36060
[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       if (wtd->param_prefix == NULL)
2361         break;
2362
2363     case TYPE_STRUCT:
2364     case TYPE_UNION:
2365     case TYPE_LANG_STRUCT:
2366     case TYPE_PARAM_STRUCT:
2367       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2368       output_mangled_typename (d->of, f);
2369       oprintf (d->of, " (%s%s);\n", cast, d->val);
2370       if (d->reorder_fn && wtd->reorder_note_routine)
2371         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2372                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
2373                  d->reorder_fn);
2374       break;
2375
2376     case TYPE_SCALAR:
2377       break;
2378
2379     default:
2380       gcc_unreachable ();
2381     }
2382 }
2383
2384 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2385
2386 static void
2387 output_type_enum (outf_p of, type_p s)
2388 {
2389   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2390     {
2391       oprintf (of, ", gt_e_");
2392       output_mangled_typename (of, s);
2393     }
2394   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2395     {
2396       oprintf (of, ", gt_ggc_e_");
2397       output_mangled_typename (of, s);
2398     }
2399   else
2400     oprintf (of, ", gt_types_enum_last");
2401 }
2402
2403 /* For S, a structure that's part of ORIG_S, and using parameters
2404    PARAM, write out a routine that:
2405    - Takes a parameter, a void * but actually of type *S
2406    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2407      field of S or its substructures and (in some cases) things
2408      that are pointed to by S.
2409 */
2410
2411 static void
2412 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2413                           const struct write_types_data *wtd)
2414 {
2415   const char *fn = s->u.s.line.file;
2416   int i;
2417   const char *chain_next = NULL;
2418   const char *chain_prev = NULL;
2419   const char *chain_circular = NULL;
2420   const char *mark_hook_name = NULL;
2421   options_p opt;
2422   struct walk_type_data d;
2423
2424   /* This is a hack, and not the good kind either.  */
2425   for (i = NUM_PARAM - 1; i >= 0; i--)
2426     if (param && param[i] && param[i]->kind == TYPE_POINTER
2427         && UNION_OR_STRUCT_P (param[i]->u.p))
2428       fn = param[i]->u.p->u.s.line.file;
2429
2430   memset (&d, 0, sizeof (d));
2431   d.of = get_output_file_with_visibility (fn);
2432
2433   for (opt = s->u.s.opt; opt; opt = opt->next)
2434     if (strcmp (opt->name, "chain_next") == 0)
2435       chain_next = opt->info;
2436     else if (strcmp (opt->name, "chain_prev") == 0)
2437       chain_prev = opt->info;
2438     else if (strcmp (opt->name, "chain_circular") == 0)
2439       chain_circular = opt->info;
2440     else if (strcmp (opt->name, "mark_hook") == 0)
2441       mark_hook_name = opt->info;
2442
2443   if (chain_prev != NULL && chain_next == NULL)
2444     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2445   if (chain_circular != NULL && chain_next != NULL)
2446     error_at_line (&s->u.s.line, "chain_circular with chain_next");
2447   if (chain_circular != NULL)
2448     chain_next = chain_circular;
2449
2450   d.process_field = write_types_process_field;
2451   d.cookie = wtd;
2452   d.orig_s = orig_s;
2453   d.opt = s->u.s.opt;
2454   d.line = &s->u.s.line;
2455   d.bitmap = s->u.s.bitmap;
2456   d.param = param;
2457   d.prev_val[0] = "*x";
2458   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2459   d.prev_val[3] = "x";
2460   d.val = "(*x)";
2461
2462   oprintf (d.of, "\n");
2463   oprintf (d.of, "void\n");
2464   if (param == NULL)
2465     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2466   else
2467     {
2468       oprintf (d.of, "gt_%s_", wtd->prefix);
2469       output_mangled_typename (d.of, orig_s);
2470     }
2471   oprintf (d.of, " (void *x_p)\n");
2472   oprintf (d.of, "{\n");
2473   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2474            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2475            chain_next == NULL ? "const " : "",
2476            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2477   if (chain_next != NULL)
2478     oprintf (d.of, "  %s %s * xlimit = x;\n",
2479              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2480   if (chain_next == NULL)
2481     {
2482       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2483       if (wtd->param_prefix)
2484         {
2485           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2486           output_mangled_typename (d.of, orig_s);
2487           output_type_enum (d.of, orig_s);
2488         }
2489       oprintf (d.of, "))\n");
2490     }
2491   else
2492     {
2493       if (chain_circular != NULL)
2494         oprintf (d.of, "  if (!%s (xlimit", wtd->marker_routine);
2495       else
2496         oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2497       if (wtd->param_prefix)
2498         {
2499           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2500           output_mangled_typename (d.of, orig_s);
2501           output_type_enum (d.of, orig_s);
2502         }
2503       oprintf (d.of, "))\n");
2504       if (chain_circular != NULL)
2505         oprintf (d.of, "    return;\n  do\n");
2506       if (mark_hook_name && !wtd->skip_hooks)
2507         {
2508           oprintf (d.of, "    {\n");
2509           oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
2510         }
2511       oprintf (d.of, "   xlimit = (");
2512       d.prev_val[2] = "*xlimit";
2513       output_escaped_param (&d, chain_next, "chain_next");
2514       oprintf (d.of, ");\n");
2515       if (mark_hook_name && !wtd->skip_hooks)
2516         oprintf (d.of, "    }\n");
2517       if (chain_prev != NULL)
2518         {
2519           oprintf (d.of, "  if (x != xlimit)\n");
2520           oprintf (d.of, "    for (;;)\n");
2521           oprintf (d.of, "      {\n");
2522           oprintf (d.of, "        %s %s * const xprev = (",
2523                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2524
2525           d.prev_val[2] = "*x";
2526           output_escaped_param (&d, chain_prev, "chain_prev");
2527           oprintf (d.of, ");\n");
2528           oprintf (d.of, "        if (xprev == NULL) break;\n");
2529           oprintf (d.of, "        x = xprev;\n");
2530           oprintf (d.of, "        (void) %s (xprev",
2531                    wtd->marker_routine);
2532           if (wtd->param_prefix)
2533             {
2534               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2535               output_mangled_typename (d.of, orig_s);
2536               output_type_enum (d.of, orig_s);
2537             }
2538           oprintf (d.of, ");\n");
2539           oprintf (d.of, "      }\n");
2540         }
2541       if (chain_circular != NULL)
2542         {
2543           oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2544           if (wtd->param_prefix)
2545             {
2546               oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2547               output_mangled_typename (d.of, orig_s);
2548               output_type_enum (d.of, orig_s);
2549             }
2550           oprintf (d.of, "));\n");
2551           if (mark_hook_name && !wtd->skip_hooks)
2552             oprintf (d.of, "  %s (xlimit);\n", mark_hook_name);
2553           oprintf (d.of, "  do\n");
2554         }
2555       else
2556         oprintf (d.of, "  while (x != xlimit)\n");
2557     }
2558   oprintf (d.of, "    {\n");
2559   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2560     {
2561       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2562     }
2563   d.prev_val[2] = "*x";
2564   d.indent = 6;
2565   walk_type (s, &d);
2566
2567   if (chain_next != NULL)
2568     {
2569       oprintf (d.of, "      x = (");
2570       output_escaped_param (&d, chain_next, "chain_next");
2571       oprintf (d.of, ");\n");
2572     }
2573
2574   oprintf (d.of, "    }\n");
2575   if (chain_circular != NULL)
2576     oprintf (d.of, "  while (x != xlimit);\n");
2577   oprintf (d.of, "}\n");
2578 }
2579
2580 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2581
2582 static void
2583 write_types (type_p structures, type_p param_structs,
2584              const struct write_types_data *wtd)
2585 {
2586   type_p s;
2587
2588   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2589   for (s = structures; s; s = s->next)
2590     if (s->gc_used == GC_POINTED_TO
2591         || s->gc_used == GC_MAYBE_POINTED_TO)
2592       {
2593         options_p opt;
2594
2595         if (s->gc_used == GC_MAYBE_POINTED_TO
2596             && s->u.s.line.file == NULL)
2597           continue;
2598
2599         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2600         output_mangled_typename (header_file, s);
2601         oprintf (header_file, "(X) do { \\\n");
2602         oprintf (header_file,
2603                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2604                  s->u.s.tag);
2605         oprintf (header_file,
2606                  "  } while (0)\n");
2607
2608         for (opt = s->u.s.opt; opt; opt = opt->next)
2609           if (strcmp (opt->name, "ptr_alias") == 0)
2610             {
2611               const_type_p const t = (const_type_p) opt->info;
2612               if (t->kind == TYPE_STRUCT
2613                   || t->kind == TYPE_UNION
2614                   || t->kind == TYPE_LANG_STRUCT)
2615                 oprintf (header_file,
2616                          "#define gt_%sx_%s gt_%sx_%s\n",
2617                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2618               else
2619                 error_at_line (&s->u.s.line,
2620                                "structure alias is not a structure");
2621               break;
2622             }
2623         if (opt)
2624           continue;
2625
2626         /* Declare the marker procedure only once.  */
2627         oprintf (header_file,
2628                  "extern void gt_%sx_%s (void *);\n",
2629                  wtd->prefix, s->u.s.tag);
2630
2631         if (s->u.s.line.file == NULL)
2632           {
2633             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2634                      s->u.s.tag);
2635             continue;
2636           }
2637
2638         if (s->kind == TYPE_LANG_STRUCT)
2639           {
2640             type_p ss;
2641             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2642               write_func_for_structure (s, ss, NULL, wtd);
2643           }
2644         else
2645           write_func_for_structure (s, s, NULL, wtd);
2646       }
2647
2648   for (s = param_structs; s; s = s->next)
2649     if (s->gc_used == GC_POINTED_TO)
2650       {
2651         type_p * param = s->u.param_struct.param;
2652         type_p stru = s->u.param_struct.stru;
2653
2654         /* Declare the marker procedure.  */
2655         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2656         output_mangled_typename (header_file, s);
2657         oprintf (header_file, " (void *);\n");
2658
2659         if (stru->u.s.line.file == NULL)
2660           {
2661             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2662                      s->u.s.tag);
2663             continue;
2664           }
2665
2666         if (stru->kind == TYPE_LANG_STRUCT)
2667           {
2668             type_p ss;
2669             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2670               write_func_for_structure (s, ss, param, wtd);
2671           }
2672         else
2673           write_func_for_structure (s, stru, param, wtd);
2674       }
2675 }
2676
2677 static const struct write_types_data ggc_wtd =
2678 {
2679   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2680   "GC marker procedures.  ",
2681   FALSE
2682 };
2683
2684 static const struct write_types_data pch_wtd =
2685 {
2686   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2687   "gt_pch_note_reorder",
2688   "PCH type-walking procedures.  ",
2689   TRUE
2690 };
2691
2692 /* Write out the local pointer-walking routines.  */
2693
2694 /* process_field routine for local pointer-walking.  */
2695
2696 static void
2697 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2698 {
2699   switch (f->kind)
2700     {
2701     case TYPE_POINTER:
2702     case TYPE_STRUCT:
2703     case TYPE_UNION:
2704     case TYPE_LANG_STRUCT:
2705     case TYPE_PARAM_STRUCT:
2706     case TYPE_STRING:
2707       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2708                d->prev_val[3]);
2709       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2710       break;
2711
2712     case TYPE_SCALAR:
2713       break;
2714
2715     default:
2716       gcc_unreachable ();
2717     }
2718 }
2719
2720 /* For S, a structure that's part of ORIG_S, and using parameters
2721    PARAM, write out a routine that:
2722    - Is of type gt_note_pointers
2723    - Calls PROCESS_FIELD on each field of S or its substructures.
2724 */
2725
2726 static void
2727 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2728 {
2729   const char *fn = s->u.s.line.file;
2730   int i;
2731   struct walk_type_data d;
2732
2733   /* This is a hack, and not the good kind either.  */
2734   for (i = NUM_PARAM - 1; i >= 0; i--)
2735     if (param && param[i] && param[i]->kind == TYPE_POINTER
2736         && UNION_OR_STRUCT_P (param[i]->u.p))
2737       fn = param[i]->u.p->u.s.line.file;
2738
2739   memset (&d, 0, sizeof (d));
2740   d.of = get_output_file_with_visibility (fn);
2741
2742   d.process_field = write_types_local_process_field;
2743   d.opt = s->u.s.opt;
2744   d.line = &s->u.s.line;
2745   d.bitmap = s->u.s.bitmap;
2746   d.param = param;
2747   d.prev_val[0] = d.prev_val[2] = "*x";
2748   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2749   d.prev_val[3] = "x";
2750   d.val = "(*x)";
2751   d.fn_wants_lvalue = true;
2752
2753   oprintf (d.of, "\n");
2754   oprintf (d.of, "void\n");
2755   oprintf (d.of, "gt_pch_p_");
2756   output_mangled_typename (d.of, orig_s);
2757   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2758            "\tvoid *x_p,\n"
2759            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2760            "\tATTRIBUTE_UNUSED void *cookie)\n");
2761   oprintf (d.of, "{\n");
2762   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2763            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2764            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2765   d.indent = 2;
2766   walk_type (s, &d);
2767   oprintf (d.of, "}\n");
2768 }
2769
2770 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2771
2772 static void
2773 write_local (type_p structures, type_p param_structs)
2774 {
2775   type_p s;
2776
2777   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2778   for (s = structures; s; s = s->next)
2779     if (s->gc_used == GC_POINTED_TO
2780         || s->gc_used == GC_MAYBE_POINTED_TO)
2781       {
2782         options_p opt;
2783
2784         if (s->u.s.line.file == NULL)
2785           continue;
2786
2787         for (opt = s->u.s.opt; opt; opt = opt->next)
2788           if (strcmp (opt->name, "ptr_alias") == 0)
2789             {
2790               const_type_p const t = (const_type_p) opt->info;
2791               if (t->kind == TYPE_STRUCT
2792                   || t->kind == TYPE_UNION
2793                   || t->kind == TYPE_LANG_STRUCT)
2794                 {
2795                   oprintf (header_file, "#define gt_pch_p_");
2796                   output_mangled_typename (header_file, s);
2797                   oprintf (header_file, " gt_pch_p_");
2798                   output_mangled_typename (header_file, t);
2799                   oprintf (header_file, "\n");
2800                 }
2801               else
2802                 error_at_line (&s->u.s.line,
2803                                "structure alias is not a structure");
2804               break;
2805             }
2806         if (opt)
2807           continue;
2808
2809         /* Declare the marker procedure only once.  */
2810         oprintf (header_file, "extern void gt_pch_p_");
2811         output_mangled_typename (header_file, s);
2812         oprintf (header_file,
2813          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2814
2815         if (s->kind == TYPE_LANG_STRUCT)
2816           {
2817             type_p ss;
2818             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2819               write_local_func_for_structure (s, ss, NULL);
2820           }
2821         else
2822           write_local_func_for_structure (s, s, NULL);
2823       }
2824
2825   for (s = param_structs; s; s = s->next)
2826     if (s->gc_used == GC_POINTED_TO)
2827       {
2828         type_p * param = s->u.param_struct.param;
2829         type_p stru = s->u.param_struct.stru;
2830
2831         /* Declare the marker procedure.  */
2832         oprintf (header_file, "extern void gt_pch_p_");
2833         output_mangled_typename (header_file, s);
2834         oprintf (header_file,
2835          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2836
2837         if (stru->u.s.line.file == NULL)
2838           {
2839             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2840                      s->u.s.tag);
2841             continue;
2842           }
2843
2844         if (stru->kind == TYPE_LANG_STRUCT)
2845           {
2846             type_p ss;
2847             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2848               write_local_func_for_structure (s, ss, param);
2849           }
2850         else
2851           write_local_func_for_structure (s, stru, param);
2852       }
2853 }
2854
2855 /* Write out the 'enum' definition for gt_types_enum.  */
2856
2857 static void
2858 write_enum_defn (type_p structures, type_p param_structs)
2859 {
2860   type_p s;
2861
2862   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2863   oprintf (header_file, "enum gt_types_enum {\n");
2864   for (s = structures; s; s = s->next)
2865     if (s->gc_used == GC_POINTED_TO
2866         || s->gc_used == GC_MAYBE_POINTED_TO)
2867       {
2868         if (s->gc_used == GC_MAYBE_POINTED_TO
2869             && s->u.s.line.file == NULL)
2870           continue;
2871
2872         oprintf (header_file, " gt_ggc_e_");
2873         output_mangled_typename (header_file, s);
2874         oprintf (header_file, ", \n");
2875       }
2876   for (s = param_structs; s; s = s->next)
2877     if (s->gc_used == GC_POINTED_TO)
2878       {
2879         oprintf (header_file, " gt_e_");
2880         output_mangled_typename (header_file, s);
2881         oprintf (header_file, ", \n");
2882       }
2883   oprintf (header_file, " gt_types_enum_last\n");
2884   oprintf (header_file, "};\n");
2885 }
2886
2887 /* Might T contain any non-pointer elements?  */
2888
2889 static int
2890 contains_scalar_p (type_p t)
2891 {
2892   switch (t->kind)
2893     {
2894     case TYPE_STRING:
2895     case TYPE_POINTER:
2896       return 0;
2897     case TYPE_ARRAY:
2898       return contains_scalar_p (t->u.a.p);
2899     default:
2900       /* Could also check for structures that have no non-pointer
2901          fields, but there aren't enough of those to worry about.  */
2902       return 1;
2903     }
2904 }
2905
2906 /* Mangle FN and print it to F.  */
2907
2908 static void
2909 put_mangled_filename (outf_p f, const char *fn)
2910 {
2911   const char *name = get_output_file_name (fn);
2912   for (; *name != 0; name++)
2913     if (ISALNUM (*name))
2914       oprintf (f, "%c", *name);
2915     else
2916       oprintf (f, "%c", '_');
2917 }
2918
2919 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2920    LASTNAME, and NAME are all strings to insert in various places in
2921    the resulting code.  */
2922
2923 static void
2924 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2925                    const char *tname, const char *name)
2926 {
2927   struct flist *fli2;
2928
2929   for (fli2 = flp; fli2; fli2 = fli2->next)
2930     if (fli2->started_p)
2931       {
2932         oprintf (fli2->f, "  %s\n", lastname);
2933         oprintf (fli2->f, "};\n\n");
2934       }
2935
2936   for (fli2 = flp; fli2; fli2 = fli2->next)
2937     if (fli2->started_p)
2938       {
2939         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2940         int fnum;
2941
2942         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2943           if (bitmap & 1)
2944             {
2945               oprintf (base_files[fnum],
2946                        "extern const struct %s gt_%s_",
2947                        tname, pfx);
2948               put_mangled_filename (base_files[fnum], fli2->name);
2949               oprintf (base_files[fnum], "[];\n");
2950             }
2951       }
2952
2953   {
2954     size_t fnum;
2955     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2956       oprintf (base_files [fnum],
2957                "const struct %s * const %s[] = {\n",
2958                tname, name);
2959   }
2960
2961
2962   for (fli2 = flp; fli2; fli2 = fli2->next)
2963     if (fli2->started_p)
2964       {
2965         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
2966         int fnum;
2967
2968         fli2->started_p = 0;
2969
2970         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2971           if (bitmap & 1)
2972             {
2973               oprintf (base_files[fnum], "  gt_%s_", pfx);
2974               put_mangled_filename (base_files[fnum], fli2->name);
2975               oprintf (base_files[fnum], ",\n");
2976             }
2977       }
2978
2979   {
2980     size_t fnum;
2981     for (fnum = 0; fnum < num_lang_dirs; fnum++)
2982       {
2983         oprintf (base_files[fnum], "  NULL\n");
2984         oprintf (base_files[fnum], "};\n");
2985       }
2986   }
2987 }
2988
2989 /* Write out to F the table entry and any marker routines needed to
2990    mark NAME as TYPE.  The original variable is V, at LINE.
2991    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2992    is nonzero iff we are building the root table for hash table caches.  */
2993
2994 static void
2995 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2996             struct fileloc *line, const char *if_marked)
2997 {
2998   switch (type->kind)
2999     {
3000     case TYPE_STRUCT:
3001       {
3002         pair_p fld;
3003         for (fld = type->u.s.fields; fld; fld = fld->next)
3004           {
3005             int skip_p = 0;
3006             const char *desc = NULL;
3007             options_p o;
3008
3009             for (o = fld->opt; o; o = o->next)
3010               if (strcmp (o->name, "skip") == 0)
3011                 skip_p = 1;
3012               else if (strcmp (o->name, "desc") == 0)
3013                 desc = o->info;
3014               else if (strcmp (o->name, "param_is") == 0)
3015                 ;
3016               else
3017                 error_at_line (line,
3018                        "field `%s' of global `%s' has unknown option `%s'",
3019                                fld->name, name, o->name);
3020
3021             if (skip_p)
3022               continue;
3023             else if (desc && fld->type->kind == TYPE_UNION)
3024               {
3025                 pair_p validf = NULL;
3026                 pair_p ufld;
3027
3028                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3029                   {
3030                     const char *tag = NULL;
3031                     options_p oo;
3032
3033                     for (oo = ufld->opt; oo; oo = oo->next)
3034                       if (strcmp (oo->name, "tag") == 0)
3035                         tag = oo->info;
3036                     if (tag == NULL || strcmp (tag, desc) != 0)
3037                       continue;
3038                     if (validf != NULL)
3039                       error_at_line (line,
3040                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3041                                      name, fld->name, validf->name,
3042                                      name, fld->name, ufld->name,
3043                                      tag);
3044                     validf = ufld;
3045                   }
3046                 if (validf != NULL)
3047                   {
3048                     char *newname;
3049                     newname = xasprintf ("%s.%s.%s",
3050                                          name, fld->name, validf->name);
3051                     write_root (f, v, validf->type, newname, 0, line,
3052                                 if_marked);
3053                     free (newname);
3054                   }
3055               }
3056             else if (desc)
3057               error_at_line (line,
3058                      "global `%s.%s' has `desc' option but is not union",
3059                              name, fld->name);
3060             else
3061               {
3062                 char *newname;
3063                 newname = xasprintf ("%s.%s", name, fld->name);
3064                 write_root (f, v, fld->type, newname, 0, line, if_marked);
3065                 free (newname);
3066               }
3067           }
3068       }
3069       break;
3070
3071     case TYPE_ARRAY:
3072       {
3073         char *newname;
3074         newname = xasprintf ("%s[0]", name);
3075         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
3076         free (newname);
3077       }
3078       break;
3079
3080     case TYPE_POINTER:
3081       {
3082         type_p ap, tp;
3083
3084         oprintf (f, "  {\n");
3085         oprintf (f, "    &%s,\n", name);
3086         oprintf (f, "    1");
3087
3088         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3089           if (ap->u.a.len[0])
3090             oprintf (f, " * (%s)", ap->u.a.len);
3091           else if (ap == v->type)
3092             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3093         oprintf (f, ",\n");
3094         oprintf (f, "    sizeof (%s", v->name);
3095         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3096           oprintf (f, "[0]");
3097         oprintf (f, "),\n");
3098
3099         tp = type->u.p;
3100
3101         if (! has_length && UNION_OR_STRUCT_P (tp))
3102           {
3103             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3104             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3105           }
3106         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3107           {
3108             oprintf (f, "    &gt_ggc_m_");
3109             output_mangled_typename (f, tp);
3110             oprintf (f, ",\n    &gt_pch_n_");
3111             output_mangled_typename (f, tp);
3112           }
3113         else if (has_length
3114                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3115           {
3116             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3117             oprintf (f, "    &gt_pch_na_%s", name);
3118           }
3119         else
3120           {
3121             error_at_line (line,
3122                            "global `%s' is pointer to unimplemented type",
3123                            name);
3124           }
3125         if (if_marked)
3126           oprintf (f, ",\n    &%s", if_marked);
3127         oprintf (f, "\n  },\n");
3128       }
3129       break;
3130
3131     case TYPE_STRING:
3132       {
3133         oprintf (f, "  {\n");
3134         oprintf (f, "    &%s,\n", name);
3135         oprintf (f, "    1, \n");
3136         oprintf (f, "    sizeof (%s),\n", v->name);
3137         oprintf (f, "    &gt_ggc_m_S,\n");
3138         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3139         oprintf (f, "  },\n");
3140       }
3141       break;
3142
3143     case TYPE_SCALAR:
3144       break;
3145
3146     default:
3147       error_at_line (line,
3148                      "global `%s' is unimplemented type",
3149                      name);
3150     }
3151 }
3152
3153 /* This generates a routine to walk an array.  */
3154
3155 static void
3156 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3157 {
3158   struct walk_type_data d;
3159   char *prevval3;
3160
3161   memset (&d, 0, sizeof (d));
3162   d.of = f;
3163   d.cookie = wtd;
3164   d.indent = 2;
3165   d.line = &v->line;
3166   d.opt = v->opt;
3167   d.bitmap = get_lang_bitmap (v->line.file);
3168   d.param = NULL;
3169
3170   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3171
3172   if (wtd->param_prefix)
3173     {
3174       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3175       oprintf (f,
3176        "    (void *, void *, gt_pointer_operator, void *);\n");
3177       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3178                wtd->param_prefix, v->name);
3179       oprintf (d.of,
3180                "      ATTRIBUTE_UNUSED void *x_p,\n"
3181                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3182                "      ATTRIBUTE_UNUSED void * cookie)\n");
3183       oprintf (d.of, "{\n");
3184       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3185       d.process_field = write_types_local_process_field;
3186       walk_type (v->type, &d);
3187       oprintf (f, "}\n\n");
3188     }
3189
3190   d.opt = v->opt;
3191   oprintf (f, "static void gt_%sa_%s (void *);\n",
3192            wtd->prefix, v->name);
3193   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3194            wtd->prefix, v->name);
3195   oprintf (f, "{\n");
3196   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3197   d.process_field = write_types_process_field;
3198   walk_type (v->type, &d);
3199   free (prevval3);
3200   oprintf (f, "}\n\n");
3201 }
3202
3203 /* Output a table describing the locations and types of VARIABLES.  */
3204
3205 static void
3206 write_roots (pair_p variables)
3207 {
3208   pair_p v;
3209   struct flist *flp = NULL;
3210
3211   for (v = variables; v; v = v->next)
3212     {
3213       outf_p f = get_output_file_with_visibility (v->line.file);
3214       struct flist *fli;
3215       const char *length = NULL;
3216       int deletable_p = 0;
3217       options_p o;
3218
3219       for (o = v->opt; o; o = o->next)
3220         if (strcmp (o->name, "length") == 0)
3221           length = o->info;
3222         else if (strcmp (o->name, "deletable") == 0)
3223           deletable_p = 1;
3224         else if (strcmp (o->name, "param_is") == 0)
3225           ;
3226         else if (strncmp (o->name, "param", 5) == 0
3227                  && ISDIGIT (o->name[5])
3228                  && strcmp (o->name + 6, "_is") == 0)
3229           ;
3230         else if (strcmp (o->name, "if_marked") == 0)
3231           ;
3232         else
3233           error_at_line (&v->line,
3234                          "global `%s' has unknown option `%s'",
3235                          v->name, o->name);
3236
3237       for (fli = flp; fli; fli = fli->next)
3238         if (fli->f == f)
3239           break;
3240       if (fli == NULL)
3241         {
3242           fli = XNEW (struct flist);
3243           fli->f = f;
3244           fli->next = flp;
3245           fli->started_p = 0;
3246           fli->name = v->line.file;
3247           flp = fli;
3248
3249           oprintf (f, "\n/* GC roots.  */\n\n");
3250         }
3251
3252       if (! deletable_p
3253           && length
3254           && v->type->kind == TYPE_POINTER
3255           && (v->type->u.p->kind == TYPE_POINTER
3256               || v->type->u.p->kind == TYPE_STRUCT))
3257         {
3258           write_array (f, v, &ggc_wtd);
3259           write_array (f, v, &pch_wtd);
3260         }
3261     }
3262
3263   for (v = variables; v; v = v->next)
3264     {
3265       outf_p f = get_output_file_with_visibility (v->line.file);
3266       struct flist *fli;
3267       int skip_p = 0;
3268       int length_p = 0;
3269       options_p o;
3270
3271       for (o = v->opt; o; o = o->next)
3272         if (strcmp (o->name, "length") == 0)
3273           length_p = 1;
3274         else if (strcmp (o->name, "deletable") == 0
3275                  || strcmp (o->name, "if_marked") == 0)
3276           skip_p = 1;
3277
3278       if (skip_p)
3279         continue;
3280
3281       for (fli = flp; fli; fli = fli->next)
3282         if (fli->f == f)
3283           break;
3284       if (! fli->started_p)
3285         {
3286           fli->started_p = 1;
3287
3288           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
3289           put_mangled_filename (f, v->line.file);
3290           oprintf (f, "[] = {\n");
3291         }
3292
3293       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3294     }
3295
3296   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3297                      "gt_ggc_rtab");
3298
3299   for (v = variables; v; v = v->next)
3300     {
3301       outf_p f = get_output_file_with_visibility (v->line.file);
3302       struct flist *fli;
3303       int skip_p = 1;
3304       options_p o;
3305
3306       for (o = v->opt; o; o = o->next)
3307         if (strcmp (o->name, "deletable") == 0)
3308           skip_p = 0;
3309         else if (strcmp (o->name, "if_marked") == 0)
3310           skip_p = 1;
3311
3312       if (skip_p)
3313         continue;
3314
3315       for (fli = flp; fli; fli = fli->next)
3316         if (fli->f == f)
3317           break;
3318       if (! fli->started_p)
3319         {
3320           fli->started_p = 1;
3321
3322           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
3323           put_mangled_filename (f, v->line.file);
3324           oprintf (f, "[] = {\n");
3325         }
3326
3327       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3328                v->name, v->name);
3329     }
3330
3331   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3332                      "gt_ggc_deletable_rtab");
3333
3334   for (v = variables; v; v = v->next)
3335     {
3336       outf_p f = get_output_file_with_visibility (v->line.file);
3337       struct flist *fli;
3338       const char *if_marked = NULL;
3339       int length_p = 0;
3340       options_p o;
3341
3342       for (o = v->opt; o; o = o->next)
3343         if (strcmp (o->name, "length") == 0)
3344           length_p = 1;
3345         else if (strcmp (o->name, "if_marked") == 0)
3346           if_marked = o->info;
3347
3348       if (if_marked == NULL)
3349         continue;
3350
3351       if (v->type->kind != TYPE_POINTER
3352           || v->type->u.p->kind != TYPE_PARAM_STRUCT
3353           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3354         {
3355           error_at_line (&v->line, "if_marked option used but not hash table");
3356           continue;
3357         }
3358
3359       for (fli = flp; fli; fli = fli->next)
3360         if (fli->f == f)
3361           break;
3362       if (! fli->started_p)
3363         {
3364           fli->started_p = 1;
3365
3366           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
3367           put_mangled_filename (f, v->line.file);
3368           oprintf (f, "[] = {\n");
3369         }
3370
3371       write_root (f, v, v->type->u.p->u.param_struct.param[0],
3372                      v->name, length_p, &v->line, if_marked);
3373     }
3374
3375   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3376                      "gt_ggc_cache_rtab");
3377
3378   for (v = variables; v; v = v->next)
3379     {
3380       outf_p f = get_output_file_with_visibility (v->line.file);
3381       struct flist *fli;
3382       int length_p = 0;
3383       int if_marked_p = 0;
3384       options_p o;
3385
3386       for (o = v->opt; o; o = o->next)
3387         if (strcmp (o->name, "length") == 0)
3388           length_p = 1;
3389         else if (strcmp (o->name, "if_marked") == 0)
3390           if_marked_p = 1;
3391
3392       if (! if_marked_p)
3393         continue;
3394
3395       for (fli = flp; fli; fli = fli->next)
3396         if (fli->f == f)
3397           break;
3398       if (! fli->started_p)
3399         {
3400           fli->started_p = 1;
3401
3402           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
3403           put_mangled_filename (f, v->line.file);
3404           oprintf (f, "[] = {\n");
3405         }
3406
3407       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3408     }
3409
3410   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3411                      "gt_pch_cache_rtab");
3412
3413   for (v = variables; v; v = v->next)
3414     {
3415       outf_p f = get_output_file_with_visibility (v->line.file);
3416       struct flist *fli;
3417       int skip_p = 0;
3418       options_p o;
3419
3420       for (o = v->opt; o; o = o->next)
3421         if (strcmp (o->name, "deletable") == 0
3422             || strcmp (o->name, "if_marked") == 0)
3423           skip_p = 1;
3424
3425       if (skip_p)
3426         continue;
3427
3428       if (! contains_scalar_p (v->type))
3429         continue;
3430
3431       for (fli = flp; fli; fli = fli->next)
3432         if (fli->f == f)
3433           break;
3434       if (! fli->started_p)
3435         {
3436           fli->started_p = 1;
3437
3438           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
3439           put_mangled_filename (f, v->line.file);
3440           oprintf (f, "[] = {\n");
3441         }
3442
3443       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3444                v->name, v->name);
3445     }
3446
3447   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3448                      "gt_pch_scalar_rtab");
3449 }
3450
3451 /* Record the definition of a generic VEC structure, as if we had expanded
3452    the macros in vec.h:
3453
3454    typedef struct VEC_<type>_base GTY(()) {
3455    unsigned num;
3456    unsigned alloc;
3457    <type> GTY((length ("%h.num"))) vec[1];
3458    } VEC_<type>_base
3459
3460    where the GTY(()) tags are only present if is_scalar is _false_.  */
3461
3462 void
3463 note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
3464 {
3465   pair_p fields;
3466   type_p t;
3467   options_p o;
3468   type_p len_ty = create_scalar_type ("unsigned");
3469   const char *name = concat ("VEC_", typename, "_base", (char *)0);
3470
3471   if (is_scalar)
3472     {
3473       t = create_scalar_type (typename);
3474       o = 0;
3475     }
3476   else
3477     {
3478       t = resolve_typedef (typename, pos);
3479       o = create_option (0, "length", "%h.num");
3480     }
3481
3482   /* We assemble the field list in reverse order.  */
3483   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3484   fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3485   fields = create_field_at (fields, len_ty, "num", 0, pos);
3486
3487   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3488 }
3489
3490 /* Record the definition of an allocation-specific VEC structure, as if
3491    we had expanded the macros in vec.h:
3492
3493    typedef struct VEC_<type>_<astrat> {
3494      VEC_<type>_base base;
3495    } VEC_<type>_<astrat>;
3496 */
3497 void
3498 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3499 {
3500   const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3501   const char *basename = concat ("VEC_", type, "_base", (char *)0);
3502
3503   pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3504                                   "base", 0, pos);
3505
3506   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3507 }
3508
3509 \f
3510 int
3511 main (int argc, char **argv)
3512 {
3513   size_t i;
3514   static struct fileloc pos = { this_file, 0 };
3515
3516   /* fatal uses this */
3517   progname = "gengtype";
3518
3519   if (argc != 3)
3520     fatal ("usage: gengtype srcdir input-list");
3521
3522   srcdir = argv[1];
3523   srcdir_len = strlen (srcdir);
3524
3525   read_input_list (argv[2]);
3526   if (hit_error)
3527     return 1;
3528
3529   scalar_char.u.scalar_is_char = true;
3530   scalar_nonchar.u.scalar_is_char = false;
3531   gen_rtx_next ();
3532
3533   /* These types are set up with #define or else outside of where
3534      we can see them.  */
3535   pos.line = __LINE__ + 1;
3536   do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3537   do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
3538   do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
3539   do_scalar_typedef ("double_int", &pos); pos.line++;
3540   do_scalar_typedef ("uint8", &pos); pos.line++;
3541   do_scalar_typedef ("jword", &pos); pos.line++;
3542   do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3543   do_scalar_typedef ("void", &pos); pos.line++;
3544   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3545
3546   for (i = 0; i < num_gt_files; i++)
3547     parse_file (gt_files[i]);
3548
3549   if (hit_error)
3550     return 1;
3551
3552   set_gc_used (variables);
3553
3554   open_base_files ();
3555   write_enum_defn (structures, param_structs);
3556   write_types (structures, param_structs, &ggc_wtd);
3557   write_types (structures, param_structs, &pch_wtd);
3558   write_local (structures, param_structs);
3559   write_roots (variables);
3560   write_rtx_next ();
3561   close_output_files ();
3562
3563   if (hit_error)
3564     return 1;
3565   return 0;
3566 }