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
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
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
26 static int hit_error = 0;
28 error_at_line VPARAMS ((struct fileloc *pos, const char *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);
42 struct type string_type = {
43 TYPE_STRING, NULL, NULL, GC_USED
47 static pair_p typedefs;
48 static type_p structures;
49 static type_p param_structs;
50 static pair_p variables;
53 do_typedef (s, t, pos)
60 for (p = typedefs; p != NULL; p = p->next)
61 if (strcmp (p->name, s) == 0)
65 error_at_line (pos, "type `%s' previously defined", s);
66 error_at_line (&p->line, "previously defined here");
71 p = xmalloc (sizeof (struct pair));
80 resolve_typedef (s, pos)
85 for (p = typedefs; p != NULL; p = p->next)
86 if (strcmp (p->name, s) == 0)
88 error_at_line (pos, "unidentified type `%s'", s);
89 return create_scalar_type ("char", 4);
93 new_structure (name, isunion, pos, fields, o)
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)
109 if (si->kind == TYPE_LANG_STRUCT)
113 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
114 if (si->u.s.bitmap == bitmap)
117 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
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;
126 si->pointer_to = NULL;
127 si->u.s.lang_struct = ls;
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;
144 s = xcalloc (1, sizeof (struct type));
145 s->next = structures;
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;
159 s->u.s.fields = fields;
161 s->u.s.bitmap = bitmap;
162 if (s->u.s.lang_struct)
163 s->u.s.lang_struct->u.s.bitmap |= bitmap;
167 find_structure (name, isunion)
173 for (s = structures; s != NULL; s = s->next)
174 if (strcmp (name, s->u.s.tag) == 0
175 && UNION_P (s) == isunion)
178 s = xcalloc (1, sizeof (struct type));
179 s->next = structures;
181 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
188 create_scalar_type (name, 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);
204 type_p r = xcalloc (1, sizeof (struct type));
205 r->kind = TYPE_POINTER;
209 return t->pointer_to;
213 create_array (t, len)
219 v = xcalloc (1, sizeof (*v));
220 v->kind = TYPE_ARRAY;
227 adjust_field_type (t, opt)
232 const int pointer_p = t->kind == TYPE_POINTER;
234 for (; opt; opt = opt->next)
235 if (strcmp (opt->name, "length") == 0)
237 else if (strcmp (opt->name, "param_is") == 0)
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;
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))
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);
273 note_variable (s, t, o, pos)
280 n = xmalloc (sizeof (*n));
290 note_yacc_type (o, fields, typeinfo, pos)
299 for (p = typeinfo; p; p = p->next)
306 if (p->type == (type_p) 1)
311 for (pp = typeinfo; pp; pp = pp->next)
312 if (pp->type != (type_p) 1
313 && strcmp (pp->opt->info, p->opt->info) == 0)
322 for (m = fields; m; m = m->next)
323 if (strcmp (m->name, p->name) == 0)
327 error_at_line (&p->line,
328 "couldn't match fieldname `%s'", p->name);
339 || p->type == (type_p) 1)
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));
354 process_gc_options (opt, level, maybe_undef)
356 enum gc_used_enum level;
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)
368 set_gc_used_type (t, level)
370 enum gc_used_enum level;
372 if (t->gc_used >= level)
385 process_gc_options (t->u.s.opt, level, &dummy);
387 for (f = t->u.s.fields; f; f = f->next)
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);
395 set_gc_used_type (f->type, GC_USED);
401 set_gc_used_type (t->u.p, GC_POINTED_TO);
405 set_gc_used_type (t->u.a.p, GC_USED);
408 case TYPE_LANG_STRUCT:
409 for (t = t->u.s.lang_struct; t; t = t->next)
410 set_gc_used_type (t, level);
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);
424 set_gc_used (variables)
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;
440 const char *input_name;
441 const char *output_name;
445 static filemap_p files;
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 *));
466 static const char *const hdr[] = {
467 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
469 "This file is part of GCC.\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",
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",
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",
486 "/* This file is machine generated. Do not edit. */\n"
494 perror ("couldn't create temporary file");
497 fprintf (f, "/* Type information for %s.\n", name);
498 for (i = 0; i < sizeof(hdr)/sizeof(hdr[0]); i++)
504 open_base_files (void)
508 header_file = create_file ("GCC");
510 for (i = 0; i < NUM_BASE_FILES; i++)
515 base_files[i] = create_file (lang_names[i]);
516 newf = xmalloc (sizeof (*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)
530 get_file_basename (f)
534 const char *basename;
536 /* Determine the output file name. */
538 basename = strrchr (f, '/');
539 if (basename == NULL)
543 if (startswith (basename - f, basename-2, "f/"))
545 else if (startswith (basename - f, basename-3, "cp/"))
547 else if (startswith (basename - f, basename-4, "ada/"))
549 else if (startswith (basename - f, basename-5, "java/"))
551 else if (startswith (basename - f, basename-5, "objc/"))
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)
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)
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;
583 return (1 << NUM_BASE_FILES) - 1;
588 get_output_file_with_visibility (input_file)
589 const char *input_file;
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)
600 /* No, we'll be creating a new filemap. */
601 fm = xmalloc (sizeof (*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))
616 fm->output_name = s = xmalloc (sizeof ("gt-") + len);
617 sprintf (s, "gt-%s", basename);
618 for (; *s != '.'; s++)
619 if (! isalnum (*s) && *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";
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])] == '/')
639 sprintf (s, "gtype-%s.h", lang_names[i]);
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;
653 /* If not, create it. */
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);
685 get_output_file_name (input_file)
686 const char *input_file;
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);
698 close_output_files PARAMS ((void))
701 struct filemap header;
703 header.output_name = "gtype-desc.h";
704 header.output = header_file;
706 for (fm = &header; fm; fm = fm->next)
712 /* Handle each output file once. */
713 if (fm->output == NULL)
716 for (ofm = fm->next; ofm; ofm = ofm->next)
717 if (fm->output == ofm->output)
720 /* Compare the output file with the file to be created, avoiding
721 unnecessarily changing timestamps. */
722 newfile = fopen (fm->output_name, "r");
729 ch1 = fgetc (fm->output);
730 ch2 = fgetc (newfile);
731 } while (ch1 != EOF && ch1 == ch2);
735 no_write_p = ch1 == ch2;
740 /* Nothing interesting to do. Close the output file. */
747 newfile = fopen (fm->output_name, "w");
750 perror ("opening output file");
756 while ((ch = fgetc (fm->output)) != EOF)
771 static void output_escaped_param PARAMS ((FILE *, const char *, const char *,
772 const char *, const char *,
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,
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;
790 output_escaped_param (of, param, val, prev_val, oname, line)
794 const char *prev_val;
796 struct fileloc *line;
800 for (p = param; *p; p++)
803 else if (*++p == 'h')
804 fprintf (of, "(%s)", val);
808 fprintf (of, "(%s)", prev_val);
810 error_at_line (line, "`%s' option contains bad escape %c%c",
815 write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
820 const char *prev_val;
823 struct fileloc *line;
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;
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;
850 error_at_line (line, "missing `desc' option");
853 fprintf (of, "%*s{\n", indent, "");
855 fprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter);
856 output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
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;
867 int maybe_undef_p = 0;
872 if (t->kind == TYPE_SCALAR
873 || (t->kind == TYPE_ARRAY
874 && t->u.a.p->kind == TYPE_SCALAR))
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)
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)
888 else if (strcmp (oo->name, "always") == 0)
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)
899 error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
912 for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p)
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);
920 else if (s->kind == TYPE_UNION && ! always_p && tagid)
923 error_at_line (&f->line, "no parameter defined");
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",
932 if (s->kind == TYPE_UNION && ! always_p )
936 error_at_line (&f->line, "field `%s' has no tag", f->name);
939 fprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "",
947 /* Do nothing; strings go in the string pool. */
950 case TYPE_LANG_STRUCT:
953 for (ti = t->u.s.lang_struct; ti; ti = ti->next)
954 if (ti->u.s.bitmap & bitmap)
961 error_at_line (&f->line,
962 "structure not defined for this language");
966 /* Fall through... */
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);
984 && t->u.p->u.s.line.file == NULL)
985 fprintf (of, "%*sif (%s.%s) abort();\n", indent, "",
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,
997 error_at_line (&f->line, "field `%s' is pointer to scalar",
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, "",
1007 int loopcounter = ++gc_counter;
1009 fprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "",
1012 fprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
1013 fprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "",
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);
1020 switch (t->u.p->kind)
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,
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,
1041 error_at_line (&f->line,
1042 "field `%s' is array of pointer to scalar",
1046 error_at_line (&f->line,
1047 "field `%s' is array of unimplemented type",
1052 fprintf (of, "%*s}\n", indent, "");
1054 fprintf (of, "%*s}\n", indent, "");
1060 int loopcounter = ++gc_counter;
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)
1078 fprintf (of, "%*s{\n", indent, "");
1081 if (special != NULL && strcmp (special, "tree_exp") == 0)
1083 fprintf (of, "%*sconst size_t tree_exp_size = (",
1085 output_escaped_param (of, length, val, prev_val,
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,
1102 fputs (ta->u.a.len, of);
1106 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
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);
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);
1122 ta->kind == TYPE_ARRAY;
1123 ta = ta->u.a.p, i++)
1124 fprintf (of, "[i%d_%d]", loopcounter, i);
1127 else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
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);
1139 ta->kind == TYPE_ARRAY;
1140 ta = ta->u.a.p, i++)
1141 sprintf (newval + strlen (newval), "[i%d_%d]",
1143 write_gc_structure_fields (of, t->u.p, newval, val,
1144 f->opt, indent, &f->line, bitmap,
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, "");
1152 error_at_line (&f->line,
1153 "field `%s' is array of unimplemented type",
1155 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1158 fprintf (of, "%*s}\n", indent, "");
1161 if (special != NULL && strcmp (special, "tree_exp") == 0)
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);
1172 fprintf (of, "%*s}\n", indent, "");
1177 error_at_line (&f->line,
1178 "field `%s' is unimplemented type",
1183 if (s->kind == TYPE_UNION && ! always_p )
1186 fprintf (of, "%*s}\n", indent, "");
1189 error_at_line (&f->line, "unhandled special `%s'", special);
1191 if (s->kind == TYPE_UNION)
1194 fprintf (of, "%*s}\n", indent, "");
1199 write_gc_marker_routine_for_structure (s, param)
1205 f = get_output_file_with_visibility (s->u.s.line.file);
1207 f = get_output_file_with_visibility (param->u.s.line.file);
1210 fputs ("void\n", f);
1212 fprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag);
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);
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);
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,
1234 write_gc_types (structures, param_structs)
1236 type_p param_structs;
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)
1247 if (s->gc_used == GC_MAYBE_POINTED_TO
1248 && s->u.s.line.file == NULL)
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,
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);
1269 error_at_line (&s->u.s.line,
1270 "structure alias is not a structure");
1276 /* Declare the marker procedure only once. */
1277 fprintf (header_file,
1278 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1281 if (s->u.s.line.file == NULL)
1283 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1288 if (s->kind == TYPE_LANG_STRUCT)
1291 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
1292 write_gc_marker_routine_for_structure (ss, NULL);
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");
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,
1318 if (stru->u.s.line.file == NULL)
1320 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1325 if (stru->kind == TYPE_LANG_STRUCT)
1328 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
1329 write_gc_marker_routine_for_structure (ss, param);
1332 write_gc_marker_routine_for_structure (stru, param);
1337 put_mangled_filename (f, fn)
1341 const char *name = get_output_file_name (fn);
1342 for (; *name != 0; name++)
1343 if (isalnum (*name))
1350 finish_root_table (flp, pfx, lastname, tname, name)
1354 const char *lastname;
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);
1373 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1376 fprintf (base_files[fnum],
1377 "extern const struct %s gt_ggc_%s_",
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);
1390 fli2->started_p = 0;
1392 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1395 if (! (started_bitmap & (1 << fnum)))
1397 fprintf (base_files [fnum],
1398 "const struct %s * const %s[] = {\n",
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]);
1412 for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1415 fputs (" NULL\n", base_files[fnum]);
1416 fputs ("};\n\n", base_files[fnum]);
1422 write_gc_root (f, v, type, name, has_length, line, if_marked)
1428 struct fileloc *line;
1429 const char *if_marked;
1436 for (fld = type->u.s.fields; fld; fld = fld->next)
1439 const char *desc = NULL;
1442 for (o = fld->opt; o; o = o->next)
1443 if (strcmp (o->name, "skip") == 0)
1445 else if (strcmp (o->name, "desc") == 0)
1446 desc = (const char *)o->info;
1448 error_at_line (line,
1449 "field `%s' of global `%s' has unknown option `%s'",
1450 fld->name, name, o->name);
1454 else if (desc && fld->type->kind == TYPE_UNION)
1456 pair_p validf = NULL;
1459 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
1461 const char *tag = NULL;
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)
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,
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,
1490 error_at_line (line,
1491 "global `%s.%s' has `desc' option but is not union",
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);
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);
1520 fprintf (f, " &%s,\n", name);
1523 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1525 fprintf (f, " * (%s)", ap->u.a.len);
1526 else if (ap == v->type)
1527 fprintf (f, " * (sizeof (%s) / sizeof (%s[0]))",
1530 fprintf (f, " sizeof (%s", v->name);
1531 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1537 if (! has_length && UNION_OR_STRUCT_P (tp))
1539 fprintf (f, " >_ggc_mx_%s\n", tp->u.s.tag);
1541 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
1543 fprintf (f, " >_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);
1549 && tp->kind == TYPE_POINTER)
1551 fprintf (f, " >_ggc_ma_%s", name);
1555 error_at_line (line,
1556 "global `%s' is pointer to unimplemented type",
1560 fprintf (f, ",\n &%s", if_marked);
1561 fputs ("\n },\n", f);
1570 error_at_line (line,
1571 "global `%s' is unimplemented type",
1577 write_gc_roots (variables)
1581 struct flist *flp = NULL;
1583 for (v = variables; v; v = v->next)
1585 FILE *f = get_output_file_with_visibility (v->line.file);
1587 const char *length = NULL;
1588 int deletable_p = 0;
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)
1596 else if (strcmp (o->name, "param_is") == 0)
1598 else if (strcmp (o->name, "if_marked") == 0)
1601 error_at_line (&v->line,
1602 "global `%s' has unknown option `%s'",
1605 for (fli = flp; fli; fli = fli->next)
1610 fli = xmalloc (sizeof (*fli));
1614 fli->name = v->line.file;
1617 fputs ("\n/* GC roots. */\n\n", f);
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",
1628 fprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
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",
1650 fprintf (f, " gt_ggc_m_%s (x[i]);\n", s->u.s.tag);
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);
1662 write_gc_structure_fields (f, s, "x[i]", "x[i]",
1663 v->opt, 8, &v->line, s->u.s.bitmap,
1672 for (v = variables; v; v = v->next)
1674 FILE *f = get_output_file_with_visibility (v->line.file);
1680 for (o = v->opt; o; o = o->next)
1681 if (strcmp (o->name, "length") == 0)
1683 else if (strcmp (o->name, "deletable") == 0
1684 || strcmp (o->name, "if_marked") == 0)
1690 for (fli = flp; fli; fli = fli->next)
1693 if (! fli->started_p)
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",
1708 for (v = variables; v; v = v->next)
1710 FILE *f = get_output_file_with_visibility (v->line.file);
1715 for (o = v->opt; o; o = o->next)
1716 if (strcmp (o->name, "deletable") == 0)
1718 else if (strcmp (o->name, "if_marked") == 0)
1724 for (fli = flp; fli; fli = fli->next)
1727 if (! fli->started_p)
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",
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);
1747 const char *if_marked = NULL;
1751 for (o = v->opt; o; o = o->next)
1752 if (strcmp (o->name, "length") == 0)
1754 else if (strcmp (o->name, "if_marked") == 0)
1755 if_marked = (const char *) o->info;
1757 if (if_marked == NULL)
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");
1768 for (fli = flp; fli; fli = fli->next)
1771 if (! fli->started_p)
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));
1796 static struct fileloc pos = { __FILE__, __LINE__ };
1798 do_typedef ("CUMULATIVE_ARGS",
1799 create_scalar_type ("CUMULATIVE_ARGS",
1800 strlen ("CUMULATIVE_ARGS")),
1802 do_typedef ("REAL_VALUE_TYPE",
1803 create_scalar_type ("REAL_VALUE_TYPE",
1804 strlen ("REAL_VALUE_TYPE")),
1806 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1810 for (i = 1; i < argc; i++)
1811 parse_file (argv[i]);
1816 set_gc_used (variables);
1819 write_gc_types (structures, param_structs);
1820 write_gc_roots (variables);
1821 close_output_files ();
1823 return (hit_error != 0);