OSDN Git Service

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