Josef Zlomek <zlomekj@suse.cz>
[gcc.git] / gcc / gengtype.c
1 /* Process source files and output type information.
2 Copyright (C) 2002, 2003, 2004 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 " RTX_HDR_SIZE + %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_UNION)
399 {
400 error_at_line (&lexer_line,
401 "special `rtx_def' must be applied to a union");
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 case NOTE_INSN_VAR_LOCATION:
454 note_flds->name = "rtx";
455 note_flds->type = rtx_tp;
456 break;
457
458 default:
459 note_flds->name = "rtint";
460 note_flds->type = scalar_tp;
461 break;
462 }
463 }
464 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
465 }
466
467 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
468
469 for (i = 0; i < NUM_RTX_CODE; i++)
470 {
471 pair_p old_flds = flds;
472 pair_p subfields = NULL;
473 size_t aindex, nmindex;
474 const char *sname;
475 char *ftag;
476
477 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
478 {
479 pair_p old_subf = subfields;
480 type_p t;
481 const char *subname;
482
483 switch (rtx_format[i][aindex])
484 {
485 case '*':
486 case 'i':
487 case 'n':
488 case 'w':
489 t = scalar_tp;
490 subname = "rtint";
491 break;
492
493 case '0':
494 if (i == MEM && aindex == 1)
495 t = mem_attrs_tp, subname = "rtmem";
496 else if (i == JUMP_INSN && aindex == 9)
497 t = rtx_tp, subname = "rtx";
498 else if (i == CODE_LABEL && aindex == 4)
499 t = scalar_tp, subname = "rtint";
500 else if (i == CODE_LABEL && aindex == 5)
501 t = rtx_tp, subname = "rtx";
502 else if (i == LABEL_REF
503 && (aindex == 1 || aindex == 2))
504 t = rtx_tp, subname = "rtx";
505 else if (i == NOTE && aindex == 4)
506 t = note_union_tp, subname = "";
507 else if (i == NOTE && aindex >= 7)
508 t = scalar_tp, subname = "rtint";
509 else if (i == ADDR_DIFF_VEC && aindex == 4)
510 t = scalar_tp, subname = "rtint";
511 else if (i == VALUE && aindex == 0)
512 t = scalar_tp, subname = "rtint";
513 else if (i == REG && aindex == 1)
514 t = scalar_tp, subname = "rtint";
515 else if (i == REG && aindex == 2)
516 t = reg_attrs_tp, subname = "rtreg";
517 else if (i == SCRATCH && aindex == 0)
518 t = scalar_tp, subname = "rtint";
519 else if (i == SYMBOL_REF && aindex == 1)
520 t = scalar_tp, subname = "rtint";
521 else if (i == SYMBOL_REF && aindex == 2)
522 t = tree_tp, subname = "rttree";
523 else if (i == BARRIER && aindex >= 3)
524 t = scalar_tp, subname = "rtint";
525 else
526 {
527 error_at_line (&lexer_line,
528 "rtx type `%s' has `0' in position %lu, can't handle",
529 rtx_name[i], (unsigned long) aindex);
530 t = &string_type;
531 subname = "rtint";
532 }
533 break;
534
535 case 's':
536 case 'S':
537 case 'T':
538 t = &string_type;
539 subname = "rtstr";
540 break;
541
542 case 'e':
543 case 'u':
544 t = rtx_tp;
545 subname = "rtx";
546 break;
547
548 case 'E':
549 case 'V':
550 t = rtvec_tp;
551 subname = "rtvec";
552 break;
553
554 case 't':
555 t = tree_tp;
556 subname = "rttree";
557 break;
558
559 case 'b':
560 t = bitmap_tp;
561 subname = "rtbit";
562 break;
563
564 case 'B':
565 t = basic_block_tp;
566 subname = "bb";
567 break;
568
569 default:
570 error_at_line (&lexer_line,
571 "rtx type `%s' has `%c' in position %lu, can't handle",
572 rtx_name[i], rtx_format[i][aindex],
573 (unsigned long)aindex);
574 t = &string_type;
575 subname = "rtint";
576 break;
577 }
578
579 subfields = xmalloc (sizeof (*subfields));
580 subfields->next = old_subf;
581 subfields->type = t;
582 subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
583 subname);
584 subfields->line.file = __FILE__;
585 subfields->line.line = __LINE__;
586 if (t == note_union_tp)
587 {
588 subfields->opt = xmalloc (sizeof (*subfields->opt));
589 subfields->opt->next = nodot;
590 subfields->opt->name = "desc";
591 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
592 }
593 else if (t == basic_block_tp)
594 {
595 /* We don't presently GC basic block structures... */
596 subfields->opt = xmalloc (sizeof (*subfields->opt));
597 subfields->opt->next = nodot;
598 subfields->opt->name = "skip";
599 subfields->opt->info = NULL;
600 }
601 else
602 subfields->opt = nodot;
603 }
604
605 flds = xmalloc (sizeof (*flds));
606 flds->next = old_flds;
607 flds->name = "";
608 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
609 new_structure (sname, 0, &lexer_line, subfields, NULL);
610 flds->type = find_structure (sname, 0);
611 flds->line.file = __FILE__;
612 flds->line.line = __LINE__;
613 flds->opt = xmalloc (sizeof (*flds->opt));
614 flds->opt->next = nodot;
615 flds->opt->name = "tag";
616 ftag = xstrdup (rtx_name[i]);
617 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
618 ftag[nmindex] = TOUPPER (ftag[nmindex]);
619 flds->opt->info = ftag;
620 }
621
622 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
623 return find_structure ("rtx_def_subunion", 1);
624 }
625
626 /* Handle `special("tree_exp")'. This is a special case for
627 field `operands' of struct tree_exp, which although it claims to contain
628 pointers to trees, actually sometimes contains pointers to RTL too.
629 Passed T, the old type of the field, and OPT its options. Returns
630 a new type for the field. */
631
632 static type_p
633 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
634 {
635 pair_p flds;
636 options_p nodot;
637 size_t i;
638 static const struct {
639 const char *name;
640 int first_rtl;
641 int num_rtl;
642 } data[] = {
643 { "SAVE_EXPR", 2, 1 },
644 { "GOTO_SUBROUTINE_EXPR", 0, 2 },
645 { "RTL_EXPR", 0, 2 },
646 { "WITH_CLEANUP_EXPR", 2, 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 static 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", "optabs.h",
1092 "libfuncs.h", "debug.h", "ggc.h", "cgraph.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
1275 close_output_files (void)
1276 {
1277 outf_p of;
1278
1279 for (of = output_files; of; of = of->next)
1280 {
1281 FILE * newfile;
1282
1283 newfile = fopen (of->name, "r");
1284 if (newfile != NULL )
1285 {
1286 int no_write_p;
1287 size_t i;
1288
1289 for (i = 0; i < of->bufused; i++)
1290 {
1291 int ch;
1292 ch = fgetc (newfile);
1293 if (ch == EOF || ch != (unsigned char) of->buf[i])
1294 break;
1295 }
1296 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
1297 fclose (newfile);
1298
1299 if (no_write_p)
1300 continue;
1301 }
1302
1303 newfile = fopen (of->name, "w");
1304 if (newfile == NULL)
1305 {
1306 perror ("opening output file");
1307 exit (1);
1308 }
1309 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
1310 {
1311 perror ("writing output file");
1312 exit (1);
1313 }
1314 if (fclose (newfile) != 0)
1315 {
1316 perror ("closing output file");
1317 exit (1);
1318 }
1319 }
1320 }
1321 \f
1322 struct flist {
1323 struct flist *next;
1324 int started_p;
1325 const char *name;
1326 outf_p f;
1327 };
1328
1329 struct walk_type_data;
1330
1331 /* For scalars and strings, given the item in 'val'.
1332 For structures, given a pointer to the item in 'val'.
1333 For misc. pointers, given the item in 'val'.
1334 */
1335 typedef void (*process_field_fn)
1336 (type_p f, const struct walk_type_data *p);
1337 typedef void (*func_name_fn)
1338 (type_p s, const struct walk_type_data *p);
1339
1340 /* Parameters for write_types. */
1341
1342 struct write_types_data
1343 {
1344 const char *prefix;
1345 const char *param_prefix;
1346 const char *subfield_marker_routine;
1347 const char *marker_routine;
1348 const char *reorder_note_routine;
1349 const char *comment;
1350 };
1351
1352 static void output_escaped_param (struct walk_type_data *d,
1353 const char *, const char *);
1354 static void output_mangled_typename (outf_p, type_p);
1355 static void walk_type (type_p t, struct walk_type_data *d);
1356 static void write_func_for_structure
1357 (type_p orig_s, type_p s, type_p * param,
1358 const struct write_types_data *wtd);
1359 static void write_types_process_field
1360 (type_p f, const struct walk_type_data *d);
1361 static void write_types (type_p structures,
1362 type_p param_structs,
1363 const struct write_types_data *wtd);
1364 static void write_types_local_process_field
1365 (type_p f, const struct walk_type_data *d);
1366 static void write_local_func_for_structure
1367 (type_p orig_s, type_p s, type_p * param);
1368 static void write_local (type_p structures,
1369 type_p param_structs);
1370 static void write_enum_defn (type_p structures, type_p param_structs);
1371 static int contains_scalar_p (type_p t);
1372 static void put_mangled_filename (outf_p , const char *);
1373 static void finish_root_table (struct flist *flp, const char *pfx,
1374 const char *tname, const char *lastname,
1375 const char *name);
1376 static void write_root (outf_p , pair_p, type_p, const char *, int,
1377 struct fileloc *, const char *);
1378 static void write_array (outf_p f, pair_p v,
1379 const struct write_types_data *wtd);
1380 static void write_roots (pair_p);
1381
1382 /* Parameters for walk_type. */
1383
1384 struct walk_type_data
1385 {
1386 process_field_fn process_field;
1387 const void *cookie;
1388 outf_p of;
1389 options_p opt;
1390 const char *val;
1391 const char *prev_val[4];
1392 int indent;
1393 int counter;
1394 struct fileloc *line;
1395 lang_bitmap bitmap;
1396 type_p *param;
1397 int used_length;
1398 type_p orig_s;
1399 const char *reorder_fn;
1400 int needs_cast_p;
1401 };
1402
1403 /* Print a mangled name representing T to OF. */
1404
1405 static void
1406 output_mangled_typename (outf_p of, type_p t)
1407 {
1408 if (t == NULL)
1409 oprintf (of, "Z");
1410 else switch (t->kind)
1411 {
1412 case TYPE_POINTER:
1413 oprintf (of, "P");
1414 output_mangled_typename (of, t->u.p);
1415 break;
1416 case TYPE_SCALAR:
1417 oprintf (of, "I");
1418 break;
1419 case TYPE_STRING:
1420 oprintf (of, "S");
1421 break;
1422 case TYPE_STRUCT:
1423 case TYPE_UNION:
1424 case TYPE_LANG_STRUCT:
1425 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
1426 break;
1427 case TYPE_PARAM_STRUCT:
1428 {
1429 int i;
1430 for (i = 0; i < NUM_PARAM; i++)
1431 if (t->u.param_struct.param[i] != NULL)
1432 output_mangled_typename (of, t->u.param_struct.param[i]);
1433 output_mangled_typename (of, t->u.param_struct.stru);
1434 }
1435 break;
1436 case TYPE_ARRAY:
1437 abort ();
1438 }
1439 }
1440
1441 /* Print PARAM to D->OF processing escapes. D->VAL references the
1442 current object, D->PREV_VAL the object containing the current
1443 object, ONAME is the name of the option and D->LINE is used to
1444 print error messages. */
1445
1446 static void
1447 output_escaped_param (struct walk_type_data *d, const char *param,
1448 const char *oname)
1449 {
1450 const char *p;
1451
1452 for (p = param; *p; p++)
1453 if (*p != '%')
1454 oprintf (d->of, "%c", *p);
1455 else switch (*++p)
1456 {
1457 case 'h':
1458 oprintf (d->of, "(%s)", d->prev_val[2]);
1459 break;
1460 case '0':
1461 oprintf (d->of, "(%s)", d->prev_val[0]);
1462 break;
1463 case '1':
1464 oprintf (d->of, "(%s)", d->prev_val[1]);
1465 break;
1466 case 'a':
1467 {
1468 const char *pp = d->val + strlen (d->val);
1469 while (pp[-1] == ']')
1470 while (*pp != '[')
1471 pp--;
1472 oprintf (d->of, "%s", pp);
1473 }
1474 break;
1475 default:
1476 error_at_line (d->line, "`%s' option contains bad escape %c%c",
1477 oname, '%', *p);
1478 }
1479 }
1480
1481 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
1482 which is of type T. Write code to D->OF to constrain execution (at
1483 the point that D->PROCESS_FIELD is called) to the appropriate
1484 cases. Call D->PROCESS_FIELD on subobjects before calling it on
1485 pointers to those objects. D->PREV_VAL lists the objects
1486 containing the current object, D->OPT is a list of options to
1487 apply, D->INDENT is the current indentation level, D->LINE is used
1488 to print error messages, D->BITMAP indicates which languages to
1489 print the structure for, and D->PARAM is the current parameter
1490 (from an enclosing param_is option). */
1491
1492 static void
1493 walk_type (type_p t, struct walk_type_data *d)
1494 {
1495 const char *length = NULL;
1496 const char *desc = NULL;
1497 int maybe_undef_p = 0;
1498 int use_param_num = -1;
1499 int use_params_p = 0;
1500 options_p oo;
1501
1502 d->needs_cast_p = 0;
1503 for (oo = d->opt; oo; oo = oo->next)
1504 if (strcmp (oo->name, "length") == 0)
1505 length = (const char *)oo->info;
1506 else if (strcmp (oo->name, "maybe_undef") == 0)
1507 maybe_undef_p = 1;
1508 else if (strncmp (oo->name, "use_param", 9) == 0
1509 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1510 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
1511 else if (strcmp (oo->name, "use_params") == 0)
1512 use_params_p = 1;
1513 else if (strcmp (oo->name, "desc") == 0)
1514 desc = (const char *)oo->info;
1515 else if (strcmp (oo->name, "dot") == 0)
1516 ;
1517 else if (strcmp (oo->name, "tag") == 0)
1518 ;
1519 else if (strcmp (oo->name, "special") == 0)
1520 ;
1521 else if (strcmp (oo->name, "skip") == 0)
1522 ;
1523 else if (strcmp (oo->name, "default") == 0)
1524 ;
1525 else if (strcmp (oo->name, "descbits") == 0)
1526 ;
1527 else if (strcmp (oo->name, "param_is") == 0)
1528 ;
1529 else if (strncmp (oo->name, "param", 5) == 0
1530 && ISDIGIT (oo->name[5])
1531 && strcmp (oo->name + 6, "_is") == 0)
1532 ;
1533 else if (strcmp (oo->name, "chain_next") == 0)
1534 ;
1535 else if (strcmp (oo->name, "chain_prev") == 0)
1536 ;
1537 else if (strcmp (oo->name, "reorder") == 0)
1538 ;
1539 else
1540 error_at_line (d->line, "unknown option `%s'\n", oo->name);
1541
1542 if (d->used_length)
1543 length = NULL;
1544
1545 if (use_params_p)
1546 {
1547 int pointer_p = t->kind == TYPE_POINTER;
1548
1549 if (pointer_p)
1550 t = t->u.p;
1551 if (! UNION_OR_STRUCT_P (t))
1552 error_at_line (d->line, "`use_params' option on unimplemented type");
1553 else
1554 t = find_param_structure (t, d->param);
1555 if (pointer_p)
1556 t = create_pointer (t);
1557 }
1558
1559 if (use_param_num != -1)
1560 {
1561 if (d->param != NULL && d->param[use_param_num] != NULL)
1562 {
1563 type_p nt = d->param[use_param_num];
1564
1565 if (t->kind == TYPE_ARRAY)
1566 nt = create_array (nt, t->u.a.len);
1567 else if (length != NULL && t->kind == TYPE_POINTER)
1568 nt = create_pointer (nt);
1569 d->needs_cast_p = (t->kind != TYPE_POINTER
1570 && (nt->kind == TYPE_POINTER
1571 || nt->kind == TYPE_STRING));
1572 t = nt;
1573 }
1574 else
1575 error_at_line (d->line, "no parameter defined for `%s'",
1576 d->val);
1577 }
1578
1579 if (maybe_undef_p
1580 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
1581 {
1582 error_at_line (d->line,
1583 "field `%s' has invalid option `maybe_undef_p'\n",
1584 d->val);
1585 return;
1586 }
1587
1588 switch (t->kind)
1589 {
1590 case TYPE_SCALAR:
1591 case TYPE_STRING:
1592 d->process_field (t, d);
1593 break;
1594
1595 case TYPE_POINTER:
1596 {
1597 if (maybe_undef_p
1598 && t->u.p->u.s.line.file == NULL)
1599 {
1600 oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
1601 break;
1602 }
1603
1604 if (! length)
1605 {
1606 if (! UNION_OR_STRUCT_P (t->u.p)
1607 && t->u.p->kind != TYPE_PARAM_STRUCT)
1608 {
1609 error_at_line (d->line,
1610 "field `%s' is pointer to unimplemented type",
1611 d->val);
1612 break;
1613 }
1614
1615 d->process_field (t->u.p, d);
1616 }
1617 else
1618 {
1619 int loopcounter = d->counter++;
1620 const char *oldval = d->val;
1621 const char *oldprevval3 = d->prev_val[3];
1622 char *newval;
1623
1624 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
1625 d->indent += 2;
1626 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1627 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1628 loopcounter, loopcounter);
1629 output_escaped_param (d, length, "length");
1630 oprintf (d->of, "); i%d++) {\n", loopcounter);
1631 d->indent += 2;
1632 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1633 d->used_length = 1;
1634 d->prev_val[3] = oldval;
1635 walk_type (t->u.p, d);
1636 free (newval);
1637 d->val = oldval;
1638 d->prev_val[3] = oldprevval3;
1639 d->used_length = 0;
1640 d->indent -= 2;
1641 oprintf (d->of, "%*s}\n", d->indent, "");
1642 d->process_field(t, d);
1643 d->indent -= 2;
1644 oprintf (d->of, "%*s}\n", d->indent, "");
1645 }
1646 }
1647 break;
1648
1649 case TYPE_ARRAY:
1650 {
1651 int loopcounter = d->counter++;
1652 const char *oldval = d->val;
1653 char *newval;
1654
1655 /* If it's an array of scalars, we optimize by not generating
1656 any code. */
1657 if (t->u.a.p->kind == TYPE_SCALAR)
1658 break;
1659
1660 oprintf (d->of, "%*s{\n", d->indent, "");
1661 d->indent += 2;
1662 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
1663 oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
1664 loopcounter, loopcounter);
1665 if (length)
1666 output_escaped_param (d, length, "length");
1667 else
1668 oprintf (d->of, "%s", t->u.a.len);
1669 oprintf (d->of, "); i%d++) {\n", loopcounter);
1670 d->indent += 2;
1671 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
1672 d->used_length = 1;
1673 walk_type (t->u.a.p, d);
1674 free (newval);
1675 d->used_length = 0;
1676 d->val = oldval;
1677 d->indent -= 2;
1678 oprintf (d->of, "%*s}\n", d->indent, "");
1679 d->indent -= 2;
1680 oprintf (d->of, "%*s}\n", d->indent, "");
1681 }
1682 break;
1683
1684 case TYPE_STRUCT:
1685 case TYPE_UNION:
1686 {
1687 pair_p f;
1688 const char *oldval = d->val;
1689 const char *oldprevval1 = d->prev_val[1];
1690 const char *oldprevval2 = d->prev_val[2];
1691 const int union_p = t->kind == TYPE_UNION;
1692 int seen_default_p = 0;
1693 options_p o;
1694
1695 if (! t->u.s.line.file)
1696 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
1697
1698 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
1699 {
1700 error_at_line (d->line,
1701 "structure `%s' defined for mismatching languages",
1702 t->u.s.tag);
1703 error_at_line (&t->u.s.line, "one structure defined here");
1704 }
1705
1706 /* Some things may also be defined in the structure's options. */
1707 for (o = t->u.s.opt; o; o = o->next)
1708 if (! desc && strcmp (o->name, "desc") == 0)
1709 desc = (const char *)o->info;
1710
1711 d->prev_val[2] = oldval;
1712 d->prev_val[1] = oldprevval2;
1713 if (union_p)
1714 {
1715 if (desc == NULL)
1716 {
1717 error_at_line (d->line, "missing `desc' option for union `%s'",
1718 t->u.s.tag);
1719 desc = "1";
1720 }
1721 oprintf (d->of, "%*sswitch (", d->indent, "");
1722 output_escaped_param (d, desc, "desc");
1723 oprintf (d->of, ")\n");
1724 d->indent += 2;
1725 oprintf (d->of, "%*s{\n", d->indent, "");
1726 }
1727 for (f = t->u.s.fields; f; f = f->next)
1728 {
1729 options_p oo;
1730 const char *dot = ".";
1731 const char *tagid = NULL;
1732 int skip_p = 0;
1733 int default_p = 0;
1734 int use_param_p = 0;
1735 char *newval;
1736
1737 d->reorder_fn = NULL;
1738 for (oo = f->opt; oo; oo = oo->next)
1739 if (strcmp (oo->name, "dot") == 0)
1740 dot = (const char *)oo->info;
1741 else if (strcmp (oo->name, "tag") == 0)
1742 tagid = (const char *)oo->info;
1743 else if (strcmp (oo->name, "skip") == 0)
1744 skip_p = 1;
1745 else if (strcmp (oo->name, "default") == 0)
1746 default_p = 1;
1747 else if (strcmp (oo->name, "reorder") == 0)
1748 d->reorder_fn = (const char *)oo->info;
1749 else if (strncmp (oo->name, "use_param", 9) == 0
1750 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
1751 use_param_p = 1;
1752
1753 if (skip_p)
1754 continue;
1755
1756 if (union_p && tagid)
1757 {
1758 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
1759 d->indent += 2;
1760 }
1761 else if (union_p && default_p)
1762 {
1763 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1764 d->indent += 2;
1765 seen_default_p = 1;
1766 }
1767 else if (! union_p && (default_p || tagid))
1768 error_at_line (d->line,
1769 "can't use `%s' outside a union on field `%s'",
1770 default_p ? "default" : "tag", f->name);
1771 else if (union_p && ! (default_p || tagid)
1772 && f->type->kind == TYPE_SCALAR)
1773 {
1774 fprintf (stderr,
1775 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
1776 d->line->file, d->line->line, f->name);
1777 continue;
1778 }
1779 else if (union_p && ! (default_p || tagid))
1780 error_at_line (d->line,
1781 "field `%s' is missing `tag' or `default' option",
1782 f->name);
1783
1784 d->line = &f->line;
1785 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
1786 d->opt = f->opt;
1787
1788 if (union_p && use_param_p && d->param == NULL)
1789 oprintf (d->of, "%*sabort();\n", d->indent, "");
1790 else
1791 walk_type (f->type, d);
1792
1793 free (newval);
1794
1795 if (union_p)
1796 {
1797 oprintf (d->of, "%*sbreak;\n", d->indent, "");
1798 d->indent -= 2;
1799 }
1800 }
1801 d->reorder_fn = NULL;
1802
1803 d->val = oldval;
1804 d->prev_val[1] = oldprevval1;
1805 d->prev_val[2] = oldprevval2;
1806
1807 if (union_p && ! seen_default_p)
1808 {
1809 oprintf (d->of, "%*sdefault:\n", d->indent, "");
1810 oprintf (d->of, "%*s break;\n", d->indent, "");
1811 }
1812 if (union_p)
1813 {
1814 oprintf (d->of, "%*s}\n", d->indent, "");
1815 d->indent -= 2;
1816 }
1817 }
1818 break;
1819
1820 case TYPE_LANG_STRUCT:
1821 {
1822 type_p nt;
1823 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
1824 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
1825 break;
1826 if (nt == NULL)
1827 error_at_line (d->line, "structure `%s' differs between languages",
1828 t->u.s.tag);
1829 else
1830 walk_type (nt, d);
1831 }
1832 break;
1833
1834 case TYPE_PARAM_STRUCT:
1835 {
1836 type_p *oldparam = d->param;
1837
1838 d->param = t->u.param_struct.param;
1839 walk_type (t->u.param_struct.stru, d);
1840 d->param = oldparam;
1841 }
1842 break;
1843
1844 default:
1845 abort ();
1846 }
1847 }
1848
1849 /* process_field routine for marking routines. */
1850
1851 static void
1852 write_types_process_field (type_p f, const struct walk_type_data *d)
1853 {
1854 const struct write_types_data *wtd;
1855 const char *cast = d->needs_cast_p ? "(void *)" : "";
1856 wtd = (const struct write_types_data *) d->cookie;
1857
1858 switch (f->kind)
1859 {
1860 case TYPE_POINTER:
1861 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
1862 wtd->subfield_marker_routine, cast, d->val);
1863 if (wtd->param_prefix)
1864 {
1865 oprintf (d->of, ", %s", d->prev_val[3]);
1866 if (d->orig_s)
1867 {
1868 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
1869 output_mangled_typename (d->of, d->orig_s);
1870 }
1871 else
1872 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
1873 }
1874 oprintf (d->of, ");\n");
1875 if (d->reorder_fn && wtd->reorder_note_routine)
1876 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
1877 wtd->reorder_note_routine, cast, d->val,
1878 d->prev_val[3], d->reorder_fn);
1879 break;
1880
1881 case TYPE_STRING:
1882 if (wtd->param_prefix == NULL)
1883 break;
1884
1885 case TYPE_STRUCT:
1886 case TYPE_UNION:
1887 case TYPE_LANG_STRUCT:
1888 case TYPE_PARAM_STRUCT:
1889 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
1890 output_mangled_typename (d->of, f);
1891 oprintf (d->of, " (%s%s);\n", cast, d->val);
1892 if (d->reorder_fn && wtd->reorder_note_routine)
1893 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
1894 wtd->reorder_note_routine, cast, d->val, cast, d->val,
1895 d->reorder_fn);
1896 break;
1897
1898 case TYPE_SCALAR:
1899 break;
1900
1901 default:
1902 abort ();
1903 }
1904 }
1905
1906 /* For S, a structure that's part of ORIG_S, and using parameters
1907 PARAM, write out a routine that:
1908 - Takes a parameter, a void * but actually of type *S
1909 - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
1910 field of S or its substructures and (in some cases) things
1911 that are pointed to by S.
1912 */
1913
1914 static void
1915 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
1916 const struct write_types_data *wtd)
1917 {
1918 const char *fn = s->u.s.line.file;
1919 int i;
1920 const char *chain_next = NULL;
1921 const char *chain_prev = NULL;
1922 options_p opt;
1923 struct walk_type_data d;
1924
1925 /* This is a hack, and not the good kind either. */
1926 for (i = NUM_PARAM - 1; i >= 0; i--)
1927 if (param && param[i] && param[i]->kind == TYPE_POINTER
1928 && UNION_OR_STRUCT_P (param[i]->u.p))
1929 fn = param[i]->u.p->u.s.line.file;
1930
1931 memset (&d, 0, sizeof (d));
1932 d.of = get_output_file_with_visibility (fn);
1933
1934 for (opt = s->u.s.opt; opt; opt = opt->next)
1935 if (strcmp (opt->name, "chain_next") == 0)
1936 chain_next = (const char *) opt->info;
1937 else if (strcmp (opt->name, "chain_prev") == 0)
1938 chain_prev = (const char *) opt->info;
1939
1940 if (chain_prev != NULL && chain_next == NULL)
1941 error_at_line (&s->u.s.line, "chain_prev without chain_next");
1942
1943 d.process_field = write_types_process_field;
1944 d.cookie = wtd;
1945 d.orig_s = orig_s;
1946 d.opt = s->u.s.opt;
1947 d.line = &s->u.s.line;
1948 d.bitmap = s->u.s.bitmap;
1949 d.param = param;
1950 d.prev_val[0] = "*x";
1951 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
1952 d.prev_val[3] = "x";
1953 d.val = "(*x)";
1954
1955 oprintf (d.of, "\n");
1956 oprintf (d.of, "void\n");
1957 if (param == NULL)
1958 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
1959 else
1960 {
1961 oprintf (d.of, "gt_%s_", wtd->prefix);
1962 output_mangled_typename (d.of, orig_s);
1963 }
1964 oprintf (d.of, " (void *x_p)\n");
1965 oprintf (d.of, "{\n");
1966 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
1967 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1968 chain_next == NULL ? "const " : "",
1969 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1970 if (chain_next != NULL)
1971 oprintf (d.of, " %s %s * xlimit = x;\n",
1972 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1973 if (chain_next == NULL)
1974 {
1975 oprintf (d.of, " if (%s (x", wtd->marker_routine);
1976 if (wtd->param_prefix)
1977 {
1978 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
1979 output_mangled_typename (d.of, orig_s);
1980 }
1981 oprintf (d.of, "))\n");
1982 }
1983 else
1984 {
1985 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
1986 if (wtd->param_prefix)
1987 {
1988 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
1989 output_mangled_typename (d.of, orig_s);
1990 }
1991 oprintf (d.of, "))\n");
1992 oprintf (d.of, " xlimit = (");
1993 d.prev_val[2] = "*xlimit";
1994 output_escaped_param (&d, chain_next, "chain_next");
1995 oprintf (d.of, ");\n");
1996 if (chain_prev != NULL)
1997 {
1998 oprintf (d.of, " if (x != xlimit)\n");
1999 oprintf (d.of, " for (;;)\n");
2000 oprintf (d.of, " {\n");
2001 oprintf (d.of, " %s %s * const xprev = (",
2002 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2003
2004 d.prev_val[2] = "*x";
2005 output_escaped_param (&d, chain_prev, "chain_prev");
2006 oprintf (d.of, ");\n");
2007 oprintf (d.of, " if (xprev == NULL) break;\n");
2008 oprintf (d.of, " x = xprev;\n");
2009 oprintf (d.of, " (void) %s (xprev",
2010 wtd->marker_routine);
2011 if (wtd->param_prefix)
2012 {
2013 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
2014 output_mangled_typename (d.of, orig_s);
2015 }
2016 oprintf (d.of, ");\n");
2017 oprintf (d.of, " }\n");
2018 }
2019 oprintf (d.of, " while (x != xlimit)\n");
2020 }
2021 oprintf (d.of, " {\n");
2022
2023 d.prev_val[2] = "*x";
2024 d.indent = 6;
2025 walk_type (s, &d);
2026
2027 if (chain_next != NULL)
2028 {
2029 oprintf (d.of, " x = (");
2030 output_escaped_param (&d, chain_next, "chain_next");
2031 oprintf (d.of, ");\n");
2032 }
2033
2034 oprintf (d.of, " }\n");
2035 oprintf (d.of, "}\n");
2036 }
2037
2038 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
2039
2040 static void
2041 write_types (type_p structures, type_p param_structs,
2042 const struct write_types_data *wtd)
2043 {
2044 type_p s;
2045
2046 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
2047 for (s = structures; s; s = s->next)
2048 if (s->gc_used == GC_POINTED_TO
2049 || s->gc_used == GC_MAYBE_POINTED_TO)
2050 {
2051 options_p opt;
2052
2053 if (s->gc_used == GC_MAYBE_POINTED_TO
2054 && s->u.s.line.file == NULL)
2055 continue;
2056
2057 oprintf (header_file, "#define gt_%s_", wtd->prefix);
2058 output_mangled_typename (header_file, s);
2059 oprintf (header_file, "(X) do { \\\n");
2060 oprintf (header_file,
2061 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
2062 s->u.s.tag);
2063 oprintf (header_file,
2064 " } while (0)\n");
2065
2066 for (opt = s->u.s.opt; opt; opt = opt->next)
2067 if (strcmp (opt->name, "ptr_alias") == 0)
2068 {
2069 type_p t = (type_p) opt->info;
2070 if (t->kind == TYPE_STRUCT
2071 || t->kind == TYPE_UNION
2072 || t->kind == TYPE_LANG_STRUCT)
2073 oprintf (header_file,
2074 "#define gt_%sx_%s gt_%sx_%s\n",
2075 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
2076 else
2077 error_at_line (&s->u.s.line,
2078 "structure alias is not a structure");
2079 break;
2080 }
2081 if (opt)
2082 continue;
2083
2084 /* Declare the marker procedure only once. */
2085 oprintf (header_file,
2086 "extern void gt_%sx_%s (void *);\n",
2087 wtd->prefix, s->u.s.tag);
2088
2089 if (s->u.s.line.file == NULL)
2090 {
2091 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2092 s->u.s.tag);
2093 continue;
2094 }
2095
2096 if (s->kind == TYPE_LANG_STRUCT)
2097 {
2098 type_p ss;
2099 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2100 write_func_for_structure (s, ss, NULL, wtd);
2101 }
2102 else
2103 write_func_for_structure (s, s, NULL, wtd);
2104 }
2105
2106 for (s = param_structs; s; s = s->next)
2107 if (s->gc_used == GC_POINTED_TO)
2108 {
2109 type_p * param = s->u.param_struct.param;
2110 type_p stru = s->u.param_struct.stru;
2111
2112 /* Declare the marker procedure. */
2113 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
2114 output_mangled_typename (header_file, s);
2115 oprintf (header_file, " (void *);\n");
2116
2117 if (stru->u.s.line.file == NULL)
2118 {
2119 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2120 s->u.s.tag);
2121 continue;
2122 }
2123
2124 if (stru->kind == TYPE_LANG_STRUCT)
2125 {
2126 type_p ss;
2127 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2128 write_func_for_structure (s, ss, param, wtd);
2129 }
2130 else
2131 write_func_for_structure (s, stru, param, wtd);
2132 }
2133 }
2134
2135 static const struct write_types_data ggc_wtd =
2136 {
2137 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
2138 "GC marker procedures. "
2139 };
2140
2141 static const struct write_types_data pch_wtd =
2142 {
2143 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
2144 "gt_pch_note_reorder",
2145 "PCH type-walking procedures. "
2146 };
2147
2148 /* Write out the local pointer-walking routines. */
2149
2150 /* process_field routine for local pointer-walking. */
2151
2152 static void
2153 write_types_local_process_field (type_p f, const struct walk_type_data *d)
2154 {
2155 switch (f->kind)
2156 {
2157 case TYPE_POINTER:
2158 case TYPE_STRUCT:
2159 case TYPE_UNION:
2160 case TYPE_LANG_STRUCT:
2161 case TYPE_PARAM_STRUCT:
2162 case TYPE_STRING:
2163 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
2164 d->prev_val[3]);
2165 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
2166 break;
2167
2168 case TYPE_SCALAR:
2169 break;
2170
2171 default:
2172 abort ();
2173 }
2174 }
2175
2176 /* For S, a structure that's part of ORIG_S, and using parameters
2177 PARAM, write out a routine that:
2178 - Is of type gt_note_pointers
2179 - If calls PROCESS_FIELD on each field of S or its substructures.
2180 */
2181
2182 static void
2183 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
2184 {
2185 const char *fn = s->u.s.line.file;
2186 int i;
2187 struct walk_type_data d;
2188
2189 /* This is a hack, and not the good kind either. */
2190 for (i = NUM_PARAM - 1; i >= 0; i--)
2191 if (param && param[i] && param[i]->kind == TYPE_POINTER
2192 && UNION_OR_STRUCT_P (param[i]->u.p))
2193 fn = param[i]->u.p->u.s.line.file;
2194
2195 memset (&d, 0, sizeof (d));
2196 d.of = get_output_file_with_visibility (fn);
2197
2198 d.process_field = write_types_local_process_field;
2199 d.opt = s->u.s.opt;
2200 d.line = &s->u.s.line;
2201 d.bitmap = s->u.s.bitmap;
2202 d.param = param;
2203 d.prev_val[0] = d.prev_val[2] = "*x";
2204 d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
2205 d.prev_val[3] = "x";
2206 d.val = "(*x)";
2207
2208 oprintf (d.of, "\n");
2209 oprintf (d.of, "void\n");
2210 oprintf (d.of, "gt_pch_p_");
2211 output_mangled_typename (d.of, orig_s);
2212 oprintf (d.of, " (void *this_obj ATTRIBUTE_UNUSED,\n\tvoid *x_p,\n\tgt_pointer_operator op ATTRIBUTE_UNUSED,\n\tvoid *cookie ATTRIBUTE_UNUSED)\n");
2213 oprintf (d.of, "{\n");
2214 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
2215 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
2216 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
2217 d.indent = 2;
2218 walk_type (s, &d);
2219 oprintf (d.of, "}\n");
2220 }
2221
2222 /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
2223
2224 static void
2225 write_local (type_p structures, type_p param_structs)
2226 {
2227 type_p s;
2228
2229 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
2230 for (s = structures; s; s = s->next)
2231 if (s->gc_used == GC_POINTED_TO
2232 || s->gc_used == GC_MAYBE_POINTED_TO)
2233 {
2234 options_p opt;
2235
2236 if (s->u.s.line.file == NULL)
2237 continue;
2238
2239 for (opt = s->u.s.opt; opt; opt = opt->next)
2240 if (strcmp (opt->name, "ptr_alias") == 0)
2241 {
2242 type_p t = (type_p) opt->info;
2243 if (t->kind == TYPE_STRUCT
2244 || t->kind == TYPE_UNION
2245 || t->kind == TYPE_LANG_STRUCT)
2246 {
2247 oprintf (header_file, "#define gt_pch_p_");
2248 output_mangled_typename (header_file, s);
2249 oprintf (header_file, " gt_pch_p_");
2250 output_mangled_typename (header_file, t);
2251 oprintf (header_file, "\n");
2252 }
2253 else
2254 error_at_line (&s->u.s.line,
2255 "structure alias is not a structure");
2256 break;
2257 }
2258 if (opt)
2259 continue;
2260
2261 /* Declare the marker procedure only once. */
2262 oprintf (header_file, "extern void gt_pch_p_");
2263 output_mangled_typename (header_file, s);
2264 oprintf (header_file,
2265 "\n (void *, void *, gt_pointer_operator, void *);\n");
2266
2267 if (s->kind == TYPE_LANG_STRUCT)
2268 {
2269 type_p ss;
2270 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
2271 write_local_func_for_structure (s, ss, NULL);
2272 }
2273 else
2274 write_local_func_for_structure (s, s, NULL);
2275 }
2276
2277 for (s = param_structs; s; s = s->next)
2278 if (s->gc_used == GC_POINTED_TO)
2279 {
2280 type_p * param = s->u.param_struct.param;
2281 type_p stru = s->u.param_struct.stru;
2282
2283 /* Declare the marker procedure. */
2284 oprintf (header_file, "extern void gt_pch_p_");
2285 output_mangled_typename (header_file, s);
2286 oprintf (header_file,
2287 "\n (void *, void *, gt_pointer_operator, void *);\n");
2288
2289 if (stru->u.s.line.file == NULL)
2290 {
2291 fprintf (stderr, "warning: structure `%s' used but not defined\n",
2292 s->u.s.tag);
2293 continue;
2294 }
2295
2296 if (stru->kind == TYPE_LANG_STRUCT)
2297 {
2298 type_p ss;
2299 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
2300 write_local_func_for_structure (s, ss, param);
2301 }
2302 else
2303 write_local_func_for_structure (s, stru, param);
2304 }
2305 }
2306
2307 /* Write out the 'enum' definition for gt_types_enum. */
2308
2309 static void
2310 write_enum_defn (type_p structures, type_p param_structs)
2311 {
2312 type_p s;
2313
2314 oprintf (header_file, "\n/* Enumeration of types known. */\n");
2315 oprintf (header_file, "enum gt_types_enum {\n");
2316 for (s = structures; s; s = s->next)
2317 if (s->gc_used == GC_POINTED_TO
2318 || s->gc_used == GC_MAYBE_POINTED_TO)
2319 {
2320 if (s->gc_used == GC_MAYBE_POINTED_TO
2321 && s->u.s.line.file == NULL)
2322 continue;
2323
2324 oprintf (header_file, " gt_ggc_e_");
2325 output_mangled_typename (header_file, s);
2326 oprintf (header_file, ", \n");
2327 }
2328 for (s = param_structs; s; s = s->next)
2329 if (s->gc_used == GC_POINTED_TO)
2330 {
2331 oprintf (header_file, " gt_e_");
2332 output_mangled_typename (header_file, s);
2333 oprintf (header_file, ", \n");
2334 }
2335 oprintf (header_file, " gt_types_enum_last\n");
2336 oprintf (header_file, "};\n");
2337 }
2338
2339 /* Might T contain any non-pointer elements? */
2340
2341 static int
2342 contains_scalar_p (type_p t)
2343 {
2344 switch (t->kind)
2345 {
2346 case TYPE_STRING:
2347 case TYPE_POINTER:
2348 return 0;
2349 case TYPE_ARRAY:
2350 return contains_scalar_p (t->u.a.p);
2351 default:
2352 /* Could also check for structures that have no non-pointer
2353 fields, but there aren't enough of those to worry about. */
2354 return 1;
2355 }
2356 }
2357
2358 /* Mangle FN and print it to F. */
2359
2360 static void
2361 put_mangled_filename (outf_p f, const char *fn)
2362 {
2363 const char *name = get_output_file_name (fn);
2364 for (; *name != 0; name++)
2365 if (ISALNUM (*name))
2366 oprintf (f, "%c", *name);
2367 else
2368 oprintf (f, "%c", '_');
2369 }
2370
2371 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
2372 LASTNAME, and NAME are all strings to insert in various places in
2373 the resulting code. */
2374
2375 static void
2376 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
2377 const char *tname, const char *name)
2378 {
2379 struct flist *fli2;
2380
2381 for (fli2 = flp; fli2; fli2 = fli2->next)
2382 if (fli2->started_p)
2383 {
2384 oprintf (fli2->f, " %s\n", lastname);
2385 oprintf (fli2->f, "};\n\n");
2386 }
2387
2388 for (fli2 = flp; fli2; fli2 = fli2->next)
2389 if (fli2->started_p)
2390 {
2391 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2392 int fnum;
2393
2394 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2395 if (bitmap & 1)
2396 {
2397 oprintf (base_files[fnum],
2398 "extern const struct %s gt_%s_",
2399 tname, pfx);
2400 put_mangled_filename (base_files[fnum], fli2->name);
2401 oprintf (base_files[fnum], "[];\n");
2402 }
2403 }
2404
2405 {
2406 size_t fnum;
2407 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2408 oprintf (base_files [fnum],
2409 "const struct %s * const %s[] = {\n",
2410 tname, name);
2411 }
2412
2413
2414 for (fli2 = flp; fli2; fli2 = fli2->next)
2415 if (fli2->started_p)
2416 {
2417 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
2418 int fnum;
2419
2420 fli2->started_p = 0;
2421
2422 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
2423 if (bitmap & 1)
2424 {
2425 oprintf (base_files[fnum], " gt_%s_", pfx);
2426 put_mangled_filename (base_files[fnum], fli2->name);
2427 oprintf (base_files[fnum], ",\n");
2428 }
2429 }
2430
2431 {
2432 size_t fnum;
2433 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
2434 {
2435 oprintf (base_files[fnum], " NULL\n");
2436 oprintf (base_files[fnum], "};\n");
2437 }
2438 }
2439 }
2440
2441 /* Write out to F the table entry and any marker routines needed to
2442 mark NAME as TYPE. The original variable is V, at LINE.
2443 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
2444 is nonzero iff we are building the root table for hash table caches. */
2445
2446 static void
2447 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
2448 struct fileloc *line, const char *if_marked)
2449 {
2450 switch (type->kind)
2451 {
2452 case TYPE_STRUCT:
2453 {
2454 pair_p fld;
2455 for (fld = type->u.s.fields; fld; fld = fld->next)
2456 {
2457 int skip_p = 0;
2458 const char *desc = NULL;
2459 options_p o;
2460
2461 for (o = fld->opt; o; o = o->next)
2462 if (strcmp (o->name, "skip") == 0)
2463 skip_p = 1;
2464 else if (strcmp (o->name, "desc") == 0)
2465 desc = (const char *)o->info;
2466 else
2467 error_at_line (line,
2468 "field `%s' of global `%s' has unknown option `%s'",
2469 fld->name, name, o->name);
2470
2471 if (skip_p)
2472 continue;
2473 else if (desc && fld->type->kind == TYPE_UNION)
2474 {
2475 pair_p validf = NULL;
2476 pair_p ufld;
2477
2478 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
2479 {
2480 const char *tag = NULL;
2481 options_p oo;
2482
2483 for (oo = ufld->opt; oo; oo = oo->next)
2484 if (strcmp (oo->name, "tag") == 0)
2485 tag = (const char *)oo->info;
2486 if (tag == NULL || strcmp (tag, desc) != 0)
2487 continue;
2488 if (validf != NULL)
2489 error_at_line (line,
2490 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
2491 name, fld->name, validf->name,
2492 name, fld->name, ufld->name,
2493 tag);
2494 validf = ufld;
2495 }
2496 if (validf != NULL)
2497 {
2498 char *newname;
2499 newname = xasprintf ("%s.%s.%s",
2500 name, fld->name, validf->name);
2501 write_root (f, v, validf->type, newname, 0, line,
2502 if_marked);
2503 free (newname);
2504 }
2505 }
2506 else if (desc)
2507 error_at_line (line,
2508 "global `%s.%s' has `desc' option but is not union",
2509 name, fld->name);
2510 else
2511 {
2512 char *newname;
2513 newname = xasprintf ("%s.%s", name, fld->name);
2514 write_root (f, v, fld->type, newname, 0, line, if_marked);
2515 free (newname);
2516 }
2517 }
2518 }
2519 break;
2520
2521 case TYPE_ARRAY:
2522 {
2523 char *newname;
2524 newname = xasprintf ("%s[0]", name);
2525 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
2526 free (newname);
2527 }
2528 break;
2529
2530 case TYPE_POINTER:
2531 {
2532 type_p ap, tp;
2533
2534 oprintf (f, " {\n");
2535 oprintf (f, " &%s,\n", name);
2536 oprintf (f, " 1");
2537
2538 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2539 if (ap->u.a.len[0])
2540 oprintf (f, " * (%s)", ap->u.a.len);
2541 else if (ap == v->type)
2542 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
2543 oprintf (f, ",\n");
2544 oprintf (f, " sizeof (%s", v->name);
2545 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
2546 oprintf (f, "[0]");
2547 oprintf (f, "),\n");
2548
2549 tp = type->u.p;
2550
2551 if (! has_length && UNION_OR_STRUCT_P (tp))
2552 {
2553 oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
2554 oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
2555 }
2556 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
2557 {
2558 oprintf (f, " &gt_ggc_m_");
2559 output_mangled_typename (f, tp);
2560 oprintf (f, ",\n &gt_pch_n_");
2561 output_mangled_typename (f, tp);
2562 }
2563 else if (has_length
2564 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
2565 {
2566 oprintf (f, " &gt_ggc_ma_%s,\n", name);
2567 oprintf (f, " &gt_pch_na_%s", name);
2568 }
2569 else
2570 {
2571 error_at_line (line,
2572 "global `%s' is pointer to unimplemented type",
2573 name);
2574 }
2575 if (if_marked)
2576 oprintf (f, ",\n &%s", if_marked);
2577 oprintf (f, "\n },\n");
2578 }
2579 break;
2580
2581 case TYPE_STRING:
2582 {
2583 oprintf (f, " {\n");
2584 oprintf (f, " &%s,\n", name);
2585 oprintf (f, " 1, \n");
2586 oprintf (f, " sizeof (%s),\n", v->name);
2587 oprintf (f, " &gt_ggc_m_S,\n");
2588 oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
2589 oprintf (f, " },\n");
2590 }
2591 break;
2592
2593 case TYPE_SCALAR:
2594 break;
2595
2596 default:
2597 error_at_line (line,
2598 "global `%s' is unimplemented type",
2599 name);
2600 }
2601 }
2602
2603 /* This generates a routine to walk an array. */
2604
2605 static void
2606 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
2607 {
2608 struct walk_type_data d;
2609 char *prevval3;
2610
2611 memset (&d, 0, sizeof (d));
2612 d.of = f;
2613 d.cookie = wtd;
2614 d.indent = 2;
2615 d.line = &v->line;
2616 d.opt = v->opt;
2617 d.bitmap = get_base_file_bitmap (v->line.file);
2618 d.param = NULL;
2619
2620 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
2621
2622 if (wtd->param_prefix)
2623 {
2624 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
2625 oprintf (f,
2626 " (void *, void *, gt_pointer_operator, void *);\n");
2627 oprintf (f, "static void gt_%sa_%s (void *this_obj ATTRIBUTE_UNUSED,\n",
2628 wtd->param_prefix, v->name);
2629 oprintf (d.of, " void *x_p ATTRIBUTE_UNUSED,\n");
2630 oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED,\n");
2631 oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED)\n");
2632 oprintf (d.of, "{\n");
2633 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2634 d.process_field = write_types_local_process_field;
2635 walk_type (v->type, &d);
2636 oprintf (f, "}\n\n");
2637 }
2638
2639 d.opt = v->opt;
2640 oprintf (f, "static void gt_%sa_%s (void *);\n",
2641 wtd->prefix, v->name);
2642 oprintf (f, "static void\ngt_%sa_%s (void *x_p ATTRIBUTE_UNUSED)\n",
2643 wtd->prefix, v->name);
2644 oprintf (f, "{\n");
2645 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
2646 d.process_field = write_types_process_field;
2647 walk_type (v->type, &d);
2648 free (prevval3);
2649 oprintf (f, "}\n\n");
2650 }
2651
2652 /* Output a table describing the locations and types of VARIABLES. */
2653
2654 static void
2655 write_roots (pair_p variables)
2656 {
2657 pair_p v;
2658 struct flist *flp = NULL;
2659
2660 for (v = variables; v; v = v->next)
2661 {
2662 outf_p f = get_output_file_with_visibility (v->line.file);
2663 struct flist *fli;
2664 const char *length = NULL;
2665 int deletable_p = 0;
2666 options_p o;
2667
2668 for (o = v->opt; o; o = o->next)
2669 if (strcmp (o->name, "length") == 0)
2670 length = (const char *)o->info;
2671 else if (strcmp (o->name, "deletable") == 0)
2672 deletable_p = 1;
2673 else if (strcmp (o->name, "param_is") == 0)
2674 ;
2675 else if (strncmp (o->name, "param", 5) == 0
2676 && ISDIGIT (o->name[5])
2677 && strcmp (o->name + 6, "_is") == 0)
2678 ;
2679 else if (strcmp (o->name, "if_marked") == 0)
2680 ;
2681 else
2682 error_at_line (&v->line,
2683 "global `%s' has unknown option `%s'",
2684 v->name, o->name);
2685
2686 for (fli = flp; fli; fli = fli->next)
2687 if (fli->f == f)
2688 break;
2689 if (fli == NULL)
2690 {
2691 fli = xmalloc (sizeof (*fli));
2692 fli->f = f;
2693 fli->next = flp;
2694 fli->started_p = 0;
2695 fli->name = v->line.file;
2696 flp = fli;
2697
2698 oprintf (f, "\n/* GC roots. */\n\n");
2699 }
2700
2701 if (! deletable_p
2702 && length
2703 && v->type->kind == TYPE_POINTER
2704 && (v->type->u.p->kind == TYPE_POINTER
2705 || v->type->u.p->kind == TYPE_STRUCT))
2706 {
2707 write_array (f, v, &ggc_wtd);
2708 write_array (f, v, &pch_wtd);
2709 }
2710 }
2711
2712 for (v = variables; v; v = v->next)
2713 {
2714 outf_p f = get_output_file_with_visibility (v->line.file);
2715 struct flist *fli;
2716 int skip_p = 0;
2717 int length_p = 0;
2718 options_p o;
2719
2720 for (o = v->opt; o; o = o->next)
2721 if (strcmp (o->name, "length") == 0)
2722 length_p = 1;
2723 else if (strcmp (o->name, "deletable") == 0
2724 || strcmp (o->name, "if_marked") == 0)
2725 skip_p = 1;
2726
2727 if (skip_p)
2728 continue;
2729
2730 for (fli = flp; fli; fli = fli->next)
2731 if (fli->f == f)
2732 break;
2733 if (! fli->started_p)
2734 {
2735 fli->started_p = 1;
2736
2737 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
2738 put_mangled_filename (f, v->line.file);
2739 oprintf (f, "[] = {\n");
2740 }
2741
2742 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2743 }
2744
2745 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2746 "gt_ggc_rtab");
2747
2748 for (v = variables; v; v = v->next)
2749 {
2750 outf_p f = get_output_file_with_visibility (v->line.file);
2751 struct flist *fli;
2752 int skip_p = 1;
2753 options_p o;
2754
2755 for (o = v->opt; o; o = o->next)
2756 if (strcmp (o->name, "deletable") == 0)
2757 skip_p = 0;
2758 else if (strcmp (o->name, "if_marked") == 0)
2759 skip_p = 1;
2760
2761 if (skip_p)
2762 continue;
2763
2764 for (fli = flp; fli; fli = fli->next)
2765 if (fli->f == f)
2766 break;
2767 if (! fli->started_p)
2768 {
2769 fli->started_p = 1;
2770
2771 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
2772 put_mangled_filename (f, v->line.file);
2773 oprintf (f, "[] = {\n");
2774 }
2775
2776 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2777 v->name, v->name);
2778 }
2779
2780 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2781 "gt_ggc_deletable_rtab");
2782
2783 for (v = variables; v; v = v->next)
2784 {
2785 outf_p f = get_output_file_with_visibility (v->line.file);
2786 struct flist *fli;
2787 const char *if_marked = NULL;
2788 int length_p = 0;
2789 options_p o;
2790
2791 for (o = v->opt; o; o = o->next)
2792 if (strcmp (o->name, "length") == 0)
2793 length_p = 1;
2794 else if (strcmp (o->name, "if_marked") == 0)
2795 if_marked = (const char *) o->info;
2796
2797 if (if_marked == NULL)
2798 continue;
2799
2800 if (v->type->kind != TYPE_POINTER
2801 || v->type->u.p->kind != TYPE_PARAM_STRUCT
2802 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
2803 {
2804 error_at_line (&v->line, "if_marked option used but not hash table");
2805 continue;
2806 }
2807
2808 for (fli = flp; fli; fli = fli->next)
2809 if (fli->f == f)
2810 break;
2811 if (! fli->started_p)
2812 {
2813 fli->started_p = 1;
2814
2815 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
2816 put_mangled_filename (f, v->line.file);
2817 oprintf (f, "[] = {\n");
2818 }
2819
2820 write_root (f, v, v->type->u.p->u.param_struct.param[0],
2821 v->name, length_p, &v->line, if_marked);
2822 }
2823
2824 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
2825 "gt_ggc_cache_rtab");
2826
2827 for (v = variables; v; v = v->next)
2828 {
2829 outf_p f = get_output_file_with_visibility (v->line.file);
2830 struct flist *fli;
2831 int length_p = 0;
2832 int if_marked_p = 0;
2833 options_p o;
2834
2835 for (o = v->opt; o; o = o->next)
2836 if (strcmp (o->name, "length") == 0)
2837 length_p = 1;
2838 else if (strcmp (o->name, "if_marked") == 0)
2839 if_marked_p = 1;
2840
2841 if (! if_marked_p)
2842 continue;
2843
2844 for (fli = flp; fli; fli = fli->next)
2845 if (fli->f == f)
2846 break;
2847 if (! fli->started_p)
2848 {
2849 fli->started_p = 1;
2850
2851 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
2852 put_mangled_filename (f, v->line.file);
2853 oprintf (f, "[] = {\n");
2854 }
2855
2856 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
2857 }
2858
2859 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2860 "gt_pch_cache_rtab");
2861
2862 for (v = variables; v; v = v->next)
2863 {
2864 outf_p f = get_output_file_with_visibility (v->line.file);
2865 struct flist *fli;
2866 int skip_p = 0;
2867 options_p o;
2868
2869 for (o = v->opt; o; o = o->next)
2870 if (strcmp (o->name, "deletable") == 0
2871 || strcmp (o->name, "if_marked") == 0)
2872 skip_p = 1;
2873
2874 if (skip_p)
2875 continue;
2876
2877 if (! contains_scalar_p (v->type))
2878 continue;
2879
2880 for (fli = flp; fli; fli = fli->next)
2881 if (fli->f == f)
2882 break;
2883 if (! fli->started_p)
2884 {
2885 fli->started_p = 1;
2886
2887 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
2888 put_mangled_filename (f, v->line.file);
2889 oprintf (f, "[] = {\n");
2890 }
2891
2892 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
2893 v->name, v->name);
2894 }
2895
2896 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
2897 "gt_pch_scalar_rtab");
2898 }
2899
2900 \f
2901 extern int main (int argc, char **argv);
2902 int
2903 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
2904 {
2905 unsigned i;
2906 static struct fileloc pos = { __FILE__, __LINE__ };
2907 unsigned j;
2908
2909 gen_rtx_next ();
2910
2911 srcdir_len = strlen (srcdir);
2912
2913 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
2914 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
2915 do_scalar_typedef ("uint8", &pos);
2916 do_scalar_typedef ("jword", &pos);
2917 do_scalar_typedef ("JCF_u2", &pos);
2918 do_scalar_typedef ("void", &pos);
2919
2920 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
2921
2922 do_typedef ("HARD_REG_SET", create_array (
2923 create_scalar_type ("unsigned long", strlen ("unsigned long")),
2924 "2"), &pos);
2925
2926 for (i = 0; i < NUM_GT_FILES; i++)
2927 {
2928 int dupflag = 0;
2929 /* Omit if already seen. */
2930 for (j = 0; j < i; j++)
2931 {
2932 if (!strcmp (all_files[i], all_files[j]))
2933 {
2934 dupflag = 1;
2935 break;
2936 }
2937 }
2938 if (!dupflag)
2939 parse_file (all_files[i]);
2940 }
2941
2942 if (hit_error != 0)
2943 exit (1);
2944
2945 set_gc_used (variables);
2946
2947 open_base_files ();
2948 write_enum_defn (structures, param_structs);
2949 write_types (structures, param_structs, &ggc_wtd);
2950 write_types (structures, param_structs, &pch_wtd);
2951 write_local (structures, param_structs);
2952 write_roots (variables);
2953 write_rtx_next ();
2954 close_output_files ();
2955
2956 return (hit_error != 0);
2957 }