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