OSDN Git Service

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