OSDN Git Service

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