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 /* Report an error at POS, printing MSG. */
31 error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
34 VA_FIXEDARG (ap, struct fileloc *, pos);
35 VA_FIXEDARG (ap, const char *, msg);
37 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
38 vfprintf (stderr, msg, ap);
45 /* The one and only TYPE_STRING. */
47 struct type string_type = {
48 TYPE_STRING, NULL, NULL, GC_USED
52 /* Lists of various things. */
54 static pair_p typedefs;
55 static type_p structures;
56 static type_p param_structs;
57 static pair_p variables;
59 /* Define S as a typedef to T at POS. */
62 do_typedef (s, t, pos)
69 for (p = typedefs; p != NULL; p = p->next)
70 if (strcmp (p->name, s) == 0)
74 error_at_line (pos, "type `%s' previously defined", s);
75 error_at_line (&p->line, "previously defined here");
80 p = xmalloc (sizeof (struct pair));
88 /* Return the type previously defined for S. Use POS to report errors. */
91 resolve_typedef (s, pos)
96 for (p = typedefs; p != NULL; p = p->next)
97 if (strcmp (p->name, s) == 0)
99 error_at_line (pos, "unidentified type `%s'", s);
100 return create_scalar_type ("char", 4);
103 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
104 at POS with fields FIELDS and options O. */
107 new_structure (name, isunion, pos, fields, o)
116 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
118 for (si = structures; si != NULL; si = si->next)
119 if (strcmp (name, si->u.s.tag) == 0
120 && UNION_P (si) == isunion)
123 if (si->kind == TYPE_LANG_STRUCT)
127 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
128 if (si->u.s.bitmap == bitmap)
131 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
134 si = xcalloc (1, sizeof (struct type));
135 memcpy (si, ls, sizeof (struct type));
136 ls->kind = TYPE_LANG_STRUCT;
137 ls->u.s.lang_struct = si;
138 ls->u.s.fields = NULL;
140 si->pointer_to = NULL;
141 si->u.s.lang_struct = ls;
146 if (ls != NULL && s == NULL)
148 s = xcalloc (1, sizeof (struct type));
149 s->next = ls->u.s.lang_struct;
150 ls->u.s.lang_struct = s;
151 s->u.s.lang_struct = ls;
158 s = xcalloc (1, sizeof (struct type));
159 s->next = structures;
163 if (s->u.s.line.file != NULL
164 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
166 error_at_line (pos, "duplicate structure definition");
167 error_at_line (&s->u.s.line, "previous definition here");
170 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
173 s->u.s.fields = fields;
175 s->u.s.bitmap = bitmap;
176 if (s->u.s.lang_struct)
177 s->u.s.lang_struct->u.s.bitmap |= bitmap;
180 /* Return the previously-defined structure with tag NAME (or a union
181 iff ISUNION is nonzero), or a new empty structure or union if none
182 was defined previously. */
185 find_structure (name, isunion)
191 for (s = structures; s != NULL; s = s->next)
192 if (strcmp (name, s->u.s.tag) == 0
193 && UNION_P (s) == isunion)
196 s = xcalloc (1, sizeof (struct type));
197 s->next = structures;
199 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
205 /* Return a scalar type with name NAME. */
208 create_scalar_type (name, name_len)
212 type_p r = xcalloc (1, sizeof (struct type));
213 r->kind = TYPE_SCALAR;
214 r->u.sc = xmemdup (name, name_len, name_len + 1);
218 /* Return a pointer to T. */
226 type_p r = xcalloc (1, sizeof (struct type));
227 r->kind = TYPE_POINTER;
231 return t->pointer_to;
234 /* Return an array of length LEN. */
237 create_array (t, len)
243 v = xcalloc (1, sizeof (*v));
244 v->kind = TYPE_ARRAY;
250 /* Perform any special processing on a type T, about to become the type
251 of a field. Return the appropriate type for the field.
253 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
254 - Similarly for arrays of pointer-to-char;
255 - Converts structures for which a parameter is provided to
260 adjust_field_type (t, opt)
265 const int pointer_p = t->kind == TYPE_POINTER;
267 for (; opt; opt = opt->next)
268 if (strcmp (opt->name, "length") == 0)
270 else if (strcmp (opt->name, "param_is") == 0)
277 for (realt = param_structs; realt; realt = realt->next)
278 if (realt->u.param_struct.stru == t
279 && realt->u.param_struct.param == (type_p) opt->info)
280 return pointer_p ? create_pointer (realt) : realt;
281 realt = xcalloc (1, sizeof (*realt));
282 realt->kind = TYPE_PARAM_STRUCT;
283 realt->next = param_structs;
284 param_structs = realt;
285 realt->u.param_struct.stru = t;
286 realt->u.param_struct.param = (type_p) opt->info;
287 return pointer_p ? create_pointer (realt) : realt;
292 && t->u.p->kind == TYPE_SCALAR
293 && (strcmp (t->u.p->u.sc, "char") == 0
294 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
296 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
297 && t->u.a.p->u.p->kind == TYPE_SCALAR
298 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
299 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
300 return create_array (&string_type, t->u.a.len);
305 /* Add a variable named S of type T with options O defined at POS,
309 note_variable (s, t, o, pos)
316 n = xmalloc (sizeof (*n));
325 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
326 and information about the correspondance between token types and fields
327 in TYPEINFO. POS is used for error messages. */
330 note_yacc_type (o, fields, typeinfo, pos)
339 for (p = typeinfo; p; p = p->next)
346 if (p->type == (type_p) 1)
351 for (pp = typeinfo; pp; pp = pp->next)
352 if (pp->type != (type_p) 1
353 && strcmp (pp->opt->info, p->opt->info) == 0)
362 for (m = fields; m; m = m->next)
363 if (strcmp (m->name, p->name) == 0)
367 error_at_line (&p->line,
368 "couldn't match fieldname `%s'", p->name);
379 || p->type == (type_p) 1)
385 new_structure ("yy_union", 1, pos, typeinfo, o);
386 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
389 static void process_gc_options PARAMS ((options_p, enum gc_used_enum, int *));
390 static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum));
391 static void set_gc_used PARAMS ((pair_p));
393 /* Handle OPT for set_gc_used_type. */
396 process_gc_options (opt, level, maybe_undef)
398 enum gc_used_enum level;
402 for (o = opt; o; o = o->next)
403 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
404 set_gc_used_type ((type_p) o->info, GC_POINTED_TO);
405 else if (strcmp (o->name, "maybe_undef") == 0)
409 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
412 set_gc_used_type (t, level)
414 enum gc_used_enum level;
416 if (t->gc_used >= level)
429 process_gc_options (t->u.s.opt, level, &dummy);
431 for (f = t->u.s.fields; f; f = f->next)
434 process_gc_options (t->u.s.opt, level, &maybe_undef);
436 if (maybe_undef && f->type->kind == TYPE_POINTER)
437 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
439 set_gc_used_type (f->type, GC_USED);
445 set_gc_used_type (t->u.p, GC_POINTED_TO);
449 set_gc_used_type (t->u.a.p, GC_USED);
452 case TYPE_LANG_STRUCT:
453 for (t = t->u.s.lang_struct; t; t = t->next)
454 set_gc_used_type (t, level);
457 case TYPE_PARAM_STRUCT:
458 set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO);
459 set_gc_used_type (t->u.param_struct.stru, GC_USED);
467 /* Set the gc_used fileds of all the types pointed to by VARIABLES. */
470 set_gc_used (variables)
474 for (p = variables; p; p = p->next)
475 set_gc_used_type (p->type, GC_USED);
478 /* File mapping routines. For each input file, there is one output .c file
479 (but some output files have many input files), and there is one .h file
480 for the whole build. */
482 typedef struct filemap *filemap_p;
486 const char *input_name;
487 const char *output_name;
491 /* The list of output files. */
493 static filemap_p files;
495 /* The output header file that is included into pretty much every
508 static const char *lang_names[] = {
509 "c", "objc", "cp", "treelang", "cobol", "f", "ada", "java"
511 #define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
512 FILE *base_files[NUM_BASE_FILES];
514 static FILE * create_file PARAMS ((const char *));
515 static const char * get_file_basename PARAMS ((const char *));
517 /* Create and return a FILE* for a new header file to be called NAME. */
523 static const char *const hdr[] = {
524 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
526 "This file is part of GCC.\n",
528 "GCC is free software; you can redistribute it and/or modify it under\n",
529 "the terms of the GNU General Public License as published by the Free\n",
530 "Software Foundation; either version 2, or (at your option) any later\n",
533 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
534 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
535 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
536 "for more details.\n",
538 "You should have received a copy of the GNU General Public License\n",
539 "along with GCC; see the file COPYING. If not, write to the Free\n",
540 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
541 "02111-1307, USA. */\n",
543 "/* This file is machine generated. Do not edit. */\n"
551 perror ("couldn't create temporary file");
554 fprintf (f, "/* Type information for %s.\n", name);
555 for (i = 0; i < sizeof(hdr)/sizeof(hdr[0]); i++)
560 /* Open the global header file and the language-specific header files. */
563 open_base_files (void)
567 header_file = create_file ("GCC");
569 for (i = 0; i < NUM_BASE_FILES; i++)
574 base_files[i] = create_file (lang_names[i]);
575 newf = xmalloc (sizeof (*newf));
578 newf->input_name = NULL;
579 newf->output = base_files[i];
580 newf->output_name = s = xmalloc (16);
581 sprintf (s, "gtype-%s.h", lang_names[i]);
585 #define startswith(len, c, s) \
586 ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
588 /* Determine the pathname to F relative to $(srcdir). */
591 get_file_basename (f)
595 const char *basename;
597 /* Determine the output file name. */
599 basename = strrchr (f, '/');
600 if (basename == NULL)
604 if (startswith (basename - f, basename-2, "f/"))
606 else if (startswith (basename - f, basename-3, "cp/"))
608 else if (startswith (basename - f, basename-4, "ada/"))
610 else if (startswith (basename - f, basename-5, "java/"))
612 else if (startswith (basename - f, basename-5, "objc/"))
614 else if (startswith (basename - f, basename-9, "treelang/"))
616 else if (startswith (basename - f, basename-6, "cobol/"))
622 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
623 INPUT_FILE is used by <lang>.
625 This function should be written to assume that a file _is_ used
626 if the situation is unclear. If it wrongly assumes a file _is_ used,
627 a linker error will result. If it wrongly assumes a file _is not_ used,
628 some GC roots may be missed, which is a much harder-to-debug problem. */
631 get_base_file_bitmap (input_file)
632 const char *input_file;
634 const char *basename = get_file_basename (input_file);
635 const char *slashpos = strchr (basename, '/');
636 size_t len = strlen (basename);
638 if (slashpos != NULL)
641 for (i = 0; i < NUM_BASE_FILES; i++)
642 if ((size_t)(slashpos - basename) == strlen (lang_names [i])
643 && memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0)
646 else if (strcmp (basename, "c-lang.c") == 0)
647 return 1 << BASE_FILE_C;
648 else if (strcmp (basename, "c-parse.in") == 0
649 || strcmp (basename, "c-tree.h") == 0
650 || strcmp (basename, "c-decl.c") == 0
651 || strcmp (basename, "c-objc-common.c") == 0)
652 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC;
653 else if (startswith (len, basename, "c-common.c"))
654 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC| 1 << BASE_FILE_CPLUSPLUS
655 | 1 << BASE_FILE_TREELANG | 1 << BASE_FILE_COBOL;
656 else if (startswith (len, basename, "c-"))
657 return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC | 1 << BASE_FILE_CPLUSPLUS;
659 return (1 << NUM_BASE_FILES) - 1;
663 /* An output file, suitable for definitions, that can see declarations
664 made in INPUT_FILE and is linked into every language that uses
668 get_output_file_with_visibility (input_file)
669 const char *input_file;
673 const char *basename;
675 /* Do we already know the file? */
676 for (fm = files; fm; fm = fm->next)
677 if (input_file == fm->input_name)
680 /* No, we'll be creating a new filemap. */
681 fm = xmalloc (sizeof (*fm));
684 fm->input_name = input_file;
686 /* Determine the output file name. */
687 basename = get_file_basename (input_file);
689 len = strlen (basename);
690 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
691 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
692 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
696 fm->output_name = s = xmalloc (sizeof ("gt-") + len);
697 sprintf (s, "gt-%s", basename);
698 for (; *s != '.'; s++)
699 if (! ISALNUM (*s) && *s != '-')
701 memcpy (s, ".h", sizeof (".h"));
703 else if (strcmp (basename, "c-common.h") == 0)
704 fm->output_name = "gt-c-common.h";
705 else if (strcmp (basename, "c-tree.h") == 0)
706 fm->output_name = "gt-c-decl.h";
711 fm->output_name = "gtype-desc.c";
712 for (i = 0; i < NUM_BASE_FILES; i++)
713 if (memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0
714 && basename[strlen(lang_names[i])] == '/')
719 sprintf (s, "gtype-%s.h", lang_names[i]);
725 /* Look through to see if we've ever seen this output filename before. */
726 for (fmo = fm->next; fmo; fmo = fmo->next)
727 if (strcmp (fmo->output_name, fm->output_name) == 0)
729 fm->output = fmo->output;
733 /* If not, create it. */
736 fm->output = create_file (fm->output_name);
737 if (strcmp (fm->output_name, "gtype-desc.c") == 0)
739 fputs ("#include \"config.h\"\n", fm->output);
740 fputs ("#include \"system.h\"\n", fm->output);
741 fputs ("#include \"varray.h\"\n", fm->output);
742 fputs ("#include \"hashtab.h\"\n", fm->output);
743 fputs ("#include \"bitmap.h\"\n", fm->output);
744 fputs ("#include \"tree.h\"\n", fm->output);
745 fputs ("#include \"rtl.h\"\n", fm->output);
746 fputs ("#include \"function.h\"\n", fm->output);
747 fputs ("#include \"insn-config.h\"\n", fm->output);
748 fputs ("#include \"expr.h\"\n", fm->output);
749 fputs ("#include \"hard-reg-set.h\"\n", fm->output);
750 fputs ("#include \"basic-block.h\"\n", fm->output);
751 fputs ("#include \"cselib.h\"\n", fm->output);
752 fputs ("#include \"insn-addr.h\"\n", fm->output);
753 fputs ("#include \"ssa.h\"\n", fm->output);
754 fputs ("#include \"optabs.h\"\n", fm->output);
755 fputs ("#include \"libfuncs.h\"\n", fm->output);
756 fputs ("#include \"debug.h\"\n", fm->output);
757 fputs ("#include \"ggc.h\"\n", fm->output);
764 /* The name of an output file, suitable for definitions, that can see
765 declarations made in INPUT_FILE and is linked into every language
766 that uses INPUT_FILE. */
769 get_output_file_name (input_file)
770 const char *input_file;
774 for (fm = files; fm; fm = fm->next)
775 if (input_file == fm->input_name)
776 return fm->output_name;
777 (void) get_output_file_with_visibility (input_file);
778 return get_output_file_name (input_file);
781 /* Close all output files and copy them to their final destinations,
782 but don't unnecessarily change modification times. */
785 close_output_files PARAMS ((void))
788 struct filemap header;
790 header.output_name = "gtype-desc.h";
791 header.output = header_file;
793 for (fm = &header; fm; fm = fm->next)
799 /* Handle each output file once. */
800 if (fm->output == NULL)
803 for (ofm = fm->next; ofm; ofm = ofm->next)
804 if (fm->output == ofm->output)
807 /* Compare the output file with the file to be created, avoiding
808 unnecessarily changing timestamps. */
809 newfile = fopen (fm->output_name, "r");
816 ch1 = fgetc (fm->output);
817 ch2 = fgetc (newfile);
818 } while (ch1 != EOF && ch1 == ch2);
822 no_write_p = ch1 == ch2;
827 /* Nothing interesting to do. Close the output file. */
834 newfile = fopen (fm->output_name, "w");
837 perror ("opening output file");
843 while ((ch = fgetc (fm->output)) != EOF)
858 static void output_escaped_param PARAMS ((FILE *, const char *, const char *,
859 const char *, const char *,
861 static void write_gc_structure_fields
862 PARAMS ((FILE *, type_p, const char *, const char *, options_p,
863 int, struct fileloc *, lang_bitmap, type_p));
864 static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
865 static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
866 static void put_mangled_filename PARAMS ((FILE *, const char *));
867 static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
868 const char *tname, const char *lastname,
870 static void write_gc_root PARAMS ((FILE *, pair_p, type_p, const char *, int,
871 struct fileloc *, const char *));
872 static void write_gc_roots PARAMS ((pair_p));
874 static int gc_counter;
876 /* Print PARAM to OF processing escapes. VAL references the current object,
877 PREV_VAL the object containing the current object, ONAME is the name
878 of the option and LINE is used to print error messages. */
881 output_escaped_param (of, param, val, prev_val, oname, line)
885 const char *prev_val;
887 struct fileloc *line;
891 for (p = param; *p; p++)
894 else if (*++p == 'h')
895 fprintf (of, "(%s)", val);
899 fprintf (of, "(%s)", prev_val);
901 error_at_line (line, "`%s' option contains bad escape %c%c",
905 /* Write out code to OF which marks the fields of S. VAL references
906 the current object, PREV_VAL the object containing the current
907 object, OPTS is a list of options to apply, INDENT is the current
908 indentation level, LINE is used to print error messages, BITMAP
909 indicates which languages to print the structure for, and PARAM is
910 the current parameter (from an enclosing param_is option). */
913 write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
918 const char *prev_val;
921 struct fileloc *line;
928 if (! s->u.s.line.file)
929 error_at_line (line, "incomplete structure `%s'", s->u.s.tag);
930 else if ((s->u.s.bitmap & bitmap) != bitmap)
932 error_at_line (line, "structure defined for mismatching languages");
933 error_at_line (&s->u.s.line, "one structure defined here");
936 if (s->kind == TYPE_UNION)
938 const char *tagexpr = NULL;
941 tagcounter = ++gc_counter;
942 for (oo = opts; oo; oo = oo->next)
943 if (strcmp (oo->name, "desc") == 0)
944 tagexpr = (const char *)oo->info;
948 error_at_line (line, "missing `desc' option");
951 fprintf (of, "%*s{\n", indent, "");
953 fprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter);
954 output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
958 for (f = s->u.s.fields; f; f = f->next)
960 const char *tagid = NULL;
961 const char *length = NULL;
962 const char *special = NULL;
965 int maybe_undef_p = 0;
970 if (t->kind == TYPE_SCALAR
971 || (t->kind == TYPE_ARRAY
972 && t->u.a.p->kind == TYPE_SCALAR))
975 for (oo = f->opt; oo; oo = oo->next)
976 if (strcmp (oo->name, "length") == 0)
977 length = (const char *)oo->info;
978 else if (strcmp (oo->name, "maybe_undef") == 0)
980 else if (strcmp (oo->name, "tag") == 0)
981 tagid = (const char *)oo->info;
982 else if (strcmp (oo->name, "special") == 0)
983 special = (const char *)oo->info;
984 else if (strcmp (oo->name, "skip") == 0)
986 else if (strcmp (oo->name, "always") == 0)
988 else if (strcmp (oo->name, "desc") == 0 && UNION_P (t))
990 else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t))
992 else if (strcmp (oo->name, "param_is") == 0)
994 else if (strcmp (oo->name, "use_param") == 0)
997 error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
1010 for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p)
1012 for (; t->kind == TYPE_POINTER; t = t->u.p)
1013 nt = create_pointer (nt);
1014 while (arraycount-- > 0)
1015 nt = create_array (nt, t->u.a.len);
1018 else if (s->kind == TYPE_UNION && ! always_p && tagid)
1021 error_at_line (&f->line, "no parameter defined");
1025 && (t->kind != TYPE_POINTER
1026 || t->u.p->kind != TYPE_STRUCT))
1027 error_at_line (&f->line,
1028 "field `%s' has invalid option `maybe_undef_p'\n",
1030 if (s->kind == TYPE_UNION && ! always_p )
1034 error_at_line (&f->line, "field `%s' has no tag", f->name);
1037 fprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "",
1045 /* Do nothing; strings go in the string pool. */
1048 case TYPE_LANG_STRUCT:
1051 for (ti = t->u.s.lang_struct; ti; ti = ti->next)
1052 if (ti->u.s.bitmap & bitmap)
1059 error_at_line (&f->line,
1060 "structure not defined for this language");
1064 /* Fall through... */
1070 newval = xmalloc (strlen (val) + sizeof (".") + strlen (f->name));
1071 sprintf (newval, "%s.%s", val, f->name);
1072 write_gc_structure_fields (of, t, newval, val, f->opt, indent,
1073 &f->line, bitmap, param);
1082 && t->u.p->u.s.line.file == NULL)
1083 fprintf (of, "%*sif (%s.%s) abort();\n", indent, "",
1085 else if (UNION_OR_STRUCT_P (t->u.p))
1086 fprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "",
1087 t->u.p->u.s.tag, val, f->name);
1088 else if (t->u.p->kind == TYPE_PARAM_STRUCT)
1089 fprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "",
1090 (int) strlen (t->u.p->u.param_struct.param->u.s.tag),
1091 t->u.p->u.param_struct.param->u.s.tag,
1092 t->u.p->u.param_struct.stru->u.s.tag,
1095 error_at_line (&f->line, "field `%s' is pointer to scalar",
1099 else if (t->u.p->kind == TYPE_SCALAR
1100 || t->u.p->kind == TYPE_STRING)
1101 fprintf (of, "%*sggc_mark (%s.%s);\n", indent, "",
1105 int loopcounter = ++gc_counter;
1107 fprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "",
1110 fprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
1111 fprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "",
1113 fprintf (of, "%*sfor (i%d = 0; i%d < (", indent, "",
1114 loopcounter, loopcounter);
1115 output_escaped_param (of, length, val, prev_val, "length", line);
1116 fprintf (of, "); i%d++) {\n", loopcounter);
1118 switch (t->u.p->kind)
1125 newval = xmalloc (strlen (val) + 8 + strlen (f->name));
1126 sprintf (newval, "%s.%s[i%d]", val, f->name, loopcounter);
1127 write_gc_structure_fields (of, t->u.p, newval, val,
1128 f->opt, indent, &f->line,
1134 if (UNION_OR_STRUCT_P (t->u.p->u.p))
1135 fprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "",
1136 t->u.p->u.p->u.s.tag, val, f->name,
1139 error_at_line (&f->line,
1140 "field `%s' is array of pointer to scalar",
1144 error_at_line (&f->line,
1145 "field `%s' is array of unimplemented type",
1150 fprintf (of, "%*s}\n", indent, "");
1152 fprintf (of, "%*s}\n", indent, "");
1158 int loopcounter = ++gc_counter;
1163 (strcmp (t->u.a.len, "0") == 0
1164 || strcmp (t->u.a.len, "1") == 0))
1165 error_at_line (&f->line,
1166 "field `%s' is array of size %s",
1167 f->name, t->u.a.len);
1169 /* Arrays of scalars can be ignored. */
1170 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1172 if (ta->kind == TYPE_SCALAR
1173 || ta->kind == TYPE_STRING)
1176 fprintf (of, "%*s{\n", indent, "");
1179 if (special != NULL && strcmp (special, "tree_exp") == 0)
1181 fprintf (of, "%*sconst size_t tree_exp_size = (",
1183 output_escaped_param (of, length, val, prev_val,
1187 length = "first_rtl_op (TREE_CODE ((tree)&%h))";
1190 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1192 fprintf (of, "%*ssize_t i%d_%d;\n",
1193 indent, "", loopcounter, i);
1194 fprintf (of, "%*sconst size_t ilimit%d_%d = (",
1195 indent, "", loopcounter, i);
1196 if (i == 0 && length != NULL)
1197 output_escaped_param (of, length, val, prev_val,
1200 fputs (ta->u.a.len, of);
1204 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1207 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1208 indent, "", loopcounter, i, loopcounter, i,
1209 loopcounter, i, loopcounter, i);
1213 if (ta->kind == TYPE_POINTER
1214 && (ta->u.p->kind == TYPE_STRUCT
1215 || ta->u.p->kind == TYPE_UNION))
1217 fprintf (of, "%*sgt_ggc_m_%s (%s.%s",
1218 indent, "", ta->u.p->u.s.tag, val, f->name);
1220 ta->kind == TYPE_ARRAY;
1221 ta = ta->u.a.p, i++)
1222 fprintf (of, "[i%d_%d]", loopcounter, i);
1225 else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
1230 len = strlen (val) + strlen (f->name) + 2;
1231 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
1232 len += sizeof ("[i_]") + 2*6;
1234 newval = xmalloc (len);
1235 sprintf (newval, "%s.%s", val, f->name);
1237 ta->kind == TYPE_ARRAY;
1238 ta = ta->u.a.p, i++)
1239 sprintf (newval + strlen (newval), "[i%d_%d]",
1241 write_gc_structure_fields (of, t->u.p, newval, val,
1242 f->opt, indent, &f->line, bitmap,
1246 else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR
1247 && use_param_p && param == NULL)
1248 fprintf (of, "%*sabort();\n", indent, "");
1250 error_at_line (&f->line,
1251 "field `%s' is array of unimplemented type",
1253 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
1256 fprintf (of, "%*s}\n", indent, "");
1259 if (special != NULL && strcmp (special, "tree_exp") == 0)
1262 "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
1263 indent, "", loopcounter, loopcounter);
1264 fprintf (of, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
1265 indent, "", val, f->name, loopcounter);
1270 fprintf (of, "%*s}\n", indent, "");
1275 error_at_line (&f->line,
1276 "field `%s' is unimplemented type",
1281 if (s->kind == TYPE_UNION && ! always_p )
1284 fprintf (of, "%*s}\n", indent, "");
1287 error_at_line (&f->line, "unhandled special `%s'", special);
1289 if (s->kind == TYPE_UNION)
1292 fprintf (of, "%*s}\n", indent, "");
1296 /* Write out a marker routine for S. PARAM is the parameter from an
1297 enclosing PARAM_IS option. */
1300 write_gc_marker_routine_for_structure (s, param)
1306 f = get_output_file_with_visibility (s->u.s.line.file);
1308 f = get_output_file_with_visibility (param->u.s.line.file);
1311 fputs ("void\n", f);
1313 fprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag);
1315 fprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param->u.s.tag),
1316 param->u.s.tag, s->u.s.tag);
1317 fputs (" void *x_p;\n", f);
1319 fprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1320 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1321 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1322 fputs (" if (! ggc_test_and_set_mark (x))\n", f);
1323 fputs (" return;\n", f);
1326 write_gc_structure_fields (f, s, "(*x)", "not valid postage",
1327 s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap,
1333 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
1336 write_gc_types (structures, param_structs)
1338 type_p param_structs;
1342 fputs ("\n/* GC marker procedures. */\n", header_file);
1343 for (s = structures; s; s = s->next)
1344 if (s->gc_used == GC_POINTED_TO
1345 || s->gc_used == GC_MAYBE_POINTED_TO)
1349 if (s->gc_used == GC_MAYBE_POINTED_TO
1350 && s->u.s.line.file == NULL)
1353 fprintf (header_file,
1354 "#define gt_ggc_m_%s(X) do { \\\n", s->u.s.tag);
1355 fprintf (header_file,
1356 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag);
1357 fprintf (header_file,
1360 for (opt = s->u.s.opt; opt; opt = opt->next)
1361 if (strcmp (opt->name, "ptr_alias") == 0)
1363 type_p t = (type_p) opt->info;
1364 if (t->kind == TYPE_STRUCT
1365 || t->kind == TYPE_UNION
1366 || t->kind == TYPE_LANG_STRUCT)
1367 fprintf (header_file,
1368 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
1369 s->u.s.tag, t->u.s.tag);
1371 error_at_line (&s->u.s.line,
1372 "structure alias is not a structure");
1378 /* Declare the marker procedure only once. */
1379 fprintf (header_file,
1380 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1383 if (s->u.s.line.file == NULL)
1385 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1390 if (s->kind == TYPE_LANG_STRUCT)
1393 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
1394 write_gc_marker_routine_for_structure (ss, NULL);
1397 write_gc_marker_routine_for_structure (s, NULL);
1400 for (s = param_structs; s; s = s->next)
1401 if (s->gc_used == GC_POINTED_TO)
1403 type_p param = s->u.param_struct.param;
1404 type_p stru = s->u.param_struct.stru;
1406 if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION
1407 && param->kind != TYPE_LANG_STRUCT)
1409 error_at_line (&s->u.param_struct.line,
1410 "unsupported parameter type");
1414 /* Declare the marker procedure. */
1415 fprintf (header_file,
1416 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
1417 (int) strlen (param->u.s.tag), param->u.s.tag,
1420 if (stru->u.s.line.file == NULL)
1422 fprintf (stderr, "warning: structure `%s' used but not defined\n",
1427 if (stru->kind == TYPE_LANG_STRUCT)
1430 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
1431 write_gc_marker_routine_for_structure (ss, param);
1434 write_gc_marker_routine_for_structure (stru, param);
1438 /* Mangle FN and print it to F. */
1441 put_mangled_filename (f, fn)
1445 const char *name = get_output_file_name (fn);
1446 for (; *name != 0; name++)
1447 if (ISALNUM (*name))
1453 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
1454 LASTNAME, and NAME are all strings to insert in various places in
1455 the resulting code. */
1458 finish_root_table (flp, pfx, lastname, tname, name)
1462 const char *lastname;
1466 unsigned started_bitmap = 0;
1468 for (fli2 = flp; fli2; fli2 = fli2->next)
1469 if (fli2->started_p)
1471 fprintf (fli2->f, " %s\n", lastname);
1472 fputs ("};\n\n", fli2->f);
1475 for (fli2 = flp; fli2; fli2 = fli2->next)
1476 if (fli2->started_p)
1478 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1481 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1484 fprintf (base_files[fnum],
1485 "extern const struct %s gt_ggc_%s_",
1487 put_mangled_filename (base_files[fnum], fli2->name);
1488 fputs ("[];\n", base_files[fnum]);
1492 for (fli2 = flp; fli2; fli2 = fli2->next)
1493 if (fli2->started_p)
1495 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
1498 fli2->started_p = 0;
1500 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1503 if (! (started_bitmap & (1 << fnum)))
1505 fprintf (base_files [fnum],
1506 "const struct %s * const %s[] = {\n",
1508 started_bitmap |= 1 << fnum;
1510 fprintf (base_files[fnum], " gt_ggc_%s_", pfx);
1511 put_mangled_filename (base_files[fnum], fli2->name);
1512 fputs (",\n", base_files[fnum]);
1520 for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
1523 fputs (" NULL\n", base_files[fnum]);
1524 fputs ("};\n\n", base_files[fnum]);
1529 /* Write out to F the table entry and any marker routines needed to
1530 mark NAME as TYPE. The original variable is V, at LINE.
1531 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
1532 is nonzero iff we are building the root table for hash table caches. */
1535 write_gc_root (f, v, type, name, has_length, line, if_marked)
1541 struct fileloc *line;
1542 const char *if_marked;
1549 for (fld = type->u.s.fields; fld; fld = fld->next)
1552 const char *desc = NULL;
1555 for (o = fld->opt; o; o = o->next)
1556 if (strcmp (o->name, "skip") == 0)
1558 else if (strcmp (o->name, "desc") == 0)
1559 desc = (const char *)o->info;
1561 error_at_line (line,
1562 "field `%s' of global `%s' has unknown option `%s'",
1563 fld->name, name, o->name);
1567 else if (desc && fld->type->kind == TYPE_UNION)
1569 pair_p validf = NULL;
1572 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
1574 const char *tag = NULL;
1577 for (oo = ufld->opt; oo; oo = oo->next)
1578 if (strcmp (oo->name, "tag") == 0)
1579 tag = (const char *)oo->info;
1580 if (tag == NULL || strcmp (tag, desc) != 0)
1583 error_at_line (line,
1584 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
1585 name, fld->name, validf->name,
1586 name, fld->name, ufld->name,
1593 newname = xmalloc (strlen (name) + 3 + strlen (fld->name)
1594 + strlen (validf->name));
1595 sprintf (newname, "%s.%s.%s",
1596 name, fld->name, validf->name);
1597 write_gc_root (f, v, validf->type, newname, 0, line,
1603 error_at_line (line,
1604 "global `%s.%s' has `desc' option but is not union",
1609 newname = xmalloc (strlen (name) + 2 + strlen (fld->name));
1610 sprintf (newname, "%s.%s", name, fld->name);
1611 write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
1621 newname = xmalloc (strlen (name) + 4);
1622 sprintf (newname, "%s[0]", name);
1623 write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
1633 fprintf (f, " &%s,\n", name);
1636 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1638 fprintf (f, " * (%s)", ap->u.a.len);
1639 else if (ap == v->type)
1640 fprintf (f, " * (sizeof (%s) / sizeof (%s[0]))",
1643 fprintf (f, " sizeof (%s", v->name);
1644 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
1650 if (! has_length && UNION_OR_STRUCT_P (tp))
1652 fprintf (f, " >_ggc_mx_%s\n", tp->u.s.tag);
1654 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
1656 fprintf (f, " >_ggc_mm_%d%s_%s",
1657 (int) strlen (tp->u.param_struct.param->u.s.tag),
1658 tp->u.param_struct.param->u.s.tag,
1659 tp->u.param_struct.stru->u.s.tag);
1662 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
1664 fprintf (f, " >_ggc_ma_%s", name);
1668 error_at_line (line,
1669 "global `%s' is pointer to unimplemented type",
1673 fprintf (f, ",\n &%s", if_marked);
1674 fputs ("\n },\n", f);
1683 error_at_line (line,
1684 "global `%s' is unimplemented type",
1689 /* Output a table describing the locations and types of VARIABLES. */
1692 write_gc_roots (variables)
1696 struct flist *flp = NULL;
1698 for (v = variables; v; v = v->next)
1700 FILE *f = get_output_file_with_visibility (v->line.file);
1702 const char *length = NULL;
1703 int deletable_p = 0;
1706 for (o = v->opt; o; o = o->next)
1707 if (strcmp (o->name, "length") == 0)
1708 length = (const char *)o->info;
1709 else if (strcmp (o->name, "deletable") == 0)
1711 else if (strcmp (o->name, "param_is") == 0)
1713 else if (strcmp (o->name, "if_marked") == 0)
1716 error_at_line (&v->line,
1717 "global `%s' has unknown option `%s'",
1720 for (fli = flp; fli; fli = fli->next)
1725 fli = xmalloc (sizeof (*fli));
1729 fli->name = v->line.file;
1732 fputs ("\n/* GC roots. */\n\n", f);
1737 && v->type->kind == TYPE_POINTER
1738 && (v->type->u.p->kind == TYPE_POINTER
1739 || v->type->u.p->kind == TYPE_STRUCT))
1741 fprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
1743 fprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
1746 fputs (" size_t i;\n", f);
1748 if (v->type->u.p->kind == TYPE_POINTER)
1750 type_p s = v->type->u.p->u.p;
1752 fprintf (f, " %s %s ** const x = (%s %s **)x_p;\n",
1753 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1754 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1755 fputs (" if (ggc_test_and_set_mark (x))\n", f);
1756 fprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1757 if (s->kind != TYPE_STRUCT && s->kind != TYPE_UNION)
1759 error_at_line (&v->line,
1760 "global `%s' has unsupported ** type",
1765 fprintf (f, " gt_ggc_m_%s (x[i]);\n", s->u.s.tag);
1769 type_p s = v->type->u.p;
1771 fprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
1772 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
1773 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
1774 fputs (" if (ggc_test_and_set_mark (x))\n", f);
1775 fprintf (f, " for (i = 0; i < (%s); i++)\n", length);
1777 write_gc_structure_fields (f, s, "x[i]", "x[i]",
1778 v->opt, 8, &v->line, s->u.s.bitmap,
1787 for (v = variables; v; v = v->next)
1789 FILE *f = get_output_file_with_visibility (v->line.file);
1795 for (o = v->opt; o; o = o->next)
1796 if (strcmp (o->name, "length") == 0)
1798 else if (strcmp (o->name, "deletable") == 0
1799 || strcmp (o->name, "if_marked") == 0)
1805 for (fli = flp; fli; fli = fli->next)
1808 if (! fli->started_p)
1812 fputs ("const struct ggc_root_tab gt_ggc_r_", f);
1813 put_mangled_filename (f, v->line.file);
1814 fputs ("[] = {\n", f);
1817 write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL);
1820 finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1823 for (v = variables; v; v = v->next)
1825 FILE *f = get_output_file_with_visibility (v->line.file);
1830 for (o = v->opt; o; o = o->next)
1831 if (strcmp (o->name, "deletable") == 0)
1833 else if (strcmp (o->name, "if_marked") == 0)
1839 for (fli = flp; fli; fli = fli->next)
1842 if (! fli->started_p)
1846 fputs ("const struct ggc_root_tab gt_ggc_rd_", f);
1847 put_mangled_filename (f, v->line.file);
1848 fputs ("[] = {\n", f);
1851 fprintf (f, " { &%s, 1, sizeof (%s), NULL },\n",
1855 finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1856 "gt_ggc_deletable_rtab");
1858 for (v = variables; v; v = v->next)
1860 FILE *f = get_output_file_with_visibility (v->line.file);
1862 const char *if_marked = NULL;
1866 for (o = v->opt; o; o = o->next)
1867 if (strcmp (o->name, "length") == 0)
1869 else if (strcmp (o->name, "if_marked") == 0)
1870 if_marked = (const char *) o->info;
1872 if (if_marked == NULL)
1875 if (v->type->kind != TYPE_POINTER
1876 || v->type->u.p->kind != TYPE_PARAM_STRUCT
1877 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
1879 error_at_line (&v->line, "if_marked option used but not hash table");
1883 for (fli = flp; fli; fli = fli->next)
1886 if (! fli->started_p)
1890 fputs ("const struct ggc_cache_tab gt_ggc_rc_", f);
1891 put_mangled_filename (f, v->line.file);
1892 fputs ("[] = {\n", f);
1895 write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param),
1896 v->name, length_p, &v->line, if_marked);
1899 finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
1900 "gt_ggc_cache_rtab");
1904 extern int main PARAMS ((int argc, char **argv));
1911 static struct fileloc pos = { __FILE__, __LINE__ };
1913 do_typedef ("CUMULATIVE_ARGS",
1914 create_scalar_type ("CUMULATIVE_ARGS",
1915 strlen ("CUMULATIVE_ARGS")),
1917 do_typedef ("REAL_VALUE_TYPE",
1918 create_scalar_type ("REAL_VALUE_TYPE",
1919 strlen ("REAL_VALUE_TYPE")),
1921 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1925 for (i = 1; i < argc; i++)
1926 parse_file (argv[i]);
1931 set_gc_used (variables);
1934 write_gc_types (structures, param_structs);
1935 write_gc_roots (variables);
1936 close_output_files ();
1938 return (hit_error != 0);