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