OSDN Git Service

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