OSDN Git Service

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