OSDN Git Service

* rtl.h (union rtunion_def): Remove rt_bit member.
[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 #include "hashtab.h"
27
28 /* Data types, macros, etc. used only in this file.  */
29
30 /* Kinds of types we can understand.  */
31 enum typekind {
32   TYPE_SCALAR,
33   TYPE_STRING,
34   TYPE_STRUCT,
35   TYPE_UNION,
36   TYPE_POINTER,
37   TYPE_ARRAY,
38   TYPE_LANG_STRUCT,
39   TYPE_PARAM_STRUCT
40 };
41
42 typedef unsigned lang_bitmap;
43
44 /* A way to pass data through to the output end.  */
45 struct options
46 {
47   struct options *next;
48   const char *name;
49   const char *info;
50 };
51
52 /* Option data for the 'nested_ptr' option.  */
53 struct nested_ptr_data
54 {
55   type_p type;
56   const char *convert_to;
57   const char *convert_from;
58 };
59
60 /* A name and a type.  */
61 struct pair
62 {
63   pair_p next;
64   const char *name;
65   type_p type;
66   struct fileloc line;
67   options_p opt;
68 };
69
70 #define NUM_PARAM 10
71
72 /* A description of a type.  */
73 enum gc_used_enum
74   {
75     GC_UNUSED = 0,
76     GC_USED,
77     /* Used for structures whose definitions we haven't seen so far when
78        we encounter a pointer to it that is annotated with ``maybe_undef''.
79        If after reading in everything we don't have source file
80        information for it, we assume that it never has been defined. */
81     GC_MAYBE_POINTED_TO,
82     GC_POINTED_TO
83   };
84
85 struct type
86 {
87   enum typekind kind;
88   type_p next;
89   type_p pointer_to;
90   enum gc_used_enum gc_used;
91   union {
92     type_p p;
93     struct {
94       const char *tag;
95       struct fileloc line;
96       pair_p fields;
97       options_p opt;
98       lang_bitmap bitmap;
99       type_p lang_struct;
100     } s;
101     bool scalar_is_char;
102     struct {
103       type_p p;
104       const char *len;
105     } a;
106     struct {
107       type_p stru;
108       type_p param[NUM_PARAM];
109       struct fileloc line;
110     } param_struct;
111   } u;
112 };
113
114 #define UNION_P(x)                                      \
115  ((x)->kind == TYPE_UNION ||                            \
116   ((x)->kind == TYPE_LANG_STRUCT                        \
117    && (x)->u.s.lang_struct->kind == TYPE_UNION))
118 #define UNION_OR_STRUCT_P(x)                    \
119  ((x)->kind == TYPE_UNION                       \
120   || (x)->kind == TYPE_STRUCT                   \
121   || (x)->kind == TYPE_LANG_STRUCT)
122
123 /* Structure representing an output file.  */
124 struct outf
125 {
126   struct outf *next;
127   const char *name;
128   size_t buflength;
129   size_t bufused;
130   char *buf;
131 };
132 typedef struct outf * outf_p;
133
134 /* An output file, suitable for definitions, that can see declarations
135    made in INPUT_FILE and is linked into every language that uses
136    INPUT_FILE.  May return NULL in plugin mode. */
137 extern outf_p get_output_file_with_visibility
138    (const char *input_file);
139 const char *get_output_file_name (const char *);
140
141 /* Print, like fprintf, to O.  No-op if O is NULL. */
142 static void oprintf (outf_p o, const char *S, ...)
143      ATTRIBUTE_PRINTF_2;
144
145 /* The list of output files.  */
146 static outf_p output_files;
147
148 /* The plugin input files and their number; in that case only
149    a single file is produced.  */
150 static char** plugin_files;
151 static size_t nb_plugin_files;
152 /* the generated plugin output name & file */
153 static outf_p plugin_output;
154
155 /* The output header file that is included into pretty much every
156    source file.  */
157 static outf_p header_file;
158
159 /* Source directory.  */
160 static const char *srcdir;
161
162 /* Length of srcdir name.  */
163 static size_t srcdir_len = 0;
164
165 static outf_p create_file (const char *, const char *);
166
167 static const char * get_file_basename (const char *);
168 static const char * get_file_realbasename (const char *);
169 static const char * get_file_srcdir_relative_path (const char *);
170
171 static int get_prefix_langdir_index (const char *);
172 static const char * get_file_langdir (const char *);
173
174 \f
175 /* Nonzero iff an error has occurred.  */
176 bool hit_error = false;
177
178 static void gen_rtx_next (void);
179 static void write_rtx_next (void);
180 static void open_base_files (void);
181 static void close_output_files (void);
182
183 /* Report an error at POS, printing MSG.  */
184
185 void
186 error_at_line (const struct fileloc *pos, const char *msg, ...)
187 {
188   va_list ap;
189
190   va_start (ap, msg);
191
192   fprintf (stderr, "%s:%d: ", pos->file, pos->line);
193   vfprintf (stderr, msg, ap);
194   fputc ('\n', stderr);
195   hit_error = true;
196
197   va_end (ap);
198 }
199
200 /* asprintf, but produces fatal message on out-of-memory.  */
201 char *
202 xasprintf (const char *format, ...)
203 {
204   int n;
205   char *result;
206   va_list ap;
207
208   va_start (ap, format);
209   n = vasprintf (&result, format, ap);
210   if (result == NULL || n < 0)
211     fatal ("out of memory");
212   va_end (ap);
213
214   return result;
215 }
216 \f
217 /* Input file handling. */
218
219 /* Table of all input files.  */
220 static const char **gt_files;
221 static size_t num_gt_files;
222
223 /* A number of places use the name of this file for a location for
224    things that we can't rely on the source to define.  Make sure we
225    can still use pointer comparison on filenames.  */
226 static const char this_file[] = __FILE__;
227
228 /* Vector of per-language directories.  */
229 static const char **lang_dir_names;
230 static size_t num_lang_dirs;
231
232 /* An array of output files suitable for definitions.  There is one
233    BASE_FILES entry for each language.  */
234 static outf_p *base_files;
235
236 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
237    INPUT_FILE is used by <lang>.
238
239    This function should be written to assume that a file _is_ used
240    if the situation is unclear.  If it wrongly assumes a file _is_ used,
241    a linker error will result.  If it wrongly assumes a file _is not_ used,
242    some GC roots may be missed, which is a much harder-to-debug problem.
243
244    The relevant bitmap is stored immediately before the file's name in the
245    buffer set up by read_input_list.  It may be unaligned, so we have to
246    read it byte-by-byte.  */
247
248 static lang_bitmap
249 get_lang_bitmap (const char *gtfile)
250 {
251
252   if (gtfile == this_file)
253     /* Things defined in this file are universal.  */
254     return (((lang_bitmap)1) << num_lang_dirs) - 1;
255   else
256     {
257       lang_bitmap n = 0;
258       int i;
259       for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
260         n = (n << CHAR_BIT) + (unsigned char)gtfile[i];
261       return n;
262     }
263 }
264
265 /* Set the bitmap returned by get_lang_bitmap.  The only legitimate
266    caller of this function is read_input_list.  */
267 static void
268 set_lang_bitmap (char *gtfile, lang_bitmap n)
269 {
270   int i;
271   for (i = -1; i >= -(int) sizeof (lang_bitmap); i--)
272     {
273       gtfile[i] = n & ((1U << CHAR_BIT)-1);
274       n >>= CHAR_BIT;
275     }
276 }
277
278 /* Scan the input file, LIST, and determine how much space we need to
279    store strings in.  Also, count the number of language directories
280    and files.  The numbers returned are overestimates as they does not
281    consider repeated files.  */
282 static size_t
283 measure_input_list (FILE *list)
284 {
285   size_t n = 0;
286   int c;
287   bool atbol = true;
288   num_lang_dirs = 0;
289   num_gt_files = plugin_files ? nb_plugin_files : 0;
290   while ((c = getc (list)) != EOF)
291     {
292       n++;
293       if (atbol)
294         {
295           if (c == '[')
296             num_lang_dirs++;
297           else
298             {
299               /* Add space for a lang_bitmap before the input file name.  */
300               n += sizeof (lang_bitmap);
301               num_gt_files++;
302             }
303           atbol = false;
304         }
305
306       if (c == '\n')
307         atbol = true;
308     }
309
310   rewind (list);
311   return n;
312 }
313
314 /* Read one input line from LIST to HEREP (which is updated).  A
315    pointer to the string is returned via LINEP.  If it was a language
316    subdirectory in square brackets, strip off the square brackets and
317    return true.  Otherwise, leave space before the string for a
318    lang_bitmap, and return false.  At EOF, returns false, does not
319    touch *HEREP, and sets *LINEP to NULL.  POS is used for
320    diagnostics.  */
321 static bool
322 read_input_line (FILE *list, char **herep, char **linep,
323                  struct fileloc *pos)
324 {
325   char *here = *herep;
326   char *line;
327   int c = getc (list);
328
329   /* Read over whitespace.  */
330   while (c == '\n' || c == ' ')
331     c = getc (list);
332
333   if (c == EOF)
334     {
335       *linep = 0;
336       return false;
337     }
338   else if (c == '[')
339     {
340       /* No space for a lang_bitmap is necessary.  Discard the '['. */
341       c = getc (list);
342       line = here;
343       while (c != ']' && c != '\n' && c != EOF)
344         {
345           *here++ = c;
346           c = getc (list);
347         }
348       *here++ = '\0';
349
350       if (c == ']')
351         {
352           c = getc (list);  /* eat what should be a newline */
353           if (c != '\n' && c != EOF)
354             error_at_line (pos, "junk on line after language tag [%s]", line);
355         }
356       else
357         error_at_line (pos, "missing close bracket for language tag [%s", line);
358
359       *herep = here;
360       *linep = line;
361       return true;
362     }
363   else
364     {
365       /* Leave space for a lang_bitmap.  */
366       memset (here, 0, sizeof (lang_bitmap));
367       here += sizeof (lang_bitmap);
368       line = here;
369       do
370         {
371           *here++ = c;
372           c = getc (list);
373         }
374       while (c != EOF && c != '\n');
375       *here++ = '\0';
376       *herep = here;
377       *linep = line;
378       return false;
379     }
380 }
381
382 /* Read the list of input files from LIST and compute all of the
383    relevant tables.  There is one file per line of the list.  At
384    first, all the files on the list are language-generic, but
385    eventually a line will appear which is the name of a language
386    subdirectory in square brackets, like this: [cp].  All subsequent
387    files are specific to that language, until another language
388    subdirectory tag appears.  Files can appear more than once, if
389    they apply to more than one language.  */
390 static void
391 read_input_list (const char *listname)
392 {
393   FILE *list = fopen (listname, "r");
394   if (!list)
395     fatal ("cannot open %s: %s", listname, strerror (errno));
396   else
397     {
398       struct fileloc epos;
399       size_t bufsz = measure_input_list (list);
400       char *buf = XNEWVEC (char, bufsz);
401       char *here = buf;
402       char *committed = buf;
403       char *limit = buf + bufsz;
404       char *line;
405       bool is_language;
406       size_t langno = 0;
407       size_t nfiles = 0;
408       lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
409
410       epos.file = listname;
411       epos.line = 0;
412
413       lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
414       gt_files = XNEWVEC (const char *, num_gt_files);
415
416       for (;;)
417         {
418         next_line:
419           epos.line++;
420           committed = here;
421           is_language = read_input_line (list, &here, &line, &epos);
422           gcc_assert (here <= limit);
423           if (line == 0)
424             break;
425           else if (is_language)
426             {
427               size_t i;
428               gcc_assert (langno <= num_lang_dirs);
429               for (i = 0; i < langno; i++)
430                 if (strcmp (lang_dir_names[i], line) == 0)
431                   {
432                     error_at_line (&epos, "duplicate language tag [%s]", line);
433                     curlangs = 1 << i;
434                     here = committed;
435                     goto next_line;
436                   }
437
438               curlangs = 1 << langno;
439               lang_dir_names[langno++] = line;
440             }
441           else
442             {
443               size_t i;
444               gcc_assert (nfiles <= num_gt_files);
445               for (i = 0; i < nfiles; i++)
446                 if (strcmp (gt_files[i], line) == 0)
447                   {
448                     /* Throw away the string we just read, and add the
449                        current language to the existing string's bitmap.  */
450                     lang_bitmap bmap = get_lang_bitmap (gt_files[i]);
451                     if (bmap & curlangs)
452                       error_at_line (&epos, "file %s specified more than once "
453                                      "for language %s", line, langno == 0
454                                      ? "(all)"
455                                      : lang_dir_names[langno - 1]);
456
457                     bmap |= curlangs;
458                     set_lang_bitmap (CONST_CAST(char *, gt_files[i]), bmap);
459                     here = committed;
460                     goto next_line;
461                   }
462
463               set_lang_bitmap (line, curlangs);
464               gt_files[nfiles++] = line;
465             }
466         }
467       /* Update the global counts now that we know accurately how many
468          things there are.  (We do not bother resizing the arrays down.)  */
469       num_lang_dirs = langno;
470       /* Add the plugin files if provided.  */
471       if (plugin_files)
472         {
473           size_t i;
474           for (i = 0; i < nb_plugin_files; i++)
475             gt_files[nfiles++] = plugin_files[i];
476         }
477       num_gt_files = nfiles;
478     }
479
480   /* Sanity check: any file that resides in a language subdirectory
481      (e.g. 'cp') ought to belong to the corresponding language.
482      ??? Still true if for instance ObjC++ is enabled and C++ isn't?
483      (Can you even do that?  Should you be allowed to?)  */
484   {
485     size_t f;
486     for (f = 0; f < num_gt_files; f++)
487       {
488         lang_bitmap bitmap = get_lang_bitmap (gt_files[f]);
489         const char *basename = get_file_basename (gt_files[f]);
490         const char *slashpos = strchr (basename, '/');
491
492         if (slashpos)
493           {
494             size_t l;
495             for (l = 0; l < num_lang_dirs; l++)
496               if ((size_t)(slashpos - basename) == strlen (lang_dir_names [l])
497                   && memcmp (basename, lang_dir_names[l],
498                              strlen (lang_dir_names[l])) == 0)
499                 {
500                   if (!(bitmap & (1 << l)))
501                     error ("%s is in language directory '%s' but is not "
502                            "tagged for that language",
503                            basename, lang_dir_names[l]);
504                   break;
505                 }
506           }
507       }
508   }
509
510   if (ferror (list))
511     fatal ("error reading %s: %s", listname, strerror (errno));
512
513   fclose (list);
514 }
515
516
517 \f
518 /* The one and only TYPE_STRING.  */
519
520 static struct type string_type = {
521   TYPE_STRING, 0, 0, GC_USED, {0}
522 };
523
524 /* The two and only TYPE_SCALARs.  Their u.scalar_is_char flags are
525    set to appropriate values at the beginning of main.  */
526
527 static struct type scalar_nonchar = {
528   TYPE_SCALAR, 0, 0, GC_USED, {0}
529 };
530 static struct type scalar_char = {
531   TYPE_SCALAR, 0, 0, GC_USED, {0}
532 };
533
534 /* Lists of various things.  */
535
536 static pair_p typedefs;
537 static type_p structures;
538 static type_p param_structs;
539 static pair_p variables;
540
541 static type_p find_param_structure
542   (type_p t, type_p param[NUM_PARAM]);
543 static type_p adjust_field_tree_exp (type_p t, options_p opt);
544 static type_p adjust_field_rtx_def (type_p t, options_p opt);
545
546 /* Define S as a typedef to T at POS.  */
547
548 void
549 do_typedef (const char *s, type_p t, struct fileloc *pos)
550 {
551   pair_p p;
552
553   /* temporary kludge - gengtype doesn't handle conditionals or
554      macros.  Ignore any attempt to typedef CUMULATIVE_ARGS, unless it
555      is coming from this file (main() sets them up with safe dummy
556      definitions).  */
557   if (!strcmp (s, "CUMULATIVE_ARGS") && pos->file != this_file)
558     return;
559
560   for (p = typedefs; p != NULL; p = p->next)
561     if (strcmp (p->name, s) == 0)
562       {
563         if (p->type != t)
564           {
565             error_at_line (pos, "type `%s' previously defined", s);
566             error_at_line (&p->line, "previously defined here");
567           }
568         return;
569       }
570
571   p = XNEW (struct pair);
572   p->next = typedefs;
573   p->name = s;
574   p->type = t;
575   p->line = *pos;
576   p->opt = NULL;
577   typedefs = p;
578 }
579
580 /* Define S as a typename of a scalar.  Cannot be used to define
581    typedefs of 'char'.  Note: is also used for pointer-to-function
582    typedefs (which are therefore not treated as pointers).  */
583
584 void
585 do_scalar_typedef (const char *s, struct fileloc *pos)
586 {
587   do_typedef (s, &scalar_nonchar, pos);
588 }
589
590 /* Return the type previously defined for S.  Use POS to report errors.  */
591
592 type_p
593 resolve_typedef (const char *s, struct fileloc *pos)
594 {
595   pair_p p;
596   for (p = typedefs; p != NULL; p = p->next)
597     if (strcmp (p->name, s) == 0)
598       return p->type;
599   error_at_line (pos, "unidentified type `%s'", s);
600   return &scalar_nonchar;  /* treat as "int" */
601 }
602
603 /* Create and return a new structure with tag NAME (or a union iff
604    ISUNION is nonzero), at POS with fields FIELDS and options O.  */
605
606 type_p
607 new_structure (const char *name, int isunion, struct fileloc *pos,
608                pair_p fields, options_p o)
609 {
610   type_p si;
611   type_p s = NULL;
612   lang_bitmap bitmap = get_lang_bitmap (pos->file);
613
614   /* temporary kludge - gengtype doesn't handle conditionals or
615      macros.  Ignore any attempt to define struct location_s, unless
616      it is coming from this file (main() sets it up safely). */
617   if (!strcmp (name, "location_s") && !isunion
618       && pos->file != this_file)
619     return find_structure (name, 0);
620
621   for (si = structures; si != NULL; si = si->next)
622     if (strcmp (name, si->u.s.tag) == 0
623         && UNION_P (si) == isunion)
624       {
625         type_p ls = NULL;
626         if (si->kind == TYPE_LANG_STRUCT)
627           {
628             ls = si;
629
630             for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
631               if (si->u.s.bitmap == bitmap)
632                 s = si;
633           }
634         else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
635           {
636             ls = si;
637             si = XCNEW (struct type);
638             memcpy (si, ls, sizeof (struct type));
639             ls->kind = TYPE_LANG_STRUCT;
640             ls->u.s.lang_struct = si;
641             ls->u.s.fields = NULL;
642             si->next = NULL;
643             si->pointer_to = NULL;
644             si->u.s.lang_struct = ls;
645           }
646         else
647           s = si;
648
649         if (ls != NULL && s == NULL)
650           {
651             s = XCNEW (struct type);
652             s->next = ls->u.s.lang_struct;
653             ls->u.s.lang_struct = s;
654             s->u.s.lang_struct = ls;
655           }
656         break;
657       }
658
659   if (s == NULL)
660     {
661       s = XCNEW (struct type);
662       s->next = structures;
663       structures = s;
664     }
665
666   if (s->u.s.line.file != NULL
667       || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
668     {
669       error_at_line (pos, "duplicate definition of '%s %s'",
670                      isunion ? "union" : "struct", s->u.s.tag);
671       error_at_line (&s->u.s.line, "previous definition here");
672     }
673
674   s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
675   s->u.s.tag = name;
676   s->u.s.line = *pos;
677   s->u.s.fields = fields;
678   s->u.s.opt = o;
679   s->u.s.bitmap = bitmap;
680   if (s->u.s.lang_struct)
681     s->u.s.lang_struct->u.s.bitmap |= bitmap;
682
683   /* Reset location_s's location to input.h so that we know where to
684      write out its mark routine.  */
685   if (!strcmp (name, "location_s") && !isunion
686       && pos->file == this_file)
687     {
688       size_t n;
689       for (n = 0; n < num_gt_files; n++)
690         if (!strcmp (gt_files[n] + strlen (gt_files[n]) - strlen ("input.h"),
691                      "input.h"))
692           {
693             s->u.s.line.file = gt_files[n];
694             break;
695           }
696     }
697
698     return s;
699 }
700
701 /* Return the previously-defined structure with tag NAME (or a union
702    iff ISUNION is nonzero), or a new empty structure or union if none
703    was defined previously.  */
704
705 type_p
706 find_structure (const char *name, int isunion)
707 {
708   type_p s;
709
710   for (s = structures; s != NULL; s = s->next)
711     if (strcmp (name, s->u.s.tag) == 0
712         && UNION_P (s) == isunion)
713       return s;
714
715   s = XCNEW (struct type);
716   s->next = structures;
717   structures = s;
718   s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
719   s->u.s.tag = name;
720   structures = s;
721   return s;
722 }
723
724 /* Return the previously-defined parameterized structure for structure
725    T and parameters PARAM, or a new parameterized empty structure or
726    union if none was defined previously.  */
727
728 static type_p
729 find_param_structure (type_p t, type_p param[NUM_PARAM])
730 {
731   type_p res;
732
733   for (res = param_structs; res; res = res->next)
734     if (res->u.param_struct.stru == t
735         && memcmp (res->u.param_struct.param, param,
736                    sizeof (type_p) * NUM_PARAM) == 0)
737       break;
738   if (res == NULL)
739     {
740       res = XCNEW (struct type);
741       res->kind = TYPE_PARAM_STRUCT;
742       res->next = param_structs;
743       param_structs = res;
744       res->u.param_struct.stru = t;
745       memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
746     }
747   return res;
748 }
749
750 /* Return a scalar type with name NAME.  */
751
752 type_p
753 create_scalar_type (const char *name)
754 {
755   if (!strcmp (name, "char") || !strcmp (name, "unsigned char"))
756     return &scalar_char;
757   else
758     return &scalar_nonchar;
759 }
760
761 /* Return a pointer to T.  */
762
763 type_p
764 create_pointer (type_p t)
765 {
766   if (! t->pointer_to)
767     {
768       type_p r = XCNEW (struct type);
769       r->kind = TYPE_POINTER;
770       r->u.p = t;
771       t->pointer_to = r;
772     }
773   return t->pointer_to;
774 }
775
776 /* Return an array of length LEN.  */
777
778 type_p
779 create_array (type_p t, const char *len)
780 {
781   type_p v;
782
783   v = XCNEW (struct type);
784   v->kind = TYPE_ARRAY;
785   v->u.a.p = t;
786   v->u.a.len = len;
787   return v;
788 }
789
790 /* Return an options structure with name NAME and info INFO.  NEXT is the
791    next option in the chain.  */
792
793 options_p
794 create_option (options_p next, const char *name, const void *info)
795 {
796   options_p o = XNEW (struct options);
797   o->next = next;
798   o->name = name;
799   o->info = (const char*) info;
800   return o;
801 }
802
803 /* Return an options structure for a "nested_ptr" option.  */
804 options_p
805 create_nested_ptr_option (options_p next, type_p t,
806                           const char *to, const char *from)
807 {
808   struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
809
810   d->type = adjust_field_type (t, 0);
811   d->convert_to = to;
812   d->convert_from = from;
813   return create_option (next, "nested_ptr", d);
814 }
815
816 /* Add a variable named S of type T with options O defined at POS,
817    to `variables'.  */
818
819 void
820 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
821 {
822   pair_p n;
823   n = XNEW (struct pair);
824   n->name = s;
825   n->type = t;
826   n->line = *pos;
827   n->opt = o;
828   n->next = variables;
829   variables = n;
830 }
831
832 /* Most-general structure field creator.  */
833 static pair_p
834 create_field_all (pair_p next, type_p type, const char *name, options_p opt,
835                   const char *file, int line)
836 {
837   pair_p field;
838
839   field = XNEW (struct pair);
840   field->next = next;
841   field->type = type;
842   field->name = name;
843   field->opt = opt;
844   field->line.file = file;
845   field->line.line = line;
846   return field;
847 }
848
849 /* Create a field that came from the source code we are scanning,
850    i.e. we have a 'struct fileloc', and possibly options; also,
851    adjust_field_type should be called.  */
852 pair_p
853 create_field_at (pair_p next, type_p type, const char *name, options_p opt,
854                  struct fileloc *pos)
855 {
856   return create_field_all (next, adjust_field_type (type, opt),
857                            name, opt, pos->file, pos->line);
858 }
859
860 /* Create a fake field with the given type and name.  NEXT is the next
861    field in the chain.  */
862 #define create_field(next,type,name) \
863     create_field_all(next,type,name, 0, this_file, __LINE__)
864
865 /* Like create_field, but the field is only valid when condition COND
866    is true.  */
867
868 static pair_p
869 create_optional_field_ (pair_p next, type_p type, const char *name,
870                         const char *cond, int line)
871 {
872   static int id = 1;
873   pair_p union_fields;
874   type_p union_type;
875
876   /* Create a fake union type with a single nameless field of type TYPE.
877      The field has a tag of "1".  This allows us to make the presence
878      of a field of type TYPE depend on some boolean "desc" being true.  */
879   union_fields = create_field (NULL, type, "");
880   union_fields->opt = create_option (union_fields->opt, "dot", "");
881   union_fields->opt = create_option (union_fields->opt, "tag", "1");
882   union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
883                               &lexer_line, union_fields, NULL);
884
885   /* Create the field and give it the new fake union type.  Add a "desc"
886      tag that specifies the condition under which the field is valid.  */
887   return create_field_all (next, union_type, name,
888                            create_option (0, "desc", cond),
889                            this_file, line);
890 }
891 #define create_optional_field(next,type,name,cond)      \
892        create_optional_field_(next,type,name,cond,__LINE__)
893
894 /* Reverse a linked list of 'struct pair's in place.  */
895 pair_p
896 nreverse_pairs (pair_p list)
897 {
898   pair_p prev = 0, p, next;
899   for (p = list; p; p = next)
900     {
901       next = p->next;
902       p->next = prev;
903       prev = p;
904     }
905   return prev;
906 }
907
908 \f
909 /* We don't care how long a CONST_DOUBLE is.  */
910 #define CONST_DOUBLE_FORMAT "ww"
911 /* We don't want to see codes that are only for generator files.  */
912 #undef GENERATOR_FILE
913
914 enum rtx_code {
915 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
916 #include "rtl.def"
917 #undef DEF_RTL_EXPR
918   NUM_RTX_CODE
919 };
920
921 static const char * const rtx_name[NUM_RTX_CODE] = {
922 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
923 #include "rtl.def"
924 #undef DEF_RTL_EXPR
925 };
926
927 static const char * const rtx_format[NUM_RTX_CODE] = {
928 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
929 #include "rtl.def"
930 #undef DEF_RTL_EXPR
931 };
932
933 static int rtx_next_new[NUM_RTX_CODE];
934
935 /* We also need codes and names for insn notes (not register notes).
936    Note that we do *not* bias the note values here.  */
937 enum insn_note {
938 #define DEF_INSN_NOTE(NAME) NAME,
939 #include "insn-notes.def"
940 #undef DEF_INSN_NOTE
941
942   NOTE_INSN_MAX
943 };
944
945 /* We must allocate one more entry here, as we use NOTE_INSN_MAX as the
946    default field for line number notes.  */
947 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
948 #define DEF_INSN_NOTE(NAME) #NAME,
949 #include "insn-notes.def"
950 #undef DEF_INSN_NOTE
951 };
952
953 #undef CONST_DOUBLE_FORMAT
954 #define GENERATOR_FILE
955
956 /* Generate the contents of the rtx_next array.  This really doesn't belong
957    in gengtype at all, but it's needed for adjust_field_rtx_def.  */
958
959 static void
960 gen_rtx_next (void)
961 {
962   int i;
963   for (i = 0; i < NUM_RTX_CODE; i++)
964     {
965       int k;
966
967       rtx_next_new[i] = -1;
968       if (strncmp (rtx_format[i], "iuu", 3) == 0)
969         rtx_next_new[i] = 2;
970       else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
971         rtx_next_new[i] = 1;
972       else
973         for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
974           if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
975             rtx_next_new[i] = k;
976     }
977 }
978
979 /* Write out the contents of the rtx_next array.  */
980 static void
981 write_rtx_next (void)
982 {
983   outf_p f = get_output_file_with_visibility (NULL);
984   int i;
985   if (!f)
986     return;
987
988   oprintf (f, "\n/* Used to implement the RTX_NEXT macro.  */\n");
989   oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
990   for (i = 0; i < NUM_RTX_CODE; i++)
991     if (rtx_next_new[i] == -1)
992       oprintf (f, "  0,\n");
993     else
994       oprintf (f,
995                "  RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
996                rtx_next_new[i]);
997   oprintf (f, "};\n");
998 }
999
1000 /* Handle `special("rtx_def")'.  This is a special case for field
1001    `fld' of struct rtx_def, which is an array of unions whose values
1002    are based in a complex way on the type of RTL.  */
1003
1004 static type_p
1005 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
1006 {
1007   pair_p flds = NULL;
1008   options_p nodot;
1009   int i;
1010   type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
1011   type_p basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
1012
1013   if (t->kind != TYPE_UNION)
1014     {
1015       error_at_line (&lexer_line,
1016                      "special `rtx_def' must be applied to a union");
1017       return &string_type;
1018     }
1019
1020   nodot = create_option (NULL, "dot", "");
1021
1022   rtx_tp = create_pointer (find_structure ("rtx_def", 0));
1023   rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
1024   tree_tp = create_pointer (find_structure ("tree_node", 1));
1025   mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
1026   reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
1027   basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
1028   constant_tp = create_pointer (find_structure ("constant_descriptor_rtx", 0));
1029   scalar_tp = &scalar_nonchar;  /* rtunion int */
1030
1031   {
1032     pair_p note_flds = NULL;
1033     int c;
1034
1035     for (c = 0; c <= NOTE_INSN_MAX; c++)
1036       {
1037         switch (c)
1038           {
1039           case NOTE_INSN_MAX:
1040           case NOTE_INSN_DELETED_LABEL:
1041             note_flds = create_field (note_flds, &string_type, "rt_str");
1042             break;
1043
1044           case NOTE_INSN_BLOCK_BEG:
1045           case NOTE_INSN_BLOCK_END:
1046             note_flds = create_field (note_flds, tree_tp, "rt_tree");
1047             break;
1048
1049           case NOTE_INSN_VAR_LOCATION:
1050             note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
1051             break;
1052
1053           default:
1054             note_flds = create_field (note_flds, scalar_tp, "rt_int");
1055             break;
1056           }
1057         /* NOTE_INSN_MAX is used as the default field for line
1058            number notes.  */
1059         if (c == NOTE_INSN_MAX)
1060           note_flds->opt = create_option (nodot, "default", "");
1061         else
1062           note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
1063       }
1064     note_union_tp = new_structure ("rtx_def_note_subunion", 1,
1065                                    &lexer_line, note_flds, NULL);
1066   }
1067   /* Create a type to represent the various forms of SYMBOL_REF_DATA.  */
1068   {
1069     pair_p sym_flds;
1070
1071     sym_flds = create_field (NULL, tree_tp, "rt_tree");
1072     sym_flds->opt = create_option (nodot, "default", "");
1073
1074     sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
1075     sym_flds->opt = create_option (nodot, "tag", "1");
1076
1077     symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
1078                                      &lexer_line, sym_flds, NULL);
1079   }
1080   for (i = 0; i < NUM_RTX_CODE; i++)
1081     {
1082       pair_p subfields = NULL;
1083       size_t aindex, nmindex;
1084       const char *sname;
1085       type_p substruct;
1086       char *ftag;
1087
1088       for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
1089         {
1090           type_p t;
1091           const char *subname;
1092
1093           switch (rtx_format[i][aindex])
1094             {
1095             case '*':
1096             case 'i':
1097             case 'n':
1098             case 'w':
1099               t = scalar_tp;
1100               subname = "rt_int";
1101               break;
1102
1103             case '0':
1104               if (i == MEM && aindex == 1)
1105                 t = mem_attrs_tp, subname = "rt_mem";
1106               else if (i == JUMP_INSN && aindex == 8)
1107                 t = rtx_tp, subname = "rt_rtx";
1108               else if (i == CODE_LABEL && aindex == 4)
1109                 t = scalar_tp, subname = "rt_int";
1110               else if (i == CODE_LABEL && aindex == 5)
1111                 t = rtx_tp, subname = "rt_rtx";
1112               else if (i == LABEL_REF
1113                        && (aindex == 1 || aindex == 2))
1114                 t = rtx_tp, subname = "rt_rtx";
1115               else if (i == NOTE && aindex == 4)
1116                 t = note_union_tp, subname = "";
1117               else if (i == NOTE && aindex == 5)
1118                 t = scalar_tp, subname = "rt_int";
1119               else if (i == NOTE && aindex >= 7)
1120                 t = scalar_tp, subname = "rt_int";
1121               else if (i == ADDR_DIFF_VEC && aindex == 4)
1122                 t = scalar_tp, subname = "rt_int";
1123               else if (i == VALUE && aindex == 0)
1124                 t = scalar_tp, subname = "rt_int";
1125               else if (i == DEBUG_EXPR && aindex == 0)
1126                 t = tree_tp, subname = "rt_tree";
1127               else if (i == REG && aindex == 1)
1128                 t = scalar_tp, subname = "rt_int";
1129               else if (i == REG && aindex == 2)
1130                 t = reg_attrs_tp, subname = "rt_reg";
1131               else if (i == SCRATCH && aindex == 0)
1132                 t = scalar_tp, subname = "rt_int";
1133               else if (i == SYMBOL_REF && aindex == 1)
1134                 t = scalar_tp, subname = "rt_int";
1135               else if (i == SYMBOL_REF && aindex == 2)
1136                 t = symbol_union_tp, subname = "";
1137               else if (i == BARRIER && aindex >= 3)
1138                 t = scalar_tp, subname = "rt_int";
1139               else
1140                 {
1141                   error_at_line (&lexer_line,
1142                         "rtx type `%s' has `0' in position %lu, can't handle",
1143                                  rtx_name[i], (unsigned long) aindex);
1144                   t = &string_type;
1145                   subname = "rt_int";
1146                 }
1147               break;
1148
1149             case 's':
1150             case 'S':
1151             case 'T':
1152               t = &string_type;
1153               subname = "rt_str";
1154               break;
1155
1156             case 'e':
1157             case 'u':
1158               t = rtx_tp;
1159               subname = "rt_rtx";
1160               break;
1161
1162             case 'E':
1163             case 'V':
1164               t = rtvec_tp;
1165               subname = "rt_rtvec";
1166               break;
1167
1168             case 't':
1169               t = tree_tp;
1170               subname = "rt_tree";
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",
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", "lto-streamer.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      extension 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      (const_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   const 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 /* Return an output file that is suitable for definitions which can
2538    reference struct S */
2539
2540 static outf_p
2541 get_output_file_for_structure (const_type_p s, type_p *param)
2542 {
2543   const char * fn = s->u.s.line.file;
2544   int i;
2545
2546   /* This is a hack, and not the good kind either.  */
2547   for (i = NUM_PARAM - 1; i >= 0; i--)
2548     if (param && param[i] && param[i]->kind == TYPE_POINTER
2549         && UNION_OR_STRUCT_P (param[i]->u.p))
2550       fn = param[i]->u.p->u.s.line.file;
2551
2552   return get_output_file_with_visibility (fn);
2553 }
2554
2555 /* For S, a structure that's part of ORIG_S, and using parameters
2556    PARAM, write out a routine that:
2557    - Takes a parameter, a void * but actually of type *S
2558    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2559      field of S or its substructures and (in some cases) things
2560      that are pointed to by S.
2561 */
2562
2563 static void
2564 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2565                           const struct write_types_data *wtd)
2566 {
2567   const char *chain_next = NULL;
2568   const char *chain_prev = NULL;
2569   const char *chain_circular = NULL;
2570   const char *mark_hook_name = NULL;
2571   options_p opt;
2572   struct walk_type_data d;
2573
2574   memset (&d, 0, sizeof (d));
2575   d.of = get_output_file_for_structure (s, param);
2576
2577   for (opt = s->u.s.opt; opt; opt = opt->next)
2578     if (strcmp (opt->name, "chain_next") == 0)
2579       chain_next = opt->info;
2580     else if (strcmp (opt->name, "chain_prev") == 0)
2581       chain_prev = opt->info;
2582     else if (strcmp (opt->name, "chain_circular") == 0)
2583       chain_circular = opt->info;
2584     else if (strcmp (opt->name, "mark_hook") == 0)
2585       mark_hook_name = opt->info;
2586
2587   if (chain_prev != NULL && chain_next == NULL)
2588     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2589   if (chain_circular != NULL && chain_next != NULL)
2590     error_at_line (&s->u.s.line, "chain_circular with chain_next");
2591   if (chain_circular != NULL)
2592     chain_next = chain_circular;
2593
2594   d.process_field = write_types_process_field;
2595   d.cookie = wtd;
2596   d.orig_s = orig_s;
2597   d.opt = s->u.s.opt;
2598   d.line = &s->u.s.line;
2599   d.bitmap = s->u.s.bitmap;
2600   d.param = param;
2601   d.prev_val[0] = "*x";
2602   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2603   d.prev_val[3] = "x";
2604   d.val = "(*x)";
2605
2606   oprintf (d.of, "\n");
2607   oprintf (d.of, "void\n");
2608   if (param == NULL)
2609     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2610   else
2611     {
2612       oprintf (d.of, "gt_%s_", wtd->prefix);
2613       output_mangled_typename (d.of, orig_s);
2614     }
2615   oprintf (d.of, " (void *x_p)\n");
2616   oprintf (d.of, "{\n");
2617   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2618            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2619            chain_next == NULL ? "const " : "",
2620            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2621   if (chain_next != NULL)
2622     oprintf (d.of, "  %s %s * xlimit = x;\n",
2623              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2624   if (chain_next == NULL)
2625     {
2626       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2627       if (wtd->param_prefix)
2628         {
2629           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2630           output_mangled_typename (d.of, orig_s);
2631           output_type_enum (d.of, orig_s);
2632         }
2633       oprintf (d.of, "))\n");
2634     }
2635   else
2636     {
2637       if (chain_circular != NULL)
2638         oprintf (d.of, "  if (!%s (xlimit", wtd->marker_routine);
2639       else
2640         oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2641       if (wtd->param_prefix)
2642         {
2643           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2644           output_mangled_typename (d.of, orig_s);
2645           output_type_enum (d.of, orig_s);
2646         }
2647       oprintf (d.of, "))\n");
2648       if (chain_circular != NULL)
2649         oprintf (d.of, "    return;\n  do\n");
2650       if (mark_hook_name && !wtd->skip_hooks)
2651         {
2652           oprintf (d.of, "    {\n");
2653           oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
2654         }
2655       oprintf (d.of, "   xlimit = (");
2656       d.prev_val[2] = "*xlimit";
2657       output_escaped_param (&d, chain_next, "chain_next");
2658       oprintf (d.of, ");\n");
2659       if (mark_hook_name && !wtd->skip_hooks)
2660         oprintf (d.of, "    }\n");
2661       if (chain_prev != NULL)
2662         {
2663           oprintf (d.of, "  if (x != xlimit)\n");
2664           oprintf (d.of, "    for (;;)\n");
2665           oprintf (d.of, "      {\n");
2666           oprintf (d.of, "        %s %s * const xprev = (",
2667                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2668
2669           d.prev_val[2] = "*x";
2670           output_escaped_param (&d, chain_prev, "chain_prev");
2671           oprintf (d.of, ");\n");
2672           oprintf (d.of, "        if (xprev == NULL) break;\n");
2673           oprintf (d.of, "        x = xprev;\n");
2674           oprintf (d.of, "        (void) %s (xprev",
2675                    wtd->marker_routine);
2676           if (wtd->param_prefix)
2677             {
2678               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2679               output_mangled_typename (d.of, orig_s);
2680               output_type_enum (d.of, orig_s);
2681             }
2682           oprintf (d.of, ");\n");
2683           oprintf (d.of, "      }\n");
2684         }
2685       if (chain_circular != NULL)
2686         {
2687           oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2688           if (wtd->param_prefix)
2689             {
2690               oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2691               output_mangled_typename (d.of, orig_s);
2692               output_type_enum (d.of, orig_s);
2693             }
2694           oprintf (d.of, "));\n");
2695           if (mark_hook_name && !wtd->skip_hooks)
2696             oprintf (d.of, "  %s (xlimit);\n", mark_hook_name);
2697           oprintf (d.of, "  do\n");
2698         }
2699       else
2700         oprintf (d.of, "  while (x != xlimit)\n");
2701     }
2702   oprintf (d.of, "    {\n");
2703   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2704     {
2705       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2706     }
2707   d.prev_val[2] = "*x";
2708   d.indent = 6;
2709   walk_type (s, &d);
2710
2711   if (chain_next != NULL)
2712     {
2713       oprintf (d.of, "      x = (");
2714       output_escaped_param (&d, chain_next, "chain_next");
2715       oprintf (d.of, ");\n");
2716     }
2717
2718   oprintf (d.of, "    }\n");
2719   if (chain_circular != NULL)
2720     oprintf (d.of, "  while (x != xlimit);\n");
2721   oprintf (d.of, "}\n");
2722 }
2723
2724 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2725
2726 static void
2727 write_types (outf_p output_header, type_p structures, type_p param_structs,
2728              const struct write_types_data *wtd)
2729 {
2730   type_p s;
2731
2732   oprintf (output_header, "\n/* %s*/\n", wtd->comment);
2733   /* We first emit the macros and the declarations. Functions' code is
2734      emitted afterwards.  This is needed in plugin mode.  */
2735   oprintf (output_header, "/* macros and declarations */\n");
2736   for (s = structures; s; s = s->next)
2737     if (s->gc_used == GC_POINTED_TO
2738         || s->gc_used == GC_MAYBE_POINTED_TO)
2739       {
2740         options_p opt;
2741
2742         if (s->gc_used == GC_MAYBE_POINTED_TO
2743             && s->u.s.line.file == NULL)
2744           continue;
2745
2746         oprintf (output_header, "#define gt_%s_", wtd->prefix);
2747         output_mangled_typename (output_header, s);
2748         oprintf (output_header, "(X) do { \\\n");
2749         oprintf (output_header,
2750                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2751                  s->u.s.tag);
2752         oprintf (output_header,
2753                  "  } while (0)\n");
2754
2755         for (opt = s->u.s.opt; opt; opt = opt->next)
2756           if (strcmp (opt->name, "ptr_alias") == 0)
2757             {
2758               const_type_p const t = (const_type_p) opt->info;
2759               if (t->kind == TYPE_STRUCT
2760                   || t->kind == TYPE_UNION
2761                   || t->kind == TYPE_LANG_STRUCT)
2762                 oprintf (output_header,
2763                          "#define gt_%sx_%s gt_%sx_%s\n",
2764                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2765               else
2766                 error_at_line (&s->u.s.line,
2767                                "structure alias is not a structure");
2768               break;
2769             }
2770         if (opt)
2771           continue;
2772
2773         /* Declare the marker procedure only once.  */
2774         oprintf (output_header,
2775                  "extern void gt_%sx_%s (void *);\n",
2776                  wtd->prefix, s->u.s.tag);
2777
2778         if (s->u.s.line.file == NULL)
2779           {
2780             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2781                      s->u.s.tag);
2782             continue;
2783           }
2784       }
2785
2786   for (s = param_structs; s; s = s->next)
2787     if (s->gc_used == GC_POINTED_TO)
2788       {
2789         type_p stru = s->u.param_struct.stru;
2790
2791         /* Declare the marker procedure.  */
2792         oprintf (output_header, "extern void gt_%s_", wtd->prefix);
2793         output_mangled_typename (output_header, s);
2794         oprintf (output_header, " (void *);\n");
2795
2796         if (stru->u.s.line.file == NULL)
2797           {
2798             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2799                      s->u.s.tag);
2800             continue;
2801           }
2802       }
2803
2804   /* At last we emit the functions code.  */
2805   oprintf (output_header, "\n/* functions code */\n");
2806   for (s = structures; s; s = s->next)
2807     if (s->gc_used == GC_POINTED_TO
2808         || s->gc_used == GC_MAYBE_POINTED_TO)
2809       {
2810         options_p opt;
2811
2812         if (s->gc_used == GC_MAYBE_POINTED_TO
2813             && s->u.s.line.file == NULL)
2814           continue;
2815         for (opt = s->u.s.opt; opt; opt = opt->next)
2816           if (strcmp (opt->name, "ptr_alias") == 0)
2817             break;
2818         if (opt)
2819           continue;
2820
2821         if (s->kind == TYPE_LANG_STRUCT)
2822           {
2823             type_p ss;
2824             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2825               write_func_for_structure (s, ss, NULL, wtd);
2826           }
2827         else
2828           write_func_for_structure (s, s, NULL, wtd);
2829       }
2830   for (s = param_structs; s; s = s->next)
2831     if (s->gc_used == GC_POINTED_TO)
2832       {
2833         type_p *param = s->u.param_struct.param;
2834         type_p stru = s->u.param_struct.stru;
2835         if (stru->u.s.line.file == NULL)
2836           continue;
2837         if (stru->kind == TYPE_LANG_STRUCT)
2838           {
2839             type_p ss;
2840             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2841               write_func_for_structure (s, ss, param, wtd);
2842           }
2843         else
2844           write_func_for_structure (s, stru, param, wtd);
2845       }
2846 }
2847
2848 static const struct write_types_data ggc_wtd =
2849 {
2850   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2851   "GC marker procedures.  ",
2852   FALSE
2853 };
2854
2855 static const struct write_types_data pch_wtd =
2856 {
2857   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2858   "gt_pch_note_reorder",
2859   "PCH type-walking procedures.  ",
2860   TRUE
2861 };
2862
2863 /* Write out the local pointer-walking routines.  */
2864
2865 /* process_field routine for local pointer-walking.  */
2866
2867 static void
2868 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2869 {
2870   switch (f->kind)
2871     {
2872     case TYPE_POINTER:
2873     case TYPE_STRUCT:
2874     case TYPE_UNION:
2875     case TYPE_LANG_STRUCT:
2876     case TYPE_PARAM_STRUCT:
2877     case TYPE_STRING:
2878       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2879                d->prev_val[3]);
2880       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2881       break;
2882
2883     case TYPE_SCALAR:
2884       break;
2885
2886     default:
2887       gcc_unreachable ();
2888     }
2889 }
2890
2891 /* For S, a structure that's part of ORIG_S, and using parameters
2892    PARAM, write out a routine that:
2893    - Is of type gt_note_pointers
2894    - Calls PROCESS_FIELD on each field of S or its substructures.
2895 */
2896
2897 static void
2898 write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param)
2899 {
2900   struct walk_type_data d;
2901
2902   memset (&d, 0, sizeof (d));
2903   d.of = get_output_file_for_structure (s, param);
2904   d.process_field = write_types_local_process_field;
2905   d.opt = s->u.s.opt;
2906   d.line = &s->u.s.line;
2907   d.bitmap = s->u.s.bitmap;
2908   d.param = param;
2909   d.prev_val[0] = d.prev_val[2] = "*x";
2910   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2911   d.prev_val[3] = "x";
2912   d.val = "(*x)";
2913   d.fn_wants_lvalue = true;
2914
2915   oprintf (d.of, "\n");
2916   oprintf (d.of, "void\n");
2917   oprintf (d.of, "gt_pch_p_");
2918   output_mangled_typename (d.of, orig_s);
2919   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2920            "\tvoid *x_p,\n"
2921            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2922            "\tATTRIBUTE_UNUSED void *cookie)\n");
2923   oprintf (d.of, "{\n");
2924   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2925            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2926            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2927   d.indent = 2;
2928   walk_type (s, &d);
2929   oprintf (d.of, "}\n");
2930 }
2931
2932 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2933
2934 static void
2935 write_local (outf_p output_header, type_p structures, type_p param_structs)
2936 {
2937   type_p s;
2938
2939   if (!output_header)
2940     return;
2941   oprintf (output_header, "\n/* Local pointer-walking routines.  */\n");
2942   for (s = structures; s; s = s->next)
2943     if (s->gc_used == GC_POINTED_TO
2944         || s->gc_used == GC_MAYBE_POINTED_TO)
2945       {
2946         options_p opt;
2947
2948         if (s->u.s.line.file == NULL)
2949           continue;
2950
2951         for (opt = s->u.s.opt; opt; opt = opt->next)
2952           if (strcmp (opt->name, "ptr_alias") == 0)
2953             {
2954               const_type_p const t = (const_type_p) opt->info;
2955               if (t->kind == TYPE_STRUCT
2956                   || t->kind == TYPE_UNION
2957                   || t->kind == TYPE_LANG_STRUCT)
2958                 {
2959                   oprintf (output_header, "#define gt_pch_p_");
2960                   output_mangled_typename (output_header, s);
2961                   oprintf (output_header, " gt_pch_p_");
2962                   output_mangled_typename (output_header, t);
2963                   oprintf (output_header, "\n");
2964                 }
2965               else
2966                 error_at_line (&s->u.s.line,
2967                                "structure alias is not a structure");
2968               break;
2969             }
2970         if (opt)
2971           continue;
2972
2973         /* Declare the marker procedure only once.  */
2974         oprintf (output_header, "extern void gt_pch_p_");
2975         output_mangled_typename (output_header, s);
2976         oprintf (output_header,
2977          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2978
2979         if (s->kind == TYPE_LANG_STRUCT)
2980           {
2981             type_p ss;
2982             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2983               write_local_func_for_structure (s, ss, NULL);
2984           }
2985         else
2986           write_local_func_for_structure (s, s, NULL);
2987       }
2988
2989   for (s = param_structs; s; s = s->next)
2990     if (s->gc_used == GC_POINTED_TO)
2991       {
2992         type_p * param = s->u.param_struct.param;
2993         type_p stru = s->u.param_struct.stru;
2994
2995         /* Declare the marker procedure.  */
2996         oprintf (output_header, "extern void gt_pch_p_");
2997         output_mangled_typename (output_header, s);
2998         oprintf (output_header,
2999          "\n    (void *, void *, gt_pointer_operator, void *);\n");
3000
3001         if (stru->u.s.line.file == NULL)
3002           {
3003             fprintf (stderr, "warning: structure `%s' used but not defined\n",
3004                      s->u.s.tag);
3005             continue;
3006           }
3007
3008         if (stru->kind == TYPE_LANG_STRUCT)
3009           {
3010             type_p ss;
3011             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
3012               write_local_func_for_structure (s, ss, param);
3013           }
3014         else
3015           write_local_func_for_structure (s, stru, param);
3016       }
3017 }
3018
3019 /* Write out the 'enum' definition for gt_types_enum.  */
3020
3021 static void
3022 write_enum_defn (type_p structures, type_p param_structs)
3023 {
3024   type_p s;
3025
3026   if (!header_file)
3027     return;
3028   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
3029   oprintf (header_file, "enum gt_types_enum {\n");
3030   for (s = structures; s; s = s->next)
3031     if (s->gc_used == GC_POINTED_TO
3032         || s->gc_used == GC_MAYBE_POINTED_TO)
3033       {
3034         if (s->gc_used == GC_MAYBE_POINTED_TO
3035             && s->u.s.line.file == NULL)
3036           continue;
3037
3038         oprintf (header_file, " gt_ggc_e_");
3039         output_mangled_typename (header_file, s);
3040         oprintf (header_file, ", \n");
3041       }
3042   for (s = param_structs; s; s = s->next)
3043     if (s->gc_used == GC_POINTED_TO)
3044       {
3045         oprintf (header_file, " gt_e_");
3046         output_mangled_typename (header_file, s);
3047         oprintf (header_file, ", \n");
3048       }
3049   oprintf (header_file, " gt_types_enum_last\n");
3050   oprintf (header_file, "};\n");
3051 }
3052
3053 /* Might T contain any non-pointer elements?  */
3054
3055 static int
3056 contains_scalar_p (type_p t)
3057 {
3058   switch (t->kind)
3059     {
3060     case TYPE_STRING:
3061     case TYPE_POINTER:
3062       return 0;
3063     case TYPE_ARRAY:
3064       return contains_scalar_p (t->u.a.p);
3065     default:
3066       /* Could also check for structures that have no non-pointer
3067          fields, but there aren't enough of those to worry about.  */
3068       return 1;
3069     }
3070 }
3071
3072 /* Mangle FN and print it to F.  */
3073
3074 static void
3075 put_mangled_filename (outf_p f, const char *fn)
3076 {
3077   const char *name = get_output_file_name (fn);
3078   if (!f || !name)
3079     return;
3080   for (; *name != 0; name++)
3081     if (ISALNUM (*name))
3082       oprintf (f, "%c", *name);
3083     else
3084       oprintf (f, "%c", '_');
3085 }
3086
3087 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
3088    LASTNAME, and NAME are all strings to insert in various places in
3089    the resulting code.  */
3090
3091 static void
3092 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3093                    const char *tname, const char *name)
3094 {
3095   struct flist *fli2;
3096
3097   for (fli2 = flp; fli2; fli2 = fli2->next)
3098     if (fli2->started_p)
3099       {
3100         oprintf (fli2->f, "  %s\n", lastname);
3101         oprintf (fli2->f, "};\n\n");
3102       }
3103
3104   for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
3105     if (fli2->started_p)
3106       {
3107         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3108         int fnum;
3109
3110         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3111           if (bitmap & 1)
3112             {
3113               oprintf (base_files[fnum],
3114                        "extern const struct %s gt_%s_",
3115                        tname, pfx);
3116               put_mangled_filename (base_files[fnum], fli2->name);
3117               oprintf (base_files[fnum], "[];\n");
3118             }
3119       }
3120
3121   {
3122     size_t fnum;
3123     for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3124       oprintf (base_files [fnum],
3125                "EXPORTED_CONST struct %s * const %s[] = {\n",
3126                tname, name);
3127   }
3128
3129
3130   for (fli2 = flp; fli2; fli2 = fli2->next)
3131     if (fli2->started_p)
3132       {
3133         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3134         int fnum;
3135
3136         fli2->started_p = 0;
3137
3138         for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
3139           if (bitmap & 1)
3140             {
3141               oprintf (base_files[fnum], "  gt_%s_", pfx);
3142               put_mangled_filename (base_files[fnum], fli2->name);
3143               oprintf (base_files[fnum], ",\n");
3144             }
3145       }
3146
3147   {
3148     size_t fnum;
3149     for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3150       {
3151         oprintf (base_files[fnum], "  NULL\n");
3152         oprintf (base_files[fnum], "};\n");
3153       }
3154   }
3155 }
3156
3157 /* Write out to F the table entry and any marker routines needed to
3158    mark NAME as TYPE.  The original variable is V, at LINE.
3159    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
3160    is nonzero iff we are building the root table for hash table caches.  */
3161
3162 static void
3163 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3164             struct fileloc *line, const char *if_marked, bool emit_pch)
3165 {
3166   switch (type->kind)
3167     {
3168     case TYPE_STRUCT:
3169       {
3170         pair_p fld;
3171         for (fld = type->u.s.fields; fld; fld = fld->next)
3172           {
3173             int skip_p = 0;
3174             const char *desc = NULL;
3175             options_p o;
3176
3177             for (o = fld->opt; o; o = o->next)
3178               if (strcmp (o->name, "skip") == 0)
3179                 skip_p = 1;
3180               else if (strcmp (o->name, "desc") == 0)
3181                 desc = o->info;
3182               else if (strcmp (o->name, "param_is") == 0)
3183                 ;
3184               else
3185                 error_at_line (line,
3186                        "field `%s' of global `%s' has unknown option `%s'",
3187                                fld->name, name, o->name);
3188
3189             if (skip_p)
3190               continue;
3191             else if (desc && fld->type->kind == TYPE_UNION)
3192               {
3193                 pair_p validf = NULL;
3194                 pair_p ufld;
3195
3196                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3197                   {
3198                     const char *tag = NULL;
3199                     options_p oo;
3200
3201                     for (oo = ufld->opt; oo; oo = oo->next)
3202                       if (strcmp (oo->name, "tag") == 0)
3203                         tag = oo->info;
3204                     if (tag == NULL || strcmp (tag, desc) != 0)
3205                       continue;
3206                     if (validf != NULL)
3207                       error_at_line (line,
3208                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3209                                      name, fld->name, validf->name,
3210                                      name, fld->name, ufld->name,
3211                                      tag);
3212                     validf = ufld;
3213                   }
3214                 if (validf != NULL)
3215                   {
3216                     char *newname;
3217                     newname = xasprintf ("%s.%s.%s",
3218                                          name, fld->name, validf->name);
3219                     write_root (f, v, validf->type, newname, 0, line,
3220                                 if_marked, emit_pch);
3221                     free (newname);
3222                   }
3223               }
3224             else if (desc)
3225               error_at_line (line,
3226                      "global `%s.%s' has `desc' option but is not union",
3227                              name, fld->name);
3228             else
3229               {
3230                 char *newname;
3231                 newname = xasprintf ("%s.%s", name, fld->name);
3232                 write_root (f, v, fld->type, newname, 0, line, if_marked,
3233                             emit_pch);
3234                 free (newname);
3235               }
3236           }
3237       }
3238       break;
3239
3240     case TYPE_ARRAY:
3241       {
3242         char *newname;
3243         newname = xasprintf ("%s[0]", name);
3244         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
3245                     emit_pch);
3246         free (newname);
3247       }
3248       break;
3249
3250     case TYPE_POINTER:
3251       {
3252         type_p ap, tp;
3253
3254         oprintf (f, "  {\n");
3255         oprintf (f, "    &%s,\n", name);
3256         oprintf (f, "    1");
3257
3258         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3259           if (ap->u.a.len[0])
3260             oprintf (f, " * (%s)", ap->u.a.len);
3261           else if (ap == v->type)
3262             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3263         oprintf (f, ",\n");
3264         oprintf (f, "    sizeof (%s", v->name);
3265         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3266           oprintf (f, "[0]");
3267         oprintf (f, "),\n");
3268
3269         tp = type->u.p;
3270
3271         if (! has_length && UNION_OR_STRUCT_P (tp))
3272           {
3273             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3274             if (emit_pch)
3275               oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3276             else
3277               oprintf (f, "    NULL");
3278           }
3279         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3280           {
3281             oprintf (f, "    &gt_ggc_m_");
3282             output_mangled_typename (f, tp);
3283             if (emit_pch)
3284               {
3285                 oprintf (f, ",\n    &gt_pch_n_");
3286                 output_mangled_typename (f, tp);
3287               }
3288             else
3289               oprintf (f, ",\n    NULL");
3290           }
3291         else if (has_length
3292                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3293           {
3294             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3295             if (emit_pch)
3296               oprintf (f, "    &gt_pch_na_%s", name);
3297             else
3298               oprintf (f, "    NULL");
3299           }
3300         else
3301           {
3302             error_at_line (line,
3303                            "global `%s' is pointer to unimplemented type",
3304                            name);
3305           }
3306         if (if_marked)
3307           oprintf (f, ",\n    &%s", if_marked);
3308         oprintf (f, "\n  },\n");
3309       }
3310       break;
3311
3312     case TYPE_STRING:
3313       {
3314         oprintf (f, "  {\n");
3315         oprintf (f, "    &%s,\n", name);
3316         oprintf (f, "    1, \n");
3317         oprintf (f, "    sizeof (%s),\n", v->name);
3318         oprintf (f, "    (gt_pointer_walker) &gt_ggc_m_S,\n");
3319         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3320         oprintf (f, "  },\n");
3321       }
3322       break;
3323
3324     case TYPE_SCALAR:
3325       break;
3326
3327     default:
3328       error_at_line (line,
3329                      "global `%s' is unimplemented type",
3330                      name);
3331     }
3332 }
3333
3334 /* This generates a routine to walk an array.  */
3335
3336 static void
3337 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3338 {
3339   struct walk_type_data d;
3340   char *prevval3;
3341
3342   memset (&d, 0, sizeof (d));
3343   d.of = f;
3344   d.cookie = wtd;
3345   d.indent = 2;
3346   d.line = &v->line;
3347   d.opt = v->opt;
3348   d.bitmap = get_lang_bitmap (v->line.file);
3349   d.param = NULL;
3350
3351   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3352
3353   if (wtd->param_prefix)
3354     {
3355       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3356       oprintf (f,
3357        "    (void *, void *, gt_pointer_operator, void *);\n");
3358       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3359                wtd->param_prefix, v->name);
3360       oprintf (d.of,
3361                "      ATTRIBUTE_UNUSED void *x_p,\n"
3362                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3363                "      ATTRIBUTE_UNUSED void * cookie)\n");
3364       oprintf (d.of, "{\n");
3365       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3366       d.process_field = write_types_local_process_field;
3367       walk_type (v->type, &d);
3368       oprintf (f, "}\n\n");
3369     }
3370
3371   d.opt = v->opt;
3372   oprintf (f, "static void gt_%sa_%s (void *);\n",
3373            wtd->prefix, v->name);
3374   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3375            wtd->prefix, v->name);
3376   oprintf (f, "{\n");
3377   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3378   d.process_field = write_types_process_field;
3379   walk_type (v->type, &d);
3380   free (prevval3);
3381   oprintf (f, "}\n\n");
3382 }
3383
3384 /* Output a table describing the locations and types of VARIABLES.  */
3385
3386 static void
3387 write_roots (pair_p variables, bool emit_pch)
3388 {
3389   pair_p v;
3390   struct flist *flp = NULL;
3391
3392   for (v = variables; v; v = v->next)
3393     {
3394       outf_p f = get_output_file_with_visibility (v->line.file);
3395       struct flist *fli;
3396       const char *length = NULL;
3397       int deletable_p = 0;
3398       options_p o;
3399
3400       for (o = v->opt; o; o = o->next)
3401         if (strcmp (o->name, "length") == 0)
3402           length = o->info;
3403         else if (strcmp (o->name, "deletable") == 0)
3404           deletable_p = 1;
3405         else if (strcmp (o->name, "param_is") == 0)
3406           ;
3407         else if (strncmp (o->name, "param", 5) == 0
3408                  && ISDIGIT (o->name[5])
3409                  && strcmp (o->name + 6, "_is") == 0)
3410           ;
3411         else if (strcmp (o->name, "if_marked") == 0)
3412           ;
3413         else
3414           error_at_line (&v->line,
3415                          "global `%s' has unknown option `%s'",
3416                          v->name, o->name);
3417
3418       for (fli = flp; fli; fli = fli->next)
3419         if (fli->f == f && f)
3420           break;
3421       if (fli == NULL)
3422         {
3423           fli = XNEW (struct flist);
3424           fli->f = f;
3425           fli->next = flp;
3426           fli->started_p = 0;
3427           fli->name = v->line.file;
3428           gcc_assert(fli->name);
3429           flp = fli;
3430
3431           oprintf (f, "\n/* GC roots.  */\n\n");
3432         }
3433
3434       if (! deletable_p
3435           && length
3436           && v->type->kind == TYPE_POINTER
3437           && (v->type->u.p->kind == TYPE_POINTER
3438               || v->type->u.p->kind == TYPE_STRUCT))
3439         {
3440           write_array (f, v, &ggc_wtd);
3441           write_array (f, v, &pch_wtd);
3442         }
3443     }
3444
3445   for (v = variables; v; v = v->next)
3446     {
3447       outf_p f = get_output_file_with_visibility (v->line.file);
3448       struct flist *fli;
3449       int skip_p = 0;
3450       int length_p = 0;
3451       options_p o;
3452
3453       for (o = v->opt; o; o = o->next)
3454         if (strcmp (o->name, "length") == 0)
3455           length_p = 1;
3456         else if (strcmp (o->name, "deletable") == 0
3457                  || strcmp (o->name, "if_marked") == 0)
3458           skip_p = 1;
3459
3460       if (skip_p)
3461         continue;
3462
3463       for (fli = flp; fli; fli = fli->next)
3464         if (fli->f == f)
3465           break;
3466       if (! fli->started_p)
3467         {
3468           fli->started_p = 1;
3469
3470           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
3471           put_mangled_filename (f, v->line.file);
3472           oprintf (f, "[] = {\n");
3473         }
3474
3475       write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
3476     }
3477
3478   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3479                      "gt_ggc_rtab");
3480
3481   for (v = variables; v; v = v->next)
3482     {
3483       outf_p f = get_output_file_with_visibility (v->line.file);
3484       struct flist *fli;
3485       int skip_p = 1;
3486       options_p o;
3487
3488       for (o = v->opt; o; o = o->next)
3489         if (strcmp (o->name, "deletable") == 0)
3490           skip_p = 0;
3491         else if (strcmp (o->name, "if_marked") == 0)
3492           skip_p = 1;
3493
3494       if (skip_p)
3495         continue;
3496
3497       for (fli = flp; fli; fli = fli->next)
3498         if (fli->f == f)
3499           break;
3500       if (! fli->started_p)
3501         {
3502           fli->started_p = 1;
3503
3504           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
3505           put_mangled_filename (f, v->line.file);
3506           oprintf (f, "[] = {\n");
3507         }
3508
3509       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3510                v->name, v->name);
3511     }
3512
3513   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3514                      "gt_ggc_deletable_rtab");
3515
3516   for (v = variables; v; v = v->next)
3517     {
3518       outf_p f = get_output_file_with_visibility (v->line.file);
3519       struct flist *fli;
3520       const char *if_marked = NULL;
3521       int length_p = 0;
3522       options_p o;
3523
3524       for (o = v->opt; o; o = o->next)