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