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