* config/xtensa/xtensa.c (xtensa_build_va_list): Use
[official-gcc.git] / gcc / gengtype.c
blob82d9a1166b10cd149e3701185a2a3d53aac993a8
1 /* Process source files and output type information.
2 Copyright (C) 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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. */
21 #include "hconfig.h"
22 #include "system.h"
23 #include <ctype.h>
24 #include "gengtype.h"
26 static int hit_error = 0;
27 void
28 error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
30 VA_OPEN (ap, msg);
31 VA_FIXEDARG (ap, struct fileloc *, pos);
32 VA_FIXEDARG (ap, const char *, msg);
34 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
35 vfprintf (stderr, msg, ap);
36 fputc ('\n', stderr);
37 hit_error = 1;
39 VA_CLOSE (ap);
42 struct type string_type = {
43 TYPE_STRING, NULL, NULL, GC_USED
44 UNION_INIT_ZERO
45 };
47 static pair_p typedefs;
48 static type_p structures;
49 static type_p param_structs;
50 static pair_p variables;
52 void
53 do_typedef (s, t, pos)
54 const char *s;
55 type_p t;
56 struct fileloc *pos;
58 pair_p p;
60 for (p = typedefs; p != NULL; p = p->next)
61 if (strcmp (p->name, s) == 0)
63 if (p->type != t)
65 error_at_line (pos, "type `%s' previously defined", s);
66 error_at_line (&p->line, "previously defined here");
68 return;
71 p = xmalloc (sizeof (struct pair));
72 p->next = typedefs;
73 p->name = s;
74 p->type = t;
75 p->line = *pos;
76 typedefs = p;
79 type_p
80 resolve_typedef (s, pos)
81 const char *s;
82 struct fileloc *pos;
84 pair_p p;
85 for (p = typedefs; p != NULL; p = p->next)
86 if (strcmp (p->name, s) == 0)
87 return p->type;
88 error_at_line (pos, "unidentified type `%s'", s);
89 return create_scalar_type ("char", 4);
92 void
93 new_structure (name, isunion, pos, fields, o)
94 const char *name;
95 int isunion;
96 struct fileloc *pos;
97 pair_p fields;
98 options_p o;
100 type_p si;
101 type_p s = NULL;
102 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
104 for (si = structures; si != NULL; si = si->next)
105 if (strcmp (name, si->u.s.tag) == 0
106 && UNION_P (si) == isunion)
108 type_p ls = NULL;
109 if (si->kind == TYPE_LANG_STRUCT)
111 ls = si;
113 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
114 if (si->u.s.bitmap == bitmap)
115 s = si;
117 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
119 ls = si;
120 si = xcalloc (1, sizeof (struct type));
121 memcpy (si, ls, sizeof (struct type));
122 ls->kind = TYPE_LANG_STRUCT;
123 ls->u.s.lang_struct = si;
124 ls->u.s.fields = NULL;
125 si->next = NULL;
126 si->pointer_to = NULL;
127 si->u.s.lang_struct = ls;
129 else
130 s = si;
132 if (ls != NULL && s == NULL)
134 s = xcalloc (1, sizeof (struct type));
135 s->next = ls->u.s.lang_struct;
136 ls->u.s.lang_struct = s;
137 s->u.s.lang_struct = ls;
139 break;
142 if (s == NULL)
144 s = xcalloc (1, sizeof (struct type));
145 s->next = structures;
146 structures = s;
149 if (s->u.s.line.file != NULL
150 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
152 error_at_line (pos, "duplicate structure definition");
153 error_at_line (&s->u.s.line, "previous definition here");
156 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
157 s->u.s.tag = name;
158 s->u.s.line = *pos;
159 s->u.s.fields = fields;
160 s->u.s.opt = o;
161 s->u.s.bitmap = bitmap;
162 if (s->u.s.lang_struct)
163 s->u.s.lang_struct->u.s.bitmap |= bitmap;
166 type_p
167 find_structure (name, isunion)
168 const char *name;
169 int isunion;
171 type_p s;
173 for (s = structures; s != NULL; s = s->next)
174 if (strcmp (name, s->u.s.tag) == 0
175 && UNION_P (s) == isunion)
176 return s;
178 s = xcalloc (1, sizeof (struct type));
179 s->next = structures;
180 structures = s;
181 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
182 s->u.s.tag = name;
183 structures = s;
184 return s;
187 type_p
188 create_scalar_type (name, name_len)
189 const char *name;
190 size_t name_len;
192 type_p r = xcalloc (1, sizeof (struct type));
193 r->kind = TYPE_SCALAR;
194 r->u.sc = xmemdup (name, name_len, name_len + 1);
195 return r;
198 type_p
199 create_pointer (t)
200 type_p t;
202 if (! t->pointer_to)
204 type_p r = xcalloc (1, sizeof (struct type));
205 r->kind = TYPE_POINTER;
206 r->u.p = t;
207 t->pointer_to = r;
209 return t->pointer_to;
212 type_p
213 create_array (t, len)
214 type_p t;
215 const char *len;
217 type_p v;
219 v = xcalloc (1, sizeof (*v));
220 v->kind = TYPE_ARRAY;
221 v->u.a.p = t;
222 v->u.a.len = len;
223 return v;
226 type_p
227 adjust_field_type (t, opt)
228 type_p t;
229 options_p opt;
231 int length_p = 0;
232 const int pointer_p = t->kind == TYPE_POINTER;
234 for (; opt; opt = opt->next)
235 if (strcmp (opt->name, "length") == 0)
236 length_p = 1;
237 else if (strcmp (opt->name, "param_is") == 0)
239 type_p realt;
241 if (pointer_p)
242 t = t->u.p;
244 for (realt = param_structs; realt; realt = realt->next)
245 if (realt->u.param_struct.stru == t
246 && realt->u.param_struct.param == (type_p) opt->info)
247 return pointer_p ? create_pointer (realt) : realt;
248 realt = xcalloc (1, sizeof (*realt));
249 realt->kind = TYPE_PARAM_STRUCT;
250 realt->next = param_structs;
251 param_structs = realt;
252 realt->u.param_struct.stru = t;
253 realt->u.param_struct.param = (type_p) opt->info;
254 return pointer_p ? create_pointer (realt) : realt;
257 if (! length_p
258 && pointer_p
259 && t->u.p->kind == TYPE_SCALAR
260 && (strcmp (t->u.p->u.sc, "char") == 0
261 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
262 return &string_type;
263 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
264 && t->u.a.p->u.p->kind == TYPE_SCALAR
265 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
266 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
267 return create_array (&string_type, t->u.a.len);
269 return t;
272 void
273 note_variable (s, t, o, pos)
274 const char *s;
275 type_p t;
276 options_p o;
277 struct fileloc *pos;
279 pair_p n;
280 n = xmalloc (sizeof (*n));
281 n->name = s;
282 n->type = t;
283 n->line = *pos;
284 n->opt = o;
285 n->next = variables;
286 variables = n;
289 void
290 note_yacc_type (o, fields, typeinfo, pos)
291 options_p o;
292 pair_p fields;
293 pair_p typeinfo;
294 struct fileloc *pos;
296 pair_p p;
297 pair_p *p_p;
299 for (p = typeinfo; p; p = p->next)
301 pair_p m;
303 if (p->name == NULL)
304 continue;
306 if (p->type == (type_p) 1)
308 pair_p pp;
309 int ok = 0;
311 for (pp = typeinfo; pp; pp = pp->next)
312 if (pp->type != (type_p) 1
313 && strcmp (pp->opt->info, p->opt->info) == 0)
315 ok = 1;
316 break;
318 if (! ok)
319 continue;
322 for (m = fields; m; m = m->next)
323 if (strcmp (m->name, p->name) == 0)
324 p->type = m->type;
325 if (p->type == NULL)
327 error_at_line (&p->line,
328 "couldn't match fieldname `%s'", p->name);
329 p->name = NULL;
333 p_p = &typeinfo;
334 while (*p_p)
336 pair_p p = *p_p;
338 if (p->name == NULL
339 || p->type == (type_p) 1)
340 *p_p = p->next;
341 else
342 p_p = &p->next;
345 new_structure ("yy_union", 1, pos, typeinfo, o);
346 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
349 static void process_gc_options PARAMS ((options_p, enum gc_used_enum, int *));
350 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum));
351 static void set_gc_used PARAMS ((pair_p));
353 static void
354 process_gc_options (opt, level, maybe_undef)
355 options_p opt;
356 enum gc_used_enum level;
357 int *maybe_undef;
359 options_p o;
360 for (o = opt; o; o = o->next)
361 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
362 set_gc_used_type ((type_p) o->info, GC_POINTED_TO);
363 else if (strcmp (o->name, "maybe_undef") == 0)
364 *maybe_undef = 1;
367 static void
368 set_gc_used_type (t, level)
369 type_p t;
370 enum gc_used_enum level;
372 if (t->gc_used >= level)
373 return;
375 t->gc_used = level;
377 switch (t->kind)
379 case TYPE_STRUCT:
380 case TYPE_UNION:
382 pair_p f;
383 int dummy;
385 process_gc_options (t->u.s.opt, level, &dummy);
387 for (f = t->u.s.fields; f; f = f->next)
389 int maybe_undef = 0;
390 process_gc_options (t->u.s.opt, level, &maybe_undef);
392 if (maybe_undef && f->type->kind == TYPE_POINTER)
393 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
394 else
395 set_gc_used_type (f->type, GC_USED);
397 break;
400 case TYPE_POINTER:
401 set_gc_used_type (t->u.p, GC_POINTED_TO);
402 break;
404 case TYPE_ARRAY:
405 set_gc_used_type (t->u.a.p, GC_USED);
406 break;
408 case TYPE_LANG_STRUCT:
409 for (t = t->u.s.lang_struct; t; t = t->next)
410 set_gc_used_type (t, level);
411 break;
413 case TYPE_PARAM_STRUCT:
414 set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO);
415 set_gc_used_type (t->u.param_struct.stru, GC_USED);
416 break;
418 default:
419 break;
423 static void
424 set_gc_used (variables)
425 pair_p variables;
427 pair_p p;
428 for (p = variables; p; p = p->next)
429 set_gc_used_type (p->type, GC_USED);
432 /* File mapping routines. For each input file, there is one output .c file
433 (but some output files have many input files), and there is one .h file
434 for the whole build. */
436 typedef struct filemap *filemap_p;
438 struct filemap {
439 filemap_p next;
440 const char *input_name;
441 const char *output_name;
442 FILE *output;
445 static filemap_p files;
446 FILE * header_file;
448 enum {
449 BASE_FILE_C,
450 BASE_FILE_OBJC,
451 BASE_FILE_CPLUSPLUS
453 static const char *lang_names[] = {
454 "c", "objc", "cp", "f", "ada", "java"
456 #define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
457 FILE *base_files[NUM_BASE_FILES];
459 static FILE * create_file PARAMS ((const char *));
460 static const char * get_file_basename PARAMS ((const char *));
462 static FILE *
463 create_file (name)
464 const char *name;
466 static const char *const hdr[] = {
467 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
468 "\n",
469 "This file is part of GCC.\n",
470 "\n",
471 "GCC is free software; you can redistribute it and/or modify it under\n",
472 "the terms of the GNU General Public License as published by the Free\n",
473 "Software Foundation; either version 2, or (at your option) any later\n",
474 "version.\n",
475 "\n",
476 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
477 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
478 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
479 "for more details.\n",
480 "\n",
481 "You should have received a copy of the GNU General Public License\n",
482 "along with GCC; see the file COPYING. If not, write to the Free\n",
483 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
484 "02111-1307, USA. */\n",
485 "\n",
486 "/* This file is machine generated. Do not edit. */\n"
488 FILE *f;
489 size_t i;
491 f = tmpfile();
492 if (f == NULL)
494 perror ("couldn't create temporary file");
495 exit (1);
497 fprintf (f, "/* Type information for %s.\n", name);
498 for (i = 0; i < sizeof(hdr)/sizeof(hdr[0]); i++)
499 fputs (hdr[i], f);
500 return f;
503 static void
504 open_base_files (void)
506 size_t i;
508 header_file = create_file ("GCC");
510 for (i = 0; i < NUM_BASE_FILES; i++)
512 filemap_p newf;
513 char *s;
515 base_files[i] = create_file (lang_names[i]);
516 newf = xmalloc (sizeof (*newf));
517 newf->next = files;
518 files = newf;
519 newf->input_name = NULL;
520 newf->output = base_files[i];
521 newf->output_name = s = xmalloc (16);
522 sprintf (s, "gtype-%s.h", lang_names[i]);
526 #define startswith(len, c, s) \
527 ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
529 static const char *
530 get_file_basename (f)
531 const char *f;
533 size_t len;
534 const char *basename;
536 /* Determine the output file name. */
537 len = strlen (f);
538 basename = strrchr (f, '/');
539 if (basename == NULL)
540 basename = f;
541 else
542 basename++;
543 if (startswith (basename - f, basename-2, "f/"))
544 basename -= 2;
545 else if (startswith (basename - f, basename-3, "cp/"))
546 basename -= 3;
547 else if (startswith (basename - f, basename-4, "ada/"))
548 basename -= 4;
549 else if (startswith (basename - f, basename-5, "java/"))
550 basename -= 5;
551 else if (startswith (basename - f, basename-5, "objc/"))
552 basename -= 5;
554 return basename;
557 unsigned
558 get_base_file_bitmap (input_file)
559 const char *input_file;
561 const char *basename = get_file_basename (input_file);
562 const char *slashpos = strchr (basename, '/');
563 size_t len = strlen (basename);
565 if (slashpos != NULL)
567 size_t i;
568 for (i = 0; i < NUM_BASE_FILES; i++)
569 if ((size_t)(slashpos - basename) == strlen (lang_names [i])
570 && memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0)
571 return 1 << i;
573 else if (strcmp (basename, "c-lang.c") == 0)
574 return 1 << BASE_FILE_C;
575 else if (strcmp (basename, "c-parse.in") == 0
576 || strcmp (basename, "c-tree.h") == 0
577 || strcmp (basename, "c-decl.c") == 0
578 || strcmp (basename, "c-objc-common.c") == 0)
579 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC;
580 else if (startswith (len, basename, "c-"))
581 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC | 1 << BASE_FILE_CPLUSPLUS;
582 else
583 return (1 << NUM_BASE_FILES) - 1;
584 abort ();
587 FILE *
588 get_output_file_with_visibility (input_file)
589 const char *input_file;
591 filemap_p fm, fmo;
592 size_t len;
593 const char *basename;
595 /* Do we already know the file? */
596 for (fm = files; fm; fm = fm->next)
597 if (input_file == fm->input_name)
598 return fm->output;
600 /* No, we'll be creating a new filemap. */
601 fm = xmalloc (sizeof (*fm));
602 fm->next = files;
603 files = fm;
604 fm->input_name = input_file;
606 /* Determine the output file name. */
607 basename = get_file_basename (input_file);
609 len = strlen (basename);
610 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
611 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
612 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
614 char *s;
616 fm->output_name = s = xmalloc (sizeof ("gt-") + len);
617 sprintf (s, "gt-%s", basename);
618 for (; *s != '.'; s++)
619 if (! isalnum (*s) && *s != '-')
620 *s = '-';
621 memcpy (s, ".h", sizeof (".h"));
623 else if (strcmp (basename, "c-common.h") == 0)
624 fm->output_name = "gt-c-common.h";
625 else if (strcmp (basename, "c-tree.h") == 0)
626 fm->output_name = "gt-c-decl.h";
627 else
629 size_t i;
631 fm->output_name = "gtype-desc.c";
632 for (i = 0; i < NUM_BASE_FILES; i++)
633 if (memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0
634 && basename[strlen(lang_names[i])] == '/')
636 char *s;
638 s = xmalloc (16);
639 sprintf (s, "gtype-%s.h", lang_names[i]);
640 fm->output_name = s;
641 break;
645 /* Look through to see if we've ever seen this output filename before. */
646 for (fmo = fm->next; fmo; fmo = fmo->next)
647 if (strcmp (fmo->output_name, fm->output_name) == 0)
649 fm->output = fmo->output;
650 break;
653 /* If not, create it. */
654 if (fmo == NULL)
656 fm->output = create_file (fm->output_name);
657 if (strcmp (fm->output_name, "gtype-desc.c") == 0)
659 fputs ("#include \"config.h\"\n", fm->output);
660 fputs ("#include \"system.h\"\n", fm->output);
661 fputs ("#include \"varray.h\"\n", fm->output);
662 fputs ("#include \"hashtab.h\"\n", fm->output);
663 fputs ("#include \"bitmap.h\"\n", fm->output);
664 fputs ("#include \"tree.h\"\n", fm->output);
665 fputs ("#include \"rtl.h\"\n", fm->output);
666 fputs ("#include \"function.h\"\n", fm->output);
667 fputs ("#include \"insn-config.h\"\n", fm->output);
668 fputs ("#include \"expr.h\"\n", fm->output);
669 fputs ("#include \"hard-reg-set.h\"\n", fm->output);
670 fputs ("#include \"basic-block.h\"\n", fm->output);
671 fputs ("#include \"cselib.h\"\n", fm->output);
672 fputs ("#include \"insn-addr.h\"\n", fm->output);
673 fputs ("#include \"ssa.h\"\n", fm->output);
674 fputs ("#include \"optabs.h\"\n", fm->output);
675 fputs ("#include \"libfuncs.h\"\n", fm->output);
676 fputs ("#include \"debug.h\"\n", fm->output);
677 fputs ("#include \"ggc.h\"\n", fm->output);
681 return fm->output;
684 const char *
685 get_output_file_name (input_file)
686 const char *input_file;
688 filemap_p fm;
690 for (fm = files; fm; fm = fm->next)
691 if (input_file == fm->input_name)
692 return fm->output_name;
693 (void) get_output_file_with_visibility (input_file);
694 return get_output_file_name (input_file);
697 static void
698 close_output_files PARAMS ((void))
700 filemap_p fm;
701 struct filemap header;
702 header.next = files;
703 header.output_name = "gtype-desc.h";
704 header.output = header_file;
706 for (fm = &header; fm; fm = fm->next)
708 int no_write_p;
709 filemap_p ofm;
710 FILE *newfile;
712 /* Handle each output file once. */
713 if (fm->output == NULL)
714 continue;
716 for (ofm = fm->next; ofm; ofm = ofm->next)
717 if (fm->output == ofm->output)
718 ofm->output = NULL;
720 /* Compare the output file with the file to be created, avoiding
721 unnecessarily changing timestamps. */
722 newfile = fopen (fm->output_name, "r");
723 if (newfile != NULL)
725 int ch1, ch2;
727 rewind (fm->output);
728 do {
729 ch1 = fgetc (fm->output);
730 ch2 = fgetc (newfile);
731 } while (ch1 != EOF && ch1 == ch2);
733 fclose (newfile);
735 no_write_p = ch1 == ch2;
737 else
738 no_write_p = 0;
740 /* Nothing interesting to do. Close the output file. */
741 if (no_write_p)
743 fclose (fm->output);
744 continue;
747 newfile = fopen (fm->output_name, "w");
748 if (newfile == NULL)
750 perror ("opening output file");
751 exit (1);
754 int ch;
755 rewind (fm->output);
756 while ((ch = fgetc (fm->output)) != EOF)
757 fputc (ch, newfile);
759 fclose (newfile);
760 fclose (fm->output);
764 struct flist {
765 struct flist *next;
766 int started_p;
767 const char *name;
768 FILE *f;
771 static void output_escaped_param PARAMS ((FILE *, const char *, const char *,
772 const char *, const char *,
773 struct fileloc *));
774 static void write_gc_structure_fields
775 PARAMS ((FILE *, type_p, const char *, const char *, options_p,
776 int, struct fileloc *, lang_bitmap, type_p));
777 static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
778 static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
779 static void put_mangled_filename PARAMS ((FILE *, const char *));
780 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
781 const char *tname, const char *lastname,
782 const char *name));
783 static void write_gc_root PARAMS ((FILE *, pair_p, type_p, const char *, int,
784 struct fileloc *, const char *));
785 static void write_gc_roots PARAMS ((pair_p));
787 static int gc_counter;
789 static void
790 output_escaped_param (of, param, val, prev_val, oname, line)
791 FILE *of;
792 const char *param;
793 const char *val;
794 const char *prev_val;
795 const char *oname;
796 struct fileloc *line;
798 const char *p;
800 for (p = param; *p; p++)
801 if (*p != '%')
802 fputc (*p, of);
803 else if (*++p == 'h')
804 fprintf (of, "(%s)", val);
805 else if (*p == '0')
806 fputs ("(*x)", of);
807 else if (*p == '1')
808 fprintf (of, "(%s)", prev_val);
809 else
810 error_at_line (line, "`%s' option contains bad escape %c%c",
811 oname, '%', *p);
814 static void
815 write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
816 param)
817 FILE *of;
818 type_p s;
819 const char *val;
820 const char *prev_val;
821 options_p opts;
822 int indent;
823 struct fileloc *line;
824 lang_bitmap bitmap;
825 type_p param;
827 pair_p f;
828 int tagcounter = -1;
830 if (! s->u.s.line.file)
831 error_at_line (line, "incomplete structure `%s'", s->u.s.tag);
832 else if ((s->u.s.bitmap & bitmap) != bitmap)
834 error_at_line (line, "structure defined for mismatching languages");
835 error_at_line (&s->u.s.line, "one structure defined here");
838 if (s->kind == TYPE_UNION)
840 const char *tagexpr = NULL;
841 options_p oo;
843 tagcounter = ++gc_counter;
844 for (oo = opts; oo; oo = oo->next)
845 if (strcmp (oo->name, "desc") == 0)
846 tagexpr = (const char *)oo->info;
847 if (tagexpr == NULL)
849 tagexpr = "1";
850 error_at_line (line, "missing `desc' option");
853 fprintf (of, "%*s{\n", indent, "");
854 indent += 2;
855 fprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter);
856 output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
857 fputs (");\n", of);
860 for (f = s->u.s.fields; f; f = f->next)
862 const char *tagid = NULL;
863 const char *length = NULL;
864 const char *special = NULL;
865 int skip_p = 0;
866 int always_p = 0;
867 int maybe_undef_p = 0;
868 int use_param_p = 0;
869 options_p oo;
870 type_p t = f->type;
872 if (t->kind == TYPE_SCALAR
873 || (t->kind == TYPE_ARRAY
874 && t->u.a.p->kind == TYPE_SCALAR))
875 continue;
877 for (oo = f->opt; oo; oo = oo->next)
878 if (strcmp (oo->name, "length") == 0)
879 length = (const char *)oo->info;
880 else if (strcmp (oo->name, "maybe_undef") == 0)
881 maybe_undef_p = 1;
882 else if (strcmp (oo->name, "tag") == 0)
883 tagid = (const char *)oo->info;
884 else if (strcmp (oo->name, "special") == 0)
885 special = (const char *)oo->info;
886 else if (strcmp (oo->name, "skip") == 0)
887 skip_p = 1;
888 else if (strcmp (oo->name, "always") == 0)
889 always_p = 1;
890 else if (strcmp (oo->name, "desc") == 0 && UNION_P (t))
892 else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t))
894 else if (strcmp (oo->name, "param_is") == 0)
896 else if (strcmp (oo->name, "use_param") == 0)
897 use_param_p = 1;
898 else
899 error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
901 if (skip_p)
902 continue;
904 if (use_param_p)
906 if (param != NULL)
908 type_p t1;
909 type_p nt = param;
910 int arraycount = 0;
912 for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p)
913 arraycount++;
914 for (; t->kind == TYPE_POINTER; t = t->u.p)
915 nt = create_pointer (nt);
916 while (arraycount-- > 0)
917 nt = create_array (nt, t->u.a.len);
918 t = nt;
920 else if (s->kind == TYPE_UNION && ! always_p && tagid)
922 else
923 error_at_line (&f->line, "no parameter defined");
926 if (maybe_undef_p
927 && (t->kind != TYPE_POINTER
928 || t->u.p->kind != TYPE_STRUCT))
929 error_at_line (&f->line,
930 "field `%s' has invalid option `maybe_undef_p'\n",
931 f->name);
932 if (s->kind == TYPE_UNION && ! always_p )
934 if (! tagid)
936 error_at_line (&f->line, "field `%s' has no tag", f->name);
937 continue;
939 fprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "",
940 tagcounter, tagid);
941 indent += 2;
944 switch (t->kind)
946 case TYPE_STRING:
947 /* Do nothing; strings go in the string pool. */
948 break;
950 case TYPE_LANG_STRUCT:
952 type_p ti;
953 for (ti = t->u.s.lang_struct; ti; ti = ti->next)
954 if (ti->u.s.bitmap & bitmap)
956 t = ti;
957 break;
959 if (ti == NULL)
961 error_at_line (&f->line,
962 "structure not defined for this language");
963 break;
966 /* Fall through... */
967 case TYPE_STRUCT:
968 case TYPE_UNION:
970 char *newval;
972 newval = xmalloc (strlen (val) + sizeof (".") + strlen (f->name));
973 sprintf (newval, "%s.%s", val, f->name);
974 write_gc_structure_fields (of, t, newval, val, f->opt, indent,
975 &f->line, bitmap, param);
976 free (newval);
977 break;
980 case TYPE_POINTER:
981 if (! length)
983 if (maybe_undef_p
984 && t->u.p->u.s.line.file == NULL)
985 fprintf (of, "%*sif (%s.%s) abort();\n", indent, "",
986 val, f->name);
987 else if (UNION_OR_STRUCT_P (t->u.p))
988 fprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "",
989 t->u.p->u.s.tag, val, f->name);
990 else if (t->u.p->kind == TYPE_PARAM_STRUCT)
991 fprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "",
992 (int) strlen (t->u.p->u.param_struct.param->u.s.tag),
993 t->u.p->u.param_struct.param->u.s.tag,
994 t->u.p->u.param_struct.stru->u.s.tag,
995 val, f->name);
996 else
997 error_at_line (&f->line, "field `%s' is pointer to scalar",
998 f->name);
999 break;
1001 else if (t->u.p->kind == TYPE_SCALAR
1002 || t->u.p->kind == TYPE_STRING)
1003 fprintf (of, "%*sggc_mark (%s.%s);\n", indent, "",
1004 val, f->name);
1005 else
1007 int loopcounter = ++gc_counter;
1009 fprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "",
1010 val, f->name);
1011 indent += 2;
1012 fprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
1013 fprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "",
1014 val, f->name);
1015 fprintf (of, "%*sfor (i%d = 0; i%d < (", indent, "",
1016 loopcounter, loopcounter);
1017 output_escaped_param (of, length, val, prev_val, "length", line);
1018 fprintf (of, "); i%d++) {\n", loopcounter);
1019 indent += 2;
1020 switch (t->u.p->kind)
1022 case TYPE_STRUCT:
1023 case TYPE_UNION:
1025 char *newval;
1027 newval = xmalloc (strlen (val) + 8 + strlen (f->name));
1028 sprintf (newval, "%s.%s[i%d]", val, f->name, loopcounter);
1029 write_gc_structure_fields (of, t->u.p, newval, val,
1030 f->opt, indent, &f->line,
1031 bitmap, param);
1032 free (newval);
1033 break;
1035 case TYPE_POINTER:
1036 if (UNION_OR_STRUCT_P (t->u.p->u.p))
1037 fprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "",
1038 t->u.p->u.p->u.s.tag, val, f->name,
1039 loopcounter);
1040 else
1041 error_at_line (&f->line,
1042 "field `%s' is array of pointer to scalar",
1043 f->name);
1044 break;
1045 default:
1046 error_at_line (&f->line,
1047 "field `%s' is array of unimplemented type",
1048 f->name);
1049 break;
1051 indent -= 2;
1052 fprintf (of, "%*s}\n", indent, "");
1053 indent -= 2;
1054 fprintf (of, "%*s}\n", indent, "");
1056 break;
1058 case TYPE_ARRAY:
1060 int loopcounter = ++gc_counter;
1061 type_p ta;
1062 int i;
1064 if (! length &&
1065 (strcmp (t->u.a.len, "0") == 0
1066 || strcmp (t->u.a.len, "1") == 0))
1067 error_at_line (&f->line,
1068 "field `%s' is array of size %s",
1069 f->name, t->u.a.len);
1071 /* Arrays of scalars can be ignored. */
1072 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1074 if (ta->kind == TYPE_SCALAR
1075 || ta->kind == TYPE_STRING)
1076 break;
1078 fprintf (of, "%*s{\n", indent, "");
1079 indent += 2;
1081 if (special != NULL && strcmp (special, "tree_exp") == 0)
1083 fprintf (of, "%*sconst size_t tree_exp_size = (",
1084 indent, "");
1085 output_escaped_param (of, length, val, prev_val,
1086 "length", line);
1087 fputs (");\n", of);
1089 length = "first_rtl_op (TREE_CODE ((tree)&%h))";
1092 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1094 fprintf (of, "%*ssize_t i%d_%d;\n",
1095 indent, "", loopcounter, i);
1096 fprintf (of, "%*sconst size_t ilimit%d_%d = (",
1097 indent, "", loopcounter, i);
1098 if (i == 0 && length != NULL)
1099 output_escaped_param (of, length, val, prev_val,
1100 "length", line);
1101 else
1102 fputs (ta->u.a.len, of);
1103 fputs (");\n", of);
1106 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1108 fprintf (of,
1109 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1110 indent, "", loopcounter, i, loopcounter, i,
1111 loopcounter, i, loopcounter, i);
1112 indent += 2;
1115 if (ta->kind == TYPE_POINTER
1116 && (ta->u.p->kind == TYPE_STRUCT
1117 || ta->u.p->kind == TYPE_UNION))
1119 fprintf (of, "%*sgt_ggc_m_%s (%s.%s",
1120 indent, "", ta->u.p->u.s.tag, val, f->name);
1121 for (ta = t, i = 0;
1122 ta->kind == TYPE_ARRAY;
1123 ta = ta->u.a.p, i++)
1124 fprintf (of, "[i%d_%d]", loopcounter, i);
1125 fputs (");\n", of);
1127 else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
1129 char *newval;
1130 int len;
1132 len = strlen (val) + strlen (f->name) + 2;
1133 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1134 len += sizeof ("[i_]") + 2*6;
1136 newval = xmalloc (len);
1137 sprintf (newval, "%s.%s", val, f->name);
1138 for (ta = t, i = 0;
1139 ta->kind == TYPE_ARRAY;
1140 ta = ta->u.a.p, i++)
1141 sprintf (newval + strlen (newval), "[i%d_%d]",
1142 loopcounter, i);
1143 write_gc_structure_fields (of, t->u.p, newval, val,
1144 f->opt, indent, &f->line, bitmap,
1145 param);
1146 free (newval);
1148 else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR
1149 && use_param_p && param == NULL)
1150 fprintf (of, "%*sabort();\n", indent, "");
1151 else
1152 error_at_line (&f->line,
1153 "field `%s' is array of unimplemented type",
1154 f->name);
1155 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1157 indent -= 2;
1158 fprintf (of, "%*s}\n", indent, "");
1161 if (special != NULL && strcmp (special, "tree_exp") == 0)
1163 fprintf (of,
1164 "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
1165 indent, "", loopcounter, loopcounter);
1166 fprintf (of, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
1167 indent, "", val, f->name, loopcounter);
1168 special = NULL;
1171 indent -= 2;
1172 fprintf (of, "%*s}\n", indent, "");
1173 break;
1176 default:
1177 error_at_line (&f->line,
1178 "field `%s' is unimplemented type",
1179 f->name);
1180 break;
1183 if (s->kind == TYPE_UNION && ! always_p )
1185 indent -= 2;
1186 fprintf (of, "%*s}\n", indent, "");
1188 if (special)
1189 error_at_line (&f->line, "unhandled special `%s'", special);
1191 if (s->kind == TYPE_UNION)
1193 indent -= 2;
1194 fprintf (of, "%*s}\n", indent, "");
1198 static void
1199 write_gc_marker_routine_for_structure (s, param)
1200 type_p s;
1201 type_p param;
1203 FILE *f;
1204 if (param == NULL)
1205 f = get_output_file_with_visibility (s->u.s.line.file);
1206 else
1207 f = get_output_file_with_visibility (param->u.s.line.file);
1209 fputc ('\n', f);
1210 fputs ("void\n", f);
1211 if (param == NULL)
1212 fprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag);
1213 else
1214 fprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param->u.s.tag),
1215 param->u.s.tag, s->u.s.tag);
1216 fputs (" void *x_p;\n", f);
1217 fputs ("{\n", f);
1218 fprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1219 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1220 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1221 fputs (" if (! ggc_test_and_set_mark (x))\n", f);
1222 fputs (" return;\n", f);
1224 gc_counter = 0;
1225 write_gc_structure_fields (f, s, "(*x)", "not valid postage",
1226 s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap,
1227 param);
1229 fputs ("}\n", f);
1233 static void
1234 write_gc_types (structures, param_structs)
1235 type_p structures;
1236 type_p param_structs;
1238 type_p s;
1240 fputs ("\n/* GC marker procedures. */\n", header_file);
1241 for (s = structures; s; s = s->next)
1242 if (s->gc_used == GC_POINTED_TO
1243 || s->gc_used == GC_MAYBE_POINTED_TO)
1245 options_p opt;
1247 if (s->gc_used == GC_MAYBE_POINTED_TO
1248 && s->u.s.line.file == NULL)
1249 continue;
1251 fprintf (header_file,
1252 "#define gt_ggc_m_%s(X) do { \\\n", s->u.s.tag);
1253 fprintf (header_file,
1254 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag);
1255 fprintf (header_file,
1256 " } while (0)\n");
1258 for (opt = s->u.s.opt; opt; opt = opt->next)
1259 if (strcmp (opt->name, "ptr_alias") == 0)
1261 type_p t = (type_p) opt->info;
1262 if (t->kind == TYPE_STRUCT
1263 || t->kind == TYPE_UNION
1264 || t->kind == TYPE_LANG_STRUCT)
1265 fprintf (header_file,
1266 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
1267 s->u.s.tag, t->u.s.tag);
1268 else
1269 error_at_line (&s->u.s.line,
1270 "structure alias is not a structure");
1271 break;
1273 if (opt)
1274 continue;
1276 /* Declare the marker procedure only once. */
1277 fprintf (header_file,
1278 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1279 s->u.s.tag);
1281 if (s->u.s.line.file == NULL)
1283 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1284 s->u.s.tag);
1285 continue;
1288 if (s->kind == TYPE_LANG_STRUCT)
1290 type_p ss;
1291 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
1292 write_gc_marker_routine_for_structure (ss, NULL);
1294 else
1295 write_gc_marker_routine_for_structure (s, NULL);
1298 for (s = param_structs; s; s = s->next)
1299 if (s->gc_used == GC_POINTED_TO)
1301 type_p param = s->u.param_struct.param;
1302 type_p stru = s->u.param_struct.stru;
1304 if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION
1305 && param->kind != TYPE_LANG_STRUCT)
1307 error_at_line (&s->u.param_struct.line,
1308 "unsupported parameter type");
1309 continue;
1312 /* Declare the marker procedure. */
1313 fprintf (header_file,
1314 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
1315 (int) strlen (param->u.s.tag), param->u.s.tag,
1316 stru->u.s.tag);
1318 if (stru->u.s.line.file == NULL)
1320 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1321 s->u.s.tag);
1322 continue;
1325 if (stru->kind == TYPE_LANG_STRUCT)
1327 type_p ss;
1328 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
1329 write_gc_marker_routine_for_structure (ss, param);
1331 else
1332 write_gc_marker_routine_for_structure (stru, param);
1336 static void
1337 put_mangled_filename (f, fn)
1338 FILE *f;
1339 const char *fn;
1341 const char *name = get_output_file_name (fn);
1342 for (; *name != 0; name++)
1343 if (isalnum (*name))
1344 fputc (*name, f);
1345 else
1346 fputc ('_', f);
1349 static void
1350 finish_root_table (flp, pfx, lastname, tname, name)
1351 struct flist *flp;
1352 const char *pfx;
1353 const char *tname;
1354 const char *lastname;
1355 const char *name;
1357 struct flist *fli2;
1358 unsigned started_bitmap = 0;
1360 for (fli2 = flp; fli2; fli2 = fli2->next)
1361 if (fli2->started_p)
1363 fprintf (fli2->f, " %s\n", lastname);
1364 fputs ("};\n\n", fli2->f);
1367 for (fli2 = flp; fli2; fli2 = fli2->next)
1368 if (fli2->started_p)
1370 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1371 int fnum;
1373 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1374 if (bitmap & 1)
1376 fprintf (base_files[fnum],
1377 "extern const struct %s gt_ggc_%s_",
1378 tname, pfx);
1379 put_mangled_filename (base_files[fnum], fli2->name);
1380 fputs ("[];\n", base_files[fnum]);
1384 for (fli2 = flp; fli2; fli2 = fli2->next)
1385 if (fli2->started_p)
1387 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1388 int fnum;
1390 fli2->started_p = 0;
1392 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1393 if (bitmap & 1)
1395 if (! (started_bitmap & (1 << fnum)))
1397 fprintf (base_files [fnum],
1398 "const struct %s * const %s[] = {\n",
1399 tname, name);
1400 started_bitmap |= 1 << fnum;
1402 fprintf (base_files[fnum], " gt_ggc_%s_", pfx);
1403 put_mangled_filename (base_files[fnum], fli2->name);
1404 fputs (",\n", base_files[fnum]);
1409 unsigned bitmap;
1410 int fnum;
1412 for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1413 if (bitmap & 1)
1415 fputs (" NULL\n", base_files[fnum]);
1416 fputs ("};\n\n", base_files[fnum]);
1421 static void
1422 write_gc_root (f, v, type, name, has_length, line, if_marked)
1423 FILE *f;
1424 pair_p v;
1425 type_p type;
1426 const char *name;
1427 int has_length;
1428 struct fileloc *line;
1429 const char *if_marked;
1431 switch (type->kind)
1433 case TYPE_STRUCT:
1435 pair_p fld;
1436 for (fld = type->u.s.fields; fld; fld = fld->next)
1438 int skip_p = 0;
1439 const char *desc = NULL;
1440 options_p o;
1442 for (o = fld->opt; o; o = o->next)
1443 if (strcmp (o->name, "skip") == 0)
1444 skip_p = 1;
1445 else if (strcmp (o->name, "desc") == 0)
1446 desc = (const char *)o->info;
1447 else
1448 error_at_line (line,
1449 "field `%s' of global `%s' has unknown option `%s'",
1450 fld->name, name, o->name);
1452 if (skip_p)
1453 continue;
1454 else if (desc && fld->type->kind == TYPE_UNION)
1456 pair_p validf = NULL;
1457 pair_p ufld;
1459 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
1461 const char *tag = NULL;
1462 options_p oo;
1464 for (oo = ufld->opt; oo; oo = oo->next)
1465 if (strcmp (oo->name, "tag") == 0)
1466 tag = (const char *)oo->info;
1467 if (tag == NULL || strcmp (tag, desc) != 0)
1468 continue;
1469 if (validf != NULL)
1470 error_at_line (line,
1471 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
1472 name, fld->name, validf->name,
1473 name, fld->name, ufld->name,
1474 tag);
1475 validf = ufld;
1477 if (validf != NULL)
1479 char *newname;
1480 newname = xmalloc (strlen (name) + 3 + strlen (fld->name)
1481 + strlen (validf->name));
1482 sprintf (newname, "%s.%s.%s",
1483 name, fld->name, validf->name);
1484 write_gc_root (f, v, validf->type, newname, 0, line,
1485 if_marked);
1486 free (newname);
1489 else if (desc)
1490 error_at_line (line,
1491 "global `%s.%s' has `desc' option but is not union",
1492 name, fld->name);
1493 else
1495 char *newname;
1496 newname = xmalloc (strlen (name) + 2 + strlen (fld->name));
1497 sprintf (newname, "%s.%s", name, fld->name);
1498 write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
1499 free (newname);
1503 break;
1505 case TYPE_ARRAY:
1507 char *newname;
1508 newname = xmalloc (strlen (name) + 4);
1509 sprintf (newname, "%s[0]", name);
1510 write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
1511 free (newname);
1513 break;
1515 case TYPE_POINTER:
1517 type_p ap, tp;
1519 fputs (" {\n", f);
1520 fprintf (f, " &%s,\n", name);
1521 fputs (" 1", f);
1523 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1524 if (ap->u.a.len[0])
1525 fprintf (f, " * (%s)", ap->u.a.len);
1526 else if (ap == v->type)
1527 fprintf (f, " * (sizeof (%s) / sizeof (%s[0]))",
1528 v->name, v->name);
1529 fputs (",\n", f);
1530 fprintf (f, " sizeof (%s", v->name);
1531 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1532 fputs ("[0]", f);
1533 fputs ("),\n", f);
1535 tp = type->u.p;
1537 if (! has_length && UNION_OR_STRUCT_P (tp))
1539 fprintf (f, " &gt_ggc_mx_%s\n", tp->u.s.tag);
1541 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
1543 fprintf (f, " &gt_ggc_mm_%d%s_%s",
1544 (int) strlen (tp->u.param_struct.param->u.s.tag),
1545 tp->u.param_struct.param->u.s.tag,
1546 tp->u.param_struct.stru->u.s.tag);
1548 else if (has_length
1549 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
1551 fprintf (f, " &gt_ggc_ma_%s", name);
1553 else
1555 error_at_line (line,
1556 "global `%s' is pointer to unimplemented type",
1557 name);
1559 if (if_marked)
1560 fprintf (f, ",\n &%s", if_marked);
1561 fputs ("\n },\n", f);
1563 break;
1565 case TYPE_SCALAR:
1566 case TYPE_STRING:
1567 break;
1569 default:
1570 error_at_line (line,
1571 "global `%s' is unimplemented type",
1572 name);
1576 static void
1577 write_gc_roots (variables)
1578 pair_p variables;
1580 pair_p v;
1581 struct flist *flp = NULL;
1583 for (v = variables; v; v = v->next)
1585 FILE *f = get_output_file_with_visibility (v->line.file);
1586 struct flist *fli;
1587 const char *length = NULL;
1588 int deletable_p = 0;
1589 options_p o;
1591 for (o = v->opt; o; o = o->next)
1592 if (strcmp (o->name, "length") == 0)
1593 length = (const char *)o->info;
1594 else if (strcmp (o->name, "deletable") == 0)
1595 deletable_p = 1;
1596 else if (strcmp (o->name, "param_is") == 0)
1598 else if (strcmp (o->name, "if_marked") == 0)
1600 else
1601 error_at_line (&v->line,
1602 "global `%s' has unknown option `%s'",
1603 v->name, o->name);
1605 for (fli = flp; fli; fli = fli->next)
1606 if (fli->f == f)
1607 break;
1608 if (fli == NULL)
1610 fli = xmalloc (sizeof (*fli));
1611 fli->f = f;
1612 fli->next = flp;
1613 fli->started_p = 0;
1614 fli->name = v->line.file;
1615 flp = fli;
1617 fputs ("\n/* GC roots. */\n\n", f);
1620 if (! deletable_p
1621 && length
1622 && v->type->kind == TYPE_POINTER
1623 && (v->type->u.p->kind == TYPE_POINTER
1624 || v->type->u.p->kind == TYPE_STRUCT))
1626 fprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
1627 v->name);
1628 fprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
1629 v->name);
1630 fputs ("{\n", f);
1631 fputs (" size_t i;\n", f);
1633 if (v->type->u.p->kind == TYPE_POINTER)
1635 type_p s = v->type->u.p->u.p;
1637 fprintf (f, " %s %s ** const x = (%s %s **)x_p;\n",
1638 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1639 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1640 fputs (" if (ggc_test_and_set_mark (x))\n", f);
1641 fprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1642 if (s->kind != TYPE_STRUCT && s->kind != TYPE_UNION)
1644 error_at_line (&v->line,
1645 "global `%s' has unsupported ** type",
1646 v->name);
1647 continue;
1650 fprintf (f, " gt_ggc_m_%s (x[i]);\n", s->u.s.tag);
1652 else
1654 type_p s = v->type->u.p;
1656 fprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1657 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1658 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1659 fputs (" if (ggc_test_and_set_mark (x))\n", f);
1660 fprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1661 fputs (" {\n", f);
1662 write_gc_structure_fields (f, s, "x[i]", "x[i]",
1663 v->opt, 8, &v->line, s->u.s.bitmap,
1664 NULL);
1665 fputs (" }\n", f);
1668 fputs ("}\n\n", f);
1672 for (v = variables; v; v = v->next)
1674 FILE *f = get_output_file_with_visibility (v->line.file);
1675 struct flist *fli;
1676 int skip_p = 0;
1677 int length_p = 0;
1678 options_p o;
1680 for (o = v->opt; o; o = o->next)
1681 if (strcmp (o->name, "length") == 0)
1682 length_p = 1;
1683 else if (strcmp (o->name, "deletable") == 0
1684 || strcmp (o->name, "if_marked") == 0)
1685 skip_p = 1;
1687 if (skip_p)
1688 continue;
1690 for (fli = flp; fli; fli = fli->next)
1691 if (fli->f == f)
1692 break;
1693 if (! fli->started_p)
1695 fli->started_p = 1;
1697 fputs ("const struct ggc_root_tab gt_ggc_r_", f);
1698 put_mangled_filename (f, v->line.file);
1699 fputs ("[] = {\n", f);
1702 write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL);
1705 finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1706 "gt_ggc_rtab");
1708 for (v = variables; v; v = v->next)
1710 FILE *f = get_output_file_with_visibility (v->line.file);
1711 struct flist *fli;
1712 int skip_p = 1;
1713 options_p o;
1715 for (o = v->opt; o; o = o->next)
1716 if (strcmp (o->name, "deletable") == 0)
1717 skip_p = 0;
1718 else if (strcmp (o->name, "if_marked") == 0)
1719 skip_p = 1;
1721 if (skip_p)
1722 continue;
1724 for (fli = flp; fli; fli = fli->next)
1725 if (fli->f == f)
1726 break;
1727 if (! fli->started_p)
1729 fli->started_p = 1;
1731 fputs ("const struct ggc_root_tab gt_ggc_rd_", f);
1732 put_mangled_filename (f, v->line.file);
1733 fputs ("[] = {\n", f);
1736 fprintf (f, " { &%s, 1, sizeof (%s), NULL },\n",
1737 v->name, v->name);
1740 finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1741 "gt_ggc_deletable_rtab");
1743 for (v = variables; v; v = v->next)
1745 FILE *f = get_output_file_with_visibility (v->line.file);
1746 struct flist *fli;
1747 const char *if_marked = NULL;
1748 int length_p = 0;
1749 options_p o;
1751 for (o = v->opt; o; o = o->next)
1752 if (strcmp (o->name, "length") == 0)
1753 length_p = 1;
1754 else if (strcmp (o->name, "if_marked") == 0)
1755 if_marked = (const char *) o->info;
1757 if (if_marked == NULL)
1758 continue;
1760 if (v->type->kind != TYPE_POINTER
1761 || v->type->u.p->kind != TYPE_PARAM_STRUCT
1762 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
1764 error_at_line (&v->line, "if_marked option used but not hash table");
1765 continue;
1768 for (fli = flp; fli; fli = fli->next)
1769 if (fli->f == f)
1770 break;
1771 if (! fli->started_p)
1773 fli->started_p = 1;
1775 fputs ("const struct ggc_cache_tab gt_ggc_rc_", f);
1776 put_mangled_filename (f, v->line.file);
1777 fputs ("[] = {\n", f);
1780 write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param),
1781 v->name, length_p, &v->line, if_marked);
1784 finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
1785 "gt_ggc_cache_rtab");
1789 extern int main PARAMS ((int argc, char **argv));
1790 int
1791 main(argc, argv)
1792 int argc;
1793 char **argv;
1795 int i;
1796 static struct fileloc pos = { __FILE__, __LINE__ };
1798 do_typedef ("CUMULATIVE_ARGS",
1799 create_scalar_type ("CUMULATIVE_ARGS",
1800 strlen ("CUMULATIVE_ARGS")),
1801 &pos);
1802 do_typedef ("REAL_VALUE_TYPE",
1803 create_scalar_type ("REAL_VALUE_TYPE",
1804 strlen ("REAL_VALUE_TYPE")),
1805 &pos);
1806 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1807 strlen ("void"))),
1808 &pos);
1810 for (i = 1; i < argc; i++)
1811 parse_file (argv[i]);
1813 if (hit_error != 0)
1814 exit (1);
1816 set_gc_used (variables);
1818 open_base_files ();
1819 write_gc_types (structures, param_structs);
1820 write_gc_roots (variables);
1821 close_output_files ();
1823 return (hit_error != 0);