OSDN Git Service

Yet more Objective-C++...
[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       "except.h", 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, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1242            && strcmp (basename + 3, "cp-tree.h") == 0)
1243     output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
1244   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1245            && strcmp (basename + 3, "decl.h") == 0)
1246     output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
1247   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
1248            && strcmp (basename + 3, "name-lookup.h") == 0)
1249     output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
1250   else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1251            && strcmp (basename + 5, "objc-act.h") == 0)
1252     output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1253   else 
1254     {
1255       size_t i;
1256
1257       for (i = 0; i < NUM_BASE_FILES; i++)
1258         if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1259             && basename[strlen(lang_dir_names[i])] == '/')
1260           return base_files[i];
1261
1262       output_name = "gtype-desc.c";
1263       for_name = NULL;
1264     }
1265
1266   /* Look through to see if we've ever seen this output filename before.  */
1267   for (r = output_files; r; r = r->next)
1268     if (strcmp (r->name, output_name) == 0)
1269       return r;
1270
1271   /* If not, create it.  */
1272   r = create_file (for_name, output_name);
1273
1274   return r;
1275 }
1276
1277 /* The name of an output file, suitable for definitions, that can see
1278    declarations made in INPUT_FILE and is linked into every language
1279    that uses INPUT_FILE.  */
1280
1281 const char *
1282 get_output_file_name (const char *input_file)
1283 {
1284   return get_output_file_with_visibility (input_file)->name;
1285 }
1286
1287 /* Copy the output to its final destination,
1288    but don't unnecessarily change modification times.  */
1289
1290 static void
1291 close_output_files (void)
1292 {
1293   outf_p of;
1294
1295   for (of = output_files; of; of = of->next)
1296     {
1297       FILE * newfile;
1298
1299       newfile = fopen (of->name, "r");
1300       if (newfile != NULL )
1301         {
1302           int no_write_p;
1303           size_t i;
1304
1305           for (i = 0; i < of->bufused; i++)
1306             {
1307               int ch;
1308               ch = fgetc (newfile);
1309               if (ch == EOF || ch != (unsigned char) of->buf[i])
1310                 break;
1311             }
1312           no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1313           fclose (newfile);
1314
1315           if (no_write_p)
1316             continue;
1317         }
1318
1319       newfile = fopen (of->name, "w");
1320       if (newfile == NULL)
1321         {
1322           perror ("opening output file");
1323           exit (1);
1324         }
1325       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1326         {
1327           perror ("writing output file");
1328           exit (1);
1329         }
1330       if (fclose (newfile) != 0)
1331         {
1332           perror ("closing output file");
1333           exit (1);
1334         }
1335     }
1336 }
1337 \f
1338 struct flist {
1339   struct flist *next;
1340   int started_p;
1341   const char *name;
1342   outf_p f;
1343 };
1344
1345 struct walk_type_data;
1346
1347 /* For scalars and strings, given the item in 'val'.
1348    For structures, given a pointer to the item in 'val'.
1349    For misc. pointers, given the item in 'val'.
1350 */
1351 typedef void (*process_field_fn)
1352      (type_p f, const struct walk_type_data *p);
1353 typedef void (*func_name_fn)
1354      (type_p s, const struct walk_type_data *p);
1355
1356 /* Parameters for write_types.  */
1357
1358 struct write_types_data
1359 {
1360   const char *prefix;
1361   const char *param_prefix;
1362   const char *subfield_marker_routine;
1363   const char *marker_routine;
1364   const char *reorder_note_routine;
1365   const char *comment;
1366 };
1367
1368 static void output_escaped_param (struct walk_type_data *d,
1369                                   const char *, const char *);
1370 static void output_mangled_typename (outf_p, type_p);
1371 static void walk_type (type_p t, struct walk_type_data *d);
1372 static void write_func_for_structure
1373      (type_p orig_s, type_p s, type_p * param,
1374       const struct write_types_data *wtd);
1375 static void write_types_process_field
1376      (type_p f, const struct walk_type_data *d);
1377 static void write_types (type_p structures,
1378                          type_p param_structs,
1379                          const struct write_types_data *wtd);
1380 static void write_types_local_process_field
1381      (type_p f, const struct walk_type_data *d);
1382 static void write_local_func_for_structure
1383      (type_p orig_s, type_p s, type_p * param);
1384 static void write_local (type_p structures,
1385                          type_p param_structs);
1386 static void write_enum_defn (type_p structures, type_p param_structs);
1387 static int contains_scalar_p (type_p t);
1388 static void put_mangled_filename (outf_p , const char *);
1389 static void finish_root_table (struct flist *flp, const char *pfx,
1390                                const char *tname, const char *lastname,
1391                                const char *name);
1392 static void write_root (outf_p , pair_p, type_p, const char *, int,
1393                         struct fileloc *, const char *);
1394 static void write_array (outf_p f, pair_p v,
1395                          const struct write_types_data *wtd);
1396 static void write_roots (pair_p);
1397
1398 /* Parameters for walk_type.  */
1399
1400 struct walk_type_data
1401 {
1402   process_field_fn process_field;
1403   const void *cookie;
1404   outf_p of;
1405   options_p opt;
1406   const char *val;
1407   const char *prev_val[4];
1408   int indent;
1409   int counter;
1410   struct fileloc *line;
1411   lang_bitmap bitmap;
1412   type_p *param;
1413   int used_length;
1414   type_p orig_s;
1415   const char *reorder_fn;
1416   bool needs_cast_p;
1417   bool fn_wants_lvalue;
1418 };
1419
1420 /* Print a mangled name representing T to OF.  */
1421
1422 static void
1423 output_mangled_typename (outf_p of, type_p t)
1424 {
1425   if (t == NULL)
1426     oprintf (of, "Z");
1427   else switch (t->kind)
1428     {
1429     case TYPE_POINTER:
1430       oprintf (of, "P");
1431       output_mangled_typename (of, t->u.p);
1432       break;
1433     case TYPE_SCALAR:
1434       oprintf (of, "I");
1435       break;
1436     case TYPE_STRING:
1437       oprintf (of, "S");
1438       break;
1439     case TYPE_STRUCT:
1440     case TYPE_UNION:
1441     case TYPE_LANG_STRUCT:
1442       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1443       break;
1444     case TYPE_PARAM_STRUCT:
1445       {
1446         int i;
1447         for (i = 0; i < NUM_PARAM; i++)
1448           if (t->u.param_struct.param[i] != NULL)
1449             output_mangled_typename (of, t->u.param_struct.param[i]);
1450         output_mangled_typename (of, t->u.param_struct.stru);
1451       }
1452       break;
1453     case TYPE_ARRAY:
1454       gcc_unreachable ();
1455     }
1456 }
1457
1458 /* Print PARAM to D->OF processing escapes.  D->VAL references the
1459    current object, D->PREV_VAL the object containing the current
1460    object, ONAME is the name of the option and D->LINE is used to
1461    print error messages.  */
1462
1463 static void
1464 output_escaped_param (struct walk_type_data *d, const char *param,
1465                       const char *oname)
1466 {
1467   const char *p;
1468
1469   for (p = param; *p; p++)
1470     if (*p != '%')
1471       oprintf (d->of, "%c", *p);
1472     else switch (*++p)
1473       {
1474       case 'h':
1475         oprintf (d->of, "(%s)", d->prev_val[2]);
1476         break;
1477       case '0':
1478         oprintf (d->of, "(%s)", d->prev_val[0]);
1479         break;
1480       case '1':
1481         oprintf (d->of, "(%s)", d->prev_val[1]);
1482         break;
1483       case 'a':
1484         {
1485           const char *pp = d->val + strlen (d->val);
1486           while (pp[-1] == ']')
1487             while (*pp != '[')
1488               pp--;
1489           oprintf (d->of, "%s", pp);
1490         }
1491         break;
1492       default:
1493         error_at_line (d->line, "`%s' option contains bad escape %c%c",
1494                        oname, '%', *p);
1495       }
1496 }
1497
1498 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1499    which is of type T.  Write code to D->OF to constrain execution (at
1500    the point that D->PROCESS_FIELD is called) to the appropriate
1501    cases.  Call D->PROCESS_FIELD on subobjects before calling it on
1502    pointers to those objects.  D->PREV_VAL lists the objects
1503    containing the current object, D->OPT is a list of options to
1504    apply, D->INDENT is the current indentation level, D->LINE is used
1505    to print error messages, D->BITMAP indicates which languages to
1506    print the structure for, and D->PARAM is the current parameter
1507    (from an enclosing param_is option).  */
1508
1509 static void
1510 walk_type (type_p t, struct walk_type_data *d)
1511 {
1512   const char *length = NULL;
1513   const char *desc = NULL;
1514   int maybe_undef_p = 0;
1515   int use_param_num = -1;
1516   int use_params_p = 0;
1517   options_p oo;
1518   const struct nested_ptr_data *nested_ptr_d = NULL;
1519
1520   d->needs_cast_p = false;
1521   for (oo = d->opt; oo; oo = oo->next)
1522     if (strcmp (oo->name, "length") == 0)
1523       length = oo->info;
1524     else if (strcmp (oo->name, "maybe_undef") == 0)
1525       maybe_undef_p = 1;
1526     else if (strncmp (oo->name, "use_param", 9) == 0
1527              && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1528       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1529     else if (strcmp (oo->name, "use_params") == 0)
1530       use_params_p = 1;
1531     else if (strcmp (oo->name, "desc") == 0)
1532       desc = oo->info;
1533     else if (strcmp (oo->name, "nested_ptr") == 0)
1534       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1535     else if (strcmp (oo->name, "dot") == 0)
1536       ;
1537     else if (strcmp (oo->name, "tag") == 0)
1538       ;
1539     else if (strcmp (oo->name, "special") == 0)
1540       ;
1541     else if (strcmp (oo->name, "skip") == 0)
1542       ;
1543     else if (strcmp (oo->name, "default") == 0)
1544       ;
1545     else if (strcmp (oo->name, "descbits") == 0)
1546       ;
1547     else if (strcmp (oo->name, "param_is") == 0)
1548       ;
1549     else if (strncmp (oo->name, "param", 5) == 0
1550              && ISDIGIT (oo->name[5])
1551              && strcmp (oo->name + 6, "_is") == 0)
1552       ;
1553     else if (strcmp (oo->name, "chain_next") == 0)
1554       ;
1555     else if (strcmp (oo->name, "chain_prev") == 0)
1556       ;
1557     else if (strcmp (oo->name, "reorder") == 0)
1558       ;
1559     else
1560       error_at_line (d->line, "unknown option `%s'\n", oo->name);
1561
1562   if (d->used_length)
1563     length = NULL;
1564
1565   if (use_params_p)
1566     {
1567       int pointer_p = t->kind == TYPE_POINTER;
1568
1569       if (pointer_p)
1570         t = t->u.p;
1571       if (! UNION_OR_STRUCT_P (t))
1572         error_at_line (d->line, "`use_params' option on unimplemented type");
1573       else
1574         t = find_param_structure (t, d->param);
1575       if (pointer_p)
1576         t = create_pointer (t);
1577     }
1578
1579   if (use_param_num != -1)
1580     {
1581       if (d->param != NULL && d->param[use_param_num] != NULL)
1582         {
1583           type_p nt = d->param[use_param_num];
1584
1585           if (t->kind == TYPE_ARRAY)
1586             nt = create_array (nt, t->u.a.len);
1587           else if (length != NULL && t->kind == TYPE_POINTER)
1588             nt = create_pointer (nt);
1589           d->needs_cast_p = (t->kind != TYPE_POINTER
1590                              && (nt->kind == TYPE_POINTER
1591                                  || nt->kind == TYPE_STRING));
1592           t = nt;
1593         }
1594       else
1595         error_at_line (d->line, "no parameter defined for `%s'",
1596                        d->val);
1597     }
1598
1599   if (maybe_undef_p
1600       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1601     {
1602       error_at_line (d->line,
1603                      "field `%s' has invalid option `maybe_undef_p'\n",
1604                      d->val);
1605       return;
1606     }
1607
1608   switch (t->kind)
1609     {
1610     case TYPE_SCALAR:
1611     case TYPE_STRING:
1612       d->process_field (t, d);
1613       break;
1614
1615     case TYPE_POINTER:
1616       {
1617         if (maybe_undef_p
1618             && t->u.p->u.s.line.file == NULL)
1619           {
1620             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1621             break;
1622           }
1623
1624         if (! length)
1625           {
1626             if (! UNION_OR_STRUCT_P (t->u.p)
1627                 && t->u.p->kind != TYPE_PARAM_STRUCT)
1628               {
1629                 error_at_line (d->line,
1630                                "field `%s' is pointer to unimplemented type",
1631                                d->val);
1632                 break;
1633               }
1634
1635             if (nested_ptr_d)
1636               {
1637                 const char *oldprevval2 = d->prev_val[2];
1638
1639                 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1640                   {
1641                     error_at_line (d->line,
1642                                    "field `%s' has invalid "
1643                                    "option `nested_ptr'\n",
1644                                    d->val);
1645                     return;
1646                   }
1647
1648                 d->prev_val[2] = d->val;
1649                 oprintf (d->of, "%*s{\n", d->indent, "");
1650                 d->indent += 2;
1651                 d->val = xasprintf ("x%d", d->counter++);
1652                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1653                          (nested_ptr_d->type->kind == TYPE_UNION 
1654                           ? "union" : "struct"), 
1655                          nested_ptr_d->type->u.s.tag, 
1656                          d->fn_wants_lvalue ? "" : "const ",
1657                          d->val);
1658                 oprintf (d->of, "%*s", d->indent + 2, "");
1659                 output_escaped_param (d, nested_ptr_d->convert_from,
1660                                       "nested_ptr");
1661                 oprintf (d->of, ";\n");
1662
1663                 d->process_field (nested_ptr_d->type, d);
1664
1665                 if (d->fn_wants_lvalue)
1666                   {
1667                     oprintf (d->of, "%*s%s = ", d->indent, "",
1668                              d->prev_val[2]);
1669                     d->prev_val[2] = d->val;
1670                     output_escaped_param (d, nested_ptr_d->convert_to,
1671                                           "nested_ptr");
1672                     oprintf (d->of, ";\n");
1673                   }
1674
1675                 d->indent -= 2;
1676                 oprintf (d->of, "%*s}\n", d->indent, "");
1677                 d->val = d->prev_val[2];
1678                 d->prev_val[2] = oldprevval2;
1679               }
1680             else
1681               d->process_field (t->u.p, d);
1682           }
1683         else
1684           {
1685             int loopcounter = d->counter++;
1686             const char *oldval = d->val;
1687             const char *oldprevval3 = d->prev_val[3];
1688             char *newval;
1689
1690             oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1691             d->indent += 2;
1692             oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1693             oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1694                      loopcounter, loopcounter);
1695             output_escaped_param (d, length, "length");
1696             oprintf (d->of, "); i%d++) {\n", loopcounter);
1697             d->indent += 2;
1698             d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1699             d->used_length = 1;
1700             d->prev_val[3] = oldval;
1701             walk_type (t->u.p, d);
1702             free (newval);
1703             d->val = oldval;
1704             d->prev_val[3] = oldprevval3;
1705             d->used_length = 0;
1706             d->indent -= 2;
1707             oprintf (d->of, "%*s}\n", d->indent, "");
1708             d->process_field(t, d);
1709             d->indent -= 2;
1710             oprintf (d->of, "%*s}\n", d->indent, "");
1711           }
1712       }
1713       break;
1714
1715     case TYPE_ARRAY:
1716       {
1717         int loopcounter = d->counter++;
1718         const char *oldval = d->val;
1719         char *newval;
1720
1721         /* If it's an array of scalars, we optimize by not generating
1722            any code.  */
1723         if (t->u.a.p->kind == TYPE_SCALAR)
1724           break;
1725
1726         oprintf (d->of, "%*s{\n", d->indent, "");
1727         d->indent += 2;
1728         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1729         oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
1730                  loopcounter, loopcounter);
1731         if (length)
1732           output_escaped_param (d, length, "length");
1733         else
1734           oprintf (d->of, "%s", t->u.a.len);
1735         oprintf (d->of, "); i%d++) {\n", loopcounter);
1736         d->indent += 2;
1737         d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1738         d->used_length = 1;
1739         walk_type (t->u.a.p, d);
1740         free (newval);
1741         d->used_length = 0;
1742         d->val = oldval;
1743         d->indent -= 2;
1744         oprintf (d->of, "%*s}\n", d->indent, "");
1745         d->indent -= 2;
1746         oprintf (d->of, "%*s}\n", d->indent, "");
1747       }
1748       break;
1749
1750     case TYPE_STRUCT:
1751     case TYPE_UNION:
1752       {
1753         pair_p f;
1754         const char *oldval = d->val;
1755         const char *oldprevval1 = d->prev_val[1];
1756         const char *oldprevval2 = d->prev_val[2];
1757         const int union_p = t->kind == TYPE_UNION;
1758         int seen_default_p = 0;
1759         options_p o;
1760
1761         if (! t->u.s.line.file)
1762           error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1763
1764         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1765           {
1766             error_at_line (d->line,
1767                            "structure `%s' defined for mismatching languages",
1768                            t->u.s.tag);
1769             error_at_line (&t->u.s.line, "one structure defined here");
1770           }
1771
1772         /* Some things may also be defined in the structure's options.  */
1773         for (o = t->u.s.opt; o; o = o->next)
1774           if (! desc && strcmp (o->name, "desc") == 0)
1775             desc = o->info;
1776
1777         d->prev_val[2] = oldval;
1778         d->prev_val[1] = oldprevval2;
1779         if (union_p)
1780           {
1781             if (desc == NULL)
1782               {
1783                 error_at_line (d->line, "missing `desc' option for union `%s'",
1784                                t->u.s.tag);
1785                 desc = "1";
1786               }
1787             oprintf (d->of, "%*sswitch (", d->indent, "");
1788             output_escaped_param (d, desc, "desc");
1789             oprintf (d->of, ")\n");
1790             d->indent += 2;
1791             oprintf (d->of, "%*s{\n", d->indent, "");
1792           }
1793         for (f = t->u.s.fields; f; f = f->next)
1794           {
1795             options_p oo;
1796             const char *dot = ".";
1797             const char *tagid = NULL;
1798             int skip_p = 0;
1799             int default_p = 0;
1800             int use_param_p = 0;
1801             char *newval;
1802
1803             d->reorder_fn = NULL;
1804             for (oo = f->opt; oo; oo = oo->next)
1805               if (strcmp (oo->name, "dot") == 0)
1806                 dot = oo->info;
1807               else if (strcmp (oo->name, "tag") == 0)
1808                 tagid = oo->info;
1809               else if (strcmp (oo->name, "skip") == 0)
1810                 skip_p = 1;
1811               else if (strcmp (oo->name, "default") == 0)
1812                 default_p = 1;
1813               else if (strcmp (oo->name, "reorder") == 0)
1814                 d->reorder_fn = oo->info;
1815               else if (strncmp (oo->name, "use_param", 9) == 0
1816                        && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1817                 use_param_p = 1;
1818
1819             if (skip_p)
1820               continue;
1821
1822             if (union_p && tagid)
1823               {
1824                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1825                 d->indent += 2;
1826               }
1827             else if (union_p && default_p)
1828               {
1829                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1830                 d->indent += 2;
1831                 seen_default_p = 1;
1832               }
1833             else if (! union_p && (default_p || tagid))
1834               error_at_line (d->line,
1835                              "can't use `%s' outside a union on field `%s'",
1836                              default_p ? "default" : "tag", f->name);
1837             else if (union_p && ! (default_p || tagid)
1838                      && f->type->kind == TYPE_SCALAR)
1839               {
1840                 fprintf (stderr,
1841         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1842                          d->line->file, d->line->line, f->name);
1843                 continue;
1844               }
1845             else if (union_p && ! (default_p || tagid))
1846               error_at_line (d->line,
1847                              "field `%s' is missing `tag' or `default' option",
1848                              f->name);
1849
1850             d->line = &f->line;
1851             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1852             d->opt = f->opt;
1853             d->used_length = false;
1854
1855             if (union_p && use_param_p && d->param == NULL)
1856               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1857             else
1858               walk_type (f->type, d);
1859
1860             free (newval);
1861
1862             if (union_p)
1863               {
1864                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1865                 d->indent -= 2;
1866               }
1867           }
1868         d->reorder_fn = NULL;
1869
1870         d->val = oldval;
1871         d->prev_val[1] = oldprevval1;
1872         d->prev_val[2] = oldprevval2;
1873
1874         if (union_p && ! seen_default_p)
1875           {
1876             oprintf (d->of, "%*sdefault:\n", d->indent, "");
1877             oprintf (d->of, "%*s  break;\n", d->indent, "");
1878           }
1879         if (union_p)
1880           {
1881             oprintf (d->of, "%*s}\n", d->indent, "");
1882             d->indent -= 2;
1883           }
1884       }
1885       break;
1886
1887     case TYPE_LANG_STRUCT:
1888       {
1889         type_p nt;
1890         for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1891           if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1892             break;
1893         if (nt == NULL)
1894           error_at_line (d->line, "structure `%s' differs between languages",
1895                          t->u.s.tag);
1896         else
1897           walk_type (nt, d);
1898       }
1899       break;
1900
1901     case TYPE_PARAM_STRUCT:
1902       {
1903         type_p *oldparam = d->param;
1904
1905         d->param = t->u.param_struct.param;
1906         walk_type (t->u.param_struct.stru, d);
1907         d->param = oldparam;
1908       }
1909       break;
1910
1911     default:
1912       gcc_unreachable ();
1913     }
1914 }
1915
1916 /* process_field routine for marking routines.  */
1917
1918 static void
1919 write_types_process_field (type_p f, const struct walk_type_data *d)
1920 {
1921   const struct write_types_data *wtd;
1922   const char *cast = d->needs_cast_p ? "(void *)" : "";
1923   wtd = (const struct write_types_data *) d->cookie;
1924
1925   switch (f->kind)
1926     {
1927     case TYPE_POINTER:
1928       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1929                wtd->subfield_marker_routine, cast, d->val);
1930       if (wtd->param_prefix)
1931         {
1932           oprintf (d->of, ", %s", d->prev_val[3]);
1933           if (d->orig_s)
1934             {
1935               oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1936               output_mangled_typename (d->of, d->orig_s);
1937             }
1938           else
1939             oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1940
1941           if (f->u.p->kind == TYPE_PARAM_STRUCT
1942               && f->u.p->u.s.line.file != NULL)
1943             {
1944               oprintf (d->of, ", gt_e_");
1945               output_mangled_typename (d->of, f);
1946             }
1947           else if (UNION_OR_STRUCT_P (f)
1948                    && f->u.p->u.s.line.file != NULL)
1949             {
1950               oprintf (d->of, ", gt_ggc_e_");
1951               output_mangled_typename (d->of, f);
1952             }
1953           else
1954             oprintf (d->of, ", gt_types_enum_last");
1955         }
1956       oprintf (d->of, ");\n");
1957       if (d->reorder_fn && wtd->reorder_note_routine)
1958         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1959                  wtd->reorder_note_routine, cast, d->val,
1960                  d->prev_val[3], d->reorder_fn);
1961       break;
1962
1963     case TYPE_STRING:
1964       if (wtd->param_prefix == NULL)
1965         break;
1966
1967     case TYPE_STRUCT:
1968     case TYPE_UNION:
1969     case TYPE_LANG_STRUCT:
1970     case TYPE_PARAM_STRUCT:
1971       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1972       output_mangled_typename (d->of, f);
1973       oprintf (d->of, " (%s%s);\n", cast, d->val);
1974       if (d->reorder_fn && wtd->reorder_note_routine)
1975         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1976                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
1977                  d->reorder_fn);
1978       break;
1979
1980     case TYPE_SCALAR:
1981       break;
1982
1983     default:
1984       gcc_unreachable ();
1985     }
1986 }
1987
1988 /* A subroutine of write_func_for_structure.  Write the enum tag for S.  */
1989
1990 static void
1991 output_type_enum (outf_p of, type_p s)
1992 {
1993   if (s->kind == TYPE_PARAM_STRUCT && s->u.s.line.file != NULL)
1994     {
1995       oprintf (of, ", gt_e_");
1996       output_mangled_typename (of, s);
1997     }
1998   else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL)
1999     {
2000       oprintf (of, ", gt_ggc_e_");
2001       output_mangled_typename (of, s);
2002     }
2003   else
2004     oprintf (of, ", gt_types_enum_last");
2005 }
2006
2007 /* For S, a structure that's part of ORIG_S, and using parameters
2008    PARAM, write out a routine that:
2009    - Takes a parameter, a void * but actually of type *S
2010    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
2011      field of S or its substructures and (in some cases) things
2012      that are pointed to by S.
2013 */
2014
2015 static void
2016 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
2017                           const struct write_types_data *wtd)
2018 {
2019   const char *fn = s->u.s.line.file;
2020   int i;
2021   const char *chain_next = NULL;
2022   const char *chain_prev = NULL;
2023   options_p opt;
2024   struct walk_type_data d;
2025
2026   /* This is a hack, and not the good kind either.  */
2027   for (i = NUM_PARAM - 1; i >= 0; i--)
2028     if (param && param[i] && param[i]->kind == TYPE_POINTER
2029         && UNION_OR_STRUCT_P (param[i]->u.p))
2030       fn = param[i]->u.p->u.s.line.file;
2031
2032   memset (&d, 0, sizeof (d));
2033   d.of = get_output_file_with_visibility (fn);
2034
2035   for (opt = s->u.s.opt; opt; opt = opt->next)
2036     if (strcmp (opt->name, "chain_next") == 0)
2037       chain_next = opt->info;
2038     else if (strcmp (opt->name, "chain_prev") == 0)
2039       chain_prev = opt->info;
2040
2041   if (chain_prev != NULL && chain_next == NULL)
2042     error_at_line (&s->u.s.line, "chain_prev without chain_next");
2043
2044   d.process_field = write_types_process_field;
2045   d.cookie = wtd;
2046   d.orig_s = orig_s;
2047   d.opt = s->u.s.opt;
2048   d.line = &s->u.s.line;
2049   d.bitmap = s->u.s.bitmap;
2050   d.param = param;
2051   d.prev_val[0] = "*x";
2052   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2053   d.prev_val[3] = "x";
2054   d.val = "(*x)";
2055
2056   oprintf (d.of, "\n");
2057   oprintf (d.of, "void\n");
2058   if (param == NULL)
2059     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2060   else
2061     {
2062       oprintf (d.of, "gt_%s_", wtd->prefix);
2063       output_mangled_typename (d.of, orig_s);
2064     }
2065   oprintf (d.of, " (void *x_p)\n");
2066   oprintf (d.of, "{\n");
2067   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2068            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2069            chain_next == NULL ? "const " : "",
2070            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2071   if (chain_next != NULL)
2072     oprintf (d.of, "  %s %s * xlimit = x;\n",
2073              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2074   if (chain_next == NULL)
2075     {
2076       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2077       if (wtd->param_prefix)
2078         {
2079           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2080           output_mangled_typename (d.of, orig_s);
2081           output_type_enum (d.of, orig_s);
2082         }
2083       oprintf (d.of, "))\n");
2084     }
2085   else
2086     {
2087       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2088       if (wtd->param_prefix)
2089         {
2090           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2091           output_mangled_typename (d.of, orig_s);
2092           output_type_enum (d.of, orig_s);
2093         }
2094       oprintf (d.of, "))\n");
2095       oprintf (d.of, "   xlimit = (");
2096       d.prev_val[2] = "*xlimit";
2097       output_escaped_param (&d, chain_next, "chain_next");
2098       oprintf (d.of, ");\n");
2099       if (chain_prev != NULL)
2100         {
2101           oprintf (d.of, "  if (x != xlimit)\n");
2102           oprintf (d.of, "    for (;;)\n");
2103           oprintf (d.of, "      {\n");
2104           oprintf (d.of, "        %s %s * const xprev = (",
2105                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2106
2107           d.prev_val[2] = "*x";
2108           output_escaped_param (&d, chain_prev, "chain_prev");
2109           oprintf (d.of, ");\n");
2110           oprintf (d.of, "        if (xprev == NULL) break;\n");
2111           oprintf (d.of, "        x = xprev;\n");
2112           oprintf (d.of, "        (void) %s (xprev",
2113                    wtd->marker_routine);
2114           if (wtd->param_prefix)
2115             {
2116               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2117               output_mangled_typename (d.of, orig_s);
2118               output_type_enum (d.of, orig_s);
2119             }
2120           oprintf (d.of, ");\n");
2121           oprintf (d.of, "      }\n");
2122         }
2123       oprintf (d.of, "  while (x != xlimit)\n");
2124     }
2125   oprintf (d.of, "    {\n");
2126
2127   d.prev_val[2] = "*x";
2128   d.indent = 6;
2129   walk_type (s, &d);
2130
2131   if (chain_next != NULL)
2132     {
2133       oprintf (d.of, "      x = (");
2134       output_escaped_param (&d, chain_next, "chain_next");
2135       oprintf (d.of, ");\n");
2136     }
2137
2138   oprintf (d.of, "    }\n");
2139   oprintf (d.of, "}\n");
2140 }
2141
2142 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2143
2144 static void
2145 write_types (type_p structures, type_p param_structs,
2146              const struct write_types_data *wtd)
2147 {
2148   type_p s;
2149
2150   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2151   for (s = structures; s; s = s->next)
2152     if (s->gc_used == GC_POINTED_TO
2153         || s->gc_used == GC_MAYBE_POINTED_TO)
2154       {
2155         options_p opt;
2156
2157         if (s->gc_used == GC_MAYBE_POINTED_TO
2158             && s->u.s.line.file == NULL)
2159           continue;
2160
2161         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2162         output_mangled_typename (header_file, s);
2163         oprintf (header_file, "(X) do { \\\n");
2164         oprintf (header_file,
2165                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2166                  s->u.s.tag);
2167         oprintf (header_file,
2168                  "  } while (0)\n");
2169
2170         for (opt = s->u.s.opt; opt; opt = opt->next)
2171           if (strcmp (opt->name, "ptr_alias") == 0)
2172             {
2173               type_p t = (type_p) opt->info;
2174               if (t->kind == TYPE_STRUCT
2175                   || t->kind == TYPE_UNION
2176                   || t->kind == TYPE_LANG_STRUCT)
2177                 oprintf (header_file,
2178                          "#define gt_%sx_%s gt_%sx_%s\n",
2179                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2180               else
2181                 error_at_line (&s->u.s.line,
2182                                "structure alias is not a structure");
2183               break;
2184             }
2185         if (opt)
2186           continue;
2187
2188         /* Declare the marker procedure only once.  */
2189         oprintf (header_file,
2190                  "extern void gt_%sx_%s (void *);\n",
2191                  wtd->prefix, s->u.s.tag);
2192
2193         if (s->u.s.line.file == NULL)
2194           {
2195             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2196                      s->u.s.tag);
2197             continue;
2198           }
2199
2200         if (s->kind == TYPE_LANG_STRUCT)
2201           {
2202             type_p ss;
2203             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2204               write_func_for_structure (s, ss, NULL, wtd);
2205           }
2206         else
2207           write_func_for_structure (s, s, NULL, wtd);
2208       }
2209
2210   for (s = param_structs; s; s = s->next)
2211     if (s->gc_used == GC_POINTED_TO)
2212       {
2213         type_p * param = s->u.param_struct.param;
2214         type_p stru = s->u.param_struct.stru;
2215
2216         /* Declare the marker procedure.  */
2217         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2218         output_mangled_typename (header_file, s);
2219         oprintf (header_file, " (void *);\n");
2220
2221         if (stru->u.s.line.file == NULL)
2222           {
2223             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2224                      s->u.s.tag);
2225             continue;
2226           }
2227
2228         if (stru->kind == TYPE_LANG_STRUCT)
2229           {
2230             type_p ss;
2231             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2232               write_func_for_structure (s, ss, param, wtd);
2233           }
2234         else
2235           write_func_for_structure (s, stru, param, wtd);
2236       }
2237 }
2238
2239 static const struct write_types_data ggc_wtd =
2240 {
2241   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2242   "GC marker procedures.  "
2243 };
2244
2245 static const struct write_types_data pch_wtd =
2246 {
2247   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2248   "gt_pch_note_reorder",
2249   "PCH type-walking procedures.  "
2250 };
2251
2252 /* Write out the local pointer-walking routines.  */
2253
2254 /* process_field routine for local pointer-walking.  */
2255
2256 static void
2257 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2258 {
2259   switch (f->kind)
2260     {
2261     case TYPE_POINTER:
2262     case TYPE_STRUCT:
2263     case TYPE_UNION:
2264     case TYPE_LANG_STRUCT:
2265     case TYPE_PARAM_STRUCT:
2266     case TYPE_STRING:
2267       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2268                d->prev_val[3]);
2269       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2270       break;
2271
2272     case TYPE_SCALAR:
2273       break;
2274
2275     default:
2276       gcc_unreachable ();
2277     }
2278 }
2279
2280 /* For S, a structure that's part of ORIG_S, and using parameters
2281    PARAM, write out a routine that:
2282    - Is of type gt_note_pointers
2283    - Calls PROCESS_FIELD on each field of S or its substructures.
2284 */
2285
2286 static void
2287 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2288 {
2289   const char *fn = s->u.s.line.file;
2290   int i;
2291   struct walk_type_data d;
2292
2293   /* This is a hack, and not the good kind either.  */
2294   for (i = NUM_PARAM - 1; i >= 0; i--)
2295     if (param && param[i] && param[i]->kind == TYPE_POINTER
2296         && UNION_OR_STRUCT_P (param[i]->u.p))
2297       fn = param[i]->u.p->u.s.line.file;
2298
2299   memset (&d, 0, sizeof (d));
2300   d.of = get_output_file_with_visibility (fn);
2301
2302   d.process_field = write_types_local_process_field;
2303   d.opt = s->u.s.opt;
2304   d.line = &s->u.s.line;
2305   d.bitmap = s->u.s.bitmap;
2306   d.param = param;
2307   d.prev_val[0] = d.prev_val[2] = "*x";
2308   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2309   d.prev_val[3] = "x";
2310   d.val = "(*x)";
2311   d.fn_wants_lvalue = true;
2312
2313   oprintf (d.of, "\n");
2314   oprintf (d.of, "void\n");
2315   oprintf (d.of, "gt_pch_p_");
2316   output_mangled_typename (d.of, orig_s);
2317   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2318            "\tvoid *x_p,\n"
2319            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2320            "\tATTRIBUTE_UNUSED void *cookie)\n");
2321   oprintf (d.of, "{\n");
2322   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2323            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2324            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2325   d.indent = 2;
2326   walk_type (s, &d);
2327   oprintf (d.of, "}\n");
2328 }
2329
2330 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2331
2332 static void
2333 write_local (type_p structures, type_p param_structs)
2334 {
2335   type_p s;
2336
2337   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2338   for (s = structures; s; s = s->next)
2339     if (s->gc_used == GC_POINTED_TO
2340         || s->gc_used == GC_MAYBE_POINTED_TO)
2341       {
2342         options_p opt;
2343
2344         if (s->u.s.line.file == NULL)
2345           continue;
2346
2347         for (opt = s->u.s.opt; opt; opt = opt->next)
2348           if (strcmp (opt->name, "ptr_alias") == 0)
2349             {
2350               type_p t = (type_p) opt->info;
2351               if (t->kind == TYPE_STRUCT
2352                   || t->kind == TYPE_UNION
2353                   || t->kind == TYPE_LANG_STRUCT)
2354                 {
2355                   oprintf (header_file, "#define gt_pch_p_");
2356                   output_mangled_typename (header_file, s);
2357                   oprintf (header_file, " gt_pch_p_");
2358                   output_mangled_typename (header_file, t);
2359                   oprintf (header_file, "\n");
2360                 }
2361               else
2362                 error_at_line (&s->u.s.line,
2363                                "structure alias is not a structure");
2364               break;
2365             }
2366         if (opt)
2367           continue;
2368
2369         /* Declare the marker procedure only once.  */
2370         oprintf (header_file, "extern void gt_pch_p_");
2371         output_mangled_typename (header_file, s);
2372         oprintf (header_file,
2373          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2374
2375         if (s->kind == TYPE_LANG_STRUCT)
2376           {
2377             type_p ss;
2378             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2379               write_local_func_for_structure (s, ss, NULL);
2380           }
2381         else
2382           write_local_func_for_structure (s, s, NULL);
2383       }
2384
2385   for (s = param_structs; s; s = s->next)
2386     if (s->gc_used == GC_POINTED_TO)
2387       {
2388         type_p * param = s->u.param_struct.param;
2389         type_p stru = s->u.param_struct.stru;
2390
2391         /* Declare the marker procedure.  */
2392         oprintf (header_file, "extern void gt_pch_p_");
2393         output_mangled_typename (header_file, s);
2394         oprintf (header_file,
2395          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2396
2397         if (stru->u.s.line.file == NULL)
2398           {
2399             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2400                      s->u.s.tag);
2401             continue;
2402           }
2403
2404         if (stru->kind == TYPE_LANG_STRUCT)
2405           {
2406             type_p ss;
2407             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2408               write_local_func_for_structure (s, ss, param);
2409           }
2410         else
2411           write_local_func_for_structure (s, stru, param);
2412       }
2413 }
2414
2415 /* Write out the 'enum' definition for gt_types_enum.  */
2416
2417 static void
2418 write_enum_defn (type_p structures, type_p param_structs)
2419 {
2420   type_p s;
2421
2422   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2423   oprintf (header_file, "enum gt_types_enum {\n");
2424   for (s = structures; s; s = s->next)
2425     if (s->gc_used == GC_POINTED_TO
2426         || s->gc_used == GC_MAYBE_POINTED_TO)
2427       {
2428         if (s->gc_used == GC_MAYBE_POINTED_TO
2429             && s->u.s.line.file == NULL)
2430           continue;
2431
2432         oprintf (header_file, " gt_ggc_e_");
2433         output_mangled_typename (header_file, s);
2434         oprintf (header_file, ", \n");
2435       }
2436   for (s = param_structs; s; s = s->next)
2437     if (s->gc_used == GC_POINTED_TO)
2438       {
2439         oprintf (header_file, " gt_e_");
2440         output_mangled_typename (header_file, s);
2441         oprintf (header_file, ", \n");
2442       }
2443   oprintf (header_file, " gt_types_enum_last\n");
2444   oprintf (header_file, "};\n");
2445 }
2446
2447 /* Might T contain any non-pointer elements?  */
2448
2449 static int
2450 contains_scalar_p (type_p t)
2451 {
2452   switch (t->kind)
2453     {
2454     case TYPE_STRING:
2455     case TYPE_POINTER:
2456       return 0;
2457     case TYPE_ARRAY:
2458       return contains_scalar_p (t->u.a.p);
2459     default:
2460       /* Could also check for structures that have no non-pointer
2461          fields, but there aren't enough of those to worry about.  */
2462       return 1;
2463     }
2464 }
2465
2466 /* Mangle FN and print it to F.  */
2467
2468 static void
2469 put_mangled_filename (outf_p f, const char *fn)
2470 {
2471   const char *name = get_output_file_name (fn);
2472   for (; *name != 0; name++)
2473     if (ISALNUM (*name))
2474       oprintf (f, "%c", *name);
2475     else
2476       oprintf (f, "%c", '_');
2477 }
2478
2479 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2480    LASTNAME, and NAME are all strings to insert in various places in
2481    the resulting code.  */
2482
2483 static void
2484 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2485                    const char *tname, const char *name)
2486 {
2487   struct flist *fli2;
2488
2489   for (fli2 = flp; fli2; fli2 = fli2->next)
2490     if (fli2->started_p)
2491       {
2492         oprintf (fli2->f, "  %s\n", lastname);
2493         oprintf (fli2->f, "};\n\n");
2494       }
2495
2496   for (fli2 = flp; fli2; fli2 = fli2->next)
2497     if (fli2->started_p)
2498       {
2499         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2500         int fnum;
2501
2502         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2503           if (bitmap & 1)
2504             {
2505               oprintf (base_files[fnum],
2506                        "extern const struct %s gt_%s_",
2507                        tname, pfx);
2508               put_mangled_filename (base_files[fnum], fli2->name);
2509               oprintf (base_files[fnum], "[];\n");
2510             }
2511       }
2512
2513   {
2514     size_t fnum;
2515     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2516       oprintf (base_files [fnum],
2517                "const struct %s * const %s[] = {\n",
2518                tname, name);
2519   }
2520
2521
2522   for (fli2 = flp; fli2; fli2 = fli2->next)
2523     if (fli2->started_p)
2524       {
2525         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2526         int fnum;
2527
2528         fli2->started_p = 0;
2529
2530         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2531           if (bitmap & 1)
2532             {
2533               oprintf (base_files[fnum], "  gt_%s_", pfx);
2534               put_mangled_filename (base_files[fnum], fli2->name);
2535               oprintf (base_files[fnum], ",\n");
2536             }
2537       }
2538
2539   {
2540     size_t fnum;
2541     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2542       {
2543         oprintf (base_files[fnum], "  NULL\n");
2544         oprintf (base_files[fnum], "};\n");
2545       }
2546   }
2547 }
2548
2549 /* Write out to F the table entry and any marker routines needed to
2550    mark NAME as TYPE.  The original variable is V, at LINE.
2551    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2552    is nonzero iff we are building the root table for hash table caches.  */
2553
2554 static void
2555 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2556             struct fileloc *line, const char *if_marked)
2557 {
2558   switch (type->kind)
2559     {
2560     case TYPE_STRUCT:
2561       {
2562         pair_p fld;
2563         for (fld = type->u.s.fields; fld; fld = fld->next)
2564           {
2565             int skip_p = 0;
2566             const char *desc = NULL;
2567             options_p o;
2568
2569             for (o = fld->opt; o; o = o->next)
2570               if (strcmp (o->name, "skip") == 0)
2571                 skip_p = 1;
2572               else if (strcmp (o->name, "desc") == 0)
2573                 desc = o->info;
2574               else
2575                 error_at_line (line,
2576                        "field `%s' of global `%s' has unknown option `%s'",
2577                                fld->name, name, o->name);
2578
2579             if (skip_p)
2580               continue;
2581             else if (desc && fld->type->kind == TYPE_UNION)
2582               {
2583                 pair_p validf = NULL;
2584                 pair_p ufld;
2585
2586                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2587                   {
2588                     const char *tag = NULL;
2589                     options_p oo;
2590
2591                     for (oo = ufld->opt; oo; oo = oo->next)
2592                       if (strcmp (oo->name, "tag") == 0)
2593                         tag = oo->info;
2594                     if (tag == NULL || strcmp (tag, desc) != 0)
2595                       continue;
2596                     if (validf != NULL)
2597                       error_at_line (line,
2598                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2599                                      name, fld->name, validf->name,
2600                                      name, fld->name, ufld->name,
2601                                      tag);
2602                     validf = ufld;
2603                   }
2604                 if (validf != NULL)
2605                   {
2606                     char *newname;
2607                     newname = xasprintf ("%s.%s.%s",
2608                                          name, fld->name, validf->name);
2609                     write_root (f, v, validf->type, newname, 0, line,
2610                                 if_marked);
2611                     free (newname);
2612                   }
2613               }
2614             else if (desc)
2615               error_at_line (line,
2616                      "global `%s.%s' has `desc' option but is not union",
2617                              name, fld->name);
2618             else
2619               {
2620                 char *newname;
2621                 newname = xasprintf ("%s.%s", name, fld->name);
2622                 write_root (f, v, fld->type, newname, 0, line, if_marked);
2623                 free (newname);
2624               }
2625           }
2626       }
2627       break;
2628
2629     case TYPE_ARRAY:
2630       {
2631         char *newname;
2632         newname = xasprintf ("%s[0]", name);
2633         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2634         free (newname);
2635       }
2636       break;
2637
2638     case TYPE_POINTER:
2639       {
2640         type_p ap, tp;
2641
2642         oprintf (f, "  {\n");
2643         oprintf (f, "    &%s,\n", name);
2644         oprintf (f, "    1");
2645
2646         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2647           if (ap->u.a.len[0])
2648             oprintf (f, " * (%s)", ap->u.a.len);
2649           else if (ap == v->type)
2650             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2651         oprintf (f, ",\n");
2652         oprintf (f, "    sizeof (%s", v->name);
2653         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2654           oprintf (f, "[0]");
2655         oprintf (f, "),\n");
2656
2657         tp = type->u.p;
2658
2659         if (! has_length && UNION_OR_STRUCT_P (tp))
2660           {
2661             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
2662             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
2663           }
2664         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2665           {
2666             oprintf (f, "    &gt_ggc_m_");
2667             output_mangled_typename (f, tp);
2668             oprintf (f, ",\n    &gt_pch_n_");
2669             output_mangled_typename (f, tp);
2670           }
2671         else if (has_length
2672                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2673           {
2674             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
2675             oprintf (f, "    &gt_pch_na_%s", name);
2676           }
2677         else
2678           {
2679             error_at_line (line,
2680                            "global `%s' is pointer to unimplemented type",
2681                            name);
2682           }
2683         if (if_marked)
2684           oprintf (f, ",\n    &%s", if_marked);
2685         oprintf (f, "\n  },\n");
2686       }
2687       break;
2688
2689     case TYPE_STRING:
2690       {
2691         oprintf (f, "  {\n");
2692         oprintf (f, "    &%s,\n", name);
2693         oprintf (f, "    1, \n");
2694         oprintf (f, "    sizeof (%s),\n", v->name);
2695         oprintf (f, "    &gt_ggc_m_S,\n");
2696         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
2697         oprintf (f, "  },\n");
2698       }
2699       break;
2700
2701     case TYPE_SCALAR:
2702       break;
2703
2704     default:
2705       error_at_line (line,
2706                      "global `%s' is unimplemented type",
2707                      name);
2708     }
2709 }
2710
2711 /* This generates a routine to walk an array.  */
2712
2713 static void
2714 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2715 {
2716   struct walk_type_data d;
2717   char *prevval3;
2718
2719   memset (&d, 0, sizeof (d));
2720   d.of = f;
2721   d.cookie = wtd;
2722   d.indent = 2;
2723   d.line = &v->line;
2724   d.opt = v->opt;
2725   d.bitmap = get_base_file_bitmap (v->line.file);
2726   d.param = NULL;
2727
2728   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2729
2730   if (wtd->param_prefix)
2731     {
2732       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2733       oprintf (f,
2734        "    (void *, void *, gt_pointer_operator, void *);\n");
2735       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2736                wtd->param_prefix, v->name);
2737       oprintf (d.of,
2738                "      ATTRIBUTE_UNUSED void *x_p,\n"
2739                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2740                "      ATTRIBUTE_UNUSED void * cookie)\n");
2741       oprintf (d.of, "{\n");
2742       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2743       d.process_field = write_types_local_process_field;
2744       walk_type (v->type, &d);
2745       oprintf (f, "}\n\n");
2746     }
2747
2748   d.opt = v->opt;
2749   oprintf (f, "static void gt_%sa_%s (void *);\n",
2750            wtd->prefix, v->name);
2751   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2752            wtd->prefix, v->name);
2753   oprintf (f, "{\n");
2754   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2755   d.process_field = write_types_process_field;
2756   walk_type (v->type, &d);
2757   free (prevval3);
2758   oprintf (f, "}\n\n");
2759 }
2760
2761 /* Output a table describing the locations and types of VARIABLES.  */
2762
2763 static void
2764 write_roots (pair_p variables)
2765 {
2766   pair_p v;
2767   struct flist *flp = NULL;
2768
2769   for (v = variables; v; v = v->next)
2770     {
2771       outf_p f = get_output_file_with_visibility (v->line.file);
2772       struct flist *fli;
2773       const char *length = NULL;
2774       int deletable_p = 0;
2775       options_p o;
2776
2777       for (o = v->opt; o; o = o->next)
2778         if (strcmp (o->name, "length") == 0)
2779           length = o->info;
2780         else if (strcmp (o->name, "deletable") == 0)
2781           deletable_p = 1;
2782         else if (strcmp (o->name, "param_is") == 0)
2783           ;
2784         else if (strncmp (o->name, "param", 5) == 0
2785                  && ISDIGIT (o->name[5])
2786                  && strcmp (o->name + 6, "_is") == 0)
2787           ;
2788         else if (strcmp (o->name, "if_marked") == 0)
2789           ;
2790         else
2791           error_at_line (&v->line,
2792                          "global `%s' has unknown option `%s'",
2793                          v->name, o->name);
2794
2795       for (fli = flp; fli; fli = fli->next)
2796         if (fli->f == f)
2797           break;
2798       if (fli == NULL)
2799         {
2800           fli = XNEW (struct flist);
2801           fli->f = f;
2802           fli->next = flp;
2803           fli->started_p = 0;
2804           fli->name = v->line.file;
2805           flp = fli;
2806
2807           oprintf (f, "\n/* GC roots.  */\n\n");
2808         }
2809
2810       if (! deletable_p
2811           && length
2812           && v->type->kind == TYPE_POINTER
2813           && (v->type->u.p->kind == TYPE_POINTER
2814               || v->type->u.p->kind == TYPE_STRUCT))
2815         {
2816           write_array (f, v, &ggc_wtd);
2817           write_array (f, v, &pch_wtd);
2818         }
2819     }
2820
2821   for (v = variables; v; v = v->next)
2822     {
2823       outf_p f = get_output_file_with_visibility (v->line.file);
2824       struct flist *fli;
2825       int skip_p = 0;
2826       int length_p = 0;
2827       options_p o;
2828
2829       for (o = v->opt; o; o = o->next)
2830         if (strcmp (o->name, "length") == 0)
2831           length_p = 1;
2832         else if (strcmp (o->name, "deletable") == 0
2833                  || strcmp (o->name, "if_marked") == 0)
2834           skip_p = 1;
2835
2836       if (skip_p)
2837         continue;
2838
2839       for (fli = flp; fli; fli = fli->next)
2840         if (fli->f == f)
2841           break;
2842       if (! fli->started_p)
2843         {
2844           fli->started_p = 1;
2845
2846           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2847           put_mangled_filename (f, v->line.file);
2848           oprintf (f, "[] = {\n");
2849         }
2850
2851       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2852     }
2853
2854   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2855                      "gt_ggc_rtab");
2856
2857   for (v = variables; v; v = v->next)
2858     {
2859       outf_p f = get_output_file_with_visibility (v->line.file);
2860       struct flist *fli;
2861       int skip_p = 1;
2862       options_p o;
2863
2864       for (o = v->opt; o; o = o->next)
2865         if (strcmp (o->name, "deletable") == 0)
2866           skip_p = 0;
2867         else if (strcmp (o->name, "if_marked") == 0)
2868           skip_p = 1;
2869
2870       if (skip_p)
2871         continue;
2872
2873       for (fli = flp; fli; fli = fli->next)
2874         if (fli->f == f)
2875           break;
2876       if (! fli->started_p)
2877         {
2878           fli->started_p = 1;
2879
2880           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2881           put_mangled_filename (f, v->line.file);
2882           oprintf (f, "[] = {\n");
2883         }
2884
2885       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2886                v->name, v->name);
2887     }
2888
2889   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2890                      "gt_ggc_deletable_rtab");
2891
2892   for (v = variables; v; v = v->next)
2893     {
2894       outf_p f = get_output_file_with_visibility (v->line.file);
2895       struct flist *fli;
2896       const char *if_marked = NULL;
2897       int length_p = 0;
2898       options_p o;
2899
2900       for (o = v->opt; o; o = o->next)
2901         if (strcmp (o->name, "length") == 0)
2902           length_p = 1;
2903         else if (strcmp (o->name, "if_marked") == 0)
2904           if_marked = o->info;
2905
2906       if (if_marked == NULL)
2907         continue;
2908
2909       if (v->type->kind != TYPE_POINTER
2910           || v->type->u.p->kind != TYPE_PARAM_STRUCT
2911           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2912         {
2913           error_at_line (&v->line, "if_marked option used but not hash table");
2914           continue;
2915         }
2916
2917       for (fli = flp; fli; fli = fli->next)
2918         if (fli->f == f)
2919           break;
2920       if (! fli->started_p)
2921         {
2922           fli->started_p = 1;
2923
2924           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2925           put_mangled_filename (f, v->line.file);
2926           oprintf (f, "[] = {\n");
2927         }
2928
2929       write_root (f, v, v->type->u.p->u.param_struct.param[0],
2930                      v->name, length_p, &v->line, if_marked);
2931     }
2932
2933   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2934                      "gt_ggc_cache_rtab");
2935
2936   for (v = variables; v; v = v->next)
2937     {
2938       outf_p f = get_output_file_with_visibility (v->line.file);
2939       struct flist *fli;
2940       int length_p = 0;
2941       int if_marked_p = 0;
2942       options_p o;
2943
2944       for (o = v->opt; o; o = o->next)
2945         if (strcmp (o->name, "length") == 0)
2946           length_p = 1;
2947         else if (strcmp (o->name, "if_marked") == 0)
2948           if_marked_p = 1;
2949
2950       if (! if_marked_p)
2951         continue;
2952
2953       for (fli = flp; fli; fli = fli->next)
2954         if (fli->f == f)
2955           break;
2956       if (! fli->started_p)
2957         {
2958           fli->started_p = 1;
2959
2960           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2961           put_mangled_filename (f, v->line.file);
2962           oprintf (f, "[] = {\n");
2963         }
2964
2965       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2966     }
2967
2968   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2969                      "gt_pch_cache_rtab");
2970
2971   for (v = variables; v; v = v->next)
2972     {
2973       outf_p f = get_output_file_with_visibility (v->line.file);
2974       struct flist *fli;
2975       int skip_p = 0;
2976       options_p o;
2977
2978       for (o = v->opt; o; o = o->next)
2979         if (strcmp (o->name, "deletable") == 0
2980             || strcmp (o->name, "if_marked") == 0)
2981           skip_p = 1;
2982
2983       if (skip_p)
2984         continue;
2985
2986       if (! contains_scalar_p (v->type))
2987         continue;
2988
2989       for (fli = flp; fli; fli = fli->next)
2990         if (fli->f == f)
2991           break;
2992       if (! fli->started_p)
2993         {
2994           fli->started_p = 1;
2995
2996           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2997           put_mangled_filename (f, v->line.file);
2998           oprintf (f, "[] = {\n");
2999         }
3000
3001       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
3002                v->name, v->name);
3003     }
3004
3005   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
3006                      "gt_pch_scalar_rtab");
3007 }
3008
3009 \f
3010 extern int main (int argc, char **argv);
3011 int
3012 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
3013 {
3014   unsigned i;
3015   static struct fileloc pos = { __FILE__, __LINE__ };
3016   unsigned j;
3017
3018   gen_rtx_next ();
3019
3020   srcdir_len = strlen (srcdir);
3021
3022   do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
3023   do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
3024   do_scalar_typedef ("uint8", &pos);
3025   do_scalar_typedef ("jword", &pos);
3026   do_scalar_typedef ("JCF_u2", &pos);
3027 #ifdef USE_MAPPED_LOCATION
3028   do_scalar_typedef ("location_t", &pos);
3029   do_scalar_typedef ("source_locus", &pos);
3030 #endif
3031   do_scalar_typedef ("void", &pos);
3032
3033   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
3034
3035   do_typedef ("HARD_REG_SET", create_array (
3036               create_scalar_type ("unsigned long", strlen ("unsigned long")),
3037               "2"), &pos);
3038
3039   for (i = 0; i < NUM_GT_FILES; i++)
3040     {
3041       int dupflag = 0;
3042       /* Omit if already seen.  */
3043       for (j = 0; j < i; j++)
3044         {
3045           if (!strcmp (all_files[i], all_files[j]))
3046             {
3047               dupflag = 1;
3048               break;
3049             }
3050         }
3051       if (!dupflag)
3052         parse_file (all_files[i]);
3053 #ifndef USE_MAPPED_LOCATION
3054       /* temporary kludge - gengtype doesn't handle conditionals.
3055          Manually add source_locus *after* we've processed input.h.  */
3056       if (i == 0)
3057         do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3058 #endif
3059     }
3060
3061   if (hit_error != 0)
3062     exit (1);
3063
3064   set_gc_used (variables);
3065
3066   open_base_files ();
3067   write_enum_defn (structures, param_structs);
3068   write_types (structures, param_structs, &ggc_wtd);
3069   write_types (structures, param_structs, &pch_wtd);
3070   write_local (structures, param_structs);
3071   write_roots (variables);
3072   write_rtx_next ();
3073   close_output_files ();
3074
3075   return (hit_error != 0);
3076 }