OSDN Git Service

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