OSDN Git Service

2009-09-22 Basile Starynkevitch <basile@starynkevitch.net>
[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",
1571       "target.h", NULL
1572     };
1573     const char *const *ifp;
1574     outf_p gtype_desc_c;
1575
1576     gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1577     for (ifp = ifiles; *ifp; ifp++)
1578       oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1579
1580     /* Make sure we handle "cfun" specially.  */
1581     oprintf (gtype_desc_c, "\n/* See definition in function.h.  */\n");
1582     oprintf (gtype_desc_c, "#undef cfun\n");
1583   }
1584 }
1585
1586 /* For F a filename, return the real basename of F, with all the directory
1587    components skipped.  */
1588
1589 static const char *
1590 get_file_realbasename (const char *f)
1591 {
1592   const char * lastslash = strrchr (f, '/');
1593   
1594   return (lastslash != NULL) ? lastslash + 1 : f;
1595 }
1596
1597 /* For F a filename, return the relative path to F from $(srcdir) if the
1598    latter is a prefix in F, NULL otherwise.  */
1599
1600 static const char *
1601 get_file_srcdir_relative_path (const char *f)
1602 {
1603   if (strlen (f) > srcdir_len
1604       && IS_DIR_SEPARATOR (f[srcdir_len])
1605       && memcmp (f, srcdir, srcdir_len) == 0)
1606     return f + srcdir_len + 1;
1607   else
1608     return NULL;
1609 }
1610
1611 /* For F a filename, return the relative path to F from $(srcdir) if the
1612    latter is a prefix in F, or the real basename of F otherwise.  */
1613
1614 static const char *
1615 get_file_basename (const char *f)
1616 {
1617   const char * srcdir_path = get_file_srcdir_relative_path (f);
1618
1619   return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
1620 }
1621
1622 /* For F a filename, return the lang_dir_names relative index of the language
1623    directory that is a prefix in F, if any, -1 otherwise.  */
1624
1625 static int
1626 get_prefix_langdir_index (const char *f)
1627 {
1628   size_t f_len = strlen (f);
1629   size_t lang_index;
1630
1631   for (lang_index = 0; lang_index < num_lang_dirs; lang_index++)
1632     {
1633       const char * langdir = lang_dir_names [lang_index];
1634       size_t langdir_len = strlen (langdir);
1635           
1636       if (f_len > langdir_len
1637           && IS_DIR_SEPARATOR (f[langdir_len])
1638           && memcmp (f, langdir, langdir_len) == 0)
1639         return lang_index;
1640     }
1641
1642   return -1;
1643 }
1644
1645 /* For F a filename, return the name of language directory where F is located,
1646    if any, NULL otherwise.  */
1647
1648 static const char *
1649 get_file_langdir (const char *f)
1650 {
1651   /* Get the relative path to F from $(srcdir) and find the language by
1652      comparing the prefix with language directory names.  If F is not even
1653      srcdir relative, no point in looking further.  */
1654
1655   int lang_index;
1656   const char * srcdir_relative_path = get_file_srcdir_relative_path (f);
1657
1658   if (!srcdir_relative_path)
1659     return NULL;
1660
1661   lang_index = get_prefix_langdir_index (srcdir_relative_path);
1662
1663   return (lang_index >= 0) ? lang_dir_names [lang_index] : NULL;
1664 }
1665
1666 /* The gt- output file name for F.  */
1667
1668 static const char *
1669 get_file_gtfilename (const char *f)
1670 {
1671   /* Cook up an initial version of the gt- file name from the file real
1672      basename and the language name, if any.  */
1673
1674   const char *basename = get_file_realbasename (f);
1675   const char *langdir = get_file_langdir (f);
1676   
1677   char * result =
1678     (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
1679      : xasprintf ("gt-%s", basename));
1680
1681   /* Then replace all non alphanumerics characters by '-' and change the
1682      extenstion to ".h".  We expect the input filename extension was at least
1683      one character long.  */
1684
1685   char *s = result;
1686
1687   for (; *s != '.'; s++)
1688     if (! ISALNUM (*s) && *s != '-')
1689       *s = '-';
1690
1691   memcpy (s, ".h", sizeof (".h"));
1692
1693   return result;
1694 }
1695
1696 /* An output file, suitable for definitions, that can see declarations
1697    made in INPUT_FILE and is linked into every language that uses
1698    INPUT_FILE.  */
1699
1700 outf_p
1701 get_output_file_with_visibility (const char *input_file)
1702 {
1703   outf_p r;
1704   size_t len;
1705   const char *basename;
1706   const char *for_name;
1707   const char *output_name;
1708
1709   /* This can happen when we need a file with visibility on a
1710      structure that we've never seen.  We have to just hope that it's
1711      globally visible.  */
1712   if (input_file == NULL)
1713     input_file = "system.h";
1714
1715   /* In plugin mode, return NULL unless the input_file is one of the
1716      plugin_files.  */
1717   if (plugin_files && nb_plugin_files > 0) 
1718     { 
1719       int ix= -1, i;
1720       for (i = 0; i < nb_plugin_files && ix < 0; i++)
1721       if (strcmp (input_file, plugin_files[i]) == 0) 
1722         ix = i;
1723       if (ix < 0) 
1724         return NULL;
1725     }
1726
1727   /* Determine the output file name.  */
1728   basename = get_file_basename (input_file);
1729
1730   len = strlen (basename);
1731   if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1732       || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1733       || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1734     {
1735       output_name = get_file_gtfilename (input_file); 
1736       for_name = basename;
1737     }
1738   /* Some headers get used by more than one front-end; hence, it
1739      would be inappropriate to spew them out to a single gtype-<lang>.h
1740      (and gengtype doesn't know how to direct spewage into multiple
1741      gtype-<lang>.h headers at this time).  Instead, we pair up these
1742      headers with source files (and their special purpose gt-*.h headers).  */
1743   else if (strcmp (basename, "c-common.h") == 0)
1744     output_name = "gt-c-common.h", for_name = "c-common.c";
1745   else if (strcmp (basename, "c-lang.h") == 0)
1746     output_name = "gt-c-decl.h", for_name = "c-decl.c";
1747   else if (strcmp (basename, "c-tree.h") == 0)
1748     output_name = "gt-c-decl.h", for_name = "c-decl.c";
1749   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1750            && strcmp (basename + 3, "cp-tree.h") == 0)
1751     output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1752   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1753            && strcmp (basename + 3, "decl.h") == 0)
1754     output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1755   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1756            && strcmp (basename + 3, "name-lookup.h") == 0)
1757     output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1758   else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1759            && strcmp (basename + 5, "objc-act.h") == 0)
1760     output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1761   else 
1762     {
1763       int lang_index = get_prefix_langdir_index (basename);
1764
1765       if (lang_index >= 0)
1766         return base_files[lang_index];
1767
1768       output_name = "gtype-desc.c";
1769       for_name = NULL;
1770     }
1771
1772   /* Look through to see if we've ever seen this output filename before.  */
1773   for (r = output_files; r; r = r->next)
1774     if (strcmp (r->name, output_name) == 0)
1775       return r;
1776
1777   /* If not, create it.  */
1778   r = create_file (for_name, output_name);
1779
1780   gcc_assert (r && r->name);
1781   return r;
1782 }
1783
1784 /* The name of an output file, suitable for definitions, that can see
1785    declarations made in INPUT_FILE and is linked into every language
1786    that uses INPUT_FILE.  */
1787
1788 const char *
1789 get_output_file_name (const char *input_file)
1790 {
1791   outf_p o =  get_output_file_with_visibility (input_file);
1792   if (o)
1793     return o->name;
1794   return NULL;
1795 }
1796
1797 /* Check if existing file is equal to the in memory buffer. */
1798
1799 static bool
1800 is_file_equal (outf_p of)
1801 {
1802   FILE *newfile = fopen (of->name, "r");
1803   size_t i;
1804   bool equal;
1805   if (newfile == NULL)
1806     return false;
1807
1808   equal = true;
1809   for (i = 0; i < of->bufused; i++)
1810     {
1811       int ch;
1812       ch = fgetc (newfile);
1813       if (ch == EOF || ch != (unsigned char) of->buf[i])
1814         {
1815           equal = false;
1816           break;
1817         }
1818     }
1819   fclose (newfile);
1820   return equal;
1821 }
1822
1823 /* Copy the output to its final destination,
1824    but don't unnecessarily change modification times.  */
1825
1826 static void
1827 close_output_files (void)
1828 {
1829   outf_p of;
1830
1831   for (of = output_files; of; of = of->next)
1832     {
1833
1834       if (!is_file_equal(of))
1835       {
1836         FILE *newfile = fopen (of->name, "w");
1837         if (newfile == NULL)
1838           fatal ("opening output file %s: %s", of->name, strerror (errno));
1839         if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1840           fatal ("writing output file %s: %s", of->name, strerror (errno));
1841         if (fclose (newfile) != 0)
1842           fatal ("closing output file %s: %s", of->name, strerror (errno));
1843       }
1844       free(of->buf);
1845       of->buf = NULL;
1846       of->bufused = of->buflength = 0;
1847     }
1848 }
1849 \f
1850 struct flist {
1851   struct flist *next;
1852   int started_p;
1853   const char *name;
1854   outf_p f;
1855 };
1856
1857 struct walk_type_data;
1858
1859 /* For scalars and strings, given the item in 'val'.
1860    For structures, given a pointer to the item in 'val'.
1861    For misc. pointers, given the item in 'val'.
1862 */
1863 typedef void (*process_field_fn)
1864      (type_p f, const struct walk_type_data *p);
1865 typedef void (*func_name_fn)
1866      (type_p s, const struct walk_type_data *p);
1867
1868 /* Parameters for write_types.  */
1869
1870 struct write_types_data
1871 {
1872   const char *prefix;
1873   const char *param_prefix;
1874   const char *subfield_marker_routine;
1875   const char *marker_routine;
1876   const char *reorder_note_routine;
1877   const char *comment;
1878   int skip_hooks;               /* skip hook generation if non zero */
1879 };
1880
1881 static void output_escaped_param (struct walk_type_data *d,
1882                                   const char *, const char *);
1883 static void output_mangled_typename (outf_p, const_type_p);
1884 static void walk_type (type_p t, struct walk_type_data *d);
1885 static void write_func_for_structure
1886      (type_p orig_s, type_p s, type_p * param,
1887       const struct write_types_data *wtd);
1888 static void write_types_process_field
1889      (type_p f, const struct walk_type_data *d);
1890 static void write_types (outf_p output_header,
1891                          type_p structures,
1892                          type_p param_structs,
1893                          const struct write_types_data *wtd);
1894 static void write_types_local_process_field
1895      (type_p f, const struct walk_type_data *d);
1896 static void write_local_func_for_structure
1897      (type_p orig_s, type_p s, type_p * param);
1898 static void write_local (outf_p output_header,
1899                          type_p structures,
1900                          type_p param_structs);
1901 static void write_enum_defn (type_p structures, type_p param_structs);
1902 static int contains_scalar_p (type_p t);
1903 static void put_mangled_filename (outf_p , const char *);
1904 static void finish_root_table (struct flist *flp, const char *pfx,
1905                                const char *tname, const char *lastname,
1906                                const char *name);
1907 static void write_root (outf_p , pair_p, type_p, const char *, int,
1908                         struct fileloc *, const char *);
1909 static void write_array (outf_p f, pair_p v,
1910                          const struct write_types_data *wtd);
1911 static void write_roots (pair_p);
1912
1913 /* Parameters for walk_type.  */
1914
1915 struct walk_type_data
1916 {
1917   process_field_fn process_field;
1918   const void *cookie;
1919   outf_p of;
1920   options_p opt;
1921   const char *val;
1922   const char *prev_val[4];
1923   int indent;
1924   int counter;
1925   struct fileloc *line;
1926   lang_bitmap bitmap;
1927   type_p *param;
1928   int used_length;
1929   type_p orig_s;
1930   const char *reorder_fn;
1931   bool needs_cast_p;
1932   bool fn_wants_lvalue;
1933 };
1934
1935 /* Print a mangled name representing T to OF.  */
1936
1937 static void
1938 output_mangled_typename (outf_p of, const_type_p t)
1939 {
1940   if (t == NULL)
1941     oprintf (of, "Z");
1942   else switch (t->kind)
1943     {
1944     case TYPE_POINTER:
1945       oprintf (of, "P");
1946       output_mangled_typename (of, t->u.p);
1947       break;
1948     case TYPE_SCALAR:
1949       oprintf (of, "I");
1950       break;
1951     case TYPE_STRING:
1952       oprintf (of, "S");
1953       break;
1954     case TYPE_STRUCT:
1955     case TYPE_UNION:
1956     case TYPE_LANG_STRUCT:
1957       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1958       break;
1959     case TYPE_PARAM_STRUCT:
1960       {
1961         int i;
1962         for (i = 0; i < NUM_PARAM; i++)
1963           if (t->u.param_struct.param[i] != NULL)
1964             output_mangled_typename (of, t->u.param_struct.param[i]);
1965         output_mangled_typename (of, t->u.param_struct.stru);
1966       }
1967       break;
1968     case TYPE_ARRAY:
1969       gcc_unreachable ();
1970     }
1971 }
1972
1973 /* Print PARAM to D->OF processing escapes.  D->VAL references the
1974    current object, D->PREV_VAL the object containing the current
1975    object, ONAME is the name of the option and D->LINE is used to
1976    print error messages.  */
1977
1978 static void
1979 output_escaped_param (struct walk_type_data *d, const char *param,
1980                       const char *oname)
1981 {
1982   const char *p;
1983
1984   for (p = param; *p; p++)
1985     if (*p != '%')
1986       oprintf (d->of, "%c", *p);
1987     else switch (*++p)
1988       {
1989       case 'h':
1990         oprintf (d->of, "(%s)", d->prev_val[2]);
1991         break;
1992       case '0':
1993         oprintf (d->of, "(%s)", d->prev_val[0]);
1994         break;
1995       case '1':
1996         oprintf (d->of, "(%s)", d->prev_val[1]);
1997         break;
1998       case 'a':
1999         {
2000           const char *pp = d->val + strlen (d->val);
2001           while (pp[-1] == ']')
2002             while (*pp != '[')
2003               pp--;
2004           oprintf (d->of, "%s", pp);
2005         }
2006         break;
2007       default:
2008         error_at_line (d->line, "`%s' option contains bad escape %c%c",
2009                        oname, '%', *p);
2010       }
2011 }
2012
2013 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
2014    which is of type T.  Write code to D->OF to constrain execution (at
2015    the point that D->PROCESS_FIELD is called) to the appropriate
2016    cases.  Call D->PROCESS_FIELD on subobjects before calling it on
2017    pointers to those objects.  D->PREV_VAL lists the objects
2018    containing the current object, D->OPT is a list of options to
2019    apply, D->INDENT is the current indentation level, D->LINE is used
2020    to print error messages, D->BITMAP indicates which languages to
2021    print the structure for, and D->PARAM is the current parameter
2022    (from an enclosing param_is option).  */
2023
2024 static void
2025 walk_type (type_p t, struct walk_type_data *d)
2026 {
2027   const char *length = NULL;
2028   const char *desc = NULL;
2029   int maybe_undef_p = 0;
2030   int use_param_num = -1;
2031   int use_params_p = 0;
2032   options_p oo;
2033   const struct nested_ptr_data *nested_ptr_d = NULL;
2034
2035   d->needs_cast_p = false;
2036   for (oo = d->opt; oo; oo = oo->next)
2037     if (strcmp (oo->name, "length") == 0)
2038       length = oo->info;
2039     else if (strcmp (oo->name, "maybe_undef") == 0)
2040       maybe_undef_p = 1;
2041     else if (strncmp (oo->name, "use_param", 9) == 0
2042              && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2043       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
2044     else if (strcmp (oo->name, "use_params") == 0)
2045       use_params_p = 1;
2046     else if (strcmp (oo->name, "desc") == 0)
2047       desc = oo->info;
2048     else if (strcmp (oo->name, "mark_hook") == 0)
2049       ;
2050     else if (strcmp (oo->name, "nested_ptr") == 0)
2051       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
2052     else if (strcmp (oo->name, "dot") == 0)
2053       ;
2054     else if (strcmp (oo->name, "tag") == 0)
2055       ;
2056     else if (strcmp (oo->name, "special") == 0)
2057       ;
2058     else if (strcmp (oo->name, "skip") == 0)
2059       ;
2060     else if (strcmp (oo->name, "default") == 0)
2061       ;
2062     else if (strcmp (oo->name, "descbits") == 0)
2063       ;
2064     else if (strcmp (oo->name, "param_is") == 0)
2065       ;
2066     else if (strncmp (oo->name, "param", 5) == 0
2067              && ISDIGIT (oo->name[5])
2068              && strcmp (oo->name + 6, "_is") == 0)
2069       ;
2070     else if (strcmp (oo->name, "chain_next") == 0)
2071       ;
2072     else if (strcmp (oo->name, "chain_prev") == 0)
2073       ;
2074     else if (strcmp (oo->name, "chain_circular") == 0)
2075       ;
2076     else if (strcmp (oo->name, "reorder") == 0)
2077       ;
2078     else
2079       error_at_line (d->line, "unknown option `%s'\n", oo->name);
2080
2081   if (d->used_length)
2082     length = NULL;
2083
2084   if (use_params_p)
2085     {
2086       int pointer_p = t->kind == TYPE_POINTER;
2087
2088       if (pointer_p)
2089         t = t->u.p;
2090       if (! UNION_OR_STRUCT_P (t))
2091         error_at_line (d->line, "`use_params' option on unimplemented type");
2092       else
2093         t = find_param_structure (t, d->param);
2094       if (pointer_p)
2095         t = create_pointer (t);
2096     }
2097
2098   if (use_param_num != -1)
2099     {
2100       if (d->param != NULL && d->param[use_param_num] != NULL)
2101         {
2102           type_p nt = d->param[use_param_num];
2103
2104           if (t->kind == TYPE_ARRAY)
2105             nt = create_array (nt, t->u.a.len);
2106           else if (length != NULL && t->kind == TYPE_POINTER)
2107             nt = create_pointer (nt);
2108           d->needs_cast_p = (t->kind != TYPE_POINTER
2109                              && (nt->kind == TYPE_POINTER
2110                                  || nt->kind == TYPE_STRING));
2111           t = nt;
2112         }
2113       else
2114         error_at_line (d->line, "no parameter defined for `%s'",
2115                        d->val);
2116     }
2117
2118   if (maybe_undef_p
2119       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
2120     {
2121       error_at_line (d->line,
2122                      "field `%s' has invalid option `maybe_undef_p'\n",
2123                      d->val);
2124       return;
2125     }
2126
2127   switch (t->kind)
2128     {
2129     case TYPE_SCALAR:
2130     case TYPE_STRING:
2131       d->process_field (t, d);
2132       break;
2133
2134     case TYPE_POINTER:
2135       {
2136         if (maybe_undef_p
2137             && t->u.p->u.s.line.file == NULL)
2138           {
2139             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
2140             break;
2141           }
2142
2143         if (! length)
2144           {
2145             if (! UNION_OR_STRUCT_P (t->u.p)
2146                 && t->u.p->kind != TYPE_PARAM_STRUCT)
2147               {
2148                 error_at_line (d->line,
2149                                "field `%s' is pointer to unimplemented type",
2150                                d->val);
2151                 break;
2152               }
2153
2154             if (nested_ptr_d)
2155               {
2156                 const char *oldprevval2 = d->prev_val[2];
2157
2158                 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
2159                   {
2160                     error_at_line (d->line,
2161                                    "field `%s' has invalid "
2162                                    "option `nested_ptr'\n",
2163                                    d->val);
2164                     return;
2165                   }
2166
2167                 d->prev_val[2] = d->val;
2168                 oprintf (d->of, "%*s{\n", d->indent, "");
2169                 d->indent += 2;
2170                 d->val = xasprintf ("x%d", d->counter++);
2171                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
2172                          (nested_ptr_d->type->kind == TYPE_UNION 
2173                           ? "union" : "struct"), 
2174                          nested_ptr_d->type->u.s.tag, 
2175                          d->fn_wants_lvalue ? "" : "const ",
2176                          d->val);
2177                 oprintf (d->of, "%*s", d->indent + 2, "");
2178                 output_escaped_param (d, nested_ptr_d->convert_from,
2179                                       "nested_ptr");
2180                 oprintf (d->of, ";\n");
2181
2182                 d->process_field (nested_ptr_d->type, d);
2183
2184                 if (d->fn_wants_lvalue)
2185                   {
2186                     oprintf (d->of, "%*s%s = ", d->indent, "",
2187                              d->prev_val[2]);
2188                     d->prev_val[2] = d->val;
2189                     output_escaped_param (d, nested_ptr_d->convert_to,
2190                                           "nested_ptr");
2191                     oprintf (d->of, ";\n");
2192                   }
2193
2194                 d->indent -= 2;
2195                 oprintf (d->of, "%*s}\n", d->indent, "");
2196                 d->val = d->prev_val[2];
2197                 d->prev_val[2] = oldprevval2;
2198               }
2199             else
2200               d->process_field (t->u.p, d);
2201           }
2202         else
2203           {
2204             int loopcounter = d->counter++;
2205             const char *oldval = d->val;
2206             const char *oldprevval3 = d->prev_val[3];
2207             char *newval;
2208
2209             oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
2210             d->indent += 2;
2211             oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2212             oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
2213                      loopcounter, loopcounter);
2214             output_escaped_param (d, length, "length");
2215             oprintf (d->of, "); i%d++) {\n", loopcounter);
2216             d->indent += 2;
2217             d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2218             d->used_length = 1;
2219             d->prev_val[3] = oldval;
2220             walk_type (t->u.p, d);
2221             free (newval);
2222             d->val = oldval;
2223             d->prev_val[3] = oldprevval3;
2224             d->used_length = 0;
2225             d->indent -= 2;
2226             oprintf (d->of, "%*s}\n", d->indent, "");
2227             d->process_field(t, d);
2228             d->indent -= 2;
2229             oprintf (d->of, "%*s}\n", d->indent, "");
2230           }
2231       }
2232       break;
2233
2234     case TYPE_ARRAY:
2235       {
2236         int loopcounter = d->counter++;
2237         const char *oldval = d->val;
2238         char *newval;
2239
2240         /* If it's an array of scalars, we optimize by not generating
2241            any code.  */
2242         if (t->u.a.p->kind == TYPE_SCALAR)
2243           break;
2244
2245         /* When walking an array, compute the length and store it in a
2246            local variable before walking the array elements, instead of
2247            recomputing the length expression each time through the loop.
2248            This is necessary to handle tcc_vl_exp objects like CALL_EXPR,
2249            where the length is stored in the first array element,
2250            because otherwise that operand can get overwritten on the
2251            first iteration.  */
2252         oprintf (d->of, "%*s{\n", d->indent, "");
2253         d->indent += 2;
2254         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
2255         oprintf (d->of, "%*ssize_t l%d = (size_t)(",
2256                  d->indent, "", loopcounter);
2257         if (length)
2258           output_escaped_param (d, length, "length");
2259         else
2260           oprintf (d->of, "%s", t->u.a.len);
2261         oprintf (d->of, ");\n");
2262         
2263         oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
2264                  d->indent, "",
2265                  loopcounter, loopcounter, loopcounter, loopcounter);
2266         d->indent += 2;
2267         d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
2268         d->used_length = 1;
2269         walk_type (t->u.a.p, d);
2270         free (newval);
2271         d->used_length = 0;
2272         d->val = oldval;
2273         d->indent -= 2;
2274         oprintf (d->of, "%*s}\n", d->indent, "");
2275         d->indent -= 2;
2276         oprintf (d->of, "%*s}\n", d->indent, "");
2277       }
2278       break;
2279
2280     case TYPE_STRUCT:
2281     case TYPE_UNION:
2282       {
2283         pair_p f;
2284         const char *oldval = d->val;
2285         const char *oldprevval1 = d->prev_val[1];
2286         const char *oldprevval2 = d->prev_val[2];
2287         const int union_p = t->kind == TYPE_UNION;
2288         int seen_default_p = 0;
2289         options_p o;
2290
2291         if (! t->u.s.line.file)
2292           error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
2293
2294         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
2295           {
2296             error_at_line (d->line,
2297                            "structure `%s' defined for mismatching languages",
2298                            t->u.s.tag);
2299             error_at_line (&t->u.s.line, "one structure defined here");
2300           }
2301
2302         /* Some things may also be defined in the structure's options.  */
2303         for (o = t->u.s.opt; o; o = o->next)
2304           if (! desc && strcmp (o->name, "desc") == 0)
2305             desc = o->info;
2306
2307         d->prev_val[2] = oldval;
2308         d->prev_val[1] = oldprevval2;
2309         if (union_p)
2310           {
2311             if (desc == NULL)
2312               {
2313                 error_at_line (d->line, "missing `desc' option for union `%s'",
2314                                t->u.s.tag);
2315                 desc = "1";
2316               }
2317             oprintf (d->of, "%*sswitch (", d->indent, "");
2318             output_escaped_param (d, desc, "desc");
2319             oprintf (d->of, ")\n");
2320             d->indent += 2;
2321             oprintf (d->of, "%*s{\n", d->indent, "");
2322           }
2323         for (f = t->u.s.fields; f; f = f->next)
2324           {
2325             options_p oo;
2326             const char *dot = ".";
2327             const char *tagid = NULL;
2328             int skip_p = 0;
2329             int default_p = 0;
2330             int use_param_p = 0;
2331             char *newval;
2332
2333             d->reorder_fn = NULL;
2334             for (oo = f->opt; oo; oo = oo->next)
2335               if (strcmp (oo->name, "dot") == 0)
2336                 dot = oo->info;
2337               else if (strcmp (oo->name, "tag") == 0)
2338                 tagid = oo->info;
2339               else if (strcmp (oo->name, "skip") == 0)
2340                 skip_p = 1;
2341               else if (strcmp (oo->name, "default") == 0)
2342                 default_p = 1;
2343               else if (strcmp (oo->name, "reorder") == 0)
2344                 d->reorder_fn = oo->info;
2345               else if (strncmp (oo->name, "use_param", 9) == 0
2346                        && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
2347                 use_param_p = 1;
2348
2349             if (skip_p)
2350               continue;
2351
2352             if (union_p && tagid)
2353               {
2354                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
2355                 d->indent += 2;
2356               }
2357             else if (union_p && default_p)
2358               {
2359                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
2360                 d->indent += 2;
2361                 seen_default_p = 1;
2362               }
2363             else if (! union_p && (default_p || tagid))
2364               error_at_line (d->line,
2365                              "can't use `%s' outside a union on field `%s'",
2366                              default_p ? "default" : "tag", f->name);
2367             else if (union_p && ! (default_p || tagid)
2368                      && f->type->kind == TYPE_SCALAR)
2369               {
2370                 fprintf (stderr,
2371         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
2372                          d->line->file, d->line->line, f->name);
2373                 continue;
2374               }
2375             else if (union_p && ! (default_p || tagid))
2376               error_at_line (d->line,
2377                              "field `%s' is missing `tag' or `default' option",
2378                              f->name);
2379
2380             d->line = &f->line;
2381             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
2382             d->opt = f->opt;
2383             d->used_length = false;
2384
2385             if (union_p && use_param_p && d->param == NULL)
2386               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
2387             else
2388               walk_type (f->type, d);
2389
2390             free (newval);
2391
2392             if (union_p)
2393               {
2394                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
2395                 d->indent -= 2;
2396               }
2397           }
2398         d->reorder_fn = NULL;
2399
2400         d->val = oldval;
2401         d->prev_val[1] = oldprevval1;
2402         d->prev_val[2] = oldprevval2;
2403
2404         if (union_p && ! seen_default_p)
2405           {
2406             oprintf (d->of, "%*sdefault:\n", d->indent, "");
2407             oprintf (d->of, "%*s  break;\n", d->indent, "");
2408           }
2409         if (union_p)
2410           {
2411             oprintf (d->of, "%*s}\n", d->indent, "");
2412             d->indent -= 2;
2413           }
2414       }
2415       break;
2416
2417     case TYPE_LANG_STRUCT:
2418       {
2419         type_p nt;
2420         for (nt = t->u.s.lang_struct; nt; nt = nt->next)
2421           if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
2422             break;
2423         if (nt == NULL)
2424           error_at_line (d->line, "structure `%s' differs between languages",
2425                          t->u.s.tag);
2426         else
2427           walk_type (nt, d);
2428       }
2429       break;
2430
2431     case TYPE_PARAM_STRUCT:
2432       {
2433         type_p *oldparam = d->param;
2434
2435         d->param = t->u.param_struct.param;
2436         walk_type (t->u.param_struct.stru, d);
2437         d->param = oldparam;
2438       }
2439       break;
2440
2441     default:
2442       gcc_unreachable ();
2443     }
2444 }
2445
2446 /* process_field routine for marking routines.  */
2447
2448 static void
2449 write_types_process_field (type_p f, const struct walk_type_data *d)
2450 {
2451   const struct write_types_data *wtd;
2452   const char *cast = d->needs_cast_p ? "(void *)" : "";
2453   wtd = (const struct write_types_data *) d->cookie;
2454
2455   switch (f->kind)
2456     {
2457     case TYPE_POINTER:
2458       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
2459                wtd->subfield_marker_routine, cast, d->val);
2460       if (wtd->param_prefix)
2461         {
2462           oprintf (d->of, ", %s", d->prev_val[3]);
2463           if (d->orig_s)
2464             {
2465               oprintf (d->of, ", gt_%s_", wtd->param_prefix);
2466               output_mangled_typename (d->of, d->orig_s);
2467             }
2468           else
2469             oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
2470
2471           if (f->u.p->kind == TYPE_PARAM_STRUCT
2472               && f->u.p->u.s.line.file != NULL)
2473             {
2474               oprintf (d->of, ", gt_e_");
2475               output_mangled_typename (d->of, f);
2476             }
2477           else if (UNION_OR_STRUCT_P (f)
2478                    && f->u.p->u.s.line.file != NULL)
2479             {
2480               oprintf (d->of, ", gt_ggc_e_");
2481               output_mangled_typename (d->of, f);
2482             }
2483           else
2484             oprintf (d->of, ", gt_types_enum_last");
2485         }
2486       oprintf (d->of, ");\n");
2487       if (d->reorder_fn && wtd->reorder_note_routine)
2488         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
2489                  wtd->reorder_note_routine, cast, d->val,
2490                  d->prev_val[3], d->reorder_fn);
2491       break;
2492
2493     case TYPE_STRING:
2494     case TYPE_STRUCT:
2495     case TYPE_UNION:
2496     case TYPE_LANG_STRUCT:
2497     case TYPE_PARAM_STRUCT:
2498       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
2499       output_mangled_typename (d->of, f);
2500       oprintf (d->of, " (%s%s);\n", cast, d->val);
2501       if (d->reorder_fn && wtd->reorder_note_routine)
2502         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
2503                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
2504                  d->reorder_fn);
2505       break;
2506
2507     case TYPE_SCALAR:
2508       break;
2509
2510     default:
2511       gcc_unreachable ();
2512     }
2513 }
2514
2515 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
2516
2517 static void
2518 output_type_enum (outf_p of, type_p s)
2519 {
2520   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
2521     {
2522       oprintf (of, ", gt_e_");
2523       output_mangled_typename (of, s);
2524     }
2525   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
2526     {
2527       oprintf (of, ", gt_ggc_e_");
2528       output_mangled_typename (of, s);
2529     }
2530   else
2531     oprintf (of, ", gt_types_enum_last");
2532 }
2533
2534 /* For S, a structure that's part of ORIG_S, and using parameters
2535    PARAM, write out a routine that:
2536    - Takes a parameter, a void * but actually of type *S
2537    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2538      field of S or its substructures and (in some cases) things
2539      that are pointed to by S.
2540 */
2541
2542 static void
2543 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2544                           const struct write_types_data *wtd)
2545 {
2546   const char *fn = s->u.s.line.file;
2547   int i;
2548   const char *chain_next = NULL;
2549   const char *chain_prev = NULL;
2550   const char *chain_circular = NULL;
2551   const char *mark_hook_name = NULL;
2552   options_p opt;
2553   struct walk_type_data d;
2554
2555   /* This is a hack, and not the good kind either.  */
2556   for (i = NUM_PARAM - 1; i >= 0; i--)
2557     if (param && param[i] && param[i]->kind == TYPE_POINTER
2558         && UNION_OR_STRUCT_P (param[i]->u.p))
2559       fn = param[i]->u.p->u.s.line.file;
2560
2561   memset (&d, 0, sizeof (d));
2562   d.of = get_output_file_with_visibility (fn);
2563
2564   for (opt = s->u.s.opt; opt; opt = opt->next)
2565     if (strcmp (opt->name, "chain_next") == 0)
2566       chain_next = opt->info;
2567     else if (strcmp (opt->name, "chain_prev") == 0)
2568       chain_prev = opt->info;
2569     else if (strcmp (opt->name, "chain_circular") == 0)
2570       chain_circular = opt->info;
2571     else if (strcmp (opt->name, "mark_hook") == 0)
2572       mark_hook_name = opt->info;
2573
2574   if (chain_prev != NULL && chain_next == NULL)
2575     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2576   if (chain_circular != NULL && chain_next != NULL)
2577     error_at_line (&s->u.s.line, "chain_circular with chain_next");
2578   if (chain_circular != NULL)
2579     chain_next = chain_circular;
2580
2581   d.process_field = write_types_process_field;
2582   d.cookie = wtd;
2583   d.orig_s = orig_s;
2584   d.opt = s->u.s.opt;
2585   d.line = &s->u.s.line;
2586   d.bitmap = s->u.s.bitmap;
2587   d.param = param;
2588   d.prev_val[0] = "*x";
2589   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2590   d.prev_val[3] = "x";
2591   d.val = "(*x)";
2592
2593   oprintf (d.of, "\n");
2594   oprintf (d.of, "void\n");
2595   if (param == NULL)
2596     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2597   else
2598     {
2599       oprintf (d.of, "gt_%s_", wtd->prefix);
2600       output_mangled_typename (d.of, orig_s);
2601     }
2602   oprintf (d.of, " (void *x_p)\n");
2603   oprintf (d.of, "{\n");
2604   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2605            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2606            chain_next == NULL ? "const " : "",
2607            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2608   if (chain_next != NULL)
2609     oprintf (d.of, "  %s %s * xlimit = x;\n",
2610              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2611   if (chain_next == NULL)
2612     {
2613       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2614       if (wtd->param_prefix)
2615         {
2616           oprintf (d.of, ", x, 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     }
2622   else
2623     {
2624       if (chain_circular != NULL)
2625         oprintf (d.of, "  if (!%s (xlimit", wtd->marker_routine);
2626       else
2627         oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2628       if (wtd->param_prefix)
2629         {
2630           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2631           output_mangled_typename (d.of, orig_s);
2632           output_type_enum (d.of, orig_s);
2633         }
2634       oprintf (d.of, "))\n");
2635       if (chain_circular != NULL)
2636         oprintf (d.of, "    return;\n  do\n");
2637       if (mark_hook_name && !wtd->skip_hooks)
2638         {
2639           oprintf (d.of, "    {\n");
2640           oprintf (d.of, "      %s (xlimit);\n   ", mark_hook_name);
2641         }
2642       oprintf (d.of, "   xlimit = (");
2643       d.prev_val[2] = "*xlimit";
2644       output_escaped_param (&d, chain_next, "chain_next");
2645       oprintf (d.of, ");\n");
2646       if (mark_hook_name && !wtd->skip_hooks)
2647         oprintf (d.of, "    }\n");
2648       if (chain_prev != NULL)
2649         {
2650           oprintf (d.of, "  if (x != xlimit)\n");
2651           oprintf (d.of, "    for (;;)\n");
2652           oprintf (d.of, "      {\n");
2653           oprintf (d.of, "        %s %s * const xprev = (",
2654                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2655
2656           d.prev_val[2] = "*x";
2657           output_escaped_param (&d, chain_prev, "chain_prev");
2658           oprintf (d.of, ");\n");
2659           oprintf (d.of, "        if (xprev == NULL) break;\n");
2660           oprintf (d.of, "        x = xprev;\n");
2661           oprintf (d.of, "        (void) %s (xprev",
2662                    wtd->marker_routine);
2663           if (wtd->param_prefix)
2664             {
2665               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2666               output_mangled_typename (d.of, orig_s);
2667               output_type_enum (d.of, orig_s);
2668             }
2669           oprintf (d.of, ");\n");
2670           oprintf (d.of, "      }\n");
2671         }
2672       if (chain_circular != NULL)
2673         {
2674           oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2675           if (wtd->param_prefix)
2676             {
2677               oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2678               output_mangled_typename (d.of, orig_s);
2679               output_type_enum (d.of, orig_s);
2680             }
2681           oprintf (d.of, "));\n");
2682           if (mark_hook_name && !wtd->skip_hooks)
2683             oprintf (d.of, "  %s (xlimit);\n", mark_hook_name);
2684           oprintf (d.of, "  do\n");
2685         }
2686       else
2687         oprintf (d.of, "  while (x != xlimit)\n");
2688     }
2689   oprintf (d.of, "    {\n");
2690   if (mark_hook_name && chain_next == NULL && !wtd->skip_hooks)
2691     {
2692       oprintf (d.of, "      %s (x);\n", mark_hook_name);
2693     }
2694   d.prev_val[2] = "*x";
2695   d.indent = 6;
2696   walk_type (s, &d);
2697
2698   if (chain_next != NULL)
2699     {
2700       oprintf (d.of, "      x = (");
2701       output_escaped_param (&d, chain_next, "chain_next");
2702       oprintf (d.of, ");\n");
2703     }
2704
2705   oprintf (d.of, "    }\n");
2706   if (chain_circular != NULL)
2707     oprintf (d.of, "  while (x != xlimit);\n");
2708   oprintf (d.of, "}\n");
2709 }
2710
2711 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2712
2713 static void
2714 write_types (outf_p output_header, type_p structures, type_p param_structs,
2715              const struct write_types_data *wtd)
2716 {
2717   type_p s;
2718
2719   oprintf (output_header, "\n/* %s*/\n", wtd->comment);
2720   for (s = structures; s; s = s->next)
2721     if (s->gc_used == GC_POINTED_TO
2722         || s->gc_used == GC_MAYBE_POINTED_TO)
2723       {
2724         options_p opt;
2725
2726         if (s->gc_used == GC_MAYBE_POINTED_TO
2727             && s->u.s.line.file == NULL)
2728           continue;
2729
2730         oprintf (output_header, "#define gt_%s_", wtd->prefix);
2731         output_mangled_typename (output_header, s);
2732         oprintf (output_header, "(X) do { \\\n");
2733         oprintf (output_header,
2734                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2735                  s->u.s.tag);
2736         oprintf (output_header,
2737                  "  } while (0)\n");
2738
2739         for (opt = s->u.s.opt; opt; opt = opt->next)
2740           if (strcmp (opt->name, "ptr_alias") == 0)
2741             {
2742               const_type_p const t = (const_type_p) opt->info;
2743               if (t->kind == TYPE_STRUCT
2744                   || t->kind == TYPE_UNION
2745                   || t->kind == TYPE_LANG_STRUCT)
2746                 oprintf (output_header,
2747                          "#define gt_%sx_%s gt_%sx_%s\n",
2748                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2749               else
2750                 error_at_line (&s->u.s.line,
2751                                "structure alias is not a structure");
2752               break;
2753             }
2754         if (opt)
2755           continue;
2756
2757         /* Declare the marker procedure only once.  */
2758         oprintf (output_header,
2759                  "extern void gt_%sx_%s (void *);\n",
2760                  wtd->prefix, s->u.s.tag);
2761
2762         if (s->u.s.line.file == NULL)
2763           {
2764             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2765                      s->u.s.tag);
2766             continue;
2767           }
2768
2769         if (s->kind == TYPE_LANG_STRUCT)
2770           {
2771             type_p ss;
2772             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2773               write_func_for_structure (s, ss, NULL, wtd);
2774           }
2775         else
2776           write_func_for_structure (s, s, NULL, wtd);
2777       }
2778
2779   for (s = param_structs; s; s = s->next)
2780     if (s->gc_used == GC_POINTED_TO)
2781       {
2782         type_p * param = s->u.param_struct.param;
2783         type_p stru = s->u.param_struct.stru;
2784
2785         /* Declare the marker procedure.  */
2786         oprintf (output_header, "extern void gt_%s_", wtd->prefix);
2787         output_mangled_typename (output_header, s);
2788         oprintf (output_header, " (void *);\n");
2789
2790         if (stru->u.s.line.file == NULL)
2791           {
2792             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2793                      s->u.s.tag);
2794             continue;
2795           }
2796
2797         if (stru->kind == TYPE_LANG_STRUCT)
2798           {
2799             type_p ss;
2800             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2801               write_func_for_structure (s, ss, param, wtd);
2802           }
2803         else
2804           write_func_for_structure (s, stru, param, wtd);
2805       }
2806 }
2807
2808 static const struct write_types_data ggc_wtd =
2809 {
2810   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2811   "GC marker procedures.  ",
2812   FALSE
2813 };
2814
2815 static const struct write_types_data pch_wtd =
2816 {
2817   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2818   "gt_pch_note_reorder",
2819   "PCH type-walking procedures.  ",
2820   TRUE
2821 };
2822
2823 /* Write out the local pointer-walking routines.  */
2824
2825 /* process_field routine for local pointer-walking.  */
2826
2827 static void
2828 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2829 {
2830   switch (f->kind)
2831     {
2832     case TYPE_POINTER:
2833     case TYPE_STRUCT:
2834     case TYPE_UNION:
2835     case TYPE_LANG_STRUCT:
2836     case TYPE_PARAM_STRUCT:
2837     case TYPE_STRING:
2838       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2839                d->prev_val[3]);
2840       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2841       break;
2842
2843     case TYPE_SCALAR:
2844       break;
2845
2846     default:
2847       gcc_unreachable ();
2848     }
2849 }
2850
2851 /* For S, a structure that's part of ORIG_S, and using parameters
2852    PARAM, write out a routine that:
2853    - Is of type gt_note_pointers
2854    - Calls PROCESS_FIELD on each field of S or its substructures.
2855 */
2856
2857 static void
2858 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2859 {
2860   const char *fn = s->u.s.line.file;
2861   int i;
2862   struct walk_type_data d;
2863
2864   /* This is a hack, and not the good kind either.  */
2865   for (i = NUM_PARAM - 1; i >= 0; i--)
2866     if (param && param[i] && param[i]->kind == TYPE_POINTER
2867         && UNION_OR_STRUCT_P (param[i]->u.p))
2868       fn = param[i]->u.p->u.s.line.file;
2869
2870   memset (&d, 0, sizeof (d));
2871   d.of = get_output_file_with_visibility (fn);
2872   d.process_field = write_types_local_process_field;
2873   d.opt = s->u.s.opt;
2874   d.line = &s->u.s.line;
2875   d.bitmap = s->u.s.bitmap;
2876   d.param = param;
2877   d.prev_val[0] = d.prev_val[2] = "*x";
2878   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2879   d.prev_val[3] = "x";
2880   d.val = "(*x)";
2881   d.fn_wants_lvalue = true;
2882
2883   oprintf (d.of, "\n");
2884   oprintf (d.of, "void\n");
2885   oprintf (d.of, "gt_pch_p_");
2886   output_mangled_typename (d.of, orig_s);
2887   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2888            "\tvoid *x_p,\n"
2889            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2890            "\tATTRIBUTE_UNUSED void *cookie)\n");
2891   oprintf (d.of, "{\n");
2892   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2893            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2894            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2895   d.indent = 2;
2896   walk_type (s, &d);
2897   oprintf (d.of, "}\n");
2898 }
2899
2900 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2901
2902 static void
2903 write_local (outf_p output_header, type_p structures, type_p param_structs)
2904 {
2905   type_p s;
2906
2907   if (!output_header) 
2908     return;
2909   oprintf (output_header, "\n/* Local pointer-walking routines.  */\n");
2910   for (s = structures; s; s = s->next)
2911     if (s->gc_used == GC_POINTED_TO
2912         || s->gc_used == GC_MAYBE_POINTED_TO)
2913       {
2914         options_p opt;
2915
2916         if (s->u.s.line.file == NULL)
2917           continue;
2918
2919         for (opt = s->u.s.opt; opt; opt = opt->next)
2920           if (strcmp (opt->name, "ptr_alias") == 0)
2921             {
2922               const_type_p const t = (const_type_p) opt->info;
2923               if (t->kind == TYPE_STRUCT
2924                   || t->kind == TYPE_UNION
2925                   || t->kind == TYPE_LANG_STRUCT)
2926                 {
2927                   oprintf (output_header, "#define gt_pch_p_");
2928                   output_mangled_typename (output_header, s);
2929                   oprintf (output_header, " gt_pch_p_");
2930                   output_mangled_typename (output_header, t);
2931                   oprintf (output_header, "\n");
2932                 }
2933               else
2934                 error_at_line (&s->u.s.line,
2935                                "structure alias is not a structure");
2936               break;
2937             }
2938         if (opt)
2939           continue;
2940
2941         /* Declare the marker procedure only once.  */
2942         oprintf (output_header, "extern void gt_pch_p_");
2943         output_mangled_typename (output_header, s);
2944         oprintf (output_header,
2945          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2946
2947         if (s->kind == TYPE_LANG_STRUCT)
2948           {
2949             type_p ss;
2950             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2951               write_local_func_for_structure (s, ss, NULL);
2952           }
2953         else
2954           write_local_func_for_structure (s, s, NULL);
2955       }
2956
2957   for (s = param_structs; s; s = s->next)
2958     if (s->gc_used == GC_POINTED_TO)
2959       {
2960         type_p * param = s->u.param_struct.param;
2961         type_p stru = s->u.param_struct.stru;
2962
2963         /* Declare the marker procedure.  */
2964         oprintf (output_header, "extern void gt_pch_p_");
2965         output_mangled_typename (output_header, s);
2966         oprintf (output_header,
2967          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2968
2969         if (stru->u.s.line.file == NULL)
2970           {
2971             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2972                      s->u.s.tag);
2973             continue;
2974           }
2975
2976         if (stru->kind == TYPE_LANG_STRUCT)
2977           {
2978             type_p ss;
2979             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2980               write_local_func_for_structure (s, ss, param);
2981           }
2982         else
2983           write_local_func_for_structure (s, stru, param);
2984       }
2985 }
2986
2987 /* Write out the 'enum' definition for gt_types_enum.  */
2988
2989 static void
2990 write_enum_defn (type_p structures, type_p param_structs)
2991 {
2992   type_p s;
2993
2994   if (!header_file) 
2995     return;
2996   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2997   oprintf (header_file, "enum gt_types_enum {\n");
2998   for (s = structures; s; s = s->next)
2999     if (s->gc_used == GC_POINTED_TO
3000         || s->gc_used == GC_MAYBE_POINTED_TO)
3001       {
3002         if (s->gc_used == GC_MAYBE_POINTED_TO
3003             && s->u.s.line.file == NULL)
3004           continue;
3005
3006         oprintf (header_file, " gt_ggc_e_");
3007         output_mangled_typename (header_file, s);
3008         oprintf (header_file, ", \n");
3009       }
3010   for (s = param_structs; s; s = s->next)
3011     if (s->gc_used == GC_POINTED_TO)
3012       {
3013         oprintf (header_file, " gt_e_");
3014         output_mangled_typename (header_file, s);
3015         oprintf (header_file, ", \n");
3016       }
3017   oprintf (header_file, " gt_types_enum_last\n");
3018   oprintf (header_file, "};\n");
3019 }
3020
3021 /* Might T contain any non-pointer elements?  */
3022
3023 static int
3024 contains_scalar_p (type_p t)
3025 {
3026   switch (t->kind)
3027     {
3028     case TYPE_STRING:
3029     case TYPE_POINTER:
3030       return 0;
3031     case TYPE_ARRAY:
3032       return contains_scalar_p (t->u.a.p);
3033     default:
3034       /* Could also check for structures that have no non-pointer
3035          fields, but there aren't enough of those to worry about.  */
3036       return 1;
3037     }
3038 }
3039
3040 /* Mangle FN and print it to F.  */
3041
3042 static void
3043 put_mangled_filename (outf_p f, const char *fn)
3044 {
3045   const char *name = get_output_file_name (fn);
3046   if (!f || !name) 
3047     return;
3048   for (; *name != 0; name++)
3049     if (ISALNUM (*name))
3050       oprintf (f, "%c", *name);
3051     else
3052       oprintf (f, "%c", '_');
3053 }
3054
3055 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
3056    LASTNAME, and NAME are all strings to insert in various places in
3057    the resulting code.  */
3058
3059 static void
3060 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
3061                    const char *tname, const char *name)
3062 {
3063   struct flist *fli2;
3064
3065   for (fli2 = flp; fli2; fli2 = fli2->next)
3066     if (fli2->started_p)
3067       {
3068         oprintf (fli2->f, "  %s\n", lastname);
3069         oprintf (fli2->f, "};\n\n");
3070       }
3071
3072   for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
3073     if (fli2->started_p)
3074       {
3075         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3076         int fnum;
3077
3078         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
3079           if (bitmap & 1)
3080             {
3081               oprintf (base_files[fnum],
3082                        "extern const struct %s gt_%s_",
3083                        tname, pfx);
3084               put_mangled_filename (base_files[fnum], fli2->name);
3085               oprintf (base_files[fnum], "[];\n");
3086             }
3087       }
3088
3089   {
3090     size_t fnum;
3091     for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3092       oprintf (base_files [fnum],
3093                "EXPORTED_CONST struct %s * const %s[] = {\n",
3094                tname, name);
3095   }
3096
3097
3098   for (fli2 = flp; fli2; fli2 = fli2->next)
3099     if (fli2->started_p)
3100       {
3101         lang_bitmap bitmap = get_lang_bitmap (fli2->name);
3102         int fnum;
3103
3104         fli2->started_p = 0;
3105
3106         for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
3107           if (bitmap & 1)
3108             {
3109               oprintf (base_files[fnum], "  gt_%s_", pfx);
3110               put_mangled_filename (base_files[fnum], fli2->name);
3111               oprintf (base_files[fnum], ",\n");
3112             }
3113       }
3114
3115   {
3116     size_t fnum;
3117     for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
3118       {
3119         oprintf (base_files[fnum], "  NULL\n");
3120         oprintf (base_files[fnum], "};\n");
3121       }
3122   }
3123 }
3124
3125 /* Write out to F the table entry and any marker routines needed to
3126    mark NAME as TYPE.  The original variable is V, at LINE.
3127    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
3128    is nonzero iff we are building the root table for hash table caches.  */
3129
3130 static void
3131 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
3132             struct fileloc *line, const char *if_marked)
3133 {
3134   switch (type->kind)
3135     {
3136     case TYPE_STRUCT:
3137       {
3138         pair_p fld;
3139         for (fld = type->u.s.fields; fld; fld = fld->next)
3140           {
3141             int skip_p = 0;
3142             const char *desc = NULL;
3143             options_p o;
3144
3145             for (o = fld->opt; o; o = o->next)
3146               if (strcmp (o->name, "skip") == 0)
3147                 skip_p = 1;
3148               else if (strcmp (o->name, "desc") == 0)
3149                 desc = o->info;
3150               else if (strcmp (o->name, "param_is") == 0)
3151                 ;
3152               else
3153                 error_at_line (line,
3154                        "field `%s' of global `%s' has unknown option `%s'",
3155                                fld->name, name, o->name);
3156
3157             if (skip_p)
3158               continue;
3159             else if (desc && fld->type->kind == TYPE_UNION)
3160               {
3161                 pair_p validf = NULL;
3162                 pair_p ufld;
3163
3164                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
3165                   {
3166                     const char *tag = NULL;
3167                     options_p oo;
3168
3169                     for (oo = ufld->opt; oo; oo = oo->next)
3170                       if (strcmp (oo->name, "tag") == 0)
3171                         tag = oo->info;
3172                     if (tag == NULL || strcmp (tag, desc) != 0)
3173                       continue;
3174                     if (validf != NULL)
3175                       error_at_line (line,
3176                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
3177                                      name, fld->name, validf->name,
3178                                      name, fld->name, ufld->name,
3179                                      tag);
3180                     validf = ufld;
3181                   }
3182                 if (validf != NULL)
3183                   {
3184                     char *newname;
3185                     newname = xasprintf ("%s.%s.%s",
3186                                          name, fld->name, validf->name);
3187                     write_root (f, v, validf->type, newname, 0, line,
3188                                 if_marked);
3189                     free (newname);
3190                   }
3191               }
3192             else if (desc)
3193               error_at_line (line,
3194                      "global `%s.%s' has `desc' option but is not union",
3195                              name, fld->name);
3196             else
3197               {
3198                 char *newname;
3199                 newname = xasprintf ("%s.%s", name, fld->name);
3200                 write_root (f, v, fld->type, newname, 0, line, if_marked);
3201                 free (newname);
3202               }
3203           }
3204       }
3205       break;
3206
3207     case TYPE_ARRAY:
3208       {
3209         char *newname;
3210         newname = xasprintf ("%s[0]", name);
3211         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
3212         free (newname);
3213       }
3214       break;
3215
3216     case TYPE_POINTER:
3217       {
3218         type_p ap, tp;
3219
3220         oprintf (f, "  {\n");
3221         oprintf (f, "    &%s,\n", name);
3222         oprintf (f, "    1");
3223
3224         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3225           if (ap->u.a.len[0])
3226             oprintf (f, " * (%s)", ap->u.a.len);
3227           else if (ap == v->type)
3228             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
3229         oprintf (f, ",\n");
3230         oprintf (f, "    sizeof (%s", v->name);
3231         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
3232           oprintf (f, "[0]");
3233         oprintf (f, "),\n");
3234
3235         tp = type->u.p;
3236
3237         if (! has_length && UNION_OR_STRUCT_P (tp))
3238           {
3239             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
3240             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
3241           }
3242         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
3243           {
3244             oprintf (f, "    &gt_ggc_m_");
3245             output_mangled_typename (f, tp);
3246             oprintf (f, ",\n    &gt_pch_n_");
3247             output_mangled_typename (f, tp);
3248           }
3249         else if (has_length
3250                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
3251           {
3252             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
3253             oprintf (f, "    &gt_pch_na_%s", name);
3254           }
3255         else
3256           {
3257             error_at_line (line,
3258                            "global `%s' is pointer to unimplemented type",
3259                            name);
3260           }
3261         if (if_marked)
3262           oprintf (f, ",\n    &%s", if_marked);
3263         oprintf (f, "\n  },\n");
3264       }
3265       break;
3266
3267     case TYPE_STRING:
3268       {
3269         oprintf (f, "  {\n");
3270         oprintf (f, "    &%s,\n", name);
3271         oprintf (f, "    1, \n");
3272         oprintf (f, "    sizeof (%s),\n", v->name);
3273         oprintf (f, "    (gt_pointer_walker) &gt_ggc_m_S,\n");
3274         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
3275         oprintf (f, "  },\n");
3276       }
3277       break;
3278
3279     case TYPE_SCALAR:
3280       break;
3281
3282     default:
3283       error_at_line (line,
3284                      "global `%s' is unimplemented type",
3285                      name);
3286     }
3287 }
3288
3289 /* This generates a routine to walk an array.  */
3290
3291 static void
3292 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
3293 {
3294   struct walk_type_data d;
3295   char *prevval3;
3296
3297   memset (&d, 0, sizeof (d));
3298   d.of = f;
3299   d.cookie = wtd;
3300   d.indent = 2;
3301   d.line = &v->line;
3302   d.opt = v->opt;
3303   d.bitmap = get_lang_bitmap (v->line.file);
3304   d.param = NULL;
3305
3306   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
3307
3308   if (wtd->param_prefix)
3309     {
3310       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
3311       oprintf (f,
3312        "    (void *, void *, gt_pointer_operator, void *);\n");
3313       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
3314                wtd->param_prefix, v->name);
3315       oprintf (d.of,
3316                "      ATTRIBUTE_UNUSED void *x_p,\n"
3317                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
3318                "      ATTRIBUTE_UNUSED void * cookie)\n");
3319       oprintf (d.of, "{\n");
3320       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3321       d.process_field = write_types_local_process_field;
3322       walk_type (v->type, &d);
3323       oprintf (f, "}\n\n");
3324     }
3325
3326   d.opt = v->opt;
3327   oprintf (f, "static void gt_%sa_%s (void *);\n",
3328            wtd->prefix, v->name);
3329   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
3330            wtd->prefix, v->name);
3331   oprintf (f, "{\n");
3332   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
3333   d.process_field = write_types_process_field;
3334   walk_type (v->type, &d);
3335   free (prevval3);
3336   oprintf (f, "}\n\n");
3337 }
3338
3339 /* Output a table describing the locations and types of VARIABLES.  */
3340
3341 static void
3342 write_roots (pair_p variables)
3343 {
3344   pair_p v;
3345   struct flist *flp = NULL;
3346
3347   for (v = variables; v; v = v->next)
3348     {
3349       outf_p f = get_output_file_with_visibility (v->line.file);
3350       struct flist *fli;
3351       const char *length = NULL;
3352       int deletable_p = 0;
3353       options_p o;
3354
3355       for (o = v->opt; o; o = o->next)
3356         if (strcmp (o->name, "length") == 0)
3357           length = o->info;
3358         else if (strcmp (o->name, "deletable") == 0)
3359           deletable_p = 1;
3360         else if (strcmp (o->name, "param_is") == 0)
3361           ;
3362         else if (strncmp (o->name, "param", 5) == 0
3363                  && ISDIGIT (o->name[5])
3364                  && strcmp (o->name + 6, "_is") == 0)
3365           ;
3366         else if (strcmp (o->name, "if_marked") == 0)
3367           ;
3368         else
3369           error_at_line (&v->line,
3370                          "global `%s' has unknown option `%s'",
3371                          v->name, o->name);
3372
3373       for (fli = flp; fli; fli = fli->next)
3374         if (fli->f == f && f)
3375           break;
3376       if (fli == NULL)
3377         {
3378           fli = XNEW (struct flist);
3379           fli->f = f;
3380           fli->next = flp;
3381           fli->started_p = 0;
3382           fli->name = v->line.file;
3383           gcc_assert(fli->name);
3384           flp = fli;
3385
3386           oprintf (f, "\n/* GC roots.  */\n\n");
3387         }
3388
3389       if (! deletable_p
3390           && length
3391           && v->type->kind == TYPE_POINTER
3392           && (v->type->u.p->kind == TYPE_POINTER
3393               || v->type->u.p->kind == TYPE_STRUCT))
3394         {
3395           write_array (f, v, &ggc_wtd);
3396           write_array (f, v, &pch_wtd);
3397         }
3398     }
3399
3400   for (v = variables; v; v = v->next)
3401     {
3402       outf_p f = get_output_file_with_visibility (v->line.file);
3403       struct flist *fli;
3404       int skip_p = 0;
3405       int length_p = 0;
3406       options_p o;
3407
3408       for (o = v->opt; o; o = o->next)
3409         if (strcmp (o->name, "length") == 0)
3410           length_p = 1;
3411         else if (strcmp (o->name, "deletable") == 0
3412                  || strcmp (o->name, "if_marked") == 0)
3413           skip_p = 1;
3414
3415       if (skip_p)
3416         continue;
3417
3418       for (fli = flp; fli; fli = fli->next)
3419         if (fli->f == f)
3420           break;
3421       if (! fli->started_p)
3422         {
3423           fli->started_p = 1;
3424
3425           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
3426           put_mangled_filename (f, v->line.file);
3427           oprintf (f, "[] = {\n");
3428         }
3429
3430       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3431     }
3432
3433   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3434                      "gt_ggc_rtab");
3435
3436   for (v = variables; v; v = v->next)
3437     {
3438       outf_p f = get_output_file_with_visibility (v->line.file);
3439       struct flist *fli;
3440       int skip_p = 1;
3441       options_p o;
3442
3443       for (o = v->opt; o; o = o->next)
3444         if (strcmp (o->name, "deletable") == 0)
3445           skip_p = 0;
3446         else if (strcmp (o->name, "if_marked") == 0)
3447           skip_p = 1;
3448
3449       if (skip_p)
3450         continue;
3451
3452       for (fli = flp; fli; fli = fli->next)
3453         if (fli->f == f)
3454           break;
3455       if (! fli->started_p)
3456         {
3457           fli->started_p = 1;
3458
3459           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
3460           put_mangled_filename (f, v->line.file);
3461           oprintf (f, "[] = {\n");
3462         }
3463
3464       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3465                v->name, v->name);
3466     }
3467
3468   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3469                      "gt_ggc_deletable_rtab");
3470
3471   for (v = variables; v; v = v->next)
3472     {
3473       outf_p f = get_output_file_with_visibility (v->line.file);
3474       struct flist *fli;
3475       const char *if_marked = NULL;
3476       int length_p = 0;
3477       options_p o;
3478
3479       for (o = v->opt; o; o = o->next)
3480         if (strcmp (o->name, "length") == 0)
3481           length_p = 1;
3482         else if (strcmp (o->name, "if_marked") == 0)
3483           if_marked = o->info;
3484
3485       if (if_marked == NULL)
3486         continue;
3487
3488       if (v->type->kind != TYPE_POINTER
3489           || v->type->u.p->kind != TYPE_PARAM_STRUCT
3490           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
3491         {
3492           error_at_line (&v->line, "if_marked option used but not hash table");
3493           continue;
3494         }
3495
3496       for (fli = flp; fli; fli = fli->next)
3497         if (fli->f == f)
3498           break;
3499       if (! fli->started_p)
3500         {
3501           fli->started_p = 1;
3502
3503           oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
3504           put_mangled_filename (f, v->line.file);
3505           oprintf (f, "[] = {\n");
3506         }
3507
3508       write_root (f, v, v->type->u.p->u.param_struct.param[0],
3509                      v->name, length_p, &v->line, if_marked);
3510     }
3511
3512   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
3513                      "gt_ggc_cache_rtab");
3514
3515   for (v = variables; v; v = v->next)
3516     {
3517       outf_p f = get_output_file_with_visibility (v->line.file);
3518       struct flist *fli;
3519       int length_p = 0;
3520       int if_marked_p = 0;
3521       options_p o;
3522
3523       for (o = v->opt; o; o = o->next)
3524         if (strcmp (o->name, "length") == 0)
3525           length_p = 1;
3526         else if (strcmp (o->name, "if_marked") == 0)
3527           if_marked_p = 1;
3528
3529       if (! if_marked_p)
3530         continue;
3531
3532       for (fli = flp; fli; fli = fli->next)
3533         if (fli->f == f)
3534           break;
3535       if (! fli->started_p)
3536         {
3537           fli->started_p = 1;
3538
3539           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
3540           put_mangled_filename (f, v->line.file);
3541           oprintf (f, "[] = {\n");
3542         }
3543
3544       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
3545     }
3546
3547   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3548                      "gt_pch_cache_rtab");
3549
3550   for (v = variables; v; v = v->next)
3551     {
3552       outf_p f = get_output_file_with_visibility (v->line.file);
3553       struct flist *fli;
3554       int skip_p = 0;
3555       options_p o;
3556
3557       for (o = v->opt; o; o = o->next)
3558         if (strcmp (o->name, "deletable") == 0
3559             || strcmp (o->name, "if_marked") == 0)
3560           skip_p = 1;
3561
3562       if (skip_p)
3563         continue;
3564
3565       if (! contains_scalar_p (v->type))
3566         continue;
3567
3568       for (fli = flp; fli; fli = fli->next)
3569         if (fli->f == f)
3570           break;
3571       if (! fli->started_p)
3572         {
3573           fli->started_p = 1;
3574
3575           oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
3576           put_mangled_filename (f, v->line.file);
3577           oprintf (f, "[] = {\n");
3578         }
3579
3580       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3581                v->name, v->name);
3582     }
3583
3584   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3585                      "gt_pch_scalar_rtab");
3586 }
3587
3588 /* Record the definition of a generic VEC structure, as if we had expanded
3589    the macros in vec.h:
3590
3591    typedef struct VEC_<type>_base GTY(()) {
3592    unsigned num;
3593    unsigned alloc;
3594    <type> GTY((length ("%h.num"))) vec[1];
3595    } VEC_<type>_base
3596
3597    where the GTY(()) tags are only present if is_scalar is _false_.  */
3598
3599 void
3600 note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
3601 {
3602   pair_p fields;
3603   type_p t;
3604   options_p o;
3605   type_p len_ty = create_scalar_type ("unsigned");
3606   const char *name = concat ("VEC_", type_name, "_base", (char *)0);
3607
3608   if (is_scalar)
3609     {
3610       t = create_scalar_type (type_name);
3611       o = 0;
3612     }
3613   else
3614     {
3615       t = resolve_typedef (type_name, pos);
3616       o = create_option (0, "length", "%h.num");
3617     }
3618
3619   /* We assemble the field list in reverse order.  */
3620   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
3621   fields = create_field_at (fields, len_ty, "alloc", 0, pos);
3622   fields = create_field_at (fields, len_ty, "num", 0, pos);
3623
3624   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
3625 }
3626
3627 /* Record the definition of an allocation-specific VEC structure, as if
3628    we had expanded the macros in vec.h:
3629
3630    typedef struct VEC_<type>_<astrat> {
3631      VEC_<type>_base base;
3632    } VEC_<type>_<astrat>;
3633 */
3634 void
3635 note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
3636 {
3637   const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
3638   const char *basename = concat ("VEC_", type, "_base", (char *)0);
3639
3640   pair_p field = create_field_at (0, resolve_typedef (basename, pos),
3641                                   "base", 0, pos);
3642
3643   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
3644 }
3645
3646 \f
3647 int
3648 main (int argc, char **argv)
3649 {
3650   size_t i;
3651   static struct fileloc pos = { this_file, 0 };
3652   char* inputlist = 0;
3653   /* fatal uses this */
3654   progname = "gengtype";
3655
3656   if (argc >= 5 && !strcmp (argv[1], "-p")) 
3657     {
3658       srcdir = argv[2];
3659       inputlist = argv[3];
3660       plugin_files = argv+4;
3661       nb_plugin_files = argc-4;
3662     }
3663   else if (argc == 3) 
3664     {
3665       srcdir = argv[1];
3666       inputlist = argv[2];
3667     } 
3668   else
3669     fatal ("usage: gengtype [-p] srcdir input-list [file1 file2 ... fileN]");
3670
3671   srcdir_len = strlen (srcdir);
3672
3673   read_input_list (inputlist);
3674   if (hit_error)
3675     return 1;
3676
3677   scalar_char.u.scalar_is_char = true;
3678   scalar_nonchar.u.scalar_is_char = false;
3679   gen_rtx_next ();
3680
3681   /* These types are set up with #define or else outside of where
3682      we can see them.  */
3683   pos.line = __LINE__ + 1;
3684   do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
3685   do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
3686   do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
3687   do_scalar_typedef ("double_int", &pos); pos.line++;
3688   do_scalar_typedef ("uint64_t", &pos); pos.line++;
3689   do_scalar_typedef ("uint8", &pos); pos.line++;
3690   do_scalar_typedef ("jword", &pos); pos.line++;
3691   do_scalar_typedef ("JCF_u2", &pos); pos.line++;
3692   do_scalar_typedef ("void", &pos); pos.line++;
3693   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3694
3695   for (i = 0; i < num_gt_files; i++)
3696     parse_file (gt_files[i]);
3697
3698   if (hit_error)
3699     return 1;
3700
3701   set_gc_used (variables);
3702
3703   open_base_files ();
3704   write_enum_defn (structures, param_structs);
3705   write_types (header_file, structures, param_structs, &ggc_wtd);
3706   write_types (header_file, structures, param_structs, &pch_wtd);
3707   write_local (header_file, structures, param_structs);
3708   write_roots (variables);
3709   write_rtx_next ();
3710   close_output_files ();
3711
3712   if (hit_error)
3713     return 1;
3714   return 0;
3715 }