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 /* Nonzero iff an error has occurred. */
27 static int hit_error
= 0;
29 /* Report an error at POS, printing MSG. */
32 error_at_line
VPARAMS ((struct fileloc
*pos
, const char *msg
, ...))
35 VA_FIXEDARG (ap
, struct fileloc
*, pos
);
36 VA_FIXEDARG (ap
, const char *, msg
);
38 fprintf (stderr
, "%s:%d: ", pos
->file
, pos
->line
);
39 vfprintf (stderr
, msg
, ap
);
46 /* The one and only TYPE_STRING. */
48 struct type string_type
= {
49 TYPE_STRING
, NULL
, NULL
, GC_USED
53 /* Lists of various things. */
55 static pair_p typedefs
;
56 static type_p structures
;
57 static type_p param_structs
;
58 static pair_p variables
;
60 /* Define S as a typedef to T at POS. */
63 do_typedef (s
, t
, pos
)
70 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
71 if (strcmp (p
->name
, s
) == 0)
75 error_at_line (pos
, "type `%s' previously defined", s
);
76 error_at_line (&p
->line
, "previously defined here");
81 p
= xmalloc (sizeof (struct pair
));
89 /* Return the type previously defined for S. Use POS to report errors. */
92 resolve_typedef (s
, pos
)
97 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
98 if (strcmp (p
->name
, s
) == 0)
100 error_at_line (pos
, "unidentified type `%s'", s
);
101 return create_scalar_type ("char", 4);
104 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
105 at POS with fields FIELDS and options O. */
108 new_structure (name
, isunion
, pos
, fields
, o
)
117 lang_bitmap bitmap
= get_base_file_bitmap (pos
->file
);
119 for (si
= structures
; si
!= NULL
; si
= si
->next
)
120 if (strcmp (name
, si
->u
.s
.tag
) == 0
121 && UNION_P (si
) == isunion
)
124 if (si
->kind
== TYPE_LANG_STRUCT
)
128 for (si
= ls
->u
.s
.lang_struct
; si
!= NULL
; si
= si
->next
)
129 if (si
->u
.s
.bitmap
== bitmap
)
132 else if (si
->u
.s
.line
.file
!= NULL
&& si
->u
.s
.bitmap
!= bitmap
)
135 si
= xcalloc (1, sizeof (struct type
));
136 memcpy (si
, ls
, sizeof (struct type
));
137 ls
->kind
= TYPE_LANG_STRUCT
;
138 ls
->u
.s
.lang_struct
= si
;
139 ls
->u
.s
.fields
= NULL
;
141 si
->pointer_to
= NULL
;
142 si
->u
.s
.lang_struct
= ls
;
147 if (ls
!= NULL
&& s
== NULL
)
149 s
= xcalloc (1, sizeof (struct type
));
150 s
->next
= ls
->u
.s
.lang_struct
;
151 ls
->u
.s
.lang_struct
= s
;
152 s
->u
.s
.lang_struct
= ls
;
159 s
= xcalloc (1, sizeof (struct type
));
160 s
->next
= structures
;
164 if (s
->u
.s
.line
.file
!= NULL
165 || (s
->u
.s
.lang_struct
&& (s
->u
.s
.lang_struct
->u
.s
.bitmap
& bitmap
)))
167 error_at_line (pos
, "duplicate structure definition");
168 error_at_line (&s
->u
.s
.line
, "previous definition here");
171 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
174 s
->u
.s
.fields
= fields
;
176 s
->u
.s
.bitmap
= bitmap
;
177 if (s
->u
.s
.lang_struct
)
178 s
->u
.s
.lang_struct
->u
.s
.bitmap
|= bitmap
;
181 /* Return the previously-defined structure with tag NAME (or a union
182 iff ISUNION is nonzero), or a new empty structure or union if none
183 was defined previously. */
186 find_structure (name
, isunion
)
192 for (s
= structures
; s
!= NULL
; s
= s
->next
)
193 if (strcmp (name
, s
->u
.s
.tag
) == 0
194 && UNION_P (s
) == isunion
)
197 s
= xcalloc (1, sizeof (struct type
));
198 s
->next
= structures
;
200 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
206 /* Return a scalar type with name NAME. */
209 create_scalar_type (name
, name_len
)
213 type_p r
= xcalloc (1, sizeof (struct type
));
214 r
->kind
= TYPE_SCALAR
;
215 r
->u
.sc
= xmemdup (name
, name_len
, name_len
+ 1);
219 /* Return a pointer to T. */
227 type_p r
= xcalloc (1, sizeof (struct type
));
228 r
->kind
= TYPE_POINTER
;
232 return t
->pointer_to
;
235 /* Return an array of length LEN. */
238 create_array (t
, len
)
244 v
= xcalloc (1, sizeof (*v
));
245 v
->kind
= TYPE_ARRAY
;
251 /* Perform any special processing on a type T, about to become the type
252 of a field. Return the appropriate type for the field.
254 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
255 - Similarly for arrays of pointer-to-char;
256 - Converts structures for which a parameter is provided to
261 adjust_field_type (t
, opt
)
266 const int pointer_p
= t
->kind
== TYPE_POINTER
;
268 for (; opt
; opt
= opt
->next
)
269 if (strcmp (opt
->name
, "length") == 0)
271 else if (strcmp (opt
->name
, "param_is") == 0)
278 for (realt
= param_structs
; realt
; realt
= realt
->next
)
279 if (realt
->u
.param_struct
.stru
== t
280 && realt
->u
.param_struct
.param
== (type_p
) opt
->info
)
281 return pointer_p
? create_pointer (realt
) : realt
;
282 realt
= xcalloc (1, sizeof (*realt
));
283 realt
->kind
= TYPE_PARAM_STRUCT
;
284 realt
->next
= param_structs
;
285 param_structs
= realt
;
286 realt
->u
.param_struct
.stru
= t
;
287 realt
->u
.param_struct
.param
= (type_p
) opt
->info
;
288 return pointer_p
? create_pointer (realt
) : realt
;
293 && t
->u
.p
->kind
== TYPE_SCALAR
294 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
295 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
297 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
298 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
299 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
300 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
301 return create_array (&string_type
, t
->u
.a
.len
);
306 /* Add a variable named S of type T with options O defined at POS,
310 note_variable (s
, t
, o
, pos
)
317 n
= xmalloc (sizeof (*n
));
326 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
327 and information about the correspondance between token types and fields
328 in TYPEINFO. POS is used for error messages. */
331 note_yacc_type (o
, fields
, typeinfo
, pos
)
340 for (p
= typeinfo
; p
; p
= p
->next
)
347 if (p
->type
== (type_p
) 1)
352 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
353 if (pp
->type
!= (type_p
) 1
354 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
363 for (m
= fields
; m
; m
= m
->next
)
364 if (strcmp (m
->name
, p
->name
) == 0)
368 error_at_line (&p
->line
,
369 "couldn't match fieldname `%s'", p
->name
);
380 || p
->type
== (type_p
) 1)
386 new_structure ("yy_union", 1, pos
, typeinfo
, o
);
387 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos
);
390 static void process_gc_options
PARAMS ((options_p
, enum gc_used_enum
, int *));
391 static void set_gc_used_type
PARAMS ((type_p
, enum gc_used_enum
));
392 static void set_gc_used
PARAMS ((pair_p
));
394 /* Handle OPT for set_gc_used_type. */
397 process_gc_options (opt
, level
, maybe_undef
)
399 enum gc_used_enum level
;
403 for (o
= opt
; o
; o
= o
->next
)
404 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
405 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
);
406 else if (strcmp (o
->name
, "maybe_undef") == 0)
410 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
413 set_gc_used_type (t
, level
)
415 enum gc_used_enum level
;
417 if (t
->gc_used
>= level
)
430 process_gc_options (t
->u
.s
.opt
, level
, &dummy
);
432 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
435 process_gc_options (t
->u
.s
.opt
, level
, &maybe_undef
);
437 if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
438 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
);
440 set_gc_used_type (f
->type
, GC_USED
);
446 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
);
450 set_gc_used_type (t
->u
.a
.p
, GC_USED
);
453 case TYPE_LANG_STRUCT
:
454 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
455 set_gc_used_type (t
, level
);
458 case TYPE_PARAM_STRUCT
:
459 set_gc_used_type (t
->u
.param_struct
.param
, GC_POINTED_TO
);
460 set_gc_used_type (t
->u
.param_struct
.stru
, GC_USED
);
468 /* Set the gc_used fileds of all the types pointed to by VARIABLES. */
471 set_gc_used (variables
)
475 for (p
= variables
; p
; p
= p
->next
)
476 set_gc_used_type (p
->type
, GC_USED
);
479 /* File mapping routines. For each input file, there is one output .c file
480 (but some output files have many input files), and there is one .h file
481 for the whole build. */
483 typedef struct filemap
*filemap_p
;
487 const char *input_name
;
488 const char *output_name
;
492 /* The list of output files. */
494 static filemap_p files
;
496 /* The output header file that is included into pretty much every
506 static const char *lang_names
[] = {
507 "c", "objc", "cp", "f", "ada", "java"
509 #define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
510 FILE *base_files
[NUM_BASE_FILES
];
512 static FILE * create_file
PARAMS ((const char *));
513 static const char * get_file_basename
PARAMS ((const char *));
515 /* Create and return a FILE* for a new header file to be called NAME. */
521 static const char *const hdr
[] = {
522 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
524 "This file is part of GCC.\n",
526 "GCC is free software; you can redistribute it and/or modify it under\n",
527 "the terms of the GNU General Public License as published by the Free\n",
528 "Software Foundation; either version 2, or (at your option) any later\n",
531 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
532 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
533 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
534 "for more details.\n",
536 "You should have received a copy of the GNU General Public License\n",
537 "along with GCC; see the file COPYING. If not, write to the Free\n",
538 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
539 "02111-1307, USA. */\n",
541 "/* This file is machine generated. Do not edit. */\n"
549 perror ("couldn't create temporary file");
552 fprintf (f
, "/* Type information for %s.\n", name
);
553 for (i
= 0; i
< sizeof(hdr
)/sizeof(hdr
[0]); i
++)
558 /* Open the global header file and the language-specific header files. */
561 open_base_files (void)
565 header_file
= create_file ("GCC");
567 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
572 base_files
[i
] = create_file (lang_names
[i
]);
573 newf
= xmalloc (sizeof (*newf
));
576 newf
->input_name
= NULL
;
577 newf
->output
= base_files
[i
];
578 newf
->output_name
= s
= xmalloc (16);
579 sprintf (s
, "gtype-%s.h", lang_names
[i
]);
583 #define startswith(len, c, s) \
584 ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
586 /* Determine the pathname to F relative to $(srcdir). */
589 get_file_basename (f
)
593 const char *basename
;
595 /* Determine the output file name. */
597 basename
= strrchr (f
, '/');
598 if (basename
== NULL
)
602 if (startswith (basename
- f
, basename
-2, "f/"))
604 else if (startswith (basename
- f
, basename
-3, "cp/"))
606 else if (startswith (basename
- f
, basename
-4, "ada/"))
608 else if (startswith (basename
- f
, basename
-5, "java/"))
610 else if (startswith (basename
- f
, basename
-5, "objc/"))
616 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
617 INPUT_FILE is used by <lang>.
619 This function should be written to assume that a file _is_ used
620 if the situation is unclear. If it wrongly assumes a file _is_ used,
621 a linker error will result. If it wrongly assumes a file _is not_ used,
622 some GC roots may be missed, which is a much harder-to-debug problem. */
625 get_base_file_bitmap (input_file
)
626 const char *input_file
;
628 const char *basename
= get_file_basename (input_file
);
629 const char *slashpos
= strchr (basename
, '/');
630 size_t len
= strlen (basename
);
632 if (slashpos
!= NULL
)
635 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
636 if ((size_t)(slashpos
- basename
) == strlen (lang_names
[i
])
637 && memcmp (basename
, lang_names
[i
], strlen (lang_names
[i
])) == 0)
640 else if (strcmp (basename
, "c-lang.c") == 0)
641 return 1 << BASE_FILE_C
;
642 else if (strcmp (basename
, "c-parse.in") == 0
643 || strcmp (basename
, "c-tree.h") == 0
644 || strcmp (basename
, "c-decl.c") == 0
645 || strcmp (basename
, "c-objc-common.c") == 0)
646 return 1 << BASE_FILE_C
| 1 << BASE_FILE_OBJC
;
647 else if (startswith (len
, basename
, "c-"))
648 return 1 << BASE_FILE_C
| 1 << BASE_FILE_OBJC
| 1 << BASE_FILE_CPLUSPLUS
;
650 return (1 << NUM_BASE_FILES
) - 1;
654 /* An output file, suitable for definitions, that can see declarations
655 made in INPUT_FILE and is linked into every language that uses
659 get_output_file_with_visibility (input_file
)
660 const char *input_file
;
664 const char *basename
;
666 /* Do we already know the file? */
667 for (fm
= files
; fm
; fm
= fm
->next
)
668 if (input_file
== fm
->input_name
)
671 /* No, we'll be creating a new filemap. */
672 fm
= xmalloc (sizeof (*fm
));
675 fm
->input_name
= input_file
;
677 /* Determine the output file name. */
678 basename
= get_file_basename (input_file
);
680 len
= strlen (basename
);
681 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
682 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
683 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
687 fm
->output_name
= s
= xmalloc (sizeof ("gt-") + len
);
688 sprintf (s
, "gt-%s", basename
);
689 for (; *s
!= '.'; s
++)
690 if (! isalnum (*s
) && *s
!= '-')
692 memcpy (s
, ".h", sizeof (".h"));
694 else if (strcmp (basename
, "c-common.h") == 0)
695 fm
->output_name
= "gt-c-common.h";
696 else if (strcmp (basename
, "c-tree.h") == 0)
697 fm
->output_name
= "gt-c-decl.h";
702 fm
->output_name
= "gtype-desc.c";
703 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
704 if (memcmp (basename
, lang_names
[i
], strlen (lang_names
[i
])) == 0
705 && basename
[strlen(lang_names
[i
])] == '/')
710 sprintf (s
, "gtype-%s.h", lang_names
[i
]);
716 /* Look through to see if we've ever seen this output filename before. */
717 for (fmo
= fm
->next
; fmo
; fmo
= fmo
->next
)
718 if (strcmp (fmo
->output_name
, fm
->output_name
) == 0)
720 fm
->output
= fmo
->output
;
724 /* If not, create it. */
727 fm
->output
= create_file (fm
->output_name
);
728 if (strcmp (fm
->output_name
, "gtype-desc.c") == 0)
730 fputs ("#include \"config.h\"\n", fm
->output
);
731 fputs ("#include \"system.h\"\n", fm
->output
);
732 fputs ("#include \"varray.h\"\n", fm
->output
);
733 fputs ("#include \"hashtab.h\"\n", fm
->output
);
734 fputs ("#include \"bitmap.h\"\n", fm
->output
);
735 fputs ("#include \"tree.h\"\n", fm
->output
);
736 fputs ("#include \"rtl.h\"\n", fm
->output
);
737 fputs ("#include \"function.h\"\n", fm
->output
);
738 fputs ("#include \"insn-config.h\"\n", fm
->output
);
739 fputs ("#include \"expr.h\"\n", fm
->output
);
740 fputs ("#include \"hard-reg-set.h\"\n", fm
->output
);
741 fputs ("#include \"basic-block.h\"\n", fm
->output
);
742 fputs ("#include \"cselib.h\"\n", fm
->output
);
743 fputs ("#include \"insn-addr.h\"\n", fm
->output
);
744 fputs ("#include \"ssa.h\"\n", fm
->output
);
745 fputs ("#include \"optabs.h\"\n", fm
->output
);
746 fputs ("#include \"libfuncs.h\"\n", fm
->output
);
747 fputs ("#include \"debug.h\"\n", fm
->output
);
748 fputs ("#include \"ggc.h\"\n", fm
->output
);
755 /* The name of an output file, suitable for definitions, that can see
756 declarations made in INPUT_FILE and is linked into every language
757 that uses INPUT_FILE. */
760 get_output_file_name (input_file
)
761 const char *input_file
;
765 for (fm
= files
; fm
; fm
= fm
->next
)
766 if (input_file
== fm
->input_name
)
767 return fm
->output_name
;
768 (void) get_output_file_with_visibility (input_file
);
769 return get_output_file_name (input_file
);
772 /* Close all output files and copy them to their final destinations,
773 but don't unnecessarily change modification times. */
776 close_output_files
PARAMS ((void))
779 struct filemap header
;
781 header
.output_name
= "gtype-desc.h";
782 header
.output
= header_file
;
784 for (fm
= &header
; fm
; fm
= fm
->next
)
790 /* Handle each output file once. */
791 if (fm
->output
== NULL
)
794 for (ofm
= fm
->next
; ofm
; ofm
= ofm
->next
)
795 if (fm
->output
== ofm
->output
)
798 /* Compare the output file with the file to be created, avoiding
799 unnecessarily changing timestamps. */
800 newfile
= fopen (fm
->output_name
, "r");
807 ch1
= fgetc (fm
->output
);
808 ch2
= fgetc (newfile
);
809 } while (ch1
!= EOF
&& ch1
== ch2
);
813 no_write_p
= ch1
== ch2
;
818 /* Nothing interesting to do. Close the output file. */
825 newfile
= fopen (fm
->output_name
, "w");
828 perror ("opening output file");
834 while ((ch
= fgetc (fm
->output
)) != EOF
)
849 static void output_escaped_param
PARAMS ((FILE *, const char *, const char *,
850 const char *, const char *,
852 static void write_gc_structure_fields
853 PARAMS ((FILE *, type_p
, const char *, const char *, options_p
,
854 int, struct fileloc
*, lang_bitmap
, type_p
));
855 static void write_gc_marker_routine_for_structure
PARAMS ((type_p
, type_p
));
856 static void write_gc_types
PARAMS ((type_p structures
, type_p param_structs
));
857 static void put_mangled_filename
PARAMS ((FILE *, const char *));
858 static void finish_root_table
PARAMS ((struct flist
*flp
, const char *pfx
,
859 const char *tname
, const char *lastname
,
861 static void write_gc_root
PARAMS ((FILE *, pair_p
, type_p
, const char *, int,
862 struct fileloc
*, const char *));
863 static void write_gc_roots
PARAMS ((pair_p
));
865 static int gc_counter
;
867 /* Print PARAM to OF processing escapes. VAL references the current object,
868 PREV_VAL the object containing the current object, ONAME is the name
869 of the option and LINE is used to print error messages. */
872 output_escaped_param (of
, param
, val
, prev_val
, oname
, line
)
876 const char *prev_val
;
878 struct fileloc
*line
;
882 for (p
= param
; *p
; p
++)
885 else if (*++p
== 'h')
886 fprintf (of
, "(%s)", val
);
890 fprintf (of
, "(%s)", prev_val
);
892 error_at_line (line
, "`%s' option contains bad escape %c%c",
896 /* Write out code to OF which marks the fields of S. VAL references
897 the current object, PREV_VAL the object containing the current
898 object, OPTS is a list of options to apply, INDENT is the current
899 indentation level, LINE is used to print error messages, BITMAP
900 indicates which languages to print the structure for, and PARAM is
901 the current parameter (from an enclosing param_is option). */
904 write_gc_structure_fields (of
, s
, val
, prev_val
, opts
, indent
, line
, bitmap
,
909 const char *prev_val
;
912 struct fileloc
*line
;
919 if (! s
->u
.s
.line
.file
)
920 error_at_line (line
, "incomplete structure `%s'", s
->u
.s
.tag
);
921 else if ((s
->u
.s
.bitmap
& bitmap
) != bitmap
)
923 error_at_line (line
, "structure defined for mismatching languages");
924 error_at_line (&s
->u
.s
.line
, "one structure defined here");
927 if (s
->kind
== TYPE_UNION
)
929 const char *tagexpr
= NULL
;
932 tagcounter
= ++gc_counter
;
933 for (oo
= opts
; oo
; oo
= oo
->next
)
934 if (strcmp (oo
->name
, "desc") == 0)
935 tagexpr
= (const char *)oo
->info
;
939 error_at_line (line
, "missing `desc' option");
942 fprintf (of
, "%*s{\n", indent
, "");
944 fprintf (of
, "%*sunsigned int tag%d = (", indent
, "", tagcounter
);
945 output_escaped_param (of
, tagexpr
, val
, prev_val
, "desc", line
);
949 for (f
= s
->u
.s
.fields
; f
; f
= f
->next
)
951 const char *tagid
= NULL
;
952 const char *length
= NULL
;
953 const char *special
= NULL
;
956 int maybe_undef_p
= 0;
961 if (t
->kind
== TYPE_SCALAR
962 || (t
->kind
== TYPE_ARRAY
963 && t
->u
.a
.p
->kind
== TYPE_SCALAR
))
966 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
967 if (strcmp (oo
->name
, "length") == 0)
968 length
= (const char *)oo
->info
;
969 else if (strcmp (oo
->name
, "maybe_undef") == 0)
971 else if (strcmp (oo
->name
, "tag") == 0)
972 tagid
= (const char *)oo
->info
;
973 else if (strcmp (oo
->name
, "special") == 0)
974 special
= (const char *)oo
->info
;
975 else if (strcmp (oo
->name
, "skip") == 0)
977 else if (strcmp (oo
->name
, "always") == 0)
979 else if (strcmp (oo
->name
, "desc") == 0 && UNION_P (t
))
981 else if (strcmp (oo
->name
, "descbits") == 0 && UNION_P (t
))
983 else if (strcmp (oo
->name
, "param_is") == 0)
985 else if (strcmp (oo
->name
, "use_param") == 0)
988 error_at_line (&f
->line
, "unknown field option `%s'\n", oo
->name
);
1001 for (t1
= t
; t
->kind
== TYPE_ARRAY
; t
= t
->u
.a
.p
)
1003 for (; t
->kind
== TYPE_POINTER
; t
= t
->u
.p
)
1004 nt
= create_pointer (nt
);
1005 while (arraycount
-- > 0)
1006 nt
= create_array (nt
, t
->u
.a
.len
);
1009 else if (s
->kind
== TYPE_UNION
&& ! always_p
&& tagid
)
1012 error_at_line (&f
->line
, "no parameter defined");
1016 && (t
->kind
!= TYPE_POINTER
1017 || t
->u
.p
->kind
!= TYPE_STRUCT
))
1018 error_at_line (&f
->line
,
1019 "field `%s' has invalid option `maybe_undef_p'\n",
1021 if (s
->kind
== TYPE_UNION
&& ! always_p
)
1025 error_at_line (&f
->line
, "field `%s' has no tag", f
->name
);
1028 fprintf (of
, "%*sif (tag%d == (%s)) {\n", indent
, "",
1036 /* Do nothing; strings go in the string pool. */
1039 case TYPE_LANG_STRUCT
:
1042 for (ti
= t
->u
.s
.lang_struct
; ti
; ti
= ti
->next
)
1043 if (ti
->u
.s
.bitmap
& bitmap
)
1050 error_at_line (&f
->line
,
1051 "structure not defined for this language");
1055 /* Fall through... */
1061 newval
= xmalloc (strlen (val
) + sizeof (".") + strlen (f
->name
));
1062 sprintf (newval
, "%s.%s", val
, f
->name
);
1063 write_gc_structure_fields (of
, t
, newval
, val
, f
->opt
, indent
,
1064 &f
->line
, bitmap
, param
);
1073 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1074 fprintf (of
, "%*sif (%s.%s) abort();\n", indent
, "",
1076 else if (UNION_OR_STRUCT_P (t
->u
.p
))
1077 fprintf (of
, "%*sgt_ggc_m_%s (%s.%s);\n", indent
, "",
1078 t
->u
.p
->u
.s
.tag
, val
, f
->name
);
1079 else if (t
->u
.p
->kind
== TYPE_PARAM_STRUCT
)
1080 fprintf (of
, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent
, "",
1081 (int) strlen (t
->u
.p
->u
.param_struct
.param
->u
.s
.tag
),
1082 t
->u
.p
->u
.param_struct
.param
->u
.s
.tag
,
1083 t
->u
.p
->u
.param_struct
.stru
->u
.s
.tag
,
1086 error_at_line (&f
->line
, "field `%s' is pointer to scalar",
1090 else if (t
->u
.p
->kind
== TYPE_SCALAR
1091 || t
->u
.p
->kind
== TYPE_STRING
)
1092 fprintf (of
, "%*sggc_mark (%s.%s);\n", indent
, "",
1096 int loopcounter
= ++gc_counter
;
1098 fprintf (of
, "%*sif (%s.%s != NULL) {\n", indent
, "",
1101 fprintf (of
, "%*ssize_t i%d;\n", indent
, "", loopcounter
);
1102 fprintf (of
, "%*sggc_set_mark (%s.%s);\n", indent
, "",
1104 fprintf (of
, "%*sfor (i%d = 0; i%d < (", indent
, "",
1105 loopcounter
, loopcounter
);
1106 output_escaped_param (of
, length
, val
, prev_val
, "length", line
);
1107 fprintf (of
, "); i%d++) {\n", loopcounter
);
1109 switch (t
->u
.p
->kind
)
1116 newval
= xmalloc (strlen (val
) + 8 + strlen (f
->name
));
1117 sprintf (newval
, "%s.%s[i%d]", val
, f
->name
, loopcounter
);
1118 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1119 f
->opt
, indent
, &f
->line
,
1125 if (UNION_OR_STRUCT_P (t
->u
.p
->u
.p
))
1126 fprintf (of
, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent
, "",
1127 t
->u
.p
->u
.p
->u
.s
.tag
, val
, f
->name
,
1130 error_at_line (&f
->line
,
1131 "field `%s' is array of pointer to scalar",
1135 error_at_line (&f
->line
,
1136 "field `%s' is array of unimplemented type",
1141 fprintf (of
, "%*s}\n", indent
, "");
1143 fprintf (of
, "%*s}\n", indent
, "");
1149 int loopcounter
= ++gc_counter
;
1154 (strcmp (t
->u
.a
.len
, "0") == 0
1155 || strcmp (t
->u
.a
.len
, "1") == 0))
1156 error_at_line (&f
->line
,
1157 "field `%s' is array of size %s",
1158 f
->name
, t
->u
.a
.len
);
1160 /* Arrays of scalars can be ignored. */
1161 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1163 if (ta
->kind
== TYPE_SCALAR
1164 || ta
->kind
== TYPE_STRING
)
1167 fprintf (of
, "%*s{\n", indent
, "");
1170 if (special
!= NULL
&& strcmp (special
, "tree_exp") == 0)
1172 fprintf (of
, "%*sconst size_t tree_exp_size = (",
1174 output_escaped_param (of
, length
, val
, prev_val
,
1178 length
= "first_rtl_op (TREE_CODE ((tree)&%h))";
1181 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1183 fprintf (of
, "%*ssize_t i%d_%d;\n",
1184 indent
, "", loopcounter
, i
);
1185 fprintf (of
, "%*sconst size_t ilimit%d_%d = (",
1186 indent
, "", loopcounter
, i
);
1187 if (i
== 0 && length
!= NULL
)
1188 output_escaped_param (of
, length
, val
, prev_val
,
1191 fputs (ta
->u
.a
.len
, of
);
1195 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1198 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1199 indent
, "", loopcounter
, i
, loopcounter
, i
,
1200 loopcounter
, i
, loopcounter
, i
);
1204 if (ta
->kind
== TYPE_POINTER
1205 && (ta
->u
.p
->kind
== TYPE_STRUCT
1206 || ta
->u
.p
->kind
== TYPE_UNION
))
1208 fprintf (of
, "%*sgt_ggc_m_%s (%s.%s",
1209 indent
, "", ta
->u
.p
->u
.s
.tag
, val
, f
->name
);
1211 ta
->kind
== TYPE_ARRAY
;
1212 ta
= ta
->u
.a
.p
, i
++)
1213 fprintf (of
, "[i%d_%d]", loopcounter
, i
);
1216 else if (ta
->kind
== TYPE_STRUCT
|| ta
->kind
== TYPE_UNION
)
1221 len
= strlen (val
) + strlen (f
->name
) + 2;
1222 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1223 len
+= sizeof ("[i_]") + 2*6;
1225 newval
= xmalloc (len
);
1226 sprintf (newval
, "%s.%s", val
, f
->name
);
1228 ta
->kind
== TYPE_ARRAY
;
1229 ta
= ta
->u
.a
.p
, i
++)
1230 sprintf (newval
+ strlen (newval
), "[i%d_%d]",
1232 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1233 f
->opt
, indent
, &f
->line
, bitmap
,
1237 else if (ta
->kind
== TYPE_POINTER
&& ta
->u
.p
->kind
== TYPE_SCALAR
1238 && use_param_p
&& param
== NULL
)
1239 fprintf (of
, "%*sabort();\n", indent
, "");
1241 error_at_line (&f
->line
,
1242 "field `%s' is array of unimplemented type",
1244 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1247 fprintf (of
, "%*s}\n", indent
, "");
1250 if (special
!= NULL
&& strcmp (special
, "tree_exp") == 0)
1253 "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
1254 indent
, "", loopcounter
, loopcounter
);
1255 fprintf (of
, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
1256 indent
, "", val
, f
->name
, loopcounter
);
1261 fprintf (of
, "%*s}\n", indent
, "");
1266 error_at_line (&f
->line
,
1267 "field `%s' is unimplemented type",
1272 if (s
->kind
== TYPE_UNION
&& ! always_p
)
1275 fprintf (of
, "%*s}\n", indent
, "");
1278 error_at_line (&f
->line
, "unhandled special `%s'", special
);
1280 if (s
->kind
== TYPE_UNION
)
1283 fprintf (of
, "%*s}\n", indent
, "");
1287 /* Write out a marker routine for S. PARAM is the parameter from an
1288 enclosing PARAM_IS option. */
1291 write_gc_marker_routine_for_structure (s
, param
)
1297 f
= get_output_file_with_visibility (s
->u
.s
.line
.file
);
1299 f
= get_output_file_with_visibility (param
->u
.s
.line
.file
);
1302 fputs ("void\n", f
);
1304 fprintf (f
, "gt_ggc_mx_%s (x_p)\n", s
->u
.s
.tag
);
1306 fprintf (f
, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param
->u
.s
.tag
),
1307 param
->u
.s
.tag
, s
->u
.s
.tag
);
1308 fputs (" void *x_p;\n", f
);
1310 fprintf (f
, " %s %s * const x = (%s %s *)x_p;\n",
1311 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1312 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1313 fputs (" if (! ggc_test_and_set_mark (x))\n", f
);
1314 fputs (" return;\n", f
);
1317 write_gc_structure_fields (f
, s
, "(*x)", "not valid postage",
1318 s
->u
.s
.opt
, 2, &s
->u
.s
.line
, s
->u
.s
.bitmap
,
1324 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
1327 write_gc_types (structures
, param_structs
)
1329 type_p param_structs
;
1333 fputs ("\n/* GC marker procedures. */\n", header_file
);
1334 for (s
= structures
; s
; s
= s
->next
)
1335 if (s
->gc_used
== GC_POINTED_TO
1336 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
1340 if (s
->gc_used
== GC_MAYBE_POINTED_TO
1341 && s
->u
.s
.line
.file
== NULL
)
1344 fprintf (header_file
,
1345 "#define gt_ggc_m_%s(X) do { \\\n", s
->u
.s
.tag
);
1346 fprintf (header_file
,
1347 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s
->u
.s
.tag
);
1348 fprintf (header_file
,
1351 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
1352 if (strcmp (opt
->name
, "ptr_alias") == 0)
1354 type_p t
= (type_p
) opt
->info
;
1355 if (t
->kind
== TYPE_STRUCT
1356 || t
->kind
== TYPE_UNION
1357 || t
->kind
== TYPE_LANG_STRUCT
)
1358 fprintf (header_file
,
1359 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
1360 s
->u
.s
.tag
, t
->u
.s
.tag
);
1362 error_at_line (&s
->u
.s
.line
,
1363 "structure alias is not a structure");
1369 /* Declare the marker procedure only once. */
1370 fprintf (header_file
,
1371 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1374 if (s
->u
.s
.line
.file
== NULL
)
1376 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
1381 if (s
->kind
== TYPE_LANG_STRUCT
)
1384 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
1385 write_gc_marker_routine_for_structure (ss
, NULL
);
1388 write_gc_marker_routine_for_structure (s
, NULL
);
1391 for (s
= param_structs
; s
; s
= s
->next
)
1392 if (s
->gc_used
== GC_POINTED_TO
)
1394 type_p param
= s
->u
.param_struct
.param
;
1395 type_p stru
= s
->u
.param_struct
.stru
;
1397 if (param
->kind
!= TYPE_STRUCT
&& param
->kind
!= TYPE_UNION
1398 && param
->kind
!= TYPE_LANG_STRUCT
)
1400 error_at_line (&s
->u
.param_struct
.line
,
1401 "unsupported parameter type");
1405 /* Declare the marker procedure. */
1406 fprintf (header_file
,
1407 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
1408 (int) strlen (param
->u
.s
.tag
), param
->u
.s
.tag
,
1411 if (stru
->u
.s
.line
.file
== NULL
)
1413 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
1418 if (stru
->kind
== TYPE_LANG_STRUCT
)
1421 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
1422 write_gc_marker_routine_for_structure (ss
, param
);
1425 write_gc_marker_routine_for_structure (stru
, param
);
1429 /* Mangle FN and print it to F. */
1432 put_mangled_filename (f
, fn
)
1436 const char *name
= get_output_file_name (fn
);
1437 for (; *name
!= 0; name
++)
1438 if (isalnum (*name
))
1444 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
1445 LASTNAME, and NAME are all strings to insert in various places in
1446 the resulting code. */
1449 finish_root_table (flp
, pfx
, lastname
, tname
, name
)
1453 const char *lastname
;
1457 unsigned started_bitmap
= 0;
1459 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1460 if (fli2
->started_p
)
1462 fprintf (fli2
->f
, " %s\n", lastname
);
1463 fputs ("};\n\n", fli2
->f
);
1466 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1467 if (fli2
->started_p
)
1469 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
1472 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1475 fprintf (base_files
[fnum
],
1476 "extern const struct %s gt_ggc_%s_",
1478 put_mangled_filename (base_files
[fnum
], fli2
->name
);
1479 fputs ("[];\n", base_files
[fnum
]);
1483 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1484 if (fli2
->started_p
)
1486 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
1489 fli2
->started_p
= 0;
1491 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1494 if (! (started_bitmap
& (1 << fnum
)))
1496 fprintf (base_files
[fnum
],
1497 "const struct %s * const %s[] = {\n",
1499 started_bitmap
|= 1 << fnum
;
1501 fprintf (base_files
[fnum
], " gt_ggc_%s_", pfx
);
1502 put_mangled_filename (base_files
[fnum
], fli2
->name
);
1503 fputs (",\n", base_files
[fnum
]);
1511 for (bitmap
= started_bitmap
, fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1514 fputs (" NULL\n", base_files
[fnum
]);
1515 fputs ("};\n\n", base_files
[fnum
]);
1520 /* Write out to F the table entry and any marker routines needed to
1521 mark NAME as TYPE. The original variable is V, at LINE.
1522 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
1523 is nonzero iff we are building the root table for hash table caches. */
1526 write_gc_root (f
, v
, type
, name
, has_length
, line
, if_marked
)
1532 struct fileloc
*line
;
1533 const char *if_marked
;
1540 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
1543 const char *desc
= NULL
;
1546 for (o
= fld
->opt
; o
; o
= o
->next
)
1547 if (strcmp (o
->name
, "skip") == 0)
1549 else if (strcmp (o
->name
, "desc") == 0)
1550 desc
= (const char *)o
->info
;
1552 error_at_line (line
,
1553 "field `%s' of global `%s' has unknown option `%s'",
1554 fld
->name
, name
, o
->name
);
1558 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
1560 pair_p validf
= NULL
;
1563 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
1565 const char *tag
= NULL
;
1568 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
1569 if (strcmp (oo
->name
, "tag") == 0)
1570 tag
= (const char *)oo
->info
;
1571 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
1574 error_at_line (line
,
1575 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
1576 name
, fld
->name
, validf
->name
,
1577 name
, fld
->name
, ufld
->name
,
1584 newname
= xmalloc (strlen (name
) + 3 + strlen (fld
->name
)
1585 + strlen (validf
->name
));
1586 sprintf (newname
, "%s.%s.%s",
1587 name
, fld
->name
, validf
->name
);
1588 write_gc_root (f
, v
, validf
->type
, newname
, 0, line
,
1594 error_at_line (line
,
1595 "global `%s.%s' has `desc' option but is not union",
1600 newname
= xmalloc (strlen (name
) + 2 + strlen (fld
->name
));
1601 sprintf (newname
, "%s.%s", name
, fld
->name
);
1602 write_gc_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
1612 newname
= xmalloc (strlen (name
) + 4);
1613 sprintf (newname
, "%s[0]", name
);
1614 write_gc_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
1624 fprintf (f
, " &%s,\n", name
);
1627 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
1629 fprintf (f
, " * (%s)", ap
->u
.a
.len
);
1630 else if (ap
== v
->type
)
1631 fprintf (f
, " * (sizeof (%s) / sizeof (%s[0]))",
1634 fprintf (f
, " sizeof (%s", v
->name
);
1635 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
1641 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
1643 fprintf (f
, " >_ggc_mx_%s\n", tp
->u
.s
.tag
);
1645 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
1647 fprintf (f
, " >_ggc_mm_%d%s_%s",
1648 (int) strlen (tp
->u
.param_struct
.param
->u
.s
.tag
),
1649 tp
->u
.param_struct
.param
->u
.s
.tag
,
1650 tp
->u
.param_struct
.stru
->u
.s
.tag
);
1653 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
1655 fprintf (f
, " >_ggc_ma_%s", name
);
1659 error_at_line (line
,
1660 "global `%s' is pointer to unimplemented type",
1664 fprintf (f
, ",\n &%s", if_marked
);
1665 fputs ("\n },\n", f
);
1674 error_at_line (line
,
1675 "global `%s' is unimplemented type",
1680 /* Output a table describing the locations and types of VARIABLES. */
1683 write_gc_roots (variables
)
1687 struct flist
*flp
= NULL
;
1689 for (v
= variables
; v
; v
= v
->next
)
1691 FILE *f
= get_output_file_with_visibility (v
->line
.file
);
1693 const char *length
= NULL
;
1694 int deletable_p
= 0;
1697 for (o
= v
->opt
; o
; o
= o
->next
)
1698 if (strcmp (o
->name
, "length") == 0)
1699 length
= (const char *)o
->info
;
1700 else if (strcmp (o
->name
, "deletable") == 0)
1702 else if (strcmp (o
->name
, "param_is") == 0)
1704 else if (strcmp (o
->name
, "if_marked") == 0)
1707 error_at_line (&v
->line
,
1708 "global `%s' has unknown option `%s'",
1711 for (fli
= flp
; fli
; fli
= fli
->next
)
1716 fli
= xmalloc (sizeof (*fli
));
1720 fli
->name
= v
->line
.file
;
1723 fputs ("\n/* GC roots. */\n\n", f
);
1728 && v
->type
->kind
== TYPE_POINTER
1729 && (v
->type
->u
.p
->kind
== TYPE_POINTER
1730 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
1732 fprintf (f
, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
1734 fprintf (f
, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
1737 fputs (" size_t i;\n", f
);
1739 if (v
->type
->u
.p
->kind
== TYPE_POINTER
)
1741 type_p s
= v
->type
->u
.p
->u
.p
;
1743 fprintf (f
, " %s %s ** const x = (%s %s **)x_p;\n",
1744 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1745 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1746 fputs (" if (ggc_test_and_set_mark (x))\n", f
);
1747 fprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
1748 if (s
->kind
!= TYPE_STRUCT
&& s
->kind
!= TYPE_UNION
)
1750 error_at_line (&v
->line
,
1751 "global `%s' has unsupported ** type",
1756 fprintf (f
, " gt_ggc_m_%s (x[i]);\n", s
->u
.s
.tag
);
1760 type_p s
= v
->type
->u
.p
;
1762 fprintf (f
, " %s %s * const x = (%s %s *)x_p;\n",
1763 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1764 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1765 fputs (" if (ggc_test_and_set_mark (x))\n", f
);
1766 fprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
1768 write_gc_structure_fields (f
, s
, "x[i]", "x[i]",
1769 v
->opt
, 8, &v
->line
, s
->u
.s
.bitmap
,
1778 for (v
= variables
; v
; v
= v
->next
)
1780 FILE *f
= get_output_file_with_visibility (v
->line
.file
);
1786 for (o
= v
->opt
; o
; o
= o
->next
)
1787 if (strcmp (o
->name
, "length") == 0)
1789 else if (strcmp (o
->name
, "deletable") == 0
1790 || strcmp (o
->name
, "if_marked") == 0)
1796 for (fli
= flp
; fli
; fli
= fli
->next
)
1799 if (! fli
->started_p
)
1803 fputs ("const struct ggc_root_tab gt_ggc_r_", f
);
1804 put_mangled_filename (f
, v
->line
.file
);
1805 fputs ("[] = {\n", f
);
1808 write_gc_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
1811 finish_root_table (flp
, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1814 for (v
= variables
; v
; v
= v
->next
)
1816 FILE *f
= get_output_file_with_visibility (v
->line
.file
);
1821 for (o
= v
->opt
; o
; o
= o
->next
)
1822 if (strcmp (o
->name
, "deletable") == 0)
1824 else if (strcmp (o
->name
, "if_marked") == 0)
1830 for (fli
= flp
; fli
; fli
= fli
->next
)
1833 if (! fli
->started_p
)
1837 fputs ("const struct ggc_root_tab gt_ggc_rd_", f
);
1838 put_mangled_filename (f
, v
->line
.file
);
1839 fputs ("[] = {\n", f
);
1842 fprintf (f
, " { &%s, 1, sizeof (%s), NULL },\n",
1846 finish_root_table (flp
, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1847 "gt_ggc_deletable_rtab");
1849 for (v
= variables
; v
; v
= v
->next
)
1851 FILE *f
= get_output_file_with_visibility (v
->line
.file
);
1853 const char *if_marked
= NULL
;
1857 for (o
= v
->opt
; o
; o
= o
->next
)
1858 if (strcmp (o
->name
, "length") == 0)
1860 else if (strcmp (o
->name
, "if_marked") == 0)
1861 if_marked
= (const char *) o
->info
;
1863 if (if_marked
== NULL
)
1866 if (v
->type
->kind
!= TYPE_POINTER
1867 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
1868 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
1870 error_at_line (&v
->line
, "if_marked option used but not hash table");
1874 for (fli
= flp
; fli
; fli
= fli
->next
)
1877 if (! fli
->started_p
)
1881 fputs ("const struct ggc_cache_tab gt_ggc_rc_", f
);
1882 put_mangled_filename (f
, v
->line
.file
);
1883 fputs ("[] = {\n", f
);
1886 write_gc_root (f
, v
, create_pointer (v
->type
->u
.p
->u
.param_struct
.param
),
1887 v
->name
, length_p
, &v
->line
, if_marked
);
1890 finish_root_table (flp
, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
1891 "gt_ggc_cache_rtab");
1895 extern int main
PARAMS ((int argc
, char **argv
));
1902 static struct fileloc pos
= { __FILE__
, __LINE__
};
1904 do_typedef ("CUMULATIVE_ARGS",
1905 create_scalar_type ("CUMULATIVE_ARGS",
1906 strlen ("CUMULATIVE_ARGS")),
1908 do_typedef ("REAL_VALUE_TYPE",
1909 create_scalar_type ("REAL_VALUE_TYPE",
1910 strlen ("REAL_VALUE_TYPE")),
1912 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1916 for (i
= 1; i
< argc
; i
++)
1917 parse_file (argv
[i
]);
1922 set_gc_used (variables
);
1925 write_gc_types (structures
, param_structs
);
1926 write_gc_roots (variables
);
1927 close_output_files ();
1929 return (hit_error
!= 0);