OSDN Git Service

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