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
25 /* Nonzero iff an error has occurred. */
26 static int hit_error = 0;
28 static void open_base_files PARAMS ((void));
29 static void close_output_files PARAMS ((void));
32 /* Report an error at POS, printing MSG. */
35 error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
38 VA_FIXEDARG (ap, struct fileloc *, pos);
39 VA_FIXEDARG (ap, const char *, msg);
41 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
42 vfprintf (stderr, msg, ap);
49 /* vasprintf, but produces fatal message on out-of-memory. */
51 xvasprintf (result, format, args)
56 int ret = vasprintf (result, format, args);
57 if (*result == NULL || ret < 0)
59 fputs ("gengtype: out of memory", stderr);
65 /* Wrapper for xvasprintf. */
67 xasprintf VPARAMS ((const char *format, ...))
71 VA_FIXEDARG (ap, const char *, format);
72 xvasprintf (&result, format, ap);
77 /* The one and only TYPE_STRING. */
79 struct type string_type = {
80 TYPE_STRING, NULL, NULL, GC_USED
84 /* Lists of various things. */
86 static pair_p typedefs;
87 static type_p structures;
88 static type_p param_structs;
89 static pair_p variables;
91 /* Define S as a typedef to T at POS. */
94 do_typedef (s, t, pos)
101 for (p = typedefs; p != NULL; p = p->next)
102 if (strcmp (p->name, s) == 0)
106 error_at_line (pos, "type `%s' previously defined", s);
107 error_at_line (&p->line, "previously defined here");
112 p = xmalloc (sizeof (struct pair));
120 /* Return the type previously defined for S. Use POS to report errors. */
123 resolve_typedef (s, pos)
128 for (p = typedefs; p != NULL; p = p->next)
129 if (strcmp (p->name, s) == 0)
131 error_at_line (pos, "unidentified type `%s'", s);
132 return create_scalar_type ("char", 4);
135 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
136 at POS with fields FIELDS and options O. */
139 new_structure (name, isunion, pos, fields, o)
148 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
150 for (si = structures; si != NULL; si = si->next)
151 if (strcmp (name, si->u.s.tag) == 0
152 && UNION_P (si) == isunion)
155 if (si->kind == TYPE_LANG_STRUCT)
159 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
160 if (si->u.s.bitmap == bitmap)
163 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
166 si = xcalloc (1, sizeof (struct type));
167 memcpy (si, ls, sizeof (struct type));
168 ls->kind = TYPE_LANG_STRUCT;
169 ls->u.s.lang_struct = si;
170 ls->u.s.fields = NULL;
172 si->pointer_to = NULL;
173 si->u.s.lang_struct = ls;
178 if (ls != NULL && s == NULL)
180 s = xcalloc (1, sizeof (struct type));
181 s->next = ls->u.s.lang_struct;
182 ls->u.s.lang_struct = s;
183 s->u.s.lang_struct = ls;
190 s = xcalloc (1, sizeof (struct type));
191 s->next = structures;
195 if (s->u.s.line.file != NULL
196 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
198 error_at_line (pos, "duplicate structure definition");
199 error_at_line (&s->u.s.line, "previous definition here");
202 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
205 s->u.s.fields = fields;
207 s->u.s.bitmap = bitmap;
208 if (s->u.s.lang_struct)
209 s->u.s.lang_struct->u.s.bitmap |= bitmap;
212 /* Return the previously-defined structure with tag NAME (or a union
213 iff ISUNION is nonzero), or a new empty structure or union if none
214 was defined previously. */
217 find_structure (name, isunion)
223 for (s = structures; s != NULL; s = s->next)
224 if (strcmp (name, s->u.s.tag) == 0
225 && UNION_P (s) == isunion)
228 s = xcalloc (1, sizeof (struct type));
229 s->next = structures;
231 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
237 /* Return a scalar type with name NAME. */
240 create_scalar_type (name, name_len)
244 type_p r = xcalloc (1, sizeof (struct type));
245 r->kind = TYPE_SCALAR;
246 r->u.sc = xmemdup (name, name_len, name_len + 1);
250 /* Return a pointer to T. */
258 type_p r = xcalloc (1, sizeof (struct type));
259 r->kind = TYPE_POINTER;
263 return t->pointer_to;
266 /* Return an array of length LEN. */
269 create_array (t, len)
275 v = xcalloc (1, sizeof (*v));
276 v->kind = TYPE_ARRAY;
282 /* Perform any special processing on a type T, about to become the type
283 of a field. Return the appropriate type for the field.
285 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
286 - Similarly for arrays of pointer-to-char;
287 - Converts structures for which a parameter is provided to
292 adjust_field_type (t, opt)
297 const int pointer_p = t->kind == TYPE_POINTER;
299 for (; opt; opt = opt->next)
300 if (strcmp (opt->name, "length") == 0)
302 else if (strcmp (opt->name, "param_is") == 0)
309 for (realt = param_structs; realt; realt = realt->next)
310 if (realt->u.param_struct.stru == t
311 && realt->u.param_struct.param == (type_p) opt->info)
312 return pointer_p ? create_pointer (realt) : realt;
313 realt = xcalloc (1, sizeof (*realt));
314 realt->kind = TYPE_PARAM_STRUCT;
315 realt->next = param_structs;
316 param_structs = realt;
317 realt->u.param_struct.stru = t;
318 realt->u.param_struct.param = (type_p) opt->info;
319 return pointer_p ? create_pointer (realt) : realt;
324 && t->u.p->kind == TYPE_SCALAR
325 && (strcmp (t->u.p->u.sc, "char") == 0
326 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
328 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
329 && t->u.a.p->u.p->kind == TYPE_SCALAR
330 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
331 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
332 return create_array (&string_type, t->u.a.len);
337 /* Add a variable named S of type T with options O defined at POS,
341 note_variable (s, t, o, pos)
348 n = xmalloc (sizeof (*n));
357 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
358 and information about the correspondance between token types and fields
359 in TYPEINFO. POS is used for error messages. */
362 note_yacc_type (o, fields, typeinfo, pos)
371 for (p = typeinfo; p; p = p->next)
378 if (p->type == (type_p) 1)
383 for (pp = typeinfo; pp; pp = pp->next)
384 if (pp->type != (type_p) 1
385 && strcmp (pp->opt->info, p->opt->info) == 0)
394 for (m = fields; m; m = m->next)
395 if (strcmp (m->name, p->name) == 0)
399 error_at_line (&p->line,
400 "couldn't match fieldname `%s'", p->name);
411 || p->type == (type_p) 1)
417 new_structure ("yy_union", 1, pos, typeinfo, o);
418 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
421 static void process_gc_options PARAMS ((options_p, enum gc_used_enum, int *));
422 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum));
423 static void set_gc_used PARAMS ((pair_p));
425 /* Handle OPT for set_gc_used_type. */
428 process_gc_options (opt, level, maybe_undef)
430 enum gc_used_enum level;
434 for (o = opt; o; o = o->next)
435 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
436 set_gc_used_type ((type_p) o->info, GC_POINTED_TO);
437 else if (strcmp (o->name, "maybe_undef") == 0)
441 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
444 set_gc_used_type (t, level)
446 enum gc_used_enum level;
448 if (t->gc_used >= level)
461 process_gc_options (t->u.s.opt, level, &dummy);
463 for (f = t->u.s.fields; f; f = f->next)
466 process_gc_options (t->u.s.opt, level, &maybe_undef);
468 if (maybe_undef && f->type->kind == TYPE_POINTER)
469 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
471 set_gc_used_type (f->type, GC_USED);
477 set_gc_used_type (t->u.p, GC_POINTED_TO);
481 set_gc_used_type (t->u.a.p, GC_USED);
484 case TYPE_LANG_STRUCT:
485 for (t = t->u.s.lang_struct; t; t = t->next)
486 set_gc_used_type (t, level);
489 case TYPE_PARAM_STRUCT:
490 set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO);
491 set_gc_used_type (t->u.param_struct.stru, GC_USED);
499 /* Set the gc_used fileds of all the types pointed to by VARIABLES. */
502 set_gc_used (variables)
506 for (p = variables; p; p = p->next)
507 set_gc_used_type (p->type, GC_USED);
510 /* File mapping routines. For each input file, there is one output .c file
511 (but some output files have many input files), and there is one .h file
512 for the whole build. */
514 /* The list of output files. */
515 static outf_p output_files;
517 /* The output header file that is included into pretty much every
529 static const char *const lang_names[] = {
530 "c", "objc", "cp", "treelang", "cobol", "f", "ada", "java"
532 #define NUM_BASE_FILES ARRAY_SIZE (lang_names)
533 outf_p base_files[NUM_BASE_FILES];
535 static outf_p create_file PARAMS ((const char *, const char *));
536 static const char * get_file_basename PARAMS ((const char *));
538 /* Create and return an outf_p for a new file for NAME, to be called
542 create_file (name, oname)
546 static const char *const hdr[] = {
547 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
549 "This file is part of GCC.\n",
551 "GCC is free software; you can redistribute it and/or modify it under\n",
552 "the terms of the GNU General Public License as published by the Free\n",
553 "Software Foundation; either version 2, or (at your option) any later\n",
556 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
557 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
558 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
559 "for more details.\n",
561 "You should have received a copy of the GNU General Public License\n",
562 "along with GCC; see the file COPYING. If not, write to the Free\n",
563 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
564 "02111-1307, USA. */\n",
566 "/* This file is machine generated. Do not edit. */\n"
571 f = xcalloc (sizeof (*f), 1);
572 f->next = output_files;
576 oprintf (f, "/* Type information for %s.\n", name);
577 for (i = 0; i < ARRAY_SIZE (hdr); i++)
578 oprintf (f, "%s", hdr[i]);
582 /* Print, like fprintf, to O. */
584 oprintf VPARAMS ((outf_p o, const char *format, ...))
589 VA_OPEN (ap, format);
590 VA_FIXEDARG (ap, outf_p, o);
591 VA_FIXEDARG (ap, const char *, format);
592 slength = xvasprintf (&s, format, ap);
594 if (o->bufused + slength > o->buflength)
596 size_t new_len = o->buflength;
601 } while (o->bufused + slength >= new_len);
602 o->buf = xrealloc (o->buf, new_len);
603 o->buflength = new_len;
605 memcpy (o->buf + o->bufused, s, slength);
606 o->bufused += slength;
611 /* Open the global header file and the language-specific header files. */
618 header_file = create_file ("GCC", "gtype-desc.h");
620 for (i = 0; i < NUM_BASE_FILES; i++)
621 base_files[i] = create_file (lang_names[i],
622 xasprintf ("gtype-%s.h", lang_names[i]));
624 /* gtype-desc.c is a little special, so we create it here. */
626 /* The order of files here matters very much. */
627 static const char *const ifiles [] = {
628 "config.h", "system.h", "varray.h", "hashtab.h",
629 "bitmap.h", "tree.h", "rtl.h", "function.h", "insn-config.h",
630 "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h",
631 "insn-addr.h", "ssa.h", "optabs.h", "libfuncs.h",
635 const char *const *ifp;
638 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
639 for (ifp = ifiles; *ifp; ifp++)
640 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
644 #define startswith(len, c, s) \
645 ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
647 /* Determine the pathname to F relative to $(srcdir). */
650 get_file_basename (f)
654 const char *basename;
656 /* Determine the output file name. */
658 basename = strrchr (f, '/');
659 if (basename == NULL)
663 if (startswith (basename - f, basename-2, "f/"))
665 else if (startswith (basename - f, basename-3, "cp/"))
667 else if (startswith (basename - f, basename-4, "ada/"))
669 else if (startswith (basename - f, basename-5, "java/"))
671 else if (startswith (basename - f, basename-5, "objc/"))
673 else if (startswith (basename - f, basename-9, "treelang/"))
675 else if (startswith (basename - f, basename-6, "cobol/"))
681 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
682 INPUT_FILE is used by <lang>.
684 This function should be written to assume that a file _is_ used
685 if the situation is unclear. If it wrongly assumes a file _is_ used,
686 a linker error will result. If it wrongly assumes a file _is not_ used,
687 some GC roots may be missed, which is a much harder-to-debug problem. */
690 get_base_file_bitmap (input_file)
691 const char *input_file;
693 const char *basename = get_file_basename (input_file);
694 const char *slashpos = strchr (basename, '/');
695 size_t len = strlen (basename);
697 if (slashpos != NULL)
700 for (i = 0; i < NUM_BASE_FILES; i++)
701 if ((size_t)(slashpos - basename) == strlen (lang_names [i])
702 && memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0)
705 else if (strcmp (basename, "c-lang.c") == 0)
706 return 1 << BASE_FILE_C;
707 else if (strcmp (basename, "c-parse.in") == 0
708 || strcmp (basename, "c-tree.h") == 0
709 || strcmp (basename, "c-decl.c") == 0
710 || strcmp (basename, "c-objc-common.c") == 0)
711 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC;
712 else if (startswith (len, basename, "c-common.c"))
713 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC| 1 << BASE_FILE_CPLUSPLUS
714 | 1 << BASE_FILE_TREELANG | 1 << BASE_FILE_COBOL;
715 else if (startswith (len, basename, "c-"))
716 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC | 1 << BASE_FILE_CPLUSPLUS;
718 return (1 << NUM_BASE_FILES) - 1;
722 /* An output file, suitable for definitions, that can see declarations
723 made in INPUT_FILE and is linked into every language that uses
727 get_output_file_with_visibility (input_file)
728 const char *input_file;
732 const char *basename;
733 const char *for_name;
734 const char *output_name;
736 /* This can happen when we need a file with visibility on a
737 structure that we've never seen. We have to just hope that it's
739 if (input_file == NULL)
740 input_file = "system.h";
742 /* Determine the output file name. */
743 basename = get_file_basename (input_file);
745 len = strlen (basename);
746 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
747 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
748 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
752 output_name = s = xasprintf ("gt-%s", basename);
753 for (; *s != '.'; s++)
754 if (! ISALNUM (*s) && *s != '-')
756 memcpy (s, ".h", sizeof (".h"));
759 else if (strcmp (basename, "c-common.h") == 0)
760 output_name = "gt-c-common.h", for_name = "c-common.c";
761 else if (strcmp (basename, "c-tree.h") == 0)
762 output_name = "gt-c-decl.h", for_name = "c-decl.c";
767 for (i = 0; i < NUM_BASE_FILES; i++)
768 if (memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0
769 && basename[strlen(lang_names[i])] == '/')
770 return base_files[i];
772 output_name = "gtype-desc.c";
776 /* Look through to see if we've ever seen this output filename before. */
777 for (r = output_files; r; r = r->next)
778 if (strcmp (r->name, output_name) == 0)
781 /* If not, create it. */
782 r = create_file (for_name, output_name);
787 /* The name of an output file, suitable for definitions, that can see
788 declarations made in INPUT_FILE and is linked into every language
789 that uses INPUT_FILE. */
792 get_output_file_name (input_file)
793 const char *input_file;
795 return get_output_file_with_visibility (input_file)->name;
798 /* Copy the output to its final destination,
799 but don't unnecessarily change modification times. */
802 close_output_files ()
806 for (of = output_files; of; of = of->next)
810 newfile = fopen (of->name, "r");
811 if (newfile != NULL )
816 for (i = 0; i < of->bufused; i++)
819 ch = fgetc (newfile);
820 if (ch == EOF || ch != (unsigned char) of->buf[i])
823 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
830 newfile = fopen (of->name, "w");
833 perror ("opening output file");
836 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
838 perror ("writing output file");
841 if (fclose (newfile) != 0)
843 perror ("closing output file");
856 static void output_escaped_param PARAMS ((outf_p , const char *, const char *,
857 const char *, const char *,
859 static void write_gc_structure_fields
860 PARAMS ((outf_p , type_p, const char *, const char *, options_p,
861 int, struct fileloc *, lang_bitmap, type_p));
862 static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
863 static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
864 static void put_mangled_filename PARAMS ((outf_p , const char *));
865 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
866 const char *tname, const char *lastname,
868 static void write_gc_root PARAMS ((outf_p , pair_p, type_p, const char *, int,
869 struct fileloc *, const char *));
870 static void write_gc_roots PARAMS ((pair_p));
872 static int gc_counter;
874 /* Print PARAM to OF processing escapes. VAL references the current object,
875 PREV_VAL the object containing the current object, ONAME is the name
876 of the option and LINE is used to print error messages. */
879 output_escaped_param (of, param, val, prev_val, oname, line)
883 const char *prev_val;
885 struct fileloc *line;
889 for (p = param; *p; p++)
891 oprintf (of, "%c", *p);
892 else if (*++p == 'h')
893 oprintf (of, "(%s)", val);
895 oprintf (of, "(*x)");
897 oprintf (of, "(%s)", prev_val);
899 error_at_line (line, "`%s' option contains bad escape %c%c",
903 /* Write out code to OF which marks the fields of S. VAL references
904 the current object, PREV_VAL the object containing the current
905 object, OPTS is a list of options to apply, INDENT is the current
906 indentation level, LINE is used to print error messages, BITMAP
907 indicates which languages to print the structure for, and PARAM is
908 the current parameter (from an enclosing param_is option). */
911 write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
916 const char *prev_val;
919 struct fileloc *line;
926 if (! s->u.s.line.file)
927 error_at_line (line, "incomplete structure `%s'", s->u.s.tag);
928 else if ((s->u.s.bitmap & bitmap) != bitmap)
930 error_at_line (line, "structure defined for mismatching languages");
931 error_at_line (&s->u.s.line, "one structure defined here");
934 if (s->kind == TYPE_UNION)
936 const char *tagexpr = NULL;
939 tagcounter = ++gc_counter;
940 for (oo = opts; oo; oo = oo->next)
941 if (strcmp (oo->name, "desc") == 0)
942 tagexpr = (const char *)oo->info;
946 error_at_line (line, "missing `desc' option");
949 oprintf (of, "%*s{\n", indent, "");
951 oprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter);
952 output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
953 oprintf (of, ");\n");
956 for (f = s->u.s.fields; f; f = f->next)
958 const char *tagid = NULL;
959 const char *length = NULL;
960 const char *special = NULL;
963 int maybe_undef_p = 0;
968 if (t->kind == TYPE_SCALAR
969 || (t->kind == TYPE_ARRAY
970 && t->u.a.p->kind == TYPE_SCALAR))
973 for (oo = f->opt; oo; oo = oo->next)
974 if (strcmp (oo->name, "length") == 0)
975 length = (const char *)oo->info;
976 else if (strcmp (oo->name, "maybe_undef") == 0)
978 else if (strcmp (oo->name, "tag") == 0)
979 tagid = (const char *)oo->info;
980 else if (strcmp (oo->name, "special") == 0)
981 special = (const char *)oo->info;
982 else if (strcmp (oo->name, "skip") == 0)
984 else if (strcmp (oo->name, "always") == 0)
986 else if (strcmp (oo->name, "desc") == 0 && UNION_P (t))
988 else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t))
990 else if (strcmp (oo->name, "param_is") == 0)
992 else if (strcmp (oo->name, "use_param") == 0)
995 error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
1008 for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p)
1010 for (; t->kind == TYPE_POINTER; t = t->u.p)
1011 nt = create_pointer (nt);
1012 while (arraycount-- > 0)
1013 nt = create_array (nt, t->u.a.len);
1016 else if (s->kind == TYPE_UNION && ! always_p && tagid)
1019 error_at_line (&f->line, "no parameter defined");
1023 && (t->kind != TYPE_POINTER
1024 || t->u.p->kind != TYPE_STRUCT))
1025 error_at_line (&f->line,
1026 "field `%s' has invalid option `maybe_undef_p'\n",
1028 if (s->kind == TYPE_UNION && ! always_p )
1032 error_at_line (&f->line, "field `%s' has no tag", f->name);
1035 oprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "",
1043 /* Do nothing; strings go in the string pool. */
1046 case TYPE_LANG_STRUCT:
1049 for (ti = t->u.s.lang_struct; ti; ti = ti->next)
1050 if (ti->u.s.bitmap & bitmap)
1057 error_at_line (&f->line,
1058 "structure not defined for this language");
1062 /* Fall through... */
1068 newval = xasprintf ("%s.%s", val, f->name);
1069 write_gc_structure_fields (of, t, newval, val, f->opt, indent,
1070 &f->line, bitmap, param);
1079 && t->u.p->u.s.line.file == NULL)
1080 oprintf (of, "%*sif (%s.%s) abort();\n", indent, "",
1082 else if (UNION_OR_STRUCT_P (t->u.p))
1083 oprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "",
1084 t->u.p->u.s.tag, val, f->name);
1085 else if (t->u.p->kind == TYPE_PARAM_STRUCT)
1086 oprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "",
1087 (int) strlen (t->u.p->u.param_struct.param->u.s.tag),
1088 t->u.p->u.param_struct.param->u.s.tag,
1089 t->u.p->u.param_struct.stru->u.s.tag,
1092 error_at_line (&f->line, "field `%s' is pointer to scalar",
1096 else if (t->u.p->kind == TYPE_SCALAR
1097 || t->u.p->kind == TYPE_STRING)
1098 oprintf (of, "%*sggc_mark (%s.%s);\n", indent, "",
1102 int loopcounter = ++gc_counter;
1104 oprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "",
1107 oprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
1108 oprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "",
1110 oprintf (of, "%*sfor (i%d = 0; i%d < (", indent, "",
1111 loopcounter, loopcounter);
1112 output_escaped_param (of, length, val, prev_val, "length", line);
1113 oprintf (of, "); i%d++) {\n", loopcounter);
1115 switch (t->u.p->kind)
1122 newval = xasprintf ("%s.%s[i%d]", val, f->name,
1124 write_gc_structure_fields (of, t->u.p, newval, val,
1125 f->opt, indent, &f->line,
1131 if (UNION_OR_STRUCT_P (t->u.p->u.p))
1132 oprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "",
1133 t->u.p->u.p->u.s.tag, val, f->name,
1136 error_at_line (&f->line,
1137 "field `%s' is array of pointer to scalar",
1141 error_at_line (&f->line,
1142 "field `%s' is array of unimplemented type",
1147 oprintf (of, "%*s}\n", indent, "");
1149 oprintf (of, "%*s}\n", indent, "");
1155 int loopcounter = ++gc_counter;
1160 (strcmp (t->u.a.len, "0") == 0
1161 || strcmp (t->u.a.len, "1") == 0))
1162 error_at_line (&f->line,
1163 "field `%s' is array of size %s",
1164 f->name, t->u.a.len);
1166 /* Arrays of scalars can be ignored. */
1167 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1169 if (ta->kind == TYPE_SCALAR
1170 || ta->kind == TYPE_STRING)
1173 oprintf (of, "%*s{\n", indent, "");
1176 if (special != NULL && strcmp (special, "tree_exp") == 0)
1178 oprintf (of, "%*sconst size_t tree_exp_size = (",
1180 output_escaped_param (of, length, val, prev_val,
1182 oprintf (of, ");\n");
1184 length = "first_rtl_op (TREE_CODE ((tree)&%h))";
1187 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1189 oprintf (of, "%*ssize_t i%d_%d;\n",
1190 indent, "", loopcounter, i);
1191 oprintf (of, "%*sconst size_t ilimit%d_%d = (",
1192 indent, "", loopcounter, i);
1193 if (i == 0 && length != NULL)
1194 output_escaped_param (of, length, val, prev_val,
1197 oprintf (of, "%s", ta->u.a.len);
1198 oprintf (of, ");\n");
1201 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1204 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1205 indent, "", loopcounter, i, loopcounter, i,
1206 loopcounter, i, loopcounter, i);
1210 if (ta->kind == TYPE_POINTER
1211 && (ta->u.p->kind == TYPE_STRUCT
1212 || ta->u.p->kind == TYPE_UNION))
1214 oprintf (of, "%*sgt_ggc_m_%s (%s.%s",
1215 indent, "", ta->u.p->u.s.tag, val, f->name);
1217 ta->kind == TYPE_ARRAY;
1218 ta = ta->u.a.p, i++)
1219 oprintf (of, "[i%d_%d]", loopcounter, i);
1220 oprintf (of, ");\n");
1222 else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
1227 len = strlen (val) + strlen (f->name) + 2;
1228 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1229 len += sizeof ("[i_]") + 2*6;
1231 newval = xmalloc (len);
1232 sprintf (newval, "%s.%s", val, f->name);
1234 ta->kind == TYPE_ARRAY;
1235 ta = ta->u.a.p, i++)
1236 sprintf (newval + strlen (newval), "[i%d_%d]",
1238 write_gc_structure_fields (of, t->u.p, newval, val,
1239 f->opt, indent, &f->line, bitmap,
1243 else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR
1244 && use_param_p && param == NULL)
1245 oprintf (of, "%*sabort();\n", indent, "");
1247 error_at_line (&f->line,
1248 "field `%s' is array of unimplemented type",
1250 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1253 oprintf (of, "%*s}\n", indent, "");
1256 if (special != NULL && strcmp (special, "tree_exp") == 0)
1259 "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
1260 indent, "", loopcounter, loopcounter);
1261 oprintf (of, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
1262 indent, "", val, f->name, loopcounter);
1267 oprintf (of, "%*s}\n", indent, "");
1272 error_at_line (&f->line,
1273 "field `%s' is unimplemented type",
1278 if (s->kind == TYPE_UNION && ! always_p )
1281 oprintf (of, "%*s}\n", indent, "");
1284 error_at_line (&f->line, "unhandled special `%s'", special);
1286 if (s->kind == TYPE_UNION)
1289 oprintf (of, "%*s}\n", indent, "");
1293 /* Write out a marker routine for S. PARAM is the parameter from an
1294 enclosing PARAM_IS option. */
1297 write_gc_marker_routine_for_structure (s, param)
1303 f = get_output_file_with_visibility (s->u.s.line.file);
1305 f = get_output_file_with_visibility (param->u.s.line.file);
1307 oprintf (f, "%c", '\n');
1308 oprintf (f, "void\n");
1310 oprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag);
1312 oprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param->u.s.tag),
1313 param->u.s.tag, s->u.s.tag);
1314 oprintf (f, " void *x_p;\n");
1316 oprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1317 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1318 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1319 oprintf (f, " if (! ggc_test_and_set_mark (x))\n");
1320 oprintf (f, " return;\n");
1323 write_gc_structure_fields (f, s, "(*x)", "not valid postage",
1324 s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap,
1330 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
1333 write_gc_types (structures, param_structs)
1335 type_p param_structs;
1339 oprintf (header_file, "\n/* GC marker procedures. */\n");
1340 for (s = structures; s; s = s->next)
1341 if (s->gc_used == GC_POINTED_TO
1342 || s->gc_used == GC_MAYBE_POINTED_TO)
1346 if (s->gc_used == GC_MAYBE_POINTED_TO
1347 && s->u.s.line.file == NULL)
1350 oprintf (header_file,
1351 "#define gt_ggc_m_%s(X) do { \\\n", s->u.s.tag);
1352 oprintf (header_file,
1353 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag);
1354 oprintf (header_file,
1357 for (opt = s->u.s.opt; opt; opt = opt->next)
1358 if (strcmp (opt->name, "ptr_alias") == 0)
1360 type_p t = (type_p) opt->info;
1361 if (t->kind == TYPE_STRUCT
1362 || t->kind == TYPE_UNION
1363 || t->kind == TYPE_LANG_STRUCT)
1364 oprintf (header_file,
1365 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
1366 s->u.s.tag, t->u.s.tag);
1368 error_at_line (&s->u.s.line,
1369 "structure alias is not a structure");
1375 /* Declare the marker procedure only once. */
1376 oprintf (header_file,
1377 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1380 if (s->u.s.line.file == NULL)
1382 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1387 if (s->kind == TYPE_LANG_STRUCT)
1390 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
1391 write_gc_marker_routine_for_structure (ss, NULL);
1394 write_gc_marker_routine_for_structure (s, NULL);
1397 for (s = param_structs; s; s = s->next)
1398 if (s->gc_used == GC_POINTED_TO)
1400 type_p param = s->u.param_struct.param;
1401 type_p stru = s->u.param_struct.stru;
1403 if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION
1404 && param->kind != TYPE_LANG_STRUCT)
1406 error_at_line (&s->u.param_struct.line,
1407 "unsupported parameter type");
1411 /* Declare the marker procedure. */
1412 oprintf (header_file,
1413 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
1414 (int) strlen (param->u.s.tag), param->u.s.tag,
1417 if (stru->u.s.line.file == NULL)
1419 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1424 if (stru->kind == TYPE_LANG_STRUCT)
1427 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
1428 write_gc_marker_routine_for_structure (ss, param);
1431 write_gc_marker_routine_for_structure (stru, param);
1435 /* Mangle FN and print it to F. */
1438 put_mangled_filename (f, fn)
1442 const char *name = get_output_file_name (fn);
1443 for (; *name != 0; name++)
1444 if (ISALNUM (*name))
1445 oprintf (f, "%c", *name);
1447 oprintf (f, "%c", '_');
1450 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
1451 LASTNAME, and NAME are all strings to insert in various places in
1452 the resulting code. */
1455 finish_root_table (flp, pfx, lastname, tname, name)
1459 const char *lastname;
1463 unsigned started_bitmap = 0;
1465 for (fli2 = flp; fli2; fli2 = fli2->next)
1466 if (fli2->started_p)
1468 oprintf (fli2->f, " %s\n", lastname);
1469 oprintf (fli2->f, "};\n\n");
1472 for (fli2 = flp; fli2; fli2 = fli2->next)
1473 if (fli2->started_p)
1475 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1478 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1481 oprintf (base_files[fnum],
1482 "extern const struct %s gt_ggc_%s_",
1484 put_mangled_filename (base_files[fnum], fli2->name);
1485 oprintf (base_files[fnum], "[];\n");
1489 for (fli2 = flp; fli2; fli2 = fli2->next)
1490 if (fli2->started_p)
1492 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1495 fli2->started_p = 0;
1497 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1500 if (! (started_bitmap & (1 << fnum)))
1502 oprintf (base_files [fnum],
1503 "const struct %s * const %s[] = {\n",
1505 started_bitmap |= 1 << fnum;
1507 oprintf (base_files[fnum], " gt_ggc_%s_", pfx);
1508 put_mangled_filename (base_files[fnum], fli2->name);
1509 oprintf (base_files[fnum], ",\n");
1517 for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1520 oprintf (base_files[fnum], " NULL\n");
1521 oprintf (base_files[fnum], "};\n\n");
1526 /* Write out to F the table entry and any marker routines needed to
1527 mark NAME as TYPE. The original variable is V, at LINE.
1528 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
1529 is nonzero iff we are building the root table for hash table caches. */
1532 write_gc_root (f, v, type, name, has_length, line, if_marked)
1538 struct fileloc *line;
1539 const char *if_marked;
1546 for (fld = type->u.s.fields; fld; fld = fld->next)
1549 const char *desc = NULL;
1552 for (o = fld->opt; o; o = o->next)
1553 if (strcmp (o->name, "skip") == 0)
1555 else if (strcmp (o->name, "desc") == 0)
1556 desc = (const char *)o->info;
1558 error_at_line (line,
1559 "field `%s' of global `%s' has unknown option `%s'",
1560 fld->name, name, o->name);
1564 else if (desc && fld->type->kind == TYPE_UNION)
1566 pair_p validf = NULL;
1569 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
1571 const char *tag = NULL;
1574 for (oo = ufld->opt; oo; oo = oo->next)
1575 if (strcmp (oo->name, "tag") == 0)
1576 tag = (const char *)oo->info;
1577 if (tag == NULL || strcmp (tag, desc) != 0)
1580 error_at_line (line,
1581 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
1582 name, fld->name, validf->name,
1583 name, fld->name, ufld->name,
1590 newname = xasprintf ("%s.%s.%s",
1591 name, fld->name, validf->name);
1592 write_gc_root (f, v, validf->type, newname, 0, line,
1598 error_at_line (line,
1599 "global `%s.%s' has `desc' option but is not union",
1604 newname = xasprintf ("%s.%s", name, fld->name);
1605 write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
1615 newname = xasprintf ("%s[0]", name);
1616 write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
1625 oprintf (f, " {\n");
1626 oprintf (f, " &%s,\n", name);
1629 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1631 oprintf (f, " * (%s)", ap->u.a.len);
1632 else if (ap == v->type)
1633 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
1635 oprintf (f, " sizeof (%s", v->name);
1636 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1638 oprintf (f, "),\n");
1642 if (! has_length && UNION_OR_STRUCT_P (tp))
1644 oprintf (f, " >_ggc_mx_%s\n", tp->u.s.tag);
1646 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
1648 oprintf (f, " >_ggc_mm_%d%s_%s",
1649 (int) strlen (tp->u.param_struct.param->u.s.tag),
1650 tp->u.param_struct.param->u.s.tag,
1651 tp->u.param_struct.stru->u.s.tag);
1654 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
1656 oprintf (f, " >_ggc_ma_%s", name);
1660 error_at_line (line,
1661 "global `%s' is pointer to unimplemented type",
1665 oprintf (f, ",\n &%s", if_marked);
1666 oprintf (f, "\n },\n");
1675 error_at_line (line,
1676 "global `%s' is unimplemented type",
1681 /* Output a table describing the locations and types of VARIABLES. */
1684 write_gc_roots (variables)
1688 struct flist *flp = NULL;
1690 for (v = variables; v; v = v->next)
1692 outf_p f = get_output_file_with_visibility (v->line.file);
1694 const char *length = NULL;
1695 int deletable_p = 0;
1698 for (o = v->opt; o; o = o->next)
1699 if (strcmp (o->name, "length") == 0)
1700 length = (const char *)o->info;
1701 else if (strcmp (o->name, "deletable") == 0)
1703 else if (strcmp (o->name, "param_is") == 0)
1705 else if (strcmp (o->name, "if_marked") == 0)
1708 error_at_line (&v->line,
1709 "global `%s' has unknown option `%s'",
1712 for (fli = flp; fli; fli = fli->next)
1717 fli = xmalloc (sizeof (*fli));
1721 fli->name = v->line.file;
1724 oprintf (f, "\n/* GC roots. */\n\n");
1729 && v->type->kind == TYPE_POINTER
1730 && (v->type->u.p->kind == TYPE_POINTER
1731 || v->type->u.p->kind == TYPE_STRUCT))
1733 oprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
1735 oprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
1738 oprintf (f, " size_t i;\n");
1740 if (v->type->u.p->kind == TYPE_POINTER)
1742 type_p s = v->type->u.p->u.p;
1744 oprintf (f, " %s %s ** const x = (%s %s **)x_p;\n",
1745 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1746 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1747 oprintf (f, " if (ggc_test_and_set_mark (x))\n");
1748 oprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1749 if (s->kind != TYPE_STRUCT && s->kind != TYPE_UNION)
1751 error_at_line (&v->line,
1752 "global `%s' has unsupported ** type",
1757 oprintf (f, " gt_ggc_m_%s (x[i]);\n", s->u.s.tag);
1761 type_p s = v->type->u.p;
1763 oprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1764 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1765 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1766 oprintf (f, " if (ggc_test_and_set_mark (x))\n");
1767 oprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1768 oprintf (f, " {\n");
1769 write_gc_structure_fields (f, s, "x[i]", "x[i]",
1770 v->opt, 8, &v->line, s->u.s.bitmap,
1772 oprintf (f, " }\n");
1775 oprintf (f, "}\n\n");
1779 for (v = variables; v; v = v->next)
1781 outf_p f = get_output_file_with_visibility (v->line.file);
1787 for (o = v->opt; o; o = o->next)
1788 if (strcmp (o->name, "length") == 0)
1790 else if (strcmp (o->name, "deletable") == 0
1791 || strcmp (o->name, "if_marked") == 0)
1797 for (fli = flp; fli; fli = fli->next)
1800 if (! fli->started_p)
1804 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
1805 put_mangled_filename (f, v->line.file);
1806 oprintf (f, "[] = {\n");
1809 write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL);
1812 finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1815 for (v = variables; v; v = v->next)
1817 outf_p f = get_output_file_with_visibility (v->line.file);
1822 for (o = v->opt; o; o = o->next)
1823 if (strcmp (o->name, "deletable") == 0)
1825 else if (strcmp (o->name, "if_marked") == 0)
1831 for (fli = flp; fli; fli = fli->next)
1834 if (! fli->started_p)
1838 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
1839 put_mangled_filename (f, v->line.file);
1840 oprintf (f, "[] = {\n");
1843 oprintf (f, " { &%s, 1, sizeof (%s), NULL },\n",
1847 finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1848 "gt_ggc_deletable_rtab");
1850 for (v = variables; v; v = v->next)
1852 outf_p f = get_output_file_with_visibility (v->line.file);
1854 const char *if_marked = NULL;
1858 for (o = v->opt; o; o = o->next)
1859 if (strcmp (o->name, "length") == 0)
1861 else if (strcmp (o->name, "if_marked") == 0)
1862 if_marked = (const char *) o->info;
1864 if (if_marked == NULL)
1867 if (v->type->kind != TYPE_POINTER
1868 || v->type->u.p->kind != TYPE_PARAM_STRUCT
1869 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
1871 error_at_line (&v->line, "if_marked option used but not hash table");
1875 for (fli = flp; fli; fli = fli->next)
1878 if (! fli->started_p)
1882 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
1883 put_mangled_filename (f, v->line.file);
1884 oprintf (f, "[] = {\n");
1887 write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param),
1888 v->name, length_p, &v->line, if_marked);
1891 finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
1892 "gt_ggc_cache_rtab");
1896 extern int main PARAMS ((int argc, char **argv));
1903 static struct fileloc pos = { __FILE__, __LINE__ };
1905 do_typedef ("CUMULATIVE_ARGS",
1906 create_scalar_type ("CUMULATIVE_ARGS",
1907 strlen ("CUMULATIVE_ARGS")),
1909 do_typedef ("REAL_VALUE_TYPE",
1910 create_scalar_type ("REAL_VALUE_TYPE",
1911 strlen ("REAL_VALUE_TYPE")),
1913 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1917 for (i = 1; i < argc; i++)
1918 parse_file (argv[i]);
1923 set_gc_used (variables);
1926 write_gc_types (structures, param_structs);
1927 write_gc_roots (variables);
1928 close_output_files ();
1930 return (hit_error != 0);