OSDN Git Service

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