OSDN Git Service

* gengtype.c (write_func_for_structure): Split out ...
[pf3gnuchains/gcc-fork.git] / 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           if (f->u.p->kind == TYPE_PARAM_STRUCT
1933               && f->u.p->u.s.line.file != NULL)
1934             {
1935               oprintf (d->of, ", gt_e_");
1936               output_mangled_typename (d->of, f);
1937             }
1938           else if (UNION_OR_STRUCT_P (f)
1939                    && f->u.p->u.s.line.file != NULL)
1940             {
1941               oprintf (d->of, ", gt_ggc_e_");
1942               output_mangled_typename (d->of, f);
1943             }
1944           else
1945             oprintf (d->of, ", gt_types_enum_last");
1946         }
1947       oprintf (d->of, ");\n");
1948       if (d->reorder_fn && wtd->reorder_note_routine)
1949         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1950                  wtd->reorder_note_routine, cast, d->val,
1951                  d->prev_val[3], d->reorder_fn);
1952       break;
1953
1954     case TYPE_STRING:
1955       if (wtd->param_prefix == NULL)
1956         break;
1957
1958     case TYPE_STRUCT:
1959     case TYPE_UNION:
1960     case TYPE_LANG_STRUCT:
1961     case TYPE_PARAM_STRUCT:
1962       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1963       output_mangled_typename (d->of, f);
1964       oprintf (d->of, " (%s%s);\n", cast, d->val);
1965       if (d->reorder_fn && wtd->reorder_note_routine)
1966         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1967                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
1968                  d->reorder_fn);
1969       break;
1970
1971     case TYPE_SCALAR:
1972       break;
1973
1974     default:
1975       gcc_unreachable ();
1976     }
1977 }
1978
1979 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
1980
1981 static void
1982 output_type_enum (outf_p of, type_p s)
1983 {
1984   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
1985     {
1986       oprintf (of, ", gt_e_");
1987       output_mangled_typename (of, s);
1988     }
1989   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
1990     {
1991       oprintf (of, ", gt_ggc_e_");
1992       output_mangled_typename (of, s);
1993     }
1994   else
1995     oprintf (of, ", gt_types_enum_last");
1996 }
1997
1998 /* For S, a structure that's part of ORIG_S, and using parameters
1999    PARAM, write out a routine that:
2000    - Takes a parameter, a void * but actually of type *S
2001    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2002      field of S or its substructures and (in some cases) things
2003      that are pointed to by S.
2004 */
2005
2006 static void
2007 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2008                           const struct write_types_data *wtd)
2009 {
2010   const char *fn = s->u.s.line.file;
2011   int i;
2012   const char *chain_next = NULL;
2013   const char *chain_prev = NULL;
2014   options_p opt;
2015   struct walk_type_data d;
2016
2017   /* This is a hack, and not the good kind either.  */
2018   for (i = NUM_PARAM - 1; i >= 0; i--)
2019     if (param && param[i] && param[i]->kind == TYPE_POINTER
2020         && UNION_OR_STRUCT_P (param[i]->u.p))
2021       fn = param[i]->u.p->u.s.line.file;
2022
2023   memset (&d, 0, sizeof (d));
2024   d.of = get_output_file_with_visibility (fn);
2025
2026   for (opt = s->u.s.opt; opt; opt = opt->next)
2027     if (strcmp (opt->name, "chain_next") == 0)
2028       chain_next = opt->info;
2029     else if (strcmp (opt->name, "chain_prev") == 0)
2030       chain_prev = opt->info;
2031
2032   if (chain_prev != NULL && chain_next == NULL)
2033     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2034
2035   d.process_field = write_types_process_field;
2036   d.cookie = wtd;
2037   d.orig_s = orig_s;
2038   d.opt = s->u.s.opt;
2039   d.line = &s->u.s.line;
2040   d.bitmap = s->u.s.bitmap;
2041   d.param = param;
2042   d.prev_val[0] = "*x";
2043   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2044   d.prev_val[3] = "x";
2045   d.val = "(*x)";
2046
2047   oprintf (d.of, "\n");
2048   oprintf (d.of, "void\n");
2049   if (param == NULL)
2050     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2051   else
2052     {
2053       oprintf (d.of, "gt_%s_", wtd->prefix);
2054       output_mangled_typename (d.of, orig_s);
2055     }
2056   oprintf (d.of, " (void *x_p)\n");
2057   oprintf (d.of, "{\n");
2058   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2059            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2060            chain_next == NULL ? "const " : "",
2061            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2062   if (chain_next != NULL)
2063     oprintf (d.of, "  %s %s * xlimit = x;\n",
2064              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2065   if (chain_next == NULL)
2066     {
2067       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2068       if (wtd->param_prefix)
2069         {
2070           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2071           output_mangled_typename (d.of, orig_s);
2072           output_type_enum (d.of, orig_s);
2073         }
2074       oprintf (d.of, "))\n");
2075     }
2076   else
2077     {
2078       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2079       if (wtd->param_prefix)
2080         {
2081           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2082           output_mangled_typename (d.of, orig_s);
2083           output_type_enum (d.of, orig_s);
2084         }
2085       oprintf (d.of, "))\n");
2086       oprintf (d.of, "   xlimit = (");
2087       d.prev_val[2] = "*xlimit";
2088       output_escaped_param (&d, chain_next, "chain_next");
2089       oprintf (d.of, ");\n");
2090       if (chain_prev != NULL)
2091         {
2092           oprintf (d.of, "  if (x != xlimit)\n");
2093           oprintf (d.of, "    for (;;)\n");
2094           oprintf (d.of, "      {\n");
2095           oprintf (d.of, "        %s %s * const xprev = (",
2096                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2097
2098           d.prev_val[2] = "*x";
2099           output_escaped_param (&d, chain_prev, "chain_prev");
2100           oprintf (d.of, ");\n");
2101           oprintf (d.of, "        if (xprev == NULL) break;\n");
2102           oprintf (d.of, "        x = xprev;\n");
2103           oprintf (d.of, "        (void) %s (xprev",
2104                    wtd->marker_routine);
2105           if (wtd->param_prefix)
2106             {
2107               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2108               output_mangled_typename (d.of, orig_s);
2109               output_type_enum (d.of, orig_s);
2110             }
2111           oprintf (d.of, ");\n");
2112           oprintf (d.of, "      }\n");
2113         }
2114       oprintf (d.of, "  while (x != xlimit)\n");
2115     }
2116   oprintf (d.of, "    {\n");
2117
2118   d.prev_val[2] = "*x";
2119   d.indent = 6;
2120   walk_type (s, &d);
2121
2122   if (chain_next != NULL)
2123     {
2124       oprintf (d.of, "      x = (");
2125       output_escaped_param (&d, chain_next, "chain_next");
2126       oprintf (d.of, ");\n");
2127     }
2128
2129   oprintf (d.of, "    }\n");
2130   oprintf (d.of, "}\n");
2131 }
2132
2133 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2134
2135 static void
2136 write_types (type_p structures, type_p param_structs,
2137              const struct write_types_data *wtd)
2138 {
2139   type_p s;
2140
2141   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2142   for (s = structures; s; s = s->next)
2143     if (s->gc_used == GC_POINTED_TO
2144         || s->gc_used == GC_MAYBE_POINTED_TO)
2145       {
2146         options_p opt;
2147
2148         if (s->gc_used == GC_MAYBE_POINTED_TO
2149             && s->u.s.line.file == NULL)
2150           continue;
2151
2152         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2153         output_mangled_typename (header_file, s);
2154         oprintf (header_file, "(X) do { \\\n");
2155         oprintf (header_file,
2156                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2157                  s->u.s.tag);
2158         oprintf (header_file,
2159                  "  } while (0)\n");
2160
2161         for (opt = s->u.s.opt; opt; opt = opt->next)
2162           if (strcmp (opt->name, "ptr_alias") == 0)
2163             {
2164               type_p t = (type_p) opt->info;
2165               if (t->kind == TYPE_STRUCT
2166                   || t->kind == TYPE_UNION
2167                   || t->kind == TYPE_LANG_STRUCT)
2168                 oprintf (header_file,
2169                          "#define gt_%sx_%s gt_%sx_%s\n",
2170                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2171               else
2172                 error_at_line (&s->u.s.line,
2173                                "structure alias is not a structure");
2174               break;
2175             }
2176         if (opt)
2177           continue;
2178
2179         /* Declare the marker procedure only once.  */
2180         oprintf (header_file,
2181                  "extern void gt_%sx_%s (void *);\n",
2182                  wtd->prefix, s->u.s.tag);
2183
2184         if (s->u.s.line.file == NULL)
2185           {
2186             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2187                      s->u.s.tag);
2188             continue;
2189           }
2190
2191         if (s->kind == TYPE_LANG_STRUCT)
2192           {
2193             type_p ss;
2194             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2195               write_func_for_structure (s, ss, NULL, wtd);
2196           }
2197         else
2198           write_func_for_structure (s, s, NULL, wtd);
2199       }
2200
2201   for (s = param_structs; s; s = s->next)
2202     if (s->gc_used == GC_POINTED_TO)
2203       {
2204         type_p * param = s->u.param_struct.param;
2205         type_p stru = s->u.param_struct.stru;
2206
2207         /* Declare the marker procedure.  */
2208         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2209         output_mangled_typename (header_file, s);
2210         oprintf (header_file, " (void *);\n");
2211
2212         if (stru->u.s.line.file == NULL)
2213           {
2214             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2215                      s->u.s.tag);
2216             continue;
2217           }
2218
2219         if (stru->kind == TYPE_LANG_STRUCT)
2220           {
2221             type_p ss;
2222             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2223               write_func_for_structure (s, ss, param, wtd);
2224           }
2225         else
2226           write_func_for_structure (s, stru, param, wtd);
2227       }
2228 }
2229
2230 static const struct write_types_data ggc_wtd =
2231 {
2232   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2233   "GC marker procedures.  "
2234 };
2235
2236 static const struct write_types_data pch_wtd =
2237 {
2238   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2239   "gt_pch_note_reorder",
2240   "PCH type-walking procedures.  "
2241 };
2242
2243 /* Write out the local pointer-walking routines.  */
2244
2245 /* process_field routine for local pointer-walking.  */
2246
2247 static void
2248 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2249 {
2250   switch (f->kind)
2251     {
2252     case TYPE_POINTER:
2253     case TYPE_STRUCT:
2254     case TYPE_UNION:
2255     case TYPE_LANG_STRUCT:
2256     case TYPE_PARAM_STRUCT:
2257     case TYPE_STRING:
2258       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2259                d->prev_val[3]);
2260       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2261       break;
2262
2263     case TYPE_SCALAR:
2264       break;
2265
2266     default:
2267       gcc_unreachable ();
2268     }
2269 }
2270
2271 /* For S, a structure that's part of ORIG_S, and using parameters
2272    PARAM, write out a routine that:
2273    - Is of type gt_note_pointers
2274    - Calls PROCESS_FIELD on each field of S or its substructures.
2275 */
2276
2277 static void
2278 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2279 {
2280   const char *fn = s->u.s.line.file;
2281   int i;
2282   struct walk_type_data d;
2283
2284   /* This is a hack, and not the good kind either.  */
2285   for (i = NUM_PARAM - 1; i >= 0; i--)
2286     if (param && param[i] && param[i]->kind == TYPE_POINTER
2287         && UNION_OR_STRUCT_P (param[i]->u.p))
2288       fn = param[i]->u.p->u.s.line.file;
2289
2290   memset (&d, 0, sizeof (d));
2291   d.of = get_output_file_with_visibility (fn);
2292
2293   d.process_field = write_types_local_process_field;
2294   d.opt = s->u.s.opt;
2295   d.line = &s->u.s.line;
2296   d.bitmap = s->u.s.bitmap;
2297   d.param = param;
2298   d.prev_val[0] = d.prev_val[2] = "*x";
2299   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2300   d.prev_val[3] = "x";
2301   d.val = "(*x)";
2302   d.fn_wants_lvalue = true;
2303
2304   oprintf (d.of, "\n");
2305   oprintf (d.of, "void\n");
2306   oprintf (d.of, "gt_pch_p_");
2307   output_mangled_typename (d.of, orig_s);
2308   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2309            "\tvoid *x_p,\n"
2310            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2311            "\tATTRIBUTE_UNUSED void *cookie)\n");
2312   oprintf (d.of, "{\n");
2313   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2314            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2315            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2316   d.indent = 2;
2317   walk_type (s, &d);
2318   oprintf (d.of, "}\n");
2319 }
2320
2321 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2322
2323 static void
2324 write_local (type_p structures, type_p param_structs)
2325 {
2326   type_p s;
2327
2328   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2329   for (s = structures; s; s = s->next)
2330     if (s->gc_used == GC_POINTED_TO
2331         || s->gc_used == GC_MAYBE_POINTED_TO)
2332       {
2333         options_p opt;
2334
2335         if (s->u.s.line.file == NULL)
2336           continue;
2337
2338         for (opt = s->u.s.opt; opt; opt = opt->next)
2339           if (strcmp (opt->name, "ptr_alias") == 0)
2340             {
2341               type_p t = (type_p) opt->info;
2342               if (t->kind == TYPE_STRUCT
2343                   || t->kind == TYPE_UNION
2344                   || t->kind == TYPE_LANG_STRUCT)
2345                 {
2346                   oprintf (header_file, "#define gt_pch_p_");
2347                   output_mangled_typename (header_file, s);
2348                   oprintf (header_file, " gt_pch_p_");
2349                   output_mangled_typename (header_file, t);
2350                   oprintf (header_file, "\n");
2351                 }
2352               else
2353                 error_at_line (&s->u.s.line,
2354                                "structure alias is not a structure");
2355               break;
2356             }
2357         if (opt)
2358           continue;
2359
2360         /* Declare the marker procedure only once.  */
2361         oprintf (header_file, "extern void gt_pch_p_");
2362         output_mangled_typename (header_file, s);
2363         oprintf (header_file,
2364          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2365
2366         if (s->kind == TYPE_LANG_STRUCT)
2367           {
2368             type_p ss;
2369             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2370               write_local_func_for_structure (s, ss, NULL);
2371           }
2372         else
2373           write_local_func_for_structure (s, s, NULL);
2374       }
2375
2376   for (s = param_structs; s; s = s->next)
2377     if (s->gc_used == GC_POINTED_TO)
2378       {
2379         type_p * param = s->u.param_struct.param;
2380         type_p stru = s->u.param_struct.stru;
2381
2382         /* Declare the marker procedure.  */
2383         oprintf (header_file, "extern void gt_pch_p_");
2384         output_mangled_typename (header_file, s);
2385         oprintf (header_file,
2386          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2387
2388         if (stru->u.s.line.file == NULL)
2389           {
2390             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2391                      s->u.s.tag);
2392             continue;
2393           }
2394
2395         if (stru->kind == TYPE_LANG_STRUCT)
2396           {
2397             type_p ss;
2398             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2399               write_local_func_for_structure (s, ss, param);
2400           }
2401         else
2402           write_local_func_for_structure (s, stru, param);
2403       }
2404 }
2405
2406 /* Write out the 'enum' definition for gt_types_enum.  */
2407
2408 static void
2409 write_enum_defn (type_p structures, type_p param_structs)
2410 {
2411   type_p s;
2412
2413   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2414   oprintf (header_file, "enum gt_types_enum {\n");
2415   for (s = structures; s; s = s->next)
2416     if (s->gc_used == GC_POINTED_TO
2417         || s->gc_used == GC_MAYBE_POINTED_TO)
2418       {
2419         if (s->gc_used == GC_MAYBE_POINTED_TO
2420             && s->u.s.line.file == NULL)
2421           continue;
2422
2423         oprintf (header_file, " gt_ggc_e_");
2424         output_mangled_typename (header_file, s);
2425         oprintf (header_file, ", \n");
2426       }
2427   for (s = param_structs; s; s = s->next)
2428     if (s->gc_used == GC_POINTED_TO)
2429       {
2430         oprintf (header_file, " gt_e_");
2431         output_mangled_typename (header_file, s);
2432         oprintf (header_file, ", \n");
2433       }
2434   oprintf (header_file, " gt_types_enum_last\n");
2435   oprintf (header_file, "};\n");
2436 }
2437
2438 /* Might T contain any non-pointer elements?  */
2439
2440 static int
2441 contains_scalar_p (type_p t)
2442 {
2443   switch (t->kind)
2444     {
2445     case TYPE_STRING:
2446     case TYPE_POINTER:
2447       return 0;
2448     case TYPE_ARRAY:
2449       return contains_scalar_p (t->u.a.p);
2450     default:
2451       /* Could also check for structures that have no non-pointer
2452          fields, but there aren't enough of those to worry about.  */
2453       return 1;
2454     }
2455 }
2456
2457 /* Mangle FN and print it to F.  */
2458
2459 static void
2460 put_mangled_filename (outf_p f, const char *fn)
2461 {
2462   const char *name = get_output_file_name (fn);
2463   for (; *name != 0; name++)
2464     if (ISALNUM (*name))
2465       oprintf (f, "%c", *name);
2466     else
2467       oprintf (f, "%c", '_');
2468 }
2469
2470 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2471    LASTNAME, and NAME are all strings to insert in various places in
2472    the resulting code.  */
2473
2474 static void
2475 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2476                    const char *tname, const char *name)
2477 {
2478   struct flist *fli2;
2479
2480   for (fli2 = flp; fli2; fli2 = fli2->next)
2481     if (fli2->started_p)
2482       {
2483         oprintf (fli2->f, "  %s\n", lastname);
2484         oprintf (fli2->f, "};\n\n");
2485       }
2486
2487   for (fli2 = flp; fli2; fli2 = fli2->next)
2488     if (fli2->started_p)
2489       {
2490         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2491         int fnum;
2492
2493         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2494           if (bitmap & 1)
2495             {
2496               oprintf (base_files[fnum],
2497                        "extern const struct %s gt_%s_",
2498                        tname, pfx);
2499               put_mangled_filename (base_files[fnum], fli2->name);
2500               oprintf (base_files[fnum], "[];\n");
2501             }
2502       }
2503
2504   {
2505     size_t fnum;
2506     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2507       oprintf (base_files [fnum],
2508                "const struct %s * const %s[] = {\n",
2509                tname, name);
2510   }
2511
2512
2513   for (fli2 = flp; fli2; fli2 = fli2->next)
2514     if (fli2->started_p)
2515       {
2516         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2517         int fnum;
2518
2519         fli2->started_p = 0;
2520
2521         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2522           if (bitmap & 1)
2523             {
2524               oprintf (base_files[fnum], "  gt_%s_", pfx);
2525               put_mangled_filename (base_files[fnum], fli2->name);
2526               oprintf (base_files[fnum], ",\n");
2527             }
2528       }
2529
2530   {
2531     size_t fnum;
2532     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2533       {
2534         oprintf (base_files[fnum], "  NULL\n");
2535         oprintf (base_files[fnum], "};\n");
2536       }
2537   }
2538 }
2539
2540 /* Write out to F the table entry and any marker routines needed to
2541    mark NAME as TYPE.  The original variable is V, at LINE.
2542    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2543    is nonzero iff we are building the root table for hash table caches.  */
2544
2545 static void
2546 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2547             struct fileloc *line, const char *if_marked)
2548 {
2549   switch (type->kind)
2550     {
2551     case TYPE_STRUCT:
2552       {
2553         pair_p fld;
2554         for (fld = type->u.s.fields; fld; fld = fld->next)
2555           {
2556             int skip_p = 0;
2557             const char *desc = NULL;
2558             options_p o;
2559
2560             for (o = fld->opt; o; o = o->next)
2561               if (strcmp (o->name, "skip") == 0)
2562                 skip_p = 1;
2563               else if (strcmp (o->name, "desc") == 0)
2564                 desc = o->info;
2565               else
2566                 error_at_line (line,
2567                        "field `%s' of global `%s' has unknown option `%s'",
2568                                fld->name, name, o->name);
2569
2570             if (skip_p)
2571               continue;
2572             else if (desc && fld->type->kind == TYPE_UNION)
2573               {
2574                 pair_p validf = NULL;
2575                 pair_p ufld;
2576
2577                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2578                   {
2579                     const char *tag = NULL;
2580                     options_p oo;
2581
2582                     for (oo = ufld->opt; oo; oo = oo->next)
2583                       if (strcmp (oo->name, "tag") == 0)
2584                         tag = oo->info;
2585                     if (tag == NULL || strcmp (tag, desc) != 0)
2586                       continue;
2587                     if (validf != NULL)
2588                       error_at_line (line,
2589                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2590                                      name, fld->name, validf->name,
2591                                      name, fld->name, ufld->name,
2592                                      tag);
2593                     validf = ufld;
2594                   }
2595                 if (validf != NULL)
2596                   {
2597                     char *newname;
2598                     newname = xasprintf ("%s.%s.%s",
2599                                          name, fld->name, validf->name);
2600                     write_root (f, v, validf->type, newname, 0, line,
2601                                 if_marked);
2602                     free (newname);
2603                   }
2604               }
2605             else if (desc)
2606               error_at_line (line,
2607                      "global `%s.%s' has `desc' option but is not union",
2608                              name, fld->name);
2609             else
2610               {
2611                 char *newname;
2612                 newname = xasprintf ("%s.%s", name, fld->name);
2613                 write_root (f, v, fld->type, newname, 0, line, if_marked);
2614                 free (newname);
2615               }
2616           }
2617       }
2618       break;
2619
2620     case TYPE_ARRAY:
2621       {
2622         char *newname;
2623         newname = xasprintf ("%s[0]", name);
2624         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2625         free (newname);
2626       }
2627       break;
2628
2629     case TYPE_POINTER:
2630       {
2631         type_p ap, tp;
2632
2633         oprintf (f, "  {\n");
2634         oprintf (f, "    &%s,\n", name);
2635         oprintf (f, "    1");
2636
2637         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2638           if (ap->u.a.len[0])
2639             oprintf (f, " * (%s)", ap->u.a.len);
2640           else if (ap == v->type)
2641             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2642         oprintf (f, ",\n");
2643         oprintf (f, "    sizeof (%s", v->name);
2644         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2645           oprintf (f, "[0]");
2646         oprintf (f, "),\n");
2647
2648         tp = type->u.p;
2649
2650         if (! has_length && UNION_OR_STRUCT_P (tp))
2651           {
2652             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
2653             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
2654           }
2655         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2656           {
2657             oprintf (f, "    &gt_ggc_m_");
2658             output_mangled_typename (f, tp);
2659             oprintf (f, ",\n    &gt_pch_n_");
2660             output_mangled_typename (f, tp);
2661           }
2662         else if (has_length
2663                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2664           {
2665             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
2666             oprintf (f, "    &gt_pch_na_%s", name);
2667           }
2668         else
2669           {
2670             error_at_line (line,
2671                            "global `%s' is pointer to unimplemented type",
2672                            name);
2673           }
2674         if (if_marked)
2675           oprintf (f, ",\n    &%s", if_marked);
2676         oprintf (f, "\n  },\n");
2677       }
2678       break;
2679
2680     case TYPE_STRING:
2681       {
2682         oprintf (f, "  {\n");
2683         oprintf (f, "    &%s,\n", name);
2684         oprintf (f, "    1, \n");
2685         oprintf (f, "    sizeof (%s),\n", v->name);
2686         oprintf (f, "    &gt_ggc_m_S,\n");
2687         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
2688         oprintf (f, "  },\n");
2689       }
2690       break;
2691
2692     case TYPE_SCALAR:
2693       break;
2694
2695     default:
2696       error_at_line (line,
2697                      "global `%s' is unimplemented type",
2698                      name);
2699     }
2700 }
2701
2702 /* This generates a routine to walk an array.  */
2703
2704 static void
2705 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2706 {
2707   struct walk_type_data d;
2708   char *prevval3;
2709
2710   memset (&d, 0, sizeof (d));
2711   d.of = f;
2712   d.cookie = wtd;
2713   d.indent = 2;
2714   d.line = &v->line;
2715   d.opt = v->opt;
2716   d.bitmap = get_base_file_bitmap (v->line.file);
2717   d.param = NULL;
2718
2719   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2720
2721   if (wtd->param_prefix)
2722     {
2723       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2724       oprintf (f,
2725        "    (void *, void *, gt_pointer_operator, void *);\n");
2726       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2727                wtd->param_prefix, v->name);
2728       oprintf (d.of,
2729                "      ATTRIBUTE_UNUSED void *x_p,\n"
2730                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2731                "      ATTRIBUTE_UNUSED void * cookie)\n");
2732       oprintf (d.of, "{\n");
2733       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2734       d.process_field = write_types_local_process_field;
2735       walk_type (v->type, &d);
2736       oprintf (f, "}\n\n");
2737     }
2738
2739   d.opt = v->opt;
2740   oprintf (f, "static void gt_%sa_%s (void *);\n",
2741            wtd->prefix, v->name);
2742   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2743            wtd->prefix, v->name);
2744   oprintf (f, "{\n");
2745   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2746   d.process_field = write_types_process_field;
2747   walk_type (v->type, &d);
2748   free (prevval3);
2749   oprintf (f, "}\n\n");
2750 }
2751
2752 /* Output a table describing the locations and types of VARIABLES.  */
2753
2754 static void
2755 write_roots (pair_p variables)
2756 {
2757   pair_p v;
2758   struct flist *flp = NULL;
2759
2760   for (v = variables; v; v = v->next)
2761     {
2762       outf_p f = get_output_file_with_visibility (v->line.file);
2763       struct flist *fli;
2764       const char *length = NULL;
2765       int deletable_p = 0;
2766       options_p o;
2767
2768       for (o = v->opt; o; o = o->next)
2769         if (strcmp (o->name, "length") == 0)
2770           length = o->info;
2771         else if (strcmp (o->name, "deletable") == 0)
2772           deletable_p = 1;
2773         else if (strcmp (o->name, "param_is") == 0)
2774           ;
2775         else if (strncmp (o->name, "param", 5) == 0
2776                  && ISDIGIT (o->name[5])
2777                  && strcmp (o->name + 6, "_is") == 0)
2778           ;
2779         else if (strcmp (o->name, "if_marked") == 0)
2780           ;
2781         else
2782           error_at_line (&v->line,
2783                          "global `%s' has unknown option `%s'",
2784                          v->name, o->name);
2785
2786       for (fli = flp; fli; fli = fli->next)
2787         if (fli->f == f)
2788           break;
2789       if (fli == NULL)
2790         {
2791           fli = XNEW (struct flist);
2792           fli->f = f;
2793           fli->next = flp;
2794           fli->started_p = 0;
2795           fli->name = v->line.file;
2796           flp = fli;
2797
2798           oprintf (f, "\n/* GC roots.  */\n\n");
2799         }
2800
2801       if (! deletable_p
2802           && length
2803           && v->type->kind == TYPE_POINTER
2804           && (v->type->u.p->kind == TYPE_POINTER
2805               || v->type->u.p->kind == TYPE_STRUCT))
2806         {
2807           write_array (f, v, &ggc_wtd);
2808           write_array (f, v, &pch_wtd);
2809         }
2810     }
2811
2812   for (v = variables; v; v = v->next)
2813     {
2814       outf_p f = get_output_file_with_visibility (v->line.file);
2815       struct flist *fli;
2816       int skip_p = 0;
2817       int length_p = 0;
2818       options_p o;
2819
2820       for (o = v->opt; o; o = o->next)
2821         if (strcmp (o->name, "length") == 0)
2822           length_p = 1;
2823         else if (strcmp (o->name, "deletable") == 0
2824                  || strcmp (o->name, "if_marked") == 0)
2825           skip_p = 1;
2826
2827       if (skip_p)
2828         continue;
2829
2830       for (fli = flp; fli; fli = fli->next)
2831         if (fli->f == f)
2832           break;
2833       if (! fli->started_p)
2834         {
2835           fli->started_p = 1;
2836
2837           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2838           put_mangled_filename (f, v->line.file);
2839           oprintf (f, "[] = {\n");
2840         }
2841
2842       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2843     }
2844
2845   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2846                      "gt_ggc_rtab");
2847
2848   for (v = variables; v; v = v->next)
2849     {
2850       outf_p f = get_output_file_with_visibility (v->line.file);
2851       struct flist *fli;
2852       int skip_p = 1;
2853       options_p o;
2854
2855       for (o = v->opt; o; o = o->next)
2856         if (strcmp (o->name, "deletable") == 0)
2857           skip_p = 0;
2858         else if (strcmp (o->name, "if_marked") == 0)
2859           skip_p = 1;
2860
2861       if (skip_p)
2862         continue;
2863
2864       for (fli = flp; fli; fli = fli->next)
2865         if (fli->f == f)
2866           break;
2867       if (! fli->started_p)
2868         {
2869           fli->started_p = 1;
2870
2871           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2872           put_mangled_filename (f, v->line.file);
2873           oprintf (f, "[] = {\n");
2874         }
2875
2876       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2877                v->name, v->name);
2878     }
2879
2880   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2881                      "gt_ggc_deletable_rtab");
2882
2883   for (v = variables; v; v = v->next)
2884     {
2885       outf_p f = get_output_file_with_visibility (v->line.file);
2886       struct flist *fli;
2887       const char *if_marked = NULL;
2888       int length_p = 0;
2889       options_p o;
2890
2891       for (o = v->opt; o; o = o->next)
2892         if (strcmp (o->name, "length") == 0)
2893           length_p = 1;
2894         else if (strcmp (o->name, "if_marked") == 0)
2895           if_marked = o->info;
2896
2897       if (if_marked == NULL)
2898         continue;
2899
2900       if (v->type->kind != TYPE_POINTER
2901           || v->type->u.p->kind != TYPE_PARAM_STRUCT
2902           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2903         {
2904           error_at_line (&v->line, "if_marked option used but not hash table");
2905           continue;
2906         }
2907
2908       for (fli = flp; fli; fli = fli->next)
2909         if (fli->f == f)
2910           break;
2911       if (! fli->started_p)
2912         {
2913           fli->started_p = 1;
2914
2915           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2916           put_mangled_filename (f, v->line.file);
2917           oprintf (f, "[] = {\n");
2918         }
2919
2920       write_root (f, v, v->type->u.p->u.param_struct.param[0],
2921                      v->name, length_p, &v->line, if_marked);
2922     }
2923
2924   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2925                      "gt_ggc_cache_rtab");
2926
2927   for (v = variables; v; v = v->next)
2928     {
2929       outf_p f = get_output_file_with_visibility (v->line.file);
2930       struct flist *fli;
2931       int length_p = 0;
2932       int if_marked_p = 0;
2933       options_p o;
2934
2935       for (o = v->opt; o; o = o->next)
2936         if (strcmp (o->name, "length") == 0)
2937           length_p = 1;
2938         else if (strcmp (o->name, "if_marked") == 0)
2939           if_marked_p = 1;
2940
2941       if (! if_marked_p)
2942         continue;
2943
2944       for (fli = flp; fli; fli = fli->next)
2945         if (fli->f == f)
2946           break;
2947       if (! fli->started_p)
2948         {
2949           fli->started_p = 1;
2950
2951           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2952           put_mangled_filename (f, v->line.file);
2953           oprintf (f, "[] = {\n");
2954         }
2955
2956       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2957     }
2958
2959   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2960                      "gt_pch_cache_rtab");
2961
2962   for (v = variables; v; v = v->next)
2963     {
2964       outf_p f = get_output_file_with_visibility (v->line.file);
2965       struct flist *fli;
2966       int skip_p = 0;
2967       options_p o;
2968
2969       for (o = v->opt; o; o = o->next)
2970         if (strcmp (o->name, "deletable") == 0
2971             || strcmp (o->name, "if_marked") == 0)
2972           skip_p = 1;
2973
2974       if (skip_p)
2975         continue;
2976
2977       if (! contains_scalar_p (v->type))
2978         continue;
2979
2980       for (fli = flp; fli; fli = fli->next)
2981         if (fli->f == f)
2982           break;
2983       if (! fli->started_p)
2984         {
2985           fli->started_p = 1;
2986
2987           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2988           put_mangled_filename (f, v->line.file);
2989           oprintf (f, "[] = {\n");
2990         }
2991
2992       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2993                v->name, v->name);
2994     }
2995
2996   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2997                      "gt_pch_scalar_rtab");
2998 }
2999
3000 \f
3001 extern int main (int argc, char **argv);
3002 int
3003 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3004 {
3005   unsigned i;
3006   static struct fileloc pos = { __FILE__, __LINE__ };
3007   unsigned j;
3008
3009   gen_rtx_next ();
3010
3011   srcdir_len = strlen (srcdir);
3012
3013   do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3014   do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3015   do_scalar_typedef ("uint8", &pos);
3016   do_scalar_typedef ("jword", &pos);
3017   do_scalar_typedef ("JCF_u2", &pos);
3018 #ifdef USE_MAPPED_LOCATION
3019   do_scalar_typedef ("location_t", &pos);
3020   do_scalar_typedef ("source_locus", &pos);
3021 #endif
3022   do_scalar_typedef ("void", &pos);
3023
3024   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3025
3026   do_typedef ("HARD_REG_SET", create_array (
3027               create_scalar_type ("unsigned long", strlen ("unsigned long")),
3028               "2"), &pos);
3029
3030   for (i = 0; i < NUM_GT_FILES; i++)
3031     {
3032       int dupflag = 0;
3033       /* Omit if already seen.  */
3034       for (j = 0; j < i; j++)
3035         {
3036           if (!strcmp (all_files[i], all_files[j]))
3037             {
3038               dupflag = 1;
3039               break;
3040             }
3041         }
3042       if (!dupflag)
3043         parse_file (all_files[i]);
3044 #ifndef USE_MAPPED_LOCATION
3045       /* temporary kludge - gengtype doesn't handle conditionals.
3046          Manually add source_locus *after* we've processed input.h.  */
3047       if (i == 0)
3048         do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3049 #endif
3050     }
3051
3052   if (hit_error != 0)
3053     exit (1);
3054
3055   set_gc_used (variables);
3056
3057   open_base_files ();
3058   write_enum_defn (structures, param_structs);
3059   write_types (structures, param_structs, &ggc_wtd);
3060   write_types (structures, param_structs, &pch_wtd);
3061   write_local (structures, param_structs);
3062   write_roots (variables);
3063   write_rtx_next ();
3064   close_output_files ();
3065
3066   return (hit_error != 0);
3067 }