OSDN Git Service

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