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 /* vasprintf, but produces fatal message on out-of-memory. */
47 xvasprintf (result
, format
, args
)
52 int ret
= vasprintf (result
, format
, args
);
53 if (*result
== NULL
|| ret
< 0)
55 fputs ("gengtype: out of memory", stderr
);
61 /* Wrapper for xvasprintf. */
63 xasprintf
VPARAMS ((const char *format
, ...))
67 VA_FIXEDARG (ap
, const char *, format
);
68 xvasprintf (&result
, format
, ap
);
73 /* The one and only TYPE_STRING. */
75 struct type string_type
= {
76 TYPE_STRING
, NULL
, NULL
, GC_USED
80 /* Lists of various things. */
82 static pair_p typedefs
;
83 static type_p structures
;
84 static type_p param_structs
;
85 static pair_p variables
;
87 /* Define S as a typedef to T at POS. */
90 do_typedef (s
, t
, pos
)
97 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
98 if (strcmp (p
->name
, s
) == 0)
102 error_at_line (pos
, "type `%s' previously defined", s
);
103 error_at_line (&p
->line
, "previously defined here");
108 p
= xmalloc (sizeof (struct pair
));
116 /* Return the type previously defined for S. Use POS to report errors. */
119 resolve_typedef (s
, pos
)
124 for (p
= typedefs
; p
!= NULL
; p
= p
->next
)
125 if (strcmp (p
->name
, s
) == 0)
127 error_at_line (pos
, "unidentified type `%s'", s
);
128 return create_scalar_type ("char", 4);
131 /* Create a new structure with tag NAME (or a union iff ISUNION is nonzero),
132 at POS with fields FIELDS and options O. */
135 new_structure (name
, isunion
, pos
, fields
, o
)
144 lang_bitmap bitmap
= get_base_file_bitmap (pos
->file
);
146 for (si
= structures
; si
!= NULL
; si
= si
->next
)
147 if (strcmp (name
, si
->u
.s
.tag
) == 0
148 && UNION_P (si
) == isunion
)
151 if (si
->kind
== TYPE_LANG_STRUCT
)
155 for (si
= ls
->u
.s
.lang_struct
; si
!= NULL
; si
= si
->next
)
156 if (si
->u
.s
.bitmap
== bitmap
)
159 else if (si
->u
.s
.line
.file
!= NULL
&& si
->u
.s
.bitmap
!= bitmap
)
162 si
= xcalloc (1, sizeof (struct type
));
163 memcpy (si
, ls
, sizeof (struct type
));
164 ls
->kind
= TYPE_LANG_STRUCT
;
165 ls
->u
.s
.lang_struct
= si
;
166 ls
->u
.s
.fields
= NULL
;
168 si
->pointer_to
= NULL
;
169 si
->u
.s
.lang_struct
= ls
;
174 if (ls
!= NULL
&& s
== NULL
)
176 s
= xcalloc (1, sizeof (struct type
));
177 s
->next
= ls
->u
.s
.lang_struct
;
178 ls
->u
.s
.lang_struct
= s
;
179 s
->u
.s
.lang_struct
= ls
;
186 s
= xcalloc (1, sizeof (struct type
));
187 s
->next
= structures
;
191 if (s
->u
.s
.line
.file
!= NULL
192 || (s
->u
.s
.lang_struct
&& (s
->u
.s
.lang_struct
->u
.s
.bitmap
& bitmap
)))
194 error_at_line (pos
, "duplicate structure definition");
195 error_at_line (&s
->u
.s
.line
, "previous definition here");
198 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
201 s
->u
.s
.fields
= fields
;
203 s
->u
.s
.bitmap
= bitmap
;
204 if (s
->u
.s
.lang_struct
)
205 s
->u
.s
.lang_struct
->u
.s
.bitmap
|= bitmap
;
208 /* Return the previously-defined structure with tag NAME (or a union
209 iff ISUNION is nonzero), or a new empty structure or union if none
210 was defined previously. */
213 find_structure (name
, isunion
)
219 for (s
= structures
; s
!= NULL
; s
= s
->next
)
220 if (strcmp (name
, s
->u
.s
.tag
) == 0
221 && UNION_P (s
) == isunion
)
224 s
= xcalloc (1, sizeof (struct type
));
225 s
->next
= structures
;
227 s
->kind
= isunion
? TYPE_UNION
: TYPE_STRUCT
;
233 /* Return a scalar type with name NAME. */
236 create_scalar_type (name
, name_len
)
240 type_p r
= xcalloc (1, sizeof (struct type
));
241 r
->kind
= TYPE_SCALAR
;
242 r
->u
.sc
= xmemdup (name
, name_len
, name_len
+ 1);
246 /* Return a pointer to T. */
254 type_p r
= xcalloc (1, sizeof (struct type
));
255 r
->kind
= TYPE_POINTER
;
259 return t
->pointer_to
;
262 /* Return an array of length LEN. */
265 create_array (t
, len
)
271 v
= xcalloc (1, sizeof (*v
));
272 v
->kind
= TYPE_ARRAY
;
278 /* Perform any special processing on a type T, about to become the type
279 of a field. Return the appropriate type for the field.
281 - Converts pointer-to-char, with no length parameter, to TYPE_STRING;
282 - Similarly for arrays of pointer-to-char;
283 - Converts structures for which a parameter is provided to
288 adjust_field_type (t
, opt
)
293 const int pointer_p
= t
->kind
== TYPE_POINTER
;
295 for (; opt
; opt
= opt
->next
)
296 if (strcmp (opt
->name
, "length") == 0)
298 else if (strcmp (opt
->name
, "param_is") == 0)
305 for (realt
= param_structs
; realt
; realt
= realt
->next
)
306 if (realt
->u
.param_struct
.stru
== t
307 && realt
->u
.param_struct
.param
== (type_p
) opt
->info
)
308 return pointer_p
? create_pointer (realt
) : realt
;
309 realt
= xcalloc (1, sizeof (*realt
));
310 realt
->kind
= TYPE_PARAM_STRUCT
;
311 realt
->next
= param_structs
;
312 param_structs
= realt
;
313 realt
->u
.param_struct
.stru
= t
;
314 realt
->u
.param_struct
.param
= (type_p
) opt
->info
;
315 return pointer_p
? create_pointer (realt
) : realt
;
320 && t
->u
.p
->kind
== TYPE_SCALAR
321 && (strcmp (t
->u
.p
->u
.sc
, "char") == 0
322 || strcmp (t
->u
.p
->u
.sc
, "unsigned char") == 0))
324 if (t
->kind
== TYPE_ARRAY
&& t
->u
.a
.p
->kind
== TYPE_POINTER
325 && t
->u
.a
.p
->u
.p
->kind
== TYPE_SCALAR
326 && (strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "char") == 0
327 || strcmp (t
->u
.a
.p
->u
.p
->u
.sc
, "unsigned char") == 0))
328 return create_array (&string_type
, t
->u
.a
.len
);
333 /* Add a variable named S of type T with options O defined at POS,
337 note_variable (s
, t
, o
, pos
)
344 n
= xmalloc (sizeof (*n
));
353 /* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
354 and information about the correspondance between token types and fields
355 in TYPEINFO. POS is used for error messages. */
358 note_yacc_type (o
, fields
, typeinfo
, pos
)
367 for (p
= typeinfo
; p
; p
= p
->next
)
374 if (p
->type
== (type_p
) 1)
379 for (pp
= typeinfo
; pp
; pp
= pp
->next
)
380 if (pp
->type
!= (type_p
) 1
381 && strcmp (pp
->opt
->info
, p
->opt
->info
) == 0)
390 for (m
= fields
; m
; m
= m
->next
)
391 if (strcmp (m
->name
, p
->name
) == 0)
395 error_at_line (&p
->line
,
396 "couldn't match fieldname `%s'", p
->name
);
407 || p
->type
== (type_p
) 1)
413 new_structure ("yy_union", 1, pos
, typeinfo
, o
);
414 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos
);
417 static void process_gc_options
PARAMS ((options_p
, enum gc_used_enum
, int *));
418 static void set_gc_used_type
PARAMS ((type_p
, enum gc_used_enum
));
419 static void set_gc_used
PARAMS ((pair_p
));
421 /* Handle OPT for set_gc_used_type. */
424 process_gc_options (opt
, level
, maybe_undef
)
426 enum gc_used_enum level
;
430 for (o
= opt
; o
; o
= o
->next
)
431 if (strcmp (o
->name
, "ptr_alias") == 0 && level
== GC_POINTED_TO
)
432 set_gc_used_type ((type_p
) o
->info
, GC_POINTED_TO
);
433 else if (strcmp (o
->name
, "maybe_undef") == 0)
437 /* Set the gc_used field of T to LEVEL, and handle the types it references. */
440 set_gc_used_type (t
, level
)
442 enum gc_used_enum level
;
444 if (t
->gc_used
>= level
)
457 process_gc_options (t
->u
.s
.opt
, level
, &dummy
);
459 for (f
= t
->u
.s
.fields
; f
; f
= f
->next
)
462 process_gc_options (t
->u
.s
.opt
, level
, &maybe_undef
);
464 if (maybe_undef
&& f
->type
->kind
== TYPE_POINTER
)
465 set_gc_used_type (f
->type
->u
.p
, GC_MAYBE_POINTED_TO
);
467 set_gc_used_type (f
->type
, GC_USED
);
473 set_gc_used_type (t
->u
.p
, GC_POINTED_TO
);
477 set_gc_used_type (t
->u
.a
.p
, GC_USED
);
480 case TYPE_LANG_STRUCT
:
481 for (t
= t
->u
.s
.lang_struct
; t
; t
= t
->next
)
482 set_gc_used_type (t
, level
);
485 case TYPE_PARAM_STRUCT
:
486 set_gc_used_type (t
->u
.param_struct
.param
, GC_POINTED_TO
);
487 set_gc_used_type (t
->u
.param_struct
.stru
, GC_USED
);
495 /* Set the gc_used fileds of all the types pointed to by VARIABLES. */
498 set_gc_used (variables
)
502 for (p
= variables
; p
; p
= p
->next
)
503 set_gc_used_type (p
->type
, GC_USED
);
506 /* File mapping routines. For each input file, there is one output .c file
507 (but some output files have many input files), and there is one .h file
508 for the whole build. */
510 /* The list of output files. */
511 static outf_p output_files
;
513 /* The output header file that is included into pretty much every
525 static const char *const lang_names
[] = {
526 "c", "objc", "cp", "treelang", "cobol", "f", "ada", "java"
528 #define NUM_BASE_FILES ARRAY_SIZE (lang_names)
529 outf_p base_files
[NUM_BASE_FILES
];
531 static outf_p create_file
PARAMS ((const char *, const char *));
532 static const char * get_file_basename
PARAMS ((const char *));
534 /* Create and return an outf_p for a new file for NAME, to be called
538 create_file (name
, oname
)
542 static const char *const hdr
[] = {
543 " Copyright (C) 2002 Free Software Foundation, Inc.\n",
545 "This file is part of GCC.\n",
547 "GCC is free software; you can redistribute it and/or modify it under\n",
548 "the terms of the GNU General Public License as published by the Free\n",
549 "Software Foundation; either version 2, or (at your option) any later\n",
552 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
553 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
554 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
555 "for more details.\n",
557 "You should have received a copy of the GNU General Public License\n",
558 "along with GCC; see the file COPYING. If not, write to the Free\n",
559 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
560 "02111-1307, USA. */\n",
562 "/* This file is machine generated. Do not edit. */\n"
567 f
= xcalloc (sizeof (*f
), 1);
568 f
->next
= output_files
;
572 oprintf (f
, "/* Type information for %s.\n", name
);
573 for (i
= 0; i
< ARRAY_SIZE (hdr
); i
++)
574 oprintf (f
, "%s", hdr
[i
]);
578 /* Print, like fprintf, to O. */
580 oprintf
VPARAMS ((outf_p o
, const char *format
, ...))
585 VA_OPEN (ap
, format
);
586 VA_FIXEDARG (ap
, outf_p
, o
);
587 VA_FIXEDARG (ap
, const char *, format
);
588 slength
= xvasprintf (&s
, format
, ap
);
590 if (o
->bufused
+ slength
> o
->buflength
)
592 size_t new_len
= o
->buflength
;
597 } while (o
->bufused
+ slength
>= new_len
);
598 o
->buf
= xrealloc (o
->buf
, new_len
);
599 o
->buflength
= new_len
;
601 memcpy (o
->buf
+ o
->bufused
, s
, slength
);
602 o
->bufused
+= slength
;
607 /* Open the global header file and the language-specific header files. */
610 open_base_files (void)
614 header_file
= create_file ("GCC", "gtype-desc.h");
616 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
617 base_files
[i
] = create_file (lang_names
[i
],
618 xasprintf ("gtype-%s.h", lang_names
[i
]));
620 /* gtype-desc.c is a little special, so we create it here. */
622 /* The order of files here matters very much. */
623 static const char *const ifiles
[] = {
624 "config.h", "system.h", "varray.h", "hashtab.h",
625 "bitmap.h", "tree.h", "rtl.h", "function.h", "insn-config.h",
626 "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h",
627 "insn-addr.h", "ssa.h", "optabs.h", "libfuncs.h",
631 const char *const *ifp
;
634 gtype_desc_c
= create_file ("GCC", "gtype-desc.c");
635 for (ifp
= ifiles
; *ifp
; ifp
++)
636 oprintf (gtype_desc_c
, "#include \"%s\"\n", *ifp
);
640 #define startswith(len, c, s) \
641 ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
643 /* Determine the pathname to F relative to $(srcdir). */
646 get_file_basename (f
)
650 const char *basename
;
652 /* Determine the output file name. */
654 basename
= strrchr (f
, '/');
655 if (basename
== NULL
)
659 if (startswith (basename
- f
, basename
-2, "f/"))
661 else if (startswith (basename
- f
, basename
-3, "cp/"))
663 else if (startswith (basename
- f
, basename
-4, "ada/"))
665 else if (startswith (basename
- f
, basename
-5, "java/"))
667 else if (startswith (basename
- f
, basename
-5, "objc/"))
669 else if (startswith (basename
- f
, basename
-9, "treelang/"))
671 else if (startswith (basename
- f
, basename
-6, "cobol/"))
677 /* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
678 INPUT_FILE is used by <lang>.
680 This function should be written to assume that a file _is_ used
681 if the situation is unclear. If it wrongly assumes a file _is_ used,
682 a linker error will result. If it wrongly assumes a file _is not_ used,
683 some GC roots may be missed, which is a much harder-to-debug problem. */
686 get_base_file_bitmap (input_file
)
687 const char *input_file
;
689 const char *basename
= get_file_basename (input_file
);
690 const char *slashpos
= strchr (basename
, '/');
691 size_t len
= strlen (basename
);
693 if (slashpos
!= NULL
)
696 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
697 if ((size_t)(slashpos
- basename
) == strlen (lang_names
[i
])
698 && memcmp (basename
, lang_names
[i
], strlen (lang_names
[i
])) == 0)
701 else if (strcmp (basename
, "c-lang.c") == 0)
702 return 1 << BASE_FILE_C
;
703 else if (strcmp (basename
, "c-parse.in") == 0
704 || strcmp (basename
, "c-tree.h") == 0
705 || strcmp (basename
, "c-decl.c") == 0
706 || strcmp (basename
, "c-objc-common.c") == 0)
707 return 1 << BASE_FILE_C
| 1 << BASE_FILE_OBJC
;
708 else if (startswith (len
, basename
, "c-common.c"))
709 return 1 << BASE_FILE_C
| 1 << BASE_FILE_OBJC
| 1 << BASE_FILE_CPLUSPLUS
710 | 1 << BASE_FILE_TREELANG
| 1 << BASE_FILE_COBOL
;
711 else if (startswith (len
, basename
, "c-"))
712 return 1 << BASE_FILE_C
| 1 << BASE_FILE_OBJC
| 1 << BASE_FILE_CPLUSPLUS
;
714 return (1 << NUM_BASE_FILES
) - 1;
718 /* An output file, suitable for definitions, that can see declarations
719 made in INPUT_FILE and is linked into every language that uses
723 get_output_file_with_visibility (input_file
)
724 const char *input_file
;
728 const char *basename
;
729 const char *for_name
;
730 const char *output_name
;
732 /* This can happen when we need a file with visibility on a
733 structure that we've never seen. We have to just hope that it's
735 if (input_file
== NULL
)
736 input_file
= "system.h";
738 /* Determine the output file name. */
739 basename
= get_file_basename (input_file
);
741 len
= strlen (basename
);
742 if ((len
> 2 && memcmp (basename
+len
-2, ".c", 2) == 0)
743 || (len
> 2 && memcmp (basename
+len
-2, ".y", 2) == 0)
744 || (len
> 3 && memcmp (basename
+len
-3, ".in", 3) == 0))
748 output_name
= s
= xasprintf ("gt-%s", basename
);
749 for (; *s
!= '.'; s
++)
750 if (! ISALNUM (*s
) && *s
!= '-')
752 memcpy (s
, ".h", sizeof (".h"));
755 else if (strcmp (basename
, "c-common.h") == 0)
756 output_name
= "gt-c-common.h", for_name
= "c-common.c";
757 else if (strcmp (basename
, "c-tree.h") == 0)
758 output_name
= "gt-c-decl.h", for_name
= "c-decl.c";
763 for (i
= 0; i
< NUM_BASE_FILES
; i
++)
764 if (memcmp (basename
, lang_names
[i
], strlen (lang_names
[i
])) == 0
765 && basename
[strlen(lang_names
[i
])] == '/')
766 return base_files
[i
];
768 output_name
= "gtype-desc.c";
772 /* Look through to see if we've ever seen this output filename before. */
773 for (r
= output_files
; r
; r
= r
->next
)
774 if (strcmp (r
->name
, output_name
) == 0)
777 /* If not, create it. */
778 r
= create_file (for_name
, output_name
);
783 /* The name of an output file, suitable for definitions, that can see
784 declarations made in INPUT_FILE and is linked into every language
785 that uses INPUT_FILE. */
788 get_output_file_name (input_file
)
789 const char *input_file
;
791 return get_output_file_with_visibility (input_file
)->name
;
794 /* Copy the output to its final destination,
795 but don't unnecessarily change modification times. */
798 close_output_files
PARAMS ((void))
802 for (of
= output_files
; of
; of
= of
->next
)
806 newfile
= fopen (of
->name
, "r");
807 if (newfile
!= NULL
)
812 for (i
= 0; i
< of
->bufused
; i
++)
815 ch
= fgetc (newfile
);
816 if (ch
== EOF
|| ch
!= (unsigned char) of
->buf
[i
])
819 no_write_p
= i
== of
->bufused
&& fgetc (newfile
) == EOF
;
826 newfile
= fopen (of
->name
, "w");
829 perror ("opening output file");
832 if (fwrite (of
->buf
, 1, of
->bufused
, newfile
) != of
->bufused
)
834 perror ("writing output file");
837 if (fclose (newfile
) != 0)
839 perror ("closing output file");
852 static void output_escaped_param
PARAMS ((outf_p
, const char *, const char *,
853 const char *, const char *,
855 static void write_gc_structure_fields
856 PARAMS ((outf_p
, type_p
, const char *, const char *, options_p
,
857 int, struct fileloc
*, lang_bitmap
, type_p
));
858 static void write_gc_marker_routine_for_structure
PARAMS ((type_p
, type_p
));
859 static void write_gc_types
PARAMS ((type_p structures
, type_p param_structs
));
860 static void put_mangled_filename
PARAMS ((outf_p
, const char *));
861 static void finish_root_table
PARAMS ((struct flist
*flp
, const char *pfx
,
862 const char *tname
, const char *lastname
,
864 static void write_gc_root
PARAMS ((outf_p
, pair_p
, type_p
, const char *, int,
865 struct fileloc
*, const char *));
866 static void write_gc_roots
PARAMS ((pair_p
));
868 static int gc_counter
;
870 /* Print PARAM to OF processing escapes. VAL references the current object,
871 PREV_VAL the object containing the current object, ONAME is the name
872 of the option and LINE is used to print error messages. */
875 output_escaped_param (of
, param
, val
, prev_val
, oname
, line
)
879 const char *prev_val
;
881 struct fileloc
*line
;
885 for (p
= param
; *p
; p
++)
887 oprintf (of
, "%c", *p
);
888 else if (*++p
== 'h')
889 oprintf (of
, "(%s)", val
);
891 oprintf (of
, "(*x)");
893 oprintf (of
, "(%s)", prev_val
);
895 error_at_line (line
, "`%s' option contains bad escape %c%c",
899 /* Write out code to OF which marks the fields of S. VAL references
900 the current object, PREV_VAL the object containing the current
901 object, OPTS is a list of options to apply, INDENT is the current
902 indentation level, LINE is used to print error messages, BITMAP
903 indicates which languages to print the structure for, and PARAM is
904 the current parameter (from an enclosing param_is option). */
907 write_gc_structure_fields (of
, s
, val
, prev_val
, opts
, indent
, line
, bitmap
,
912 const char *prev_val
;
915 struct fileloc
*line
;
922 if (! s
->u
.s
.line
.file
)
923 error_at_line (line
, "incomplete structure `%s'", s
->u
.s
.tag
);
924 else if ((s
->u
.s
.bitmap
& bitmap
) != bitmap
)
926 error_at_line (line
, "structure defined for mismatching languages");
927 error_at_line (&s
->u
.s
.line
, "one structure defined here");
930 if (s
->kind
== TYPE_UNION
)
932 const char *tagexpr
= NULL
;
935 tagcounter
= ++gc_counter
;
936 for (oo
= opts
; oo
; oo
= oo
->next
)
937 if (strcmp (oo
->name
, "desc") == 0)
938 tagexpr
= (const char *)oo
->info
;
942 error_at_line (line
, "missing `desc' option");
945 oprintf (of
, "%*s{\n", indent
, "");
947 oprintf (of
, "%*sunsigned int tag%d = (", indent
, "", tagcounter
);
948 output_escaped_param (of
, tagexpr
, val
, prev_val
, "desc", line
);
949 oprintf (of
, ");\n");
952 for (f
= s
->u
.s
.fields
; f
; f
= f
->next
)
954 const char *tagid
= NULL
;
955 const char *length
= NULL
;
956 const char *special
= NULL
;
959 int maybe_undef_p
= 0;
964 if (t
->kind
== TYPE_SCALAR
965 || (t
->kind
== TYPE_ARRAY
966 && t
->u
.a
.p
->kind
== TYPE_SCALAR
))
969 for (oo
= f
->opt
; oo
; oo
= oo
->next
)
970 if (strcmp (oo
->name
, "length") == 0)
971 length
= (const char *)oo
->info
;
972 else if (strcmp (oo
->name
, "maybe_undef") == 0)
974 else if (strcmp (oo
->name
, "tag") == 0)
975 tagid
= (const char *)oo
->info
;
976 else if (strcmp (oo
->name
, "special") == 0)
977 special
= (const char *)oo
->info
;
978 else if (strcmp (oo
->name
, "skip") == 0)
980 else if (strcmp (oo
->name
, "always") == 0)
982 else if (strcmp (oo
->name
, "desc") == 0 && UNION_P (t
))
984 else if (strcmp (oo
->name
, "descbits") == 0 && UNION_P (t
))
986 else if (strcmp (oo
->name
, "param_is") == 0)
988 else if (strcmp (oo
->name
, "use_param") == 0)
991 error_at_line (&f
->line
, "unknown field option `%s'\n", oo
->name
);
1004 for (t1
= t
; t
->kind
== TYPE_ARRAY
; t
= t
->u
.a
.p
)
1006 for (; t
->kind
== TYPE_POINTER
; t
= t
->u
.p
)
1007 nt
= create_pointer (nt
);
1008 while (arraycount
-- > 0)
1009 nt
= create_array (nt
, t
->u
.a
.len
);
1012 else if (s
->kind
== TYPE_UNION
&& ! always_p
&& tagid
)
1015 error_at_line (&f
->line
, "no parameter defined");
1019 && (t
->kind
!= TYPE_POINTER
1020 || t
->u
.p
->kind
!= TYPE_STRUCT
))
1021 error_at_line (&f
->line
,
1022 "field `%s' has invalid option `maybe_undef_p'\n",
1024 if (s
->kind
== TYPE_UNION
&& ! always_p
)
1028 error_at_line (&f
->line
, "field `%s' has no tag", f
->name
);
1031 oprintf (of
, "%*sif (tag%d == (%s)) {\n", indent
, "",
1039 /* Do nothing; strings go in the string pool. */
1042 case TYPE_LANG_STRUCT
:
1045 for (ti
= t
->u
.s
.lang_struct
; ti
; ti
= ti
->next
)
1046 if (ti
->u
.s
.bitmap
& bitmap
)
1053 error_at_line (&f
->line
,
1054 "structure not defined for this language");
1058 /* Fall through... */
1064 newval
= xasprintf ("%s.%s", val
, f
->name
);
1065 write_gc_structure_fields (of
, t
, newval
, val
, f
->opt
, indent
,
1066 &f
->line
, bitmap
, param
);
1075 && t
->u
.p
->u
.s
.line
.file
== NULL
)
1076 oprintf (of
, "%*sif (%s.%s) abort();\n", indent
, "",
1078 else if (UNION_OR_STRUCT_P (t
->u
.p
))
1079 oprintf (of
, "%*sgt_ggc_m_%s (%s.%s);\n", indent
, "",
1080 t
->u
.p
->u
.s
.tag
, val
, f
->name
);
1081 else if (t
->u
.p
->kind
== TYPE_PARAM_STRUCT
)
1082 oprintf (of
, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent
, "",
1083 (int) strlen (t
->u
.p
->u
.param_struct
.param
->u
.s
.tag
),
1084 t
->u
.p
->u
.param_struct
.param
->u
.s
.tag
,
1085 t
->u
.p
->u
.param_struct
.stru
->u
.s
.tag
,
1088 error_at_line (&f
->line
, "field `%s' is pointer to scalar",
1092 else if (t
->u
.p
->kind
== TYPE_SCALAR
1093 || t
->u
.p
->kind
== TYPE_STRING
)
1094 oprintf (of
, "%*sggc_mark (%s.%s);\n", indent
, "",
1098 int loopcounter
= ++gc_counter
;
1100 oprintf (of
, "%*sif (%s.%s != NULL) {\n", indent
, "",
1103 oprintf (of
, "%*ssize_t i%d;\n", indent
, "", loopcounter
);
1104 oprintf (of
, "%*sggc_set_mark (%s.%s);\n", indent
, "",
1106 oprintf (of
, "%*sfor (i%d = 0; i%d < (", indent
, "",
1107 loopcounter
, loopcounter
);
1108 output_escaped_param (of
, length
, val
, prev_val
, "length", line
);
1109 oprintf (of
, "); i%d++) {\n", loopcounter
);
1111 switch (t
->u
.p
->kind
)
1118 newval
= xasprintf ("%s.%s[i%d]", val
, f
->name
,
1120 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1121 f
->opt
, indent
, &f
->line
,
1127 if (UNION_OR_STRUCT_P (t
->u
.p
->u
.p
))
1128 oprintf (of
, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent
, "",
1129 t
->u
.p
->u
.p
->u
.s
.tag
, val
, f
->name
,
1132 error_at_line (&f
->line
,
1133 "field `%s' is array of pointer to scalar",
1137 error_at_line (&f
->line
,
1138 "field `%s' is array of unimplemented type",
1143 oprintf (of
, "%*s}\n", indent
, "");
1145 oprintf (of
, "%*s}\n", indent
, "");
1151 int loopcounter
= ++gc_counter
;
1156 (strcmp (t
->u
.a
.len
, "0") == 0
1157 || strcmp (t
->u
.a
.len
, "1") == 0))
1158 error_at_line (&f
->line
,
1159 "field `%s' is array of size %s",
1160 f
->name
, t
->u
.a
.len
);
1162 /* Arrays of scalars can be ignored. */
1163 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1165 if (ta
->kind
== TYPE_SCALAR
1166 || ta
->kind
== TYPE_STRING
)
1169 oprintf (of
, "%*s{\n", indent
, "");
1172 if (special
!= NULL
&& strcmp (special
, "tree_exp") == 0)
1174 oprintf (of
, "%*sconst size_t tree_exp_size = (",
1176 output_escaped_param (of
, length
, val
, prev_val
,
1178 oprintf (of
, ");\n");
1180 length
= "first_rtl_op (TREE_CODE ((tree)&%h))";
1183 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1185 oprintf (of
, "%*ssize_t i%d_%d;\n",
1186 indent
, "", loopcounter
, i
);
1187 oprintf (of
, "%*sconst size_t ilimit%d_%d = (",
1188 indent
, "", loopcounter
, i
);
1189 if (i
== 0 && length
!= NULL
)
1190 output_escaped_param (of
, length
, val
, prev_val
,
1193 oprintf (of
, "%s", ta
->u
.a
.len
);
1194 oprintf (of
, ");\n");
1197 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1200 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
1201 indent
, "", loopcounter
, i
, loopcounter
, i
,
1202 loopcounter
, i
, loopcounter
, i
);
1206 if (ta
->kind
== TYPE_POINTER
1207 && (ta
->u
.p
->kind
== TYPE_STRUCT
1208 || ta
->u
.p
->kind
== TYPE_UNION
))
1210 oprintf (of
, "%*sgt_ggc_m_%s (%s.%s",
1211 indent
, "", ta
->u
.p
->u
.s
.tag
, val
, f
->name
);
1213 ta
->kind
== TYPE_ARRAY
;
1214 ta
= ta
->u
.a
.p
, i
++)
1215 oprintf (of
, "[i%d_%d]", loopcounter
, i
);
1216 oprintf (of
, ");\n");
1218 else if (ta
->kind
== TYPE_STRUCT
|| ta
->kind
== TYPE_UNION
)
1223 len
= strlen (val
) + strlen (f
->name
) + 2;
1224 for (ta
= t
; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
)
1225 len
+= sizeof ("[i_]") + 2*6;
1227 newval
= xmalloc (len
);
1228 sprintf (newval
, "%s.%s", val
, f
->name
);
1230 ta
->kind
== TYPE_ARRAY
;
1231 ta
= ta
->u
.a
.p
, i
++)
1232 sprintf (newval
+ strlen (newval
), "[i%d_%d]",
1234 write_gc_structure_fields (of
, t
->u
.p
, newval
, val
,
1235 f
->opt
, indent
, &f
->line
, bitmap
,
1239 else if (ta
->kind
== TYPE_POINTER
&& ta
->u
.p
->kind
== TYPE_SCALAR
1240 && use_param_p
&& param
== NULL
)
1241 oprintf (of
, "%*sabort();\n", indent
, "");
1243 error_at_line (&f
->line
,
1244 "field `%s' is array of unimplemented type",
1246 for (ta
= t
, i
= 0; ta
->kind
== TYPE_ARRAY
; ta
= ta
->u
.a
.p
, i
++)
1249 oprintf (of
, "%*s}\n", indent
, "");
1252 if (special
!= NULL
&& strcmp (special
, "tree_exp") == 0)
1255 "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
1256 indent
, "", loopcounter
, loopcounter
);
1257 oprintf (of
, "%*s gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
1258 indent
, "", val
, f
->name
, loopcounter
);
1263 oprintf (of
, "%*s}\n", indent
, "");
1268 error_at_line (&f
->line
,
1269 "field `%s' is unimplemented type",
1274 if (s
->kind
== TYPE_UNION
&& ! always_p
)
1277 oprintf (of
, "%*s}\n", indent
, "");
1280 error_at_line (&f
->line
, "unhandled special `%s'", special
);
1282 if (s
->kind
== TYPE_UNION
)
1285 oprintf (of
, "%*s}\n", indent
, "");
1289 /* Write out a marker routine for S. PARAM is the parameter from an
1290 enclosing PARAM_IS option. */
1293 write_gc_marker_routine_for_structure (s
, param
)
1299 f
= get_output_file_with_visibility (s
->u
.s
.line
.file
);
1301 f
= get_output_file_with_visibility (param
->u
.s
.line
.file
);
1303 oprintf (f
, "%c", '\n');
1304 oprintf (f
, "void\n");
1306 oprintf (f
, "gt_ggc_mx_%s (x_p)\n", s
->u
.s
.tag
);
1308 oprintf (f
, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param
->u
.s
.tag
),
1309 param
->u
.s
.tag
, s
->u
.s
.tag
);
1310 oprintf (f
, " void *x_p;\n");
1312 oprintf (f
, " %s %s * const x = (%s %s *)x_p;\n",
1313 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1314 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1315 oprintf (f
, " if (! ggc_test_and_set_mark (x))\n");
1316 oprintf (f
, " return;\n");
1319 write_gc_structure_fields (f
, s
, "(*x)", "not valid postage",
1320 s
->u
.s
.opt
, 2, &s
->u
.s
.line
, s
->u
.s
.bitmap
,
1326 /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
1329 write_gc_types (structures
, param_structs
)
1331 type_p param_structs
;
1335 oprintf (header_file
, "\n/* GC marker procedures. */\n");
1336 for (s
= structures
; s
; s
= s
->next
)
1337 if (s
->gc_used
== GC_POINTED_TO
1338 || s
->gc_used
== GC_MAYBE_POINTED_TO
)
1342 if (s
->gc_used
== GC_MAYBE_POINTED_TO
1343 && s
->u
.s
.line
.file
== NULL
)
1346 oprintf (header_file
,
1347 "#define gt_ggc_m_%s(X) do { \\\n", s
->u
.s
.tag
);
1348 oprintf (header_file
,
1349 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s
->u
.s
.tag
);
1350 oprintf (header_file
,
1353 for (opt
= s
->u
.s
.opt
; opt
; opt
= opt
->next
)
1354 if (strcmp (opt
->name
, "ptr_alias") == 0)
1356 type_p t
= (type_p
) opt
->info
;
1357 if (t
->kind
== TYPE_STRUCT
1358 || t
->kind
== TYPE_UNION
1359 || t
->kind
== TYPE_LANG_STRUCT
)
1360 oprintf (header_file
,
1361 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
1362 s
->u
.s
.tag
, t
->u
.s
.tag
);
1364 error_at_line (&s
->u
.s
.line
,
1365 "structure alias is not a structure");
1371 /* Declare the marker procedure only once. */
1372 oprintf (header_file
,
1373 "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
1376 if (s
->u
.s
.line
.file
== NULL
)
1378 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
1383 if (s
->kind
== TYPE_LANG_STRUCT
)
1386 for (ss
= s
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
1387 write_gc_marker_routine_for_structure (ss
, NULL
);
1390 write_gc_marker_routine_for_structure (s
, NULL
);
1393 for (s
= param_structs
; s
; s
= s
->next
)
1394 if (s
->gc_used
== GC_POINTED_TO
)
1396 type_p param
= s
->u
.param_struct
.param
;
1397 type_p stru
= s
->u
.param_struct
.stru
;
1399 if (param
->kind
!= TYPE_STRUCT
&& param
->kind
!= TYPE_UNION
1400 && param
->kind
!= TYPE_LANG_STRUCT
)
1402 error_at_line (&s
->u
.param_struct
.line
,
1403 "unsupported parameter type");
1407 /* Declare the marker procedure. */
1408 oprintf (header_file
,
1409 "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
1410 (int) strlen (param
->u
.s
.tag
), param
->u
.s
.tag
,
1413 if (stru
->u
.s
.line
.file
== NULL
)
1415 fprintf (stderr
, "warning: structure `%s' used but not defined\n",
1420 if (stru
->kind
== TYPE_LANG_STRUCT
)
1423 for (ss
= stru
->u
.s
.lang_struct
; ss
; ss
= ss
->next
)
1424 write_gc_marker_routine_for_structure (ss
, param
);
1427 write_gc_marker_routine_for_structure (stru
, param
);
1431 /* Mangle FN and print it to F. */
1434 put_mangled_filename (f
, fn
)
1438 const char *name
= get_output_file_name (fn
);
1439 for (; *name
!= 0; name
++)
1440 if (ISALNUM (*name
))
1441 oprintf (f
, "%c", *name
);
1443 oprintf (f
, "%c", '_');
1446 /* Finish off the currently-created root tables in FLP. PFX, TNAME,
1447 LASTNAME, and NAME are all strings to insert in various places in
1448 the resulting code. */
1451 finish_root_table (flp
, pfx
, lastname
, tname
, name
)
1455 const char *lastname
;
1459 unsigned started_bitmap
= 0;
1461 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1462 if (fli2
->started_p
)
1464 oprintf (fli2
->f
, " %s\n", lastname
);
1465 oprintf (fli2
->f
, "};\n\n");
1468 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1469 if (fli2
->started_p
)
1471 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
1474 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1477 oprintf (base_files
[fnum
],
1478 "extern const struct %s gt_ggc_%s_",
1480 put_mangled_filename (base_files
[fnum
], fli2
->name
);
1481 oprintf (base_files
[fnum
], "[];\n");
1485 for (fli2
= flp
; fli2
; fli2
= fli2
->next
)
1486 if (fli2
->started_p
)
1488 lang_bitmap bitmap
= get_base_file_bitmap (fli2
->name
);
1491 fli2
->started_p
= 0;
1493 for (fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1496 if (! (started_bitmap
& (1 << fnum
)))
1498 oprintf (base_files
[fnum
],
1499 "const struct %s * const %s[] = {\n",
1501 started_bitmap
|= 1 << fnum
;
1503 oprintf (base_files
[fnum
], " gt_ggc_%s_", pfx
);
1504 put_mangled_filename (base_files
[fnum
], fli2
->name
);
1505 oprintf (base_files
[fnum
], ",\n");
1513 for (bitmap
= started_bitmap
, fnum
= 0; bitmap
!= 0; fnum
++, bitmap
>>= 1)
1516 oprintf (base_files
[fnum
], " NULL\n");
1517 oprintf (base_files
[fnum
], "};\n\n");
1522 /* Write out to F the table entry and any marker routines needed to
1523 mark NAME as TYPE. The original variable is V, at LINE.
1524 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED
1525 is nonzero iff we are building the root table for hash table caches. */
1528 write_gc_root (f
, v
, type
, name
, has_length
, line
, if_marked
)
1534 struct fileloc
*line
;
1535 const char *if_marked
;
1542 for (fld
= type
->u
.s
.fields
; fld
; fld
= fld
->next
)
1545 const char *desc
= NULL
;
1548 for (o
= fld
->opt
; o
; o
= o
->next
)
1549 if (strcmp (o
->name
, "skip") == 0)
1551 else if (strcmp (o
->name
, "desc") == 0)
1552 desc
= (const char *)o
->info
;
1554 error_at_line (line
,
1555 "field `%s' of global `%s' has unknown option `%s'",
1556 fld
->name
, name
, o
->name
);
1560 else if (desc
&& fld
->type
->kind
== TYPE_UNION
)
1562 pair_p validf
= NULL
;
1565 for (ufld
= fld
->type
->u
.s
.fields
; ufld
; ufld
= ufld
->next
)
1567 const char *tag
= NULL
;
1570 for (oo
= ufld
->opt
; oo
; oo
= oo
->next
)
1571 if (strcmp (oo
->name
, "tag") == 0)
1572 tag
= (const char *)oo
->info
;
1573 if (tag
== NULL
|| strcmp (tag
, desc
) != 0)
1576 error_at_line (line
,
1577 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
1578 name
, fld
->name
, validf
->name
,
1579 name
, fld
->name
, ufld
->name
,
1586 newname
= xasprintf ("%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
= xasprintf ("%s.%s", name
, fld
->name
);
1601 write_gc_root (f
, v
, fld
->type
, newname
, 0, line
, if_marked
);
1611 newname
= xasprintf ("%s[0]", name
);
1612 write_gc_root (f
, v
, type
->u
.a
.p
, newname
, has_length
, line
, if_marked
);
1621 oprintf (f
, " {\n");
1622 oprintf (f
, " &%s,\n", name
);
1625 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
1627 oprintf (f
, " * (%s)", ap
->u
.a
.len
);
1628 else if (ap
== v
->type
)
1629 oprintf (f
, " * ARRAY_SIZE (%s)", v
->name
);
1631 oprintf (f
, " sizeof (%s", v
->name
);
1632 for (ap
= v
->type
; ap
->kind
== TYPE_ARRAY
; ap
= ap
->u
.a
.p
)
1634 oprintf (f
, "),\n");
1638 if (! has_length
&& UNION_OR_STRUCT_P (tp
))
1640 oprintf (f
, " >_ggc_mx_%s\n", tp
->u
.s
.tag
);
1642 else if (! has_length
&& tp
->kind
== TYPE_PARAM_STRUCT
)
1644 oprintf (f
, " >_ggc_mm_%d%s_%s",
1645 (int) strlen (tp
->u
.param_struct
.param
->u
.s
.tag
),
1646 tp
->u
.param_struct
.param
->u
.s
.tag
,
1647 tp
->u
.param_struct
.stru
->u
.s
.tag
);
1650 && (tp
->kind
== TYPE_POINTER
|| UNION_OR_STRUCT_P (tp
)))
1652 oprintf (f
, " >_ggc_ma_%s", name
);
1656 error_at_line (line
,
1657 "global `%s' is pointer to unimplemented type",
1661 oprintf (f
, ",\n &%s", if_marked
);
1662 oprintf (f
, "\n },\n");
1671 error_at_line (line
,
1672 "global `%s' is unimplemented type",
1677 /* Output a table describing the locations and types of VARIABLES. */
1680 write_gc_roots (variables
)
1684 struct flist
*flp
= NULL
;
1686 for (v
= variables
; v
; v
= v
->next
)
1688 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
1690 const char *length
= NULL
;
1691 int deletable_p
= 0;
1694 for (o
= v
->opt
; o
; o
= o
->next
)
1695 if (strcmp (o
->name
, "length") == 0)
1696 length
= (const char *)o
->info
;
1697 else if (strcmp (o
->name
, "deletable") == 0)
1699 else if (strcmp (o
->name
, "param_is") == 0)
1701 else if (strcmp (o
->name
, "if_marked") == 0)
1704 error_at_line (&v
->line
,
1705 "global `%s' has unknown option `%s'",
1708 for (fli
= flp
; fli
; fli
= fli
->next
)
1713 fli
= xmalloc (sizeof (*fli
));
1717 fli
->name
= v
->line
.file
;
1720 oprintf (f
, "\n/* GC roots. */\n\n");
1725 && v
->type
->kind
== TYPE_POINTER
1726 && (v
->type
->u
.p
->kind
== TYPE_POINTER
1727 || v
->type
->u
.p
->kind
== TYPE_STRUCT
))
1729 oprintf (f
, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
1731 oprintf (f
, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
1734 oprintf (f
, " size_t i;\n");
1736 if (v
->type
->u
.p
->kind
== TYPE_POINTER
)
1738 type_p s
= v
->type
->u
.p
->u
.p
;
1740 oprintf (f
, " %s %s ** const x = (%s %s **)x_p;\n",
1741 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1742 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1743 oprintf (f
, " if (ggc_test_and_set_mark (x))\n");
1744 oprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
1745 if (s
->kind
!= TYPE_STRUCT
&& s
->kind
!= TYPE_UNION
)
1747 error_at_line (&v
->line
,
1748 "global `%s' has unsupported ** type",
1753 oprintf (f
, " gt_ggc_m_%s (x[i]);\n", s
->u
.s
.tag
);
1757 type_p s
= v
->type
->u
.p
;
1759 oprintf (f
, " %s %s * const x = (%s %s *)x_p;\n",
1760 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
,
1761 s
->kind
== TYPE_UNION
? "union" : "struct", s
->u
.s
.tag
);
1762 oprintf (f
, " if (ggc_test_and_set_mark (x))\n");
1763 oprintf (f
, " for (i = 0; i < (%s); i++)\n", length
);
1764 oprintf (f
, " {\n");
1765 write_gc_structure_fields (f
, s
, "x[i]", "x[i]",
1766 v
->opt
, 8, &v
->line
, s
->u
.s
.bitmap
,
1768 oprintf (f
, " }\n");
1771 oprintf (f
, "}\n\n");
1775 for (v
= variables
; v
; v
= v
->next
)
1777 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
1783 for (o
= v
->opt
; o
; o
= o
->next
)
1784 if (strcmp (o
->name
, "length") == 0)
1786 else if (strcmp (o
->name
, "deletable") == 0
1787 || strcmp (o
->name
, "if_marked") == 0)
1793 for (fli
= flp
; fli
; fli
= fli
->next
)
1796 if (! fli
->started_p
)
1800 oprintf (f
, "const struct ggc_root_tab gt_ggc_r_");
1801 put_mangled_filename (f
, v
->line
.file
);
1802 oprintf (f
, "[] = {\n");
1805 write_gc_root (f
, v
, v
->type
, v
->name
, length_p
, &v
->line
, NULL
);
1808 finish_root_table (flp
, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1811 for (v
= variables
; v
; v
= v
->next
)
1813 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
1818 for (o
= v
->opt
; o
; o
= o
->next
)
1819 if (strcmp (o
->name
, "deletable") == 0)
1821 else if (strcmp (o
->name
, "if_marked") == 0)
1827 for (fli
= flp
; fli
; fli
= fli
->next
)
1830 if (! fli
->started_p
)
1834 oprintf (f
, "const struct ggc_root_tab gt_ggc_rd_");
1835 put_mangled_filename (f
, v
->line
.file
);
1836 oprintf (f
, "[] = {\n");
1839 oprintf (f
, " { &%s, 1, sizeof (%s), NULL },\n",
1843 finish_root_table (flp
, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
1844 "gt_ggc_deletable_rtab");
1846 for (v
= variables
; v
; v
= v
->next
)
1848 outf_p f
= get_output_file_with_visibility (v
->line
.file
);
1850 const char *if_marked
= NULL
;
1854 for (o
= v
->opt
; o
; o
= o
->next
)
1855 if (strcmp (o
->name
, "length") == 0)
1857 else if (strcmp (o
->name
, "if_marked") == 0)
1858 if_marked
= (const char *) o
->info
;
1860 if (if_marked
== NULL
)
1863 if (v
->type
->kind
!= TYPE_POINTER
1864 || v
->type
->u
.p
->kind
!= TYPE_PARAM_STRUCT
1865 || v
->type
->u
.p
->u
.param_struct
.stru
!= find_structure ("htab", 0))
1867 error_at_line (&v
->line
, "if_marked option used but not hash table");
1871 for (fli
= flp
; fli
; fli
= fli
->next
)
1874 if (! fli
->started_p
)
1878 oprintf (f
, "const struct ggc_cache_tab gt_ggc_rc_");
1879 put_mangled_filename (f
, v
->line
.file
);
1880 oprintf (f
, "[] = {\n");
1883 write_gc_root (f
, v
, create_pointer (v
->type
->u
.p
->u
.param_struct
.param
),
1884 v
->name
, length_p
, &v
->line
, if_marked
);
1887 finish_root_table (flp
, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
1888 "gt_ggc_cache_rtab");
1892 extern int main
PARAMS ((int argc
, char **argv
));
1899 static struct fileloc pos
= { __FILE__
, __LINE__
};
1901 do_typedef ("CUMULATIVE_ARGS",
1902 create_scalar_type ("CUMULATIVE_ARGS",
1903 strlen ("CUMULATIVE_ARGS")),
1905 do_typedef ("REAL_VALUE_TYPE",
1906 create_scalar_type ("REAL_VALUE_TYPE",
1907 strlen ("REAL_VALUE_TYPE")),
1909 do_typedef ("PTR", create_pointer (create_scalar_type ("void",
1913 for (i
= 1; i
< argc
; i
++)
1914 parse_file (argv
[i
]);
1919 set_gc_used (variables
);
1922 write_gc_types (structures
, param_structs
);
1923 write_gc_roots (variables
);
1924 close_output_files ();
1926 return (hit_error
!= 0);