OSDN Git Service

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