OSDN Git Service

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