OSDN Git Service

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