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