OSDN Git Service

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