OSDN Git Service

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