OSDN Git Service

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