OSDN Git Service

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