OSDN Git Service

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