OSDN Git Service

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