OSDN Git Service

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