OSDN Git Service

* config/sh/sh.c (sh_output_mi_thunk): Initialize bitmap obstacks
[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",  "obstack.h", "bitmap.h", "input.h",
1085       "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
1086       "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
1087       "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
1088       "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
1089       NULL
1090     };
1091     const char *const *ifp;
1092     outf_p gtype_desc_c;
1093
1094     gtype_desc_c = create_file ("GCC", "gtype-desc.c");
1095     for (ifp = ifiles; *ifp; ifp++)
1096       oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
1097   }
1098 }
1099
1100 /* Determine the pathname to F relative to $(srcdir).  */
1101
1102 static const char *
1103 get_file_basename (const char *f)
1104 {
1105   const char *basename;
1106   unsigned i;
1107
1108   basename = strrchr (f, '/');
1109
1110   if (!basename)
1111     return f;
1112
1113   basename++;
1114
1115   for (i = 1; i < NUM_BASE_FILES; i++)
1116     {
1117       const char * s1;
1118       const char * s2;
1119       int l1;
1120       int l2;
1121       s1 = basename - strlen (lang_dir_names [i]) - 1;
1122       s2 = lang_dir_names [i];
1123       l1 = strlen (s1);
1124       l2 = strlen (s2);
1125       if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
1126         {
1127           basename -= l2 + 1;
1128           if ((basename - f - 1) != srcdir_len)
1129             fatal ("filename `%s' should be preceded by $srcdir", f);
1130           break;
1131         }
1132     }
1133
1134   return basename;
1135 }
1136
1137 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
1138    INPUT_FILE is used by <lang>.
1139
1140    This function should be written to assume that a file _is_ used
1141    if the situation is unclear.  If it wrongly assumes a file _is_ used,
1142    a linker error will result.  If it wrongly assumes a file _is not_ used,
1143    some GC roots may be missed, which is a much harder-to-debug problem.  */
1144
1145 unsigned
1146 get_base_file_bitmap (const char *input_file)
1147 {
1148   const char *basename = get_file_basename (input_file);
1149   const char *slashpos = strchr (basename, '/');
1150   unsigned j;
1151   unsigned k;
1152   unsigned bitmap;
1153
1154   /* If the file resides in a language subdirectory (e.g., 'cp'), assume that
1155      it belongs to the corresponding language.  The file may belong to other
1156      languages as well (which is checked for below).  */
1157
1158   if (slashpos)
1159     {
1160       size_t i;
1161       for (i = 1; i < NUM_BASE_FILES; i++)
1162         if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
1163             && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
1164           {
1165             /* It's in a language directory, set that language.  */
1166             bitmap = 1 << i;
1167           }
1168     }
1169
1170   /* If it's in any config-lang.in, then set for the languages
1171      specified.  */
1172
1173   bitmap = 0;
1174
1175   for (j = 0; j < NUM_LANG_FILES; j++)
1176     {
1177       if (!strcmp(input_file, lang_files[j]))
1178         {
1179           for (k = 0; k < NUM_BASE_FILES; k++)
1180             {
1181               if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
1182                 bitmap |= (1 << k);
1183             }
1184         }
1185     }
1186
1187   /* Otherwise, set all languages.  */
1188   if (!bitmap)
1189     bitmap = (1 << NUM_BASE_FILES) - 1;
1190
1191   return bitmap;
1192 }
1193
1194 /* An output file, suitable for definitions, that can see declarations
1195    made in INPUT_FILE and is linked into every language that uses
1196    INPUT_FILE.  */
1197
1198 outf_p
1199 get_output_file_with_visibility (const char *input_file)
1200 {
1201   outf_p r;
1202   size_t len;
1203   const char *basename;
1204   const char *for_name;
1205   const char *output_name;
1206
1207   /* This can happen when we need a file with visibility on a
1208      structure that we've never seen.  We have to just hope that it's
1209      globally visible.  */
1210   if (input_file == NULL)
1211     input_file = "system.h";
1212
1213   /* Determine the output file name.  */
1214   basename = get_file_basename (input_file);
1215
1216   len = strlen (basename);
1217   if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
1218       || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
1219       || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
1220     {
1221       char *s;
1222
1223       output_name = s = xasprintf ("gt-%s", basename);
1224       for (; *s != '.'; s++)
1225         if (! ISALNUM (*s) && *s != '-')
1226           *s = '-';
1227       memcpy (s, ".h", sizeof (".h"));
1228       for_name = basename;
1229     }
1230   /* Some headers get used by more than one front-end; hence, it
1231      would be inappropriate to spew them out to a single gtype-<lang>.h
1232      (and gengtype doesn't know how to direct spewage into multiple
1233      gtype-<lang>.h headers at this time).  Instead, we pair up these
1234      headers with source files (and their special purpose gt-*.h headers).  */
1235   else if (strcmp (basename, "c-common.h") == 0)
1236     output_name = "gt-c-common.h", for_name = "c-common.c";
1237   else if (strcmp (basename, "c-tree.h") == 0)
1238     output_name = "gt-c-decl.h", for_name = "c-decl.c";
1239   else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
1240            && strcmp (basename + 5, "objc-act.h") == 0)
1241     output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
1242   else 
1243     {
1244       size_t i;
1245
1246       for (i = 0; i < NUM_BASE_FILES; i++)
1247         if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
1248             && basename[strlen(lang_dir_names[i])] == '/')
1249           return base_files[i];
1250
1251       output_name = "gtype-desc.c";
1252       for_name = NULL;
1253     }
1254
1255   /* Look through to see if we've ever seen this output filename before.  */
1256   for (r = output_files; r; r = r->next)
1257     if (strcmp (r->name, output_name) == 0)
1258       return r;
1259
1260   /* If not, create it.  */
1261   r = create_file (for_name, output_name);
1262
1263   return r;
1264 }
1265
1266 /* The name of an output file, suitable for definitions, that can see
1267    declarations made in INPUT_FILE and is linked into every language
1268    that uses INPUT_FILE.  */
1269
1270 const char *
1271 get_output_file_name (const char *input_file)
1272 {
1273   return get_output_file_with_visibility (input_file)->name;
1274 }
1275
1276 /* Copy the output to its final destination,
1277    but don't unnecessarily change modification times.  */
1278
1279 static void
1280 close_output_files (void)
1281 {
1282   outf_p of;
1283
1284   for (of = output_files; of; of = of->next)
1285     {
1286       FILE * newfile;
1287
1288       newfile = fopen (of->name, "r");
1289       if (newfile != NULL )
1290         {
1291           int no_write_p;
1292           size_t i;
1293
1294           for (i = 0; i < of->bufused; i++)
1295             {
1296               int ch;
1297               ch = fgetc (newfile);
1298               if (ch == EOF || ch != (unsigned char) of->buf[i])
1299                 break;
1300             }
1301           no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1302           fclose (newfile);
1303
1304           if (no_write_p)
1305             continue;
1306         }
1307
1308       newfile = fopen (of->name, "w");
1309       if (newfile == NULL)
1310         {
1311           perror ("opening output file");
1312           exit (1);
1313         }
1314       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1315         {
1316           perror ("writing output file");
1317           exit (1);
1318         }
1319       if (fclose (newfile) != 0)
1320         {
1321           perror ("closing output file");
1322           exit (1);
1323         }
1324     }
1325 }
1326 \f
1327 struct flist {
1328   struct flist *next;
1329   int started_p;
1330   const char *name;
1331   outf_p f;
1332 };
1333
1334 struct walk_type_data;
1335
1336 /* For scalars and strings, given the item in 'val'.
1337    For structures, given a pointer to the item in 'val'.
1338    For misc. pointers, given the item in 'val'.
1339 */
1340 typedef void (*process_field_fn)
1341      (type_p f, const struct walk_type_data *p);
1342 typedef void (*func_name_fn)
1343      (type_p s, const struct walk_type_data *p);
1344
1345 /* Parameters for write_types.  */
1346
1347 struct write_types_data
1348 {
1349   const char *prefix;
1350   const char *param_prefix;
1351   const char *subfield_marker_routine;
1352   const char *marker_routine;
1353   const char *reorder_note_routine;
1354   const char *comment;
1355 };
1356
1357 static void output_escaped_param (struct walk_type_data *d,
1358                                   const char *, const char *);
1359 static void output_mangled_typename (outf_p, type_p);
1360 static void walk_type (type_p t, struct walk_type_data *d);
1361 static void write_func_for_structure
1362      (type_p orig_s, type_p s, type_p * param,
1363       const struct write_types_data *wtd);
1364 static void write_types_process_field
1365      (type_p f, const struct walk_type_data *d);
1366 static void write_types (type_p structures,
1367                          type_p param_structs,
1368                          const struct write_types_data *wtd);
1369 static void write_types_local_process_field
1370      (type_p f, const struct walk_type_data *d);
1371 static void write_local_func_for_structure
1372      (type_p orig_s, type_p s, type_p * param);
1373 static void write_local (type_p structures,
1374                          type_p param_structs);
1375 static void write_enum_defn (type_p structures, type_p param_structs);
1376 static int contains_scalar_p (type_p t);
1377 static void put_mangled_filename (outf_p , const char *);
1378 static void finish_root_table (struct flist *flp, const char *pfx,
1379                                const char *tname, const char *lastname,
1380                                const char *name);
1381 static void write_root (outf_p , pair_p, type_p, const char *, int,
1382                         struct fileloc *, const char *);
1383 static void write_array (outf_p f, pair_p v,
1384                          const struct write_types_data *wtd);
1385 static void write_roots (pair_p);
1386
1387 /* Parameters for walk_type.  */
1388
1389 struct walk_type_data
1390 {
1391   process_field_fn process_field;
1392   const void *cookie;
1393   outf_p of;
1394   options_p opt;
1395   const char *val;
1396   const char *prev_val[4];
1397   int indent;
1398   int counter;
1399   struct fileloc *line;
1400   lang_bitmap bitmap;
1401   type_p *param;
1402   int used_length;
1403   type_p orig_s;
1404   const char *reorder_fn;
1405   bool needs_cast_p;
1406   bool fn_wants_lvalue;
1407 };
1408
1409 /* Print a mangled name representing T to OF.  */
1410
1411 static void
1412 output_mangled_typename (outf_p of, type_p t)
1413 {
1414   if (t == NULL)
1415     oprintf (of, "Z");
1416   else switch (t->kind)
1417     {
1418     case TYPE_POINTER:
1419       oprintf (of, "P");
1420       output_mangled_typename (of, t->u.p);
1421       break;
1422     case TYPE_SCALAR:
1423       oprintf (of, "I");
1424       break;
1425     case TYPE_STRING:
1426       oprintf (of, "S");
1427       break;
1428     case TYPE_STRUCT:
1429     case TYPE_UNION:
1430     case TYPE_LANG_STRUCT:
1431       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1432       break;
1433     case TYPE_PARAM_STRUCT:
1434       {
1435         int i;
1436         for (i = 0; i < NUM_PARAM; i++)
1437           if (t->u.param_struct.param[i] != NULL)
1438             output_mangled_typename (of, t->u.param_struct.param[i]);
1439         output_mangled_typename (of, t->u.param_struct.stru);
1440       }
1441       break;
1442     case TYPE_ARRAY:
1443       gcc_unreachable ();
1444     }
1445 }
1446
1447 /* Print PARAM to D->OF processing escapes.  D->VAL references the
1448    current object, D->PREV_VAL the object containing the current
1449    object, ONAME is the name of the option and D->LINE is used to
1450    print error messages.  */
1451
1452 static void
1453 output_escaped_param (struct walk_type_data *d, const char *param,
1454                       const char *oname)
1455 {
1456   const char *p;
1457
1458   for (p = param; *p; p++)
1459     if (*p != '%')
1460       oprintf (d->of, "%c", *p);
1461     else switch (*++p)
1462       {
1463       case 'h':
1464         oprintf (d->of, "(%s)", d->prev_val[2]);
1465         break;
1466       case '0':
1467         oprintf (d->of, "(%s)", d->prev_val[0]);
1468         break;
1469       case '1':
1470         oprintf (d->of, "(%s)", d->prev_val[1]);
1471         break;
1472       case 'a':
1473         {
1474           const char *pp = d->val + strlen (d->val);
1475           while (pp[-1] == ']')
1476             while (*pp != '[')
1477               pp--;
1478           oprintf (d->of, "%s", pp);
1479         }
1480         break;
1481       default:
1482         error_at_line (d->line, "`%s' option contains bad escape %c%c",
1483                        oname, '%', *p);
1484       }
1485 }
1486
1487 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1488    which is of type T.  Write code to D->OF to constrain execution (at
1489    the point that D->PROCESS_FIELD is called) to the appropriate
1490    cases.  Call D->PROCESS_FIELD on subobjects before calling it on
1491    pointers to those objects.  D->PREV_VAL lists the objects
1492    containing the current object, D->OPT is a list of options to
1493    apply, D->INDENT is the current indentation level, D->LINE is used
1494    to print error messages, D->BITMAP indicates which languages to
1495    print the structure for, and D->PARAM is the current parameter
1496    (from an enclosing param_is option).  */
1497
1498 static void
1499 walk_type (type_p t, struct walk_type_data *d)
1500 {
1501   const char *length = NULL;
1502   const char *desc = NULL;
1503   int maybe_undef_p = 0;
1504   int use_param_num = -1;
1505   int use_params_p = 0;
1506   options_p oo;
1507   const struct nested_ptr_data *nested_ptr_d = NULL;
1508
1509   d->needs_cast_p = false;
1510   for (oo = d->opt; oo; oo = oo->next)
1511     if (strcmp (oo->name, "length") == 0)
1512       length = oo->info;
1513     else if (strcmp (oo->name, "maybe_undef") == 0)
1514       maybe_undef_p = 1;
1515     else if (strncmp (oo->name, "use_param", 9) == 0
1516              && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1517       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1518     else if (strcmp (oo->name, "use_params") == 0)
1519       use_params_p = 1;
1520     else if (strcmp (oo->name, "desc") == 0)
1521       desc = oo->info;
1522     else if (strcmp (oo->name, "nested_ptr") == 0)
1523       nested_ptr_d = (const struct nested_ptr_data *) oo->info;
1524     else if (strcmp (oo->name, "dot") == 0)
1525       ;
1526     else if (strcmp (oo->name, "tag") == 0)
1527       ;
1528     else if (strcmp (oo->name, "special") == 0)
1529       ;
1530     else if (strcmp (oo->name, "skip") == 0)
1531       ;
1532     else if (strcmp (oo->name, "default") == 0)
1533       ;
1534     else if (strcmp (oo->name, "descbits") == 0)
1535       ;
1536     else if (strcmp (oo->name, "param_is") == 0)
1537       ;
1538     else if (strncmp (oo->name, "param", 5) == 0
1539              && ISDIGIT (oo->name[5])
1540              && strcmp (oo->name + 6, "_is") == 0)
1541       ;
1542     else if (strcmp (oo->name, "chain_next") == 0)
1543       ;
1544     else if (strcmp (oo->name, "chain_prev") == 0)
1545       ;
1546     else if (strcmp (oo->name, "reorder") == 0)
1547       ;
1548     else
1549       error_at_line (d->line, "unknown option `%s'\n", oo->name);
1550
1551   if (d->used_length)
1552     length = NULL;
1553
1554   if (use_params_p)
1555     {
1556       int pointer_p = t->kind == TYPE_POINTER;
1557
1558       if (pointer_p)
1559         t = t->u.p;
1560       if (! UNION_OR_STRUCT_P (t))
1561         error_at_line (d->line, "`use_params' option on unimplemented type");
1562       else
1563         t = find_param_structure (t, d->param);
1564       if (pointer_p)
1565         t = create_pointer (t);
1566     }
1567
1568   if (use_param_num != -1)
1569     {
1570       if (d->param != NULL && d->param[use_param_num] != NULL)
1571         {
1572           type_p nt = d->param[use_param_num];
1573
1574           if (t->kind == TYPE_ARRAY)
1575             nt = create_array (nt, t->u.a.len);
1576           else if (length != NULL && t->kind == TYPE_POINTER)
1577             nt = create_pointer (nt);
1578           d->needs_cast_p = (t->kind != TYPE_POINTER
1579                              && (nt->kind == TYPE_POINTER
1580                                  || nt->kind == TYPE_STRING));
1581           t = nt;
1582         }
1583       else
1584         error_at_line (d->line, "no parameter defined for `%s'",
1585                        d->val);
1586     }
1587
1588   if (maybe_undef_p
1589       && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1590     {
1591       error_at_line (d->line,
1592                      "field `%s' has invalid option `maybe_undef_p'\n",
1593                      d->val);
1594       return;
1595     }
1596
1597   switch (t->kind)
1598     {
1599     case TYPE_SCALAR:
1600     case TYPE_STRING:
1601       d->process_field (t, d);
1602       break;
1603
1604     case TYPE_POINTER:
1605       {
1606         if (maybe_undef_p
1607             && t->u.p->u.s.line.file == NULL)
1608           {
1609             oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
1610             break;
1611           }
1612
1613         if (! length)
1614           {
1615             if (! UNION_OR_STRUCT_P (t->u.p)
1616                 && t->u.p->kind != TYPE_PARAM_STRUCT)
1617               {
1618                 error_at_line (d->line,
1619                                "field `%s' is pointer to unimplemented type",
1620                                d->val);
1621                 break;
1622               }
1623
1624             if (nested_ptr_d)
1625               {
1626                 const char *oldprevval2 = d->prev_val[2];
1627
1628                 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
1629                   {
1630                     error_at_line (d->line,
1631                                    "field `%s' has invalid "
1632                                    "option `nested_ptr'\n",
1633                                    d->val);
1634                     return;
1635                   }
1636
1637                 d->prev_val[2] = d->val;
1638                 oprintf (d->of, "%*s{\n", d->indent, "");
1639                 d->indent += 2;
1640                 d->val = xasprintf ("x%d", d->counter++);
1641                 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
1642                          (nested_ptr_d->type->kind == TYPE_UNION 
1643                           ? "union" : "struct"), 
1644                          nested_ptr_d->type->u.s.tag, 
1645                          d->fn_wants_lvalue ? "" : "const ",
1646                          d->val);
1647                 oprintf (d->of, "%*s", d->indent + 2, "");
1648                 output_escaped_param (d, nested_ptr_d->convert_from,
1649                                       "nested_ptr");
1650                 oprintf (d->of, ";\n");
1651
1652                 d->process_field (nested_ptr_d->type, d);
1653
1654                 if (d->fn_wants_lvalue)
1655                   {
1656                     oprintf (d->of, "%*s%s = ", d->indent, "",
1657                              d->prev_val[2]);
1658                     d->prev_val[2] = d->val;
1659                     output_escaped_param (d, nested_ptr_d->convert_to,
1660                                           "nested_ptr");
1661                     oprintf (d->of, ";\n");
1662                   }
1663
1664                 d->indent -= 2;
1665                 oprintf (d->of, "%*s}\n", d->indent, "");
1666                 d->val = d->prev_val[2];
1667                 d->prev_val[2] = oldprevval2;
1668               }
1669             else
1670               d->process_field (t->u.p, d);
1671           }
1672         else
1673           {
1674             int loopcounter = d->counter++;
1675             const char *oldval = d->val;
1676             const char *oldprevval3 = d->prev_val[3];
1677             char *newval;
1678
1679             oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1680             d->indent += 2;
1681             oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1682             oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1683                      loopcounter, loopcounter);
1684             output_escaped_param (d, length, "length");
1685             oprintf (d->of, "); i%d++) {\n", loopcounter);
1686             d->indent += 2;
1687             d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1688             d->used_length = 1;
1689             d->prev_val[3] = oldval;
1690             walk_type (t->u.p, d);
1691             free (newval);
1692             d->val = oldval;
1693             d->prev_val[3] = oldprevval3;
1694             d->used_length = 0;
1695             d->indent -= 2;
1696             oprintf (d->of, "%*s}\n", d->indent, "");
1697             d->process_field(t, d);
1698             d->indent -= 2;
1699             oprintf (d->of, "%*s}\n", d->indent, "");
1700           }
1701       }
1702       break;
1703
1704     case TYPE_ARRAY:
1705       {
1706         int loopcounter = d->counter++;
1707         const char *oldval = d->val;
1708         char *newval;
1709
1710         /* If it's an array of scalars, we optimize by not generating
1711            any code.  */
1712         if (t->u.a.p->kind == TYPE_SCALAR)
1713           break;
1714
1715         oprintf (d->of, "%*s{\n", d->indent, "");
1716         d->indent += 2;
1717         oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1718         oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1719                  loopcounter, loopcounter);
1720         if (length)
1721           output_escaped_param (d, length, "length");
1722         else
1723           oprintf (d->of, "%s", t->u.a.len);
1724         oprintf (d->of, "); i%d++) {\n", loopcounter);
1725         d->indent += 2;
1726         d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1727         d->used_length = 1;
1728         walk_type (t->u.a.p, d);
1729         free (newval);
1730         d->used_length = 0;
1731         d->val = oldval;
1732         d->indent -= 2;
1733         oprintf (d->of, "%*s}\n", d->indent, "");
1734         d->indent -= 2;
1735         oprintf (d->of, "%*s}\n", d->indent, "");
1736       }
1737       break;
1738
1739     case TYPE_STRUCT:
1740     case TYPE_UNION:
1741       {
1742         pair_p f;
1743         const char *oldval = d->val;
1744         const char *oldprevval1 = d->prev_val[1];
1745         const char *oldprevval2 = d->prev_val[2];
1746         const int union_p = t->kind == TYPE_UNION;
1747         int seen_default_p = 0;
1748         options_p o;
1749
1750         if (! t->u.s.line.file)
1751           error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1752
1753         if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1754           {
1755             error_at_line (d->line,
1756                            "structure `%s' defined for mismatching languages",
1757                            t->u.s.tag);
1758             error_at_line (&t->u.s.line, "one structure defined here");
1759           }
1760
1761         /* Some things may also be defined in the structure's options.  */
1762         for (o = t->u.s.opt; o; o = o->next)
1763           if (! desc && strcmp (o->name, "desc") == 0)
1764             desc = o->info;
1765
1766         d->prev_val[2] = oldval;
1767         d->prev_val[1] = oldprevval2;
1768         if (union_p)
1769           {
1770             if (desc == NULL)
1771               {
1772                 error_at_line (d->line, "missing `desc' option for union `%s'",
1773                                t->u.s.tag);
1774                 desc = "1";
1775               }
1776             oprintf (d->of, "%*sswitch (", d->indent, "");
1777             output_escaped_param (d, desc, "desc");
1778             oprintf (d->of, ")\n");
1779             d->indent += 2;
1780             oprintf (d->of, "%*s{\n", d->indent, "");
1781           }
1782         for (f = t->u.s.fields; f; f = f->next)
1783           {
1784             options_p oo;
1785             const char *dot = ".";
1786             const char *tagid = NULL;
1787             int skip_p = 0;
1788             int default_p = 0;
1789             int use_param_p = 0;
1790             char *newval;
1791
1792             d->reorder_fn = NULL;
1793             for (oo = f->opt; oo; oo = oo->next)
1794               if (strcmp (oo->name, "dot") == 0)
1795                 dot = oo->info;
1796               else if (strcmp (oo->name, "tag") == 0)
1797                 tagid = oo->info;
1798               else if (strcmp (oo->name, "skip") == 0)
1799                 skip_p = 1;
1800               else if (strcmp (oo->name, "default") == 0)
1801                 default_p = 1;
1802               else if (strcmp (oo->name, "reorder") == 0)
1803                 d->reorder_fn = oo->info;
1804               else if (strncmp (oo->name, "use_param", 9) == 0
1805                        && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1806                 use_param_p = 1;
1807
1808             if (skip_p)
1809               continue;
1810
1811             if (union_p && tagid)
1812               {
1813                 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1814                 d->indent += 2;
1815               }
1816             else if (union_p && default_p)
1817               {
1818                 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1819                 d->indent += 2;
1820                 seen_default_p = 1;
1821               }
1822             else if (! union_p && (default_p || tagid))
1823               error_at_line (d->line,
1824                              "can't use `%s' outside a union on field `%s'",
1825                              default_p ? "default" : "tag", f->name);
1826             else if (union_p && ! (default_p || tagid)
1827                      && f->type->kind == TYPE_SCALAR)
1828               {
1829                 fprintf (stderr,
1830         "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1831                          d->line->file, d->line->line, f->name);
1832                 continue;
1833               }
1834             else if (union_p && ! (default_p || tagid))
1835               error_at_line (d->line,
1836                              "field `%s' is missing `tag' or `default' option",
1837                              f->name);
1838
1839             d->line = &f->line;
1840             d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1841             d->opt = f->opt;
1842             d->used_length = false;
1843
1844             if (union_p && use_param_p && d->param == NULL)
1845               oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
1846             else
1847               walk_type (f->type, d);
1848
1849             free (newval);
1850
1851             if (union_p)
1852               {
1853                 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1854                 d->indent -= 2;
1855               }
1856           }
1857         d->reorder_fn = NULL;
1858
1859         d->val = oldval;
1860         d->prev_val[1] = oldprevval1;
1861         d->prev_val[2] = oldprevval2;
1862
1863         if (union_p && ! seen_default_p)
1864           {
1865             oprintf (d->of, "%*sdefault:\n", d->indent, "");
1866             oprintf (d->of, "%*s  break;\n", d->indent, "");
1867           }
1868         if (union_p)
1869           {
1870             oprintf (d->of, "%*s}\n", d->indent, "");
1871             d->indent -= 2;
1872           }
1873       }
1874       break;
1875
1876     case TYPE_LANG_STRUCT:
1877       {
1878         type_p nt;
1879         for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1880           if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1881             break;
1882         if (nt == NULL)
1883           error_at_line (d->line, "structure `%s' differs between languages",
1884                          t->u.s.tag);
1885         else
1886           walk_type (nt, d);
1887       }
1888       break;
1889
1890     case TYPE_PARAM_STRUCT:
1891       {
1892         type_p *oldparam = d->param;
1893
1894         d->param = t->u.param_struct.param;
1895         walk_type (t->u.param_struct.stru, d);
1896         d->param = oldparam;
1897       }
1898       break;
1899
1900     default:
1901       gcc_unreachable ();
1902     }
1903 }
1904
1905 /* process_field routine for marking routines.  */
1906
1907 static void
1908 write_types_process_field (type_p f, const struct walk_type_data *d)
1909 {
1910   const struct write_types_data *wtd;
1911   const char *cast = d->needs_cast_p ? "(void *)" : "";
1912   wtd = (const struct write_types_data *) d->cookie;
1913
1914   switch (f->kind)
1915     {
1916     case TYPE_POINTER:
1917       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1918                wtd->subfield_marker_routine, cast, d->val);
1919       if (wtd->param_prefix)
1920         {
1921           oprintf (d->of, ", %s", d->prev_val[3]);
1922           if (d->orig_s)
1923             {
1924               oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1925               output_mangled_typename (d->of, d->orig_s);
1926             }
1927           else
1928             oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1929         }
1930       oprintf (d->of, ");\n");
1931       if (d->reorder_fn && wtd->reorder_note_routine)
1932         oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1933                  wtd->reorder_note_routine, cast, d->val,
1934                  d->prev_val[3], d->reorder_fn);
1935       break;
1936
1937     case TYPE_STRING:
1938       if (wtd->param_prefix == NULL)
1939         break;
1940
1941     case TYPE_STRUCT:
1942     case TYPE_UNION:
1943     case TYPE_LANG_STRUCT:
1944     case TYPE_PARAM_STRUCT:
1945       oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1946       output_mangled_typename (d->of, f);
1947       oprintf (d->of, " (%s%s);\n", cast, d->val);
1948       if (d->reorder_fn && wtd->reorder_note_routine)
1949         oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1950                  wtd->reorder_note_routine, cast, d->val, cast, d->val,
1951                  d->reorder_fn);
1952       break;
1953
1954     case TYPE_SCALAR:
1955       break;
1956
1957     default:
1958       gcc_unreachable ();
1959     }
1960 }
1961
1962 /* For S, a structure that's part of ORIG_S, and using parameters
1963    PARAM, write out a routine that:
1964    - Takes a parameter, a void * but actually of type *S
1965    - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1966      field of S or its substructures and (in some cases) things
1967      that are pointed to by S.
1968 */
1969
1970 static void
1971 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1972                           const struct write_types_data *wtd)
1973 {
1974   const char *fn = s->u.s.line.file;
1975   int i;
1976   const char *chain_next = NULL;
1977   const char *chain_prev = NULL;
1978   options_p opt;
1979   struct walk_type_data d;
1980
1981   /* This is a hack, and not the good kind either.  */
1982   for (i = NUM_PARAM - 1; i >= 0; i--)
1983     if (param && param[i] && param[i]->kind == TYPE_POINTER
1984         && UNION_OR_STRUCT_P (param[i]->u.p))
1985       fn = param[i]->u.p->u.s.line.file;
1986
1987   memset (&d, 0, sizeof (d));
1988   d.of = get_output_file_with_visibility (fn);
1989
1990   for (opt = s->u.s.opt; opt; opt = opt->next)
1991     if (strcmp (opt->name, "chain_next") == 0)
1992       chain_next = opt->info;
1993     else if (strcmp (opt->name, "chain_prev") == 0)
1994       chain_prev = opt->info;
1995
1996   if (chain_prev != NULL && chain_next == NULL)
1997     error_at_line (&s->u.s.line, "chain_prev without chain_next");
1998
1999   d.process_field = write_types_process_field;
2000   d.cookie = wtd;
2001   d.orig_s = orig_s;
2002   d.opt = s->u.s.opt;
2003   d.line = &s->u.s.line;
2004   d.bitmap = s->u.s.bitmap;
2005   d.param = param;
2006   d.prev_val[0] = "*x";
2007   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2008   d.prev_val[3] = "x";
2009   d.val = "(*x)";
2010
2011   oprintf (d.of, "\n");
2012   oprintf (d.of, "void\n");
2013   if (param == NULL)
2014     oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
2015   else
2016     {
2017       oprintf (d.of, "gt_%s_", wtd->prefix);
2018       output_mangled_typename (d.of, orig_s);
2019     }
2020   oprintf (d.of, " (void *x_p)\n");
2021   oprintf (d.of, "{\n");
2022   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
2023            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2024            chain_next == NULL ? "const " : "",
2025            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2026   if (chain_next != NULL)
2027     oprintf (d.of, "  %s %s * xlimit = x;\n",
2028              s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2029   if (chain_next == NULL)
2030     {
2031       oprintf (d.of, "  if (%s (x", wtd->marker_routine);
2032       if (wtd->param_prefix)
2033         {
2034           oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
2035           output_mangled_typename (d.of, orig_s);
2036         }
2037       oprintf (d.of, "))\n");
2038     }
2039   else
2040     {
2041       oprintf (d.of, "  while (%s (xlimit", wtd->marker_routine);
2042       if (wtd->param_prefix)
2043         {
2044           oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
2045           output_mangled_typename (d.of, orig_s);
2046         }
2047       oprintf (d.of, "))\n");
2048       oprintf (d.of, "   xlimit = (");
2049       d.prev_val[2] = "*xlimit";
2050       output_escaped_param (&d, chain_next, "chain_next");
2051       oprintf (d.of, ");\n");
2052       if (chain_prev != NULL)
2053         {
2054           oprintf (d.of, "  if (x != xlimit)\n");
2055           oprintf (d.of, "    for (;;)\n");
2056           oprintf (d.of, "      {\n");
2057           oprintf (d.of, "        %s %s * const xprev = (",
2058                    s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2059
2060           d.prev_val[2] = "*x";
2061           output_escaped_param (&d, chain_prev, "chain_prev");
2062           oprintf (d.of, ");\n");
2063           oprintf (d.of, "        if (xprev == NULL) break;\n");
2064           oprintf (d.of, "        x = xprev;\n");
2065           oprintf (d.of, "        (void) %s (xprev",
2066                    wtd->marker_routine);
2067           if (wtd->param_prefix)
2068             {
2069               oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2070               output_mangled_typename (d.of, orig_s);
2071             }
2072           oprintf (d.of, ");\n");
2073           oprintf (d.of, "      }\n");
2074         }
2075       oprintf (d.of, "  while (x != xlimit)\n");
2076     }
2077   oprintf (d.of, "    {\n");
2078
2079   d.prev_val[2] = "*x";
2080   d.indent = 6;
2081   walk_type (s, &d);
2082
2083   if (chain_next != NULL)
2084     {
2085       oprintf (d.of, "      x = (");
2086       output_escaped_param (&d, chain_next, "chain_next");
2087       oprintf (d.of, ");\n");
2088     }
2089
2090   oprintf (d.of, "    }\n");
2091   oprintf (d.of, "}\n");
2092 }
2093
2094 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS.  */
2095
2096 static void
2097 write_types (type_p structures, type_p param_structs,
2098              const struct write_types_data *wtd)
2099 {
2100   type_p s;
2101
2102   oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2103   for (s = structures; s; s = s->next)
2104     if (s->gc_used == GC_POINTED_TO
2105         || s->gc_used == GC_MAYBE_POINTED_TO)
2106       {
2107         options_p opt;
2108
2109         if (s->gc_used == GC_MAYBE_POINTED_TO
2110             && s->u.s.line.file == NULL)
2111           continue;
2112
2113         oprintf (header_file, "#define gt_%s_", wtd->prefix);
2114         output_mangled_typename (header_file, s);
2115         oprintf (header_file, "(X) do { \\\n");
2116         oprintf (header_file,
2117                  "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2118                  s->u.s.tag);
2119         oprintf (header_file,
2120                  "  } while (0)\n");
2121
2122         for (opt = s->u.s.opt; opt; opt = opt->next)
2123           if (strcmp (opt->name, "ptr_alias") == 0)
2124             {
2125               type_p t = (type_p) opt->info;
2126               if (t->kind == TYPE_STRUCT
2127                   || t->kind == TYPE_UNION
2128                   || t->kind == TYPE_LANG_STRUCT)
2129                 oprintf (header_file,
2130                          "#define gt_%sx_%s gt_%sx_%s\n",
2131                          wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2132               else
2133                 error_at_line (&s->u.s.line,
2134                                "structure alias is not a structure");
2135               break;
2136             }
2137         if (opt)
2138           continue;
2139
2140         /* Declare the marker procedure only once.  */
2141         oprintf (header_file,
2142                  "extern void gt_%sx_%s (void *);\n",
2143                  wtd->prefix, s->u.s.tag);
2144
2145         if (s->u.s.line.file == NULL)
2146           {
2147             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2148                      s->u.s.tag);
2149             continue;
2150           }
2151
2152         if (s->kind == TYPE_LANG_STRUCT)
2153           {
2154             type_p ss;
2155             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2156               write_func_for_structure (s, ss, NULL, wtd);
2157           }
2158         else
2159           write_func_for_structure (s, s, NULL, wtd);
2160       }
2161
2162   for (s = param_structs; s; s = s->next)
2163     if (s->gc_used == GC_POINTED_TO)
2164       {
2165         type_p * param = s->u.param_struct.param;
2166         type_p stru = s->u.param_struct.stru;
2167
2168         /* Declare the marker procedure.  */
2169         oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2170         output_mangled_typename (header_file, s);
2171         oprintf (header_file, " (void *);\n");
2172
2173         if (stru->u.s.line.file == NULL)
2174           {
2175             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2176                      s->u.s.tag);
2177             continue;
2178           }
2179
2180         if (stru->kind == TYPE_LANG_STRUCT)
2181           {
2182             type_p ss;
2183             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2184               write_func_for_structure (s, ss, param, wtd);
2185           }
2186         else
2187           write_func_for_structure (s, stru, param, wtd);
2188       }
2189 }
2190
2191 static const struct write_types_data ggc_wtd =
2192 {
2193   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2194   "GC marker procedures.  "
2195 };
2196
2197 static const struct write_types_data pch_wtd =
2198 {
2199   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2200   "gt_pch_note_reorder",
2201   "PCH type-walking procedures.  "
2202 };
2203
2204 /* Write out the local pointer-walking routines.  */
2205
2206 /* process_field routine for local pointer-walking.  */
2207
2208 static void
2209 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2210 {
2211   switch (f->kind)
2212     {
2213     case TYPE_POINTER:
2214     case TYPE_STRUCT:
2215     case TYPE_UNION:
2216     case TYPE_LANG_STRUCT:
2217     case TYPE_PARAM_STRUCT:
2218     case TYPE_STRING:
2219       oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2220                d->prev_val[3]);
2221       oprintf (d->of, "%*s  op (&(%s), cookie);\n", d->indent, "", d->val);
2222       break;
2223
2224     case TYPE_SCALAR:
2225       break;
2226
2227     default:
2228       gcc_unreachable ();
2229     }
2230 }
2231
2232 /* For S, a structure that's part of ORIG_S, and using parameters
2233    PARAM, write out a routine that:
2234    - Is of type gt_note_pointers
2235    - Calls PROCESS_FIELD on each field of S or its substructures.
2236 */
2237
2238 static void
2239 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2240 {
2241   const char *fn = s->u.s.line.file;
2242   int i;
2243   struct walk_type_data d;
2244
2245   /* This is a hack, and not the good kind either.  */
2246   for (i = NUM_PARAM - 1; i >= 0; i--)
2247     if (param && param[i] && param[i]->kind == TYPE_POINTER
2248         && UNION_OR_STRUCT_P (param[i]->u.p))
2249       fn = param[i]->u.p->u.s.line.file;
2250
2251   memset (&d, 0, sizeof (d));
2252   d.of = get_output_file_with_visibility (fn);
2253
2254   d.process_field = write_types_local_process_field;
2255   d.opt = s->u.s.opt;
2256   d.line = &s->u.s.line;
2257   d.bitmap = s->u.s.bitmap;
2258   d.param = param;
2259   d.prev_val[0] = d.prev_val[2] = "*x";
2260   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
2261   d.prev_val[3] = "x";
2262   d.val = "(*x)";
2263   d.fn_wants_lvalue = true;
2264
2265   oprintf (d.of, "\n");
2266   oprintf (d.of, "void\n");
2267   oprintf (d.of, "gt_pch_p_");
2268   output_mangled_typename (d.of, orig_s);
2269   oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
2270            "\tvoid *x_p,\n"
2271            "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2272            "\tATTRIBUTE_UNUSED void *cookie)\n");
2273   oprintf (d.of, "{\n");
2274   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2275            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2276            s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2277   d.indent = 2;
2278   walk_type (s, &d);
2279   oprintf (d.of, "}\n");
2280 }
2281
2282 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS.  */
2283
2284 static void
2285 write_local (type_p structures, type_p param_structs)
2286 {
2287   type_p s;
2288
2289   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
2290   for (s = structures; s; s = s->next)
2291     if (s->gc_used == GC_POINTED_TO
2292         || s->gc_used == GC_MAYBE_POINTED_TO)
2293       {
2294         options_p opt;
2295
2296         if (s->u.s.line.file == NULL)
2297           continue;
2298
2299         for (opt = s->u.s.opt; opt; opt = opt->next)
2300           if (strcmp (opt->name, "ptr_alias") == 0)
2301             {
2302               type_p t = (type_p) opt->info;
2303               if (t->kind == TYPE_STRUCT
2304                   || t->kind == TYPE_UNION
2305                   || t->kind == TYPE_LANG_STRUCT)
2306                 {
2307                   oprintf (header_file, "#define gt_pch_p_");
2308                   output_mangled_typename (header_file, s);
2309                   oprintf (header_file, " gt_pch_p_");
2310                   output_mangled_typename (header_file, t);
2311                   oprintf (header_file, "\n");
2312                 }
2313               else
2314                 error_at_line (&s->u.s.line,
2315                                "structure alias is not a structure");
2316               break;
2317             }
2318         if (opt)
2319           continue;
2320
2321         /* Declare the marker procedure only once.  */
2322         oprintf (header_file, "extern void gt_pch_p_");
2323         output_mangled_typename (header_file, s);
2324         oprintf (header_file,
2325          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2326
2327         if (s->kind == TYPE_LANG_STRUCT)
2328           {
2329             type_p ss;
2330             for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2331               write_local_func_for_structure (s, ss, NULL);
2332           }
2333         else
2334           write_local_func_for_structure (s, s, NULL);
2335       }
2336
2337   for (s = param_structs; s; s = s->next)
2338     if (s->gc_used == GC_POINTED_TO)
2339       {
2340         type_p * param = s->u.param_struct.param;
2341         type_p stru = s->u.param_struct.stru;
2342
2343         /* Declare the marker procedure.  */
2344         oprintf (header_file, "extern void gt_pch_p_");
2345         output_mangled_typename (header_file, s);
2346         oprintf (header_file,
2347          "\n    (void *, void *, gt_pointer_operator, void *);\n");
2348
2349         if (stru->u.s.line.file == NULL)
2350           {
2351             fprintf (stderr, "warning: structure `%s' used but not defined\n",
2352                      s->u.s.tag);
2353             continue;
2354           }
2355
2356         if (stru->kind == TYPE_LANG_STRUCT)
2357           {
2358             type_p ss;
2359             for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2360               write_local_func_for_structure (s, ss, param);
2361           }
2362         else
2363           write_local_func_for_structure (s, stru, param);
2364       }
2365 }
2366
2367 /* Write out the 'enum' definition for gt_types_enum.  */
2368
2369 static void
2370 write_enum_defn (type_p structures, type_p param_structs)
2371 {
2372   type_p s;
2373
2374   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
2375   oprintf (header_file, "enum gt_types_enum {\n");
2376   for (s = structures; s; s = s->next)
2377     if (s->gc_used == GC_POINTED_TO
2378         || s->gc_used == GC_MAYBE_POINTED_TO)
2379       {
2380         if (s->gc_used == GC_MAYBE_POINTED_TO
2381             && s->u.s.line.file == NULL)
2382           continue;
2383
2384         oprintf (header_file, " gt_ggc_e_");
2385         output_mangled_typename (header_file, s);
2386         oprintf (header_file, ", \n");
2387       }
2388   for (s = param_structs; s; s = s->next)
2389     if (s->gc_used == GC_POINTED_TO)
2390       {
2391         oprintf (header_file, " gt_e_");
2392         output_mangled_typename (header_file, s);
2393         oprintf (header_file, ", \n");
2394       }
2395   oprintf (header_file, " gt_types_enum_last\n");
2396   oprintf (header_file, "};\n");
2397 }
2398
2399 /* Might T contain any non-pointer elements?  */
2400
2401 static int
2402 contains_scalar_p (type_p t)
2403 {
2404   switch (t->kind)
2405     {
2406     case TYPE_STRING:
2407     case TYPE_POINTER:
2408       return 0;
2409     case TYPE_ARRAY:
2410       return contains_scalar_p (t->u.a.p);
2411     default:
2412       /* Could also check for structures that have no non-pointer
2413          fields, but there aren't enough of those to worry about.  */
2414       return 1;
2415     }
2416 }
2417
2418 /* Mangle FN and print it to F.  */
2419
2420 static void
2421 put_mangled_filename (outf_p f, const char *fn)
2422 {
2423   const char *name = get_output_file_name (fn);
2424   for (; *name != 0; name++)
2425     if (ISALNUM (*name))
2426       oprintf (f, "%c", *name);
2427     else
2428       oprintf (f, "%c", '_');
2429 }
2430
2431 /* Finish off the currently-created root tables in FLP.  PFX, TNAME,
2432    LASTNAME, and NAME are all strings to insert in various places in
2433    the resulting code.  */
2434
2435 static void
2436 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2437                    const char *tname, const char *name)
2438 {
2439   struct flist *fli2;
2440
2441   for (fli2 = flp; fli2; fli2 = fli2->next)
2442     if (fli2->started_p)
2443       {
2444         oprintf (fli2->f, "  %s\n", lastname);
2445         oprintf (fli2->f, "};\n\n");
2446       }
2447
2448   for (fli2 = flp; fli2; fli2 = fli2->next)
2449     if (fli2->started_p)
2450       {
2451         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2452         int fnum;
2453
2454         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2455           if (bitmap & 1)
2456             {
2457               oprintf (base_files[fnum],
2458                        "extern const struct %s gt_%s_",
2459                        tname, pfx);
2460               put_mangled_filename (base_files[fnum], fli2->name);
2461               oprintf (base_files[fnum], "[];\n");
2462             }
2463       }
2464
2465   {
2466     size_t fnum;
2467     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2468       oprintf (base_files [fnum],
2469                "const struct %s * const %s[] = {\n",
2470                tname, name);
2471   }
2472
2473
2474   for (fli2 = flp; fli2; fli2 = fli2->next)
2475     if (fli2->started_p)
2476       {
2477         lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2478         int fnum;
2479
2480         fli2->started_p = 0;
2481
2482         for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2483           if (bitmap & 1)
2484             {
2485               oprintf (base_files[fnum], "  gt_%s_", pfx);
2486               put_mangled_filename (base_files[fnum], fli2->name);
2487               oprintf (base_files[fnum], ",\n");
2488             }
2489       }
2490
2491   {
2492     size_t fnum;
2493     for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2494       {
2495         oprintf (base_files[fnum], "  NULL\n");
2496         oprintf (base_files[fnum], "};\n");
2497       }
2498   }
2499 }
2500
2501 /* Write out to F the table entry and any marker routines needed to
2502    mark NAME as TYPE.  The original variable is V, at LINE.
2503    HAS_LENGTH is nonzero iff V was a variable-length array.  IF_MARKED
2504    is nonzero iff we are building the root table for hash table caches.  */
2505
2506 static void
2507 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2508             struct fileloc *line, const char *if_marked)
2509 {
2510   switch (type->kind)
2511     {
2512     case TYPE_STRUCT:
2513       {
2514         pair_p fld;
2515         for (fld = type->u.s.fields; fld; fld = fld->next)
2516           {
2517             int skip_p = 0;
2518             const char *desc = NULL;
2519             options_p o;
2520
2521             for (o = fld->opt; o; o = o->next)
2522               if (strcmp (o->name, "skip") == 0)
2523                 skip_p = 1;
2524               else if (strcmp (o->name, "desc") == 0)
2525                 desc = o->info;
2526               else
2527                 error_at_line (line,
2528                        "field `%s' of global `%s' has unknown option `%s'",
2529                                fld->name, name, o->name);
2530
2531             if (skip_p)
2532               continue;
2533             else if (desc && fld->type->kind == TYPE_UNION)
2534               {
2535                 pair_p validf = NULL;
2536                 pair_p ufld;
2537
2538                 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2539                   {
2540                     const char *tag = NULL;
2541                     options_p oo;
2542
2543                     for (oo = ufld->opt; oo; oo = oo->next)
2544                       if (strcmp (oo->name, "tag") == 0)
2545                         tag = oo->info;
2546                     if (tag == NULL || strcmp (tag, desc) != 0)
2547                       continue;
2548                     if (validf != NULL)
2549                       error_at_line (line,
2550                            "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2551                                      name, fld->name, validf->name,
2552                                      name, fld->name, ufld->name,
2553                                      tag);
2554                     validf = ufld;
2555                   }
2556                 if (validf != NULL)
2557                   {
2558                     char *newname;
2559                     newname = xasprintf ("%s.%s.%s",
2560                                          name, fld->name, validf->name);
2561                     write_root (f, v, validf->type, newname, 0, line,
2562                                 if_marked);
2563                     free (newname);
2564                   }
2565               }
2566             else if (desc)
2567               error_at_line (line,
2568                      "global `%s.%s' has `desc' option but is not union",
2569                              name, fld->name);
2570             else
2571               {
2572                 char *newname;
2573                 newname = xasprintf ("%s.%s", name, fld->name);
2574                 write_root (f, v, fld->type, newname, 0, line, if_marked);
2575                 free (newname);
2576               }
2577           }
2578       }
2579       break;
2580
2581     case TYPE_ARRAY:
2582       {
2583         char *newname;
2584         newname = xasprintf ("%s[0]", name);
2585         write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2586         free (newname);
2587       }
2588       break;
2589
2590     case TYPE_POINTER:
2591       {
2592         type_p ap, tp;
2593
2594         oprintf (f, "  {\n");
2595         oprintf (f, "    &%s,\n", name);
2596         oprintf (f, "    1");
2597
2598         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2599           if (ap->u.a.len[0])
2600             oprintf (f, " * (%s)", ap->u.a.len);
2601           else if (ap == v->type)
2602             oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2603         oprintf (f, ",\n");
2604         oprintf (f, "    sizeof (%s", v->name);
2605         for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2606           oprintf (f, "[0]");
2607         oprintf (f, "),\n");
2608
2609         tp = type->u.p;
2610
2611         if (! has_length && UNION_OR_STRUCT_P (tp))
2612           {
2613             oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
2614             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
2615           }
2616         else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2617           {
2618             oprintf (f, "    &gt_ggc_m_");
2619             output_mangled_typename (f, tp);
2620             oprintf (f, ",\n    &gt_pch_n_");
2621             output_mangled_typename (f, tp);
2622           }
2623         else if (has_length
2624                  && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2625           {
2626             oprintf (f, "    &gt_ggc_ma_%s,\n", name);
2627             oprintf (f, "    &gt_pch_na_%s", name);
2628           }
2629         else
2630           {
2631             error_at_line (line,
2632                            "global `%s' is pointer to unimplemented type",
2633                            name);
2634           }
2635         if (if_marked)
2636           oprintf (f, ",\n    &%s", if_marked);
2637         oprintf (f, "\n  },\n");
2638       }
2639       break;
2640
2641     case TYPE_STRING:
2642       {
2643         oprintf (f, "  {\n");
2644         oprintf (f, "    &%s,\n", name);
2645         oprintf (f, "    1, \n");
2646         oprintf (f, "    sizeof (%s),\n", v->name);
2647         oprintf (f, "    &gt_ggc_m_S,\n");
2648         oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
2649         oprintf (f, "  },\n");
2650       }
2651       break;
2652
2653     case TYPE_SCALAR:
2654       break;
2655
2656     default:
2657       error_at_line (line,
2658                      "global `%s' is unimplemented type",
2659                      name);
2660     }
2661 }
2662
2663 /* This generates a routine to walk an array.  */
2664
2665 static void
2666 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2667 {
2668   struct walk_type_data d;
2669   char *prevval3;
2670
2671   memset (&d, 0, sizeof (d));
2672   d.of = f;
2673   d.cookie = wtd;
2674   d.indent = 2;
2675   d.line = &v->line;
2676   d.opt = v->opt;
2677   d.bitmap = get_base_file_bitmap (v->line.file);
2678   d.param = NULL;
2679
2680   d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2681
2682   if (wtd->param_prefix)
2683     {
2684       oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2685       oprintf (f,
2686        "    (void *, void *, gt_pointer_operator, void *);\n");
2687       oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
2688                wtd->param_prefix, v->name);
2689       oprintf (d.of,
2690                "      ATTRIBUTE_UNUSED void *x_p,\n"
2691                "      ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
2692                "      ATTRIBUTE_UNUSED void * cookie)\n");
2693       oprintf (d.of, "{\n");
2694       d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2695       d.process_field = write_types_local_process_field;
2696       walk_type (v->type, &d);
2697       oprintf (f, "}\n\n");
2698     }
2699
2700   d.opt = v->opt;
2701   oprintf (f, "static void gt_%sa_%s (void *);\n",
2702            wtd->prefix, v->name);
2703   oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
2704            wtd->prefix, v->name);
2705   oprintf (f, "{\n");
2706   d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2707   d.process_field = write_types_process_field;
2708   walk_type (v->type, &d);
2709   free (prevval3);
2710   oprintf (f, "}\n\n");
2711 }
2712
2713 /* Output a table describing the locations and types of VARIABLES.  */
2714
2715 static void
2716 write_roots (pair_p variables)
2717 {
2718   pair_p v;
2719   struct flist *flp = NULL;
2720
2721   for (v = variables; v; v = v->next)
2722     {
2723       outf_p f = get_output_file_with_visibility (v->line.file);
2724       struct flist *fli;
2725       const char *length = NULL;
2726       int deletable_p = 0;
2727       options_p o;
2728
2729       for (o = v->opt; o; o = o->next)
2730         if (strcmp (o->name, "length") == 0)
2731           length = o->info;
2732         else if (strcmp (o->name, "deletable") == 0)
2733           deletable_p = 1;
2734         else if (strcmp (o->name, "param_is") == 0)
2735           ;
2736         else if (strncmp (o->name, "param", 5) == 0
2737                  && ISDIGIT (o->name[5])
2738                  && strcmp (o->name + 6, "_is") == 0)
2739           ;
2740         else if (strcmp (o->name, "if_marked") == 0)
2741           ;
2742         else
2743           error_at_line (&v->line,
2744                          "global `%s' has unknown option `%s'",
2745                          v->name, o->name);
2746
2747       for (fli = flp; fli; fli = fli->next)
2748         if (fli->f == f)
2749           break;
2750       if (fli == NULL)
2751         {
2752           fli = XNEW (struct flist);
2753           fli->f = f;
2754           fli->next = flp;
2755           fli->started_p = 0;
2756           fli->name = v->line.file;
2757           flp = fli;
2758
2759           oprintf (f, "\n/* GC roots.  */\n\n");
2760         }
2761
2762       if (! deletable_p
2763           && length
2764           && v->type->kind == TYPE_POINTER
2765           && (v->type->u.p->kind == TYPE_POINTER
2766               || v->type->u.p->kind == TYPE_STRUCT))
2767         {
2768           write_array (f, v, &ggc_wtd);
2769           write_array (f, v, &pch_wtd);
2770         }
2771     }
2772
2773   for (v = variables; v; v = v->next)
2774     {
2775       outf_p f = get_output_file_with_visibility (v->line.file);
2776       struct flist *fli;
2777       int skip_p = 0;
2778       int length_p = 0;
2779       options_p o;
2780
2781       for (o = v->opt; o; o = o->next)
2782         if (strcmp (o->name, "length") == 0)
2783           length_p = 1;
2784         else if (strcmp (o->name, "deletable") == 0
2785                  || strcmp (o->name, "if_marked") == 0)
2786           skip_p = 1;
2787
2788       if (skip_p)
2789         continue;
2790
2791       for (fli = flp; fli; fli = fli->next)
2792         if (fli->f == f)
2793           break;
2794       if (! fli->started_p)
2795         {
2796           fli->started_p = 1;
2797
2798           oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2799           put_mangled_filename (f, v->line.file);
2800           oprintf (f, "[] = {\n");
2801         }
2802
2803       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2804     }
2805
2806   finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2807                      "gt_ggc_rtab");
2808
2809   for (v = variables; v; v = v->next)
2810     {
2811       outf_p f = get_output_file_with_visibility (v->line.file);
2812       struct flist *fli;
2813       int skip_p = 1;
2814       options_p o;
2815
2816       for (o = v->opt; o; o = o->next)
2817         if (strcmp (o->name, "deletable") == 0)
2818           skip_p = 0;
2819         else if (strcmp (o->name, "if_marked") == 0)
2820           skip_p = 1;
2821
2822       if (skip_p)
2823         continue;
2824
2825       for (fli = flp; fli; fli = fli->next)
2826         if (fli->f == f)
2827           break;
2828       if (! fli->started_p)
2829         {
2830           fli->started_p = 1;
2831
2832           oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2833           put_mangled_filename (f, v->line.file);
2834           oprintf (f, "[] = {\n");
2835         }
2836
2837       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2838                v->name, v->name);
2839     }
2840
2841   finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2842                      "gt_ggc_deletable_rtab");
2843
2844   for (v = variables; v; v = v->next)
2845     {
2846       outf_p f = get_output_file_with_visibility (v->line.file);
2847       struct flist *fli;
2848       const char *if_marked = NULL;
2849       int length_p = 0;
2850       options_p o;
2851
2852       for (o = v->opt; o; o = o->next)
2853         if (strcmp (o->name, "length") == 0)
2854           length_p = 1;
2855         else if (strcmp (o->name, "if_marked") == 0)
2856           if_marked = o->info;
2857
2858       if (if_marked == NULL)
2859         continue;
2860
2861       if (v->type->kind != TYPE_POINTER
2862           || v->type->u.p->kind != TYPE_PARAM_STRUCT
2863           || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2864         {
2865           error_at_line (&v->line, "if_marked option used but not hash table");
2866           continue;
2867         }
2868
2869       for (fli = flp; fli; fli = fli->next)
2870         if (fli->f == f)
2871           break;
2872       if (! fli->started_p)
2873         {
2874           fli->started_p = 1;
2875
2876           oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2877           put_mangled_filename (f, v->line.file);
2878           oprintf (f, "[] = {\n");
2879         }
2880
2881       write_root (f, v, v->type->u.p->u.param_struct.param[0],
2882                      v->name, length_p, &v->line, if_marked);
2883     }
2884
2885   finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2886                      "gt_ggc_cache_rtab");
2887
2888   for (v = variables; v; v = v->next)
2889     {
2890       outf_p f = get_output_file_with_visibility (v->line.file);
2891       struct flist *fli;
2892       int length_p = 0;
2893       int if_marked_p = 0;
2894       options_p o;
2895
2896       for (o = v->opt; o; o = o->next)
2897         if (strcmp (o->name, "length") == 0)
2898           length_p = 1;
2899         else if (strcmp (o->name, "if_marked") == 0)
2900           if_marked_p = 1;
2901
2902       if (! if_marked_p)
2903         continue;
2904
2905       for (fli = flp; fli; fli = fli->next)
2906         if (fli->f == f)
2907           break;
2908       if (! fli->started_p)
2909         {
2910           fli->started_p = 1;
2911
2912           oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2913           put_mangled_filename (f, v->line.file);
2914           oprintf (f, "[] = {\n");
2915         }
2916
2917       write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2918     }
2919
2920   finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2921                      "gt_pch_cache_rtab");
2922
2923   for (v = variables; v; v = v->next)
2924     {
2925       outf_p f = get_output_file_with_visibility (v->line.file);
2926       struct flist *fli;
2927       int skip_p = 0;
2928       options_p o;
2929
2930       for (o = v->opt; o; o = o->next)
2931         if (strcmp (o->name, "deletable") == 0
2932             || strcmp (o->name, "if_marked") == 0)
2933           skip_p = 1;
2934
2935       if (skip_p)
2936         continue;
2937
2938       if (! contains_scalar_p (v->type))
2939         continue;
2940
2941       for (fli = flp; fli; fli = fli->next)
2942         if (fli->f == f)
2943           break;
2944       if (! fli->started_p)
2945         {
2946           fli->started_p = 1;
2947
2948           oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2949           put_mangled_filename (f, v->line.file);
2950           oprintf (f, "[] = {\n");
2951         }
2952
2953       oprintf (f, "  { &%s, 1, sizeof (%s), NULL, NULL },\n",
2954                v->name, v->name);
2955     }
2956
2957   finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2958                      "gt_pch_scalar_rtab");
2959 }
2960
2961 \f
2962 extern int main (int argc, char **argv);
2963 int
2964 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
2965 {
2966   unsigned i;
2967   static struct fileloc pos = { __FILE__, __LINE__ };
2968   unsigned j;
2969
2970   gen_rtx_next ();
2971
2972   srcdir_len = strlen (srcdir);
2973
2974   do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2975   do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2976   do_scalar_typedef ("uint8", &pos);
2977   do_scalar_typedef ("jword", &pos);
2978   do_scalar_typedef ("JCF_u2", &pos);
2979 #ifdef USE_MAPPED_LOCATION
2980   do_scalar_typedef ("location_t", &pos);
2981   do_scalar_typedef ("source_locus", &pos);
2982 #endif
2983   do_scalar_typedef ("void", &pos);
2984
2985   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
2986
2987   do_typedef ("HARD_REG_SET", create_array (
2988               create_scalar_type ("unsigned long", strlen ("unsigned long")),
2989               "2"), &pos);
2990
2991   for (i = 0; i < NUM_GT_FILES; i++)
2992     {
2993       int dupflag = 0;
2994       /* Omit if already seen.  */
2995       for (j = 0; j < i; j++)
2996         {
2997           if (!strcmp (all_files[i], all_files[j]))
2998             {
2999               dupflag = 1;
3000               break;
3001             }
3002         }
3003       if (!dupflag)
3004         parse_file (all_files[i]);
3005 #ifndef USE_MAPPED_LOCATION
3006       /* temporary kludge - gengtype doesn't handle conditionals.
3007          Manually add source_locus *after* we've processed input.h.  */
3008       if (i == 0)
3009         do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
3010 #endif
3011     }
3012
3013   if (hit_error != 0)
3014     exit (1);
3015
3016   set_gc_used (variables);
3017
3018   open_base_files ();
3019   write_enum_defn (structures, param_structs);
3020   write_types (structures, param_structs, &ggc_wtd);
3021   write_types (structures, param_structs, &pch_wtd);
3022   write_local (structures, param_structs);
3023   write_roots (variables);
3024   write_rtx_next ();
3025   close_output_files ();
3026
3027   return (hit_error != 0);
3028 }