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