OSDN Git Service

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